ActivityManagerService.java revision 36927a3600520686495cba4f3fc19e1445f8a64c
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199 200import java.io.BufferedInputStream; 201import java.io.BufferedOutputStream; 202import java.io.DataInputStream; 203import java.io.DataOutputStream; 204import java.io.File; 205import java.io.FileDescriptor; 206import java.io.FileInputStream; 207import java.io.FileNotFoundException; 208import java.io.FileOutputStream; 209import java.io.IOException; 210import java.io.InputStreamReader; 211import java.io.PrintWriter; 212import java.io.StringWriter; 213import java.lang.ref.WeakReference; 214import java.util.ArrayList; 215import java.util.Arrays; 216import java.util.Collections; 217import java.util.Comparator; 218import java.util.HashMap; 219import java.util.HashSet; 220import java.util.Iterator; 221import java.util.List; 222import java.util.Locale; 223import java.util.Map; 224import java.util.Set; 225import java.util.concurrent.atomic.AtomicBoolean; 226import java.util.concurrent.atomic.AtomicLong; 227 228public final class ActivityManagerService extends ActivityManagerNative 229 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 230 231 private static final String USER_DATA_DIR = "/data/user/"; 232 // File that stores last updated system version and called preboot receivers 233 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 234 235 static final String TAG = "ActivityManager"; 236 static final String TAG_MU = "ActivityManagerServiceMU"; 237 static final boolean DEBUG = false; 238 static final boolean localLOGV = DEBUG; 239 static final boolean DEBUG_BACKUP = localLOGV || false; 240 static final boolean DEBUG_BROADCAST = localLOGV || false; 241 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 242 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_CLEANUP = localLOGV || false; 244 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 245 static final boolean DEBUG_FOCUS = false; 246 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 247 static final boolean DEBUG_MU = localLOGV || false; 248 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 249 static final boolean DEBUG_LRU = localLOGV || false; 250 static final boolean DEBUG_PAUSE = localLOGV || false; 251 static final boolean DEBUG_POWER = localLOGV || false; 252 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 253 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 254 static final boolean DEBUG_PROCESSES = localLOGV || false; 255 static final boolean DEBUG_PROVIDER = localLOGV || false; 256 static final boolean DEBUG_RESULTS = localLOGV || false; 257 static final boolean DEBUG_SERVICE = localLOGV || false; 258 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 259 static final boolean DEBUG_STACK = localLOGV || false; 260 static final boolean DEBUG_SWITCH = localLOGV || false; 261 static final boolean DEBUG_TASKS = localLOGV || false; 262 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 263 static final boolean DEBUG_TRANSITION = localLOGV || false; 264 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 265 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 266 static final boolean DEBUG_VISBILITY = localLOGV || false; 267 static final boolean DEBUG_PSS = localLOGV || false; 268 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 269 static final boolean DEBUG_RECENTS = localLOGV || false; 270 static final boolean VALIDATE_TOKENS = false; 271 static final boolean SHOW_ACTIVITY_START_TIME = true; 272 273 // Control over CPU and battery monitoring. 274 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 275 static final boolean MONITOR_CPU_USAGE = true; 276 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 277 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 278 static final boolean MONITOR_THREAD_CPU_USAGE = false; 279 280 // The flags that are set for all calls we make to the package manager. 281 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 282 283 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 284 285 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 286 287 // Maximum number recent bitmaps to keep in memory. 288 static final int MAX_RECENT_BITMAPS = 5; 289 290 // Amount of time after a call to stopAppSwitches() during which we will 291 // prevent further untrusted switches from happening. 292 static final long APP_SWITCH_DELAY_TIME = 5*1000; 293 294 // How long we wait for a launched process to attach to the activity manager 295 // before we decide it's never going to come up for real. 296 static final int PROC_START_TIMEOUT = 10*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real, when the process was 300 // started with a wrapper for instrumentation (such as Valgrind) because it 301 // could take much longer than usual. 302 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 303 304 // How long to wait after going idle before forcing apps to GC. 305 static final int GC_TIMEOUT = 5*1000; 306 307 // The minimum amount of time between successive GC requests for a process. 308 static final int GC_MIN_INTERVAL = 60*1000; 309 310 // The minimum amount of time between successive PSS requests for a process. 311 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 312 313 // The minimum amount of time between successive PSS requests for a process 314 // when the request is due to the memory state being lowered. 315 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 316 317 // The rate at which we check for apps using excessive power -- 15 mins. 318 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 319 320 // The minimum sample duration we will allow before deciding we have 321 // enough data on wake locks to start killing things. 322 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on CPU usage to start killing things. 326 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // How long we allow a receiver to run before giving up on it. 329 static final int BROADCAST_FG_TIMEOUT = 10*1000; 330 static final int BROADCAST_BG_TIMEOUT = 60*1000; 331 332 // How long we wait until we timeout on key dispatching. 333 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 334 335 // How long we wait until we timeout on key dispatching during instrumentation. 336 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 337 338 // Amount of time we wait for observers to handle a user switch before 339 // giving up on them and unfreezing the screen. 340 static final int USER_SWITCH_TIMEOUT = 2*1000; 341 342 // Maximum number of users we allow to be running at a time. 343 static final int MAX_RUNNING_USERS = 3; 344 345 // How long to wait in getAssistContextExtras for the activity and foreground services 346 // to respond with the result. 347 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 348 349 // Maximum number of persisted Uri grants a package is allowed 350 static final int MAX_PERSISTED_URI_GRANTS = 128; 351 352 static final int MY_PID = Process.myPid(); 353 354 static final String[] EMPTY_STRING_ARRAY = new String[0]; 355 356 // How many bytes to write into the dropbox log before truncating 357 static final int DROPBOX_MAX_SIZE = 256 * 1024; 358 359 // Access modes for handleIncomingUser. 360 static final int ALLOW_NON_FULL = 0; 361 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 362 static final int ALLOW_FULL_ONLY = 2; 363 364 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 365 366 /** All system services */ 367 SystemServiceManager mSystemServiceManager; 368 369 /** Run all ActivityStacks through this */ 370 ActivityStackSupervisor mStackSupervisor; 371 372 public IntentFirewall mIntentFirewall; 373 374 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 375 // default actuion automatically. Important for devices without direct input 376 // devices. 377 private boolean mShowDialogs = true; 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 415 416 /** 417 * For addAppTask: cached of the last activity component that was added. 418 */ 419 ComponentName mLastAddedTaskComponent; 420 421 /** 422 * For addAppTask: cached of the last activity uid that was added. 423 */ 424 int mLastAddedTaskUid; 425 426 /** 427 * For addAppTask: cached of the last ActivityInfo that was added. 428 */ 429 ActivityInfo mLastAddedTaskActivity; 430 431 public class PendingAssistExtras extends Binder implements Runnable { 432 public final ActivityRecord activity; 433 public boolean haveResult = false; 434 public Bundle result = null; 435 public PendingAssistExtras(ActivityRecord _activity) { 436 activity = _activity; 437 } 438 @Override 439 public void run() { 440 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 441 synchronized (this) { 442 haveResult = true; 443 notifyAll(); 444 } 445 } 446 } 447 448 final ArrayList<PendingAssistExtras> mPendingAssistExtras 449 = new ArrayList<PendingAssistExtras>(); 450 451 /** 452 * Process management. 453 */ 454 final ProcessList mProcessList = new ProcessList(); 455 456 /** 457 * All of the applications we currently have running organized by name. 458 * The keys are strings of the application package name (as 459 * returned by the package manager), and the keys are ApplicationRecord 460 * objects. 461 */ 462 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 463 464 /** 465 * Tracking long-term execution of processes to look for abuse and other 466 * bad app behavior. 467 */ 468 final ProcessStatsService mProcessStats; 469 470 /** 471 * The currently running isolated processes. 472 */ 473 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 474 475 /** 476 * Counter for assigning isolated process uids, to avoid frequently reusing the 477 * same ones. 478 */ 479 int mNextIsolatedProcessUid = 0; 480 481 /** 482 * The currently running heavy-weight process, if any. 483 */ 484 ProcessRecord mHeavyWeightProcess = null; 485 486 /** 487 * The last time that various processes have crashed. 488 */ 489 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 490 491 /** 492 * Information about a process that is currently marked as bad. 493 */ 494 static final class BadProcessInfo { 495 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 496 this.time = time; 497 this.shortMsg = shortMsg; 498 this.longMsg = longMsg; 499 this.stack = stack; 500 } 501 502 final long time; 503 final String shortMsg; 504 final String longMsg; 505 final String stack; 506 } 507 508 /** 509 * Set of applications that we consider to be bad, and will reject 510 * incoming broadcasts from (which the user has no control over). 511 * Processes are added to this set when they have crashed twice within 512 * a minimum amount of time; they are removed from it when they are 513 * later restarted (hopefully due to some user action). The value is the 514 * time it was added to the list. 515 */ 516 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 517 518 /** 519 * All of the processes we currently have running organized by pid. 520 * The keys are the pid running the application. 521 * 522 * <p>NOTE: This object is protected by its own lock, NOT the global 523 * activity manager lock! 524 */ 525 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 526 527 /** 528 * All of the processes that have been forced to be foreground. The key 529 * is the pid of the caller who requested it (we hold a death 530 * link on it). 531 */ 532 abstract class ForegroundToken implements IBinder.DeathRecipient { 533 int pid; 534 IBinder token; 535 } 536 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 537 538 /** 539 * List of records for processes that someone had tried to start before the 540 * system was ready. We don't start them at that point, but ensure they 541 * are started by the time booting is complete. 542 */ 543 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 544 545 /** 546 * List of persistent applications that are in the process 547 * of being started. 548 */ 549 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes that are being forcibly torn down. 553 */ 554 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * List of running applications, sorted by recent usage. 558 * The first entry in the list is the least recently used. 559 */ 560 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Where in mLruProcesses that the processes hosting activities start. 564 */ 565 int mLruProcessActivityStart = 0; 566 567 /** 568 * Where in mLruProcesses that the processes hosting services start. 569 * This is after (lower index) than mLruProcessesActivityStart. 570 */ 571 int mLruProcessServiceStart = 0; 572 573 /** 574 * List of processes that should gc as soon as things are idle. 575 */ 576 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes we want to collect PSS data from. 580 */ 581 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * Last time we requested PSS data of all processes. 585 */ 586 long mLastFullPssTime = SystemClock.uptimeMillis(); 587 588 /** 589 * If set, the next time we collect PSS data we should do a full collection 590 * with data from native processes and the kernel. 591 */ 592 boolean mFullPssPending = false; 593 594 /** 595 * This is the process holding what we currently consider to be 596 * the "home" activity. 597 */ 598 ProcessRecord mHomeProcess; 599 600 /** 601 * This is the process holding the activity the user last visited that 602 * is in a different process from the one they are currently in. 603 */ 604 ProcessRecord mPreviousProcess; 605 606 /** 607 * The time at which the previous process was last visible. 608 */ 609 long mPreviousProcessVisibleTime; 610 611 /** 612 * Which uses have been started, so are allowed to run code. 613 */ 614 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 615 616 /** 617 * LRU list of history of current users. Most recently current is at the end. 618 */ 619 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 620 621 /** 622 * Constant array of the users that are currently started. 623 */ 624 int[] mStartedUserArray = new int[] { 0 }; 625 626 /** 627 * Registered observers of the user switching mechanics. 628 */ 629 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 630 = new RemoteCallbackList<IUserSwitchObserver>(); 631 632 /** 633 * Currently active user switch. 634 */ 635 Object mCurUserSwitchCallback; 636 637 /** 638 * Packages that the user has asked to have run in screen size 639 * compatibility mode instead of filling the screen. 640 */ 641 final CompatModePackages mCompatModePackages; 642 643 /** 644 * Set of IntentSenderRecord objects that are currently active. 645 */ 646 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 647 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 648 649 /** 650 * Fingerprints (hashCode()) of stack traces that we've 651 * already logged DropBox entries for. Guarded by itself. If 652 * something (rogue user app) forces this over 653 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 654 */ 655 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 656 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 657 658 /** 659 * Strict Mode background batched logging state. 660 * 661 * The string buffer is guarded by itself, and its lock is also 662 * used to determine if another batched write is already 663 * in-flight. 664 */ 665 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 666 667 /** 668 * Keeps track of all IIntentReceivers that have been registered for 669 * broadcasts. Hash keys are the receiver IBinder, hash value is 670 * a ReceiverList. 671 */ 672 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 673 new HashMap<IBinder, ReceiverList>(); 674 675 /** 676 * Resolver for broadcast intents to registered receivers. 677 * Holds BroadcastFilter (subclass of IntentFilter). 678 */ 679 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 680 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 681 @Override 682 protected boolean allowFilterResult( 683 BroadcastFilter filter, List<BroadcastFilter> dest) { 684 IBinder target = filter.receiverList.receiver.asBinder(); 685 for (int i=dest.size()-1; i>=0; i--) { 686 if (dest.get(i).receiverList.receiver.asBinder() == target) { 687 return false; 688 } 689 } 690 return true; 691 } 692 693 @Override 694 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 695 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 696 || userId == filter.owningUserId) { 697 return super.newResult(filter, match, userId); 698 } 699 return null; 700 } 701 702 @Override 703 protected BroadcastFilter[] newArray(int size) { 704 return new BroadcastFilter[size]; 705 } 706 707 @Override 708 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 709 return packageName.equals(filter.packageName); 710 } 711 }; 712 713 /** 714 * State of all active sticky broadcasts per user. Keys are the action of the 715 * sticky Intent, values are an ArrayList of all broadcasted intents with 716 * that action (which should usually be one). The SparseArray is keyed 717 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 718 * for stickies that are sent to all users. 719 */ 720 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 721 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 722 723 final ActiveServices mServices; 724 725 /** 726 * Backup/restore process management 727 */ 728 String mBackupAppName = null; 729 BackupRecord mBackupTarget = null; 730 731 final ProviderMap mProviderMap; 732 733 /** 734 * List of content providers who have clients waiting for them. The 735 * application is currently being launched and the provider will be 736 * removed from this list once it is published. 737 */ 738 final ArrayList<ContentProviderRecord> mLaunchingProviders 739 = new ArrayList<ContentProviderRecord>(); 740 741 /** 742 * File storing persisted {@link #mGrantedUriPermissions}. 743 */ 744 private final AtomicFile mGrantFile; 745 746 /** XML constants used in {@link #mGrantFile} */ 747 private static final String TAG_URI_GRANTS = "uri-grants"; 748 private static final String TAG_URI_GRANT = "uri-grant"; 749 private static final String ATTR_USER_HANDLE = "userHandle"; 750 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 751 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 752 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 753 private static final String ATTR_TARGET_PKG = "targetPkg"; 754 private static final String ATTR_URI = "uri"; 755 private static final String ATTR_MODE_FLAGS = "modeFlags"; 756 private static final String ATTR_CREATED_TIME = "createdTime"; 757 private static final String ATTR_PREFIX = "prefix"; 758 759 /** 760 * Global set of specific {@link Uri} permissions that have been granted. 761 * This optimized lookup structure maps from {@link UriPermission#targetUid} 762 * to {@link UriPermission#uri} to {@link UriPermission}. 763 */ 764 @GuardedBy("this") 765 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 766 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 767 768 public static class GrantUri { 769 public final int sourceUserId; 770 public final Uri uri; 771 public boolean prefix; 772 773 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 774 this.sourceUserId = sourceUserId; 775 this.uri = uri; 776 this.prefix = prefix; 777 } 778 779 @Override 780 public int hashCode() { 781 return toString().hashCode(); 782 } 783 784 @Override 785 public boolean equals(Object o) { 786 if (o instanceof GrantUri) { 787 GrantUri other = (GrantUri) o; 788 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 789 && prefix == other.prefix; 790 } 791 return false; 792 } 793 794 @Override 795 public String toString() { 796 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 797 if (prefix) result += " [prefix]"; 798 return result; 799 } 800 801 public String toSafeString() { 802 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 803 if (prefix) result += " [prefix]"; 804 return result; 805 } 806 807 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 808 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 809 ContentProvider.getUriWithoutUserId(uri), false); 810 } 811 } 812 813 CoreSettingsObserver mCoreSettingsObserver; 814 815 /** 816 * Thread-local storage used to carry caller permissions over through 817 * indirect content-provider access. 818 */ 819 private class Identity { 820 public int pid; 821 public int uid; 822 823 Identity(int _pid, int _uid) { 824 pid = _pid; 825 uid = _uid; 826 } 827 } 828 829 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 830 831 /** 832 * All information we have collected about the runtime performance of 833 * any user id that can impact battery performance. 834 */ 835 final BatteryStatsService mBatteryStatsService; 836 837 /** 838 * Information about component usage 839 */ 840 UsageStatsManagerInternal mUsageStatsService; 841 842 /** 843 * Information about and control over application operations 844 */ 845 final AppOpsService mAppOpsService; 846 847 /** 848 * Save recent tasks information across reboots. 849 */ 850 final TaskPersister mTaskPersister; 851 852 /** 853 * Current configuration information. HistoryRecord objects are given 854 * a reference to this object to indicate which configuration they are 855 * currently running in, so this object must be kept immutable. 856 */ 857 Configuration mConfiguration = new Configuration(); 858 859 /** 860 * Current sequencing integer of the configuration, for skipping old 861 * configurations. 862 */ 863 int mConfigurationSeq = 0; 864 865 /** 866 * Hardware-reported OpenGLES version. 867 */ 868 final int GL_ES_VERSION; 869 870 /** 871 * List of initialization arguments to pass to all processes when binding applications to them. 872 * For example, references to the commonly used services. 873 */ 874 HashMap<String, IBinder> mAppBindArgs; 875 876 /** 877 * Temporary to avoid allocations. Protected by main lock. 878 */ 879 final StringBuilder mStringBuilder = new StringBuilder(256); 880 881 /** 882 * Used to control how we initialize the service. 883 */ 884 ComponentName mTopComponent; 885 String mTopAction = Intent.ACTION_MAIN; 886 String mTopData; 887 boolean mProcessesReady = false; 888 boolean mSystemReady = false; 889 boolean mBooting = false; 890 boolean mWaitingUpdate = false; 891 boolean mDidUpdate = false; 892 boolean mOnBattery = false; 893 boolean mLaunchWarningShown = false; 894 895 Context mContext; 896 897 int mFactoryTest; 898 899 boolean mCheckedForSetup; 900 901 /** 902 * The time at which we will allow normal application switches again, 903 * after a call to {@link #stopAppSwitches()}. 904 */ 905 long mAppSwitchesAllowedTime; 906 907 /** 908 * This is set to true after the first switch after mAppSwitchesAllowedTime 909 * is set; any switches after that will clear the time. 910 */ 911 boolean mDidAppSwitch; 912 913 /** 914 * Last time (in realtime) at which we checked for power usage. 915 */ 916 long mLastPowerCheckRealtime; 917 918 /** 919 * Last time (in uptime) at which we checked for power usage. 920 */ 921 long mLastPowerCheckUptime; 922 923 /** 924 * Set while we are wanting to sleep, to prevent any 925 * activities from being started/resumed. 926 */ 927 private boolean mSleeping = false; 928 929 /** 930 * Set while we are running a voice interaction. This overrides 931 * sleeping while it is active. 932 */ 933 private boolean mRunningVoice = false; 934 935 /** 936 * State of external calls telling us if the device is asleep. 937 */ 938 private boolean mWentToSleep = false; 939 940 /** 941 * State of external call telling us if the lock screen is shown. 942 */ 943 private boolean mLockScreenShown = false; 944 945 /** 946 * Set if we are shutting down the system, similar to sleeping. 947 */ 948 boolean mShuttingDown = false; 949 950 /** 951 * Current sequence id for oom_adj computation traversal. 952 */ 953 int mAdjSeq = 0; 954 955 /** 956 * Current sequence id for process LRU updating. 957 */ 958 int mLruSeq = 0; 959 960 /** 961 * Keep track of the non-cached/empty process we last found, to help 962 * determine how to distribute cached/empty processes next time. 963 */ 964 int mNumNonCachedProcs = 0; 965 966 /** 967 * Keep track of the number of cached hidden procs, to balance oom adj 968 * distribution between those and empty procs. 969 */ 970 int mNumCachedHiddenProcs = 0; 971 972 /** 973 * Keep track of the number of service processes we last found, to 974 * determine on the next iteration which should be B services. 975 */ 976 int mNumServiceProcs = 0; 977 int mNewNumAServiceProcs = 0; 978 int mNewNumServiceProcs = 0; 979 980 /** 981 * Allow the current computed overall memory level of the system to go down? 982 * This is set to false when we are killing processes for reasons other than 983 * memory management, so that the now smaller process list will not be taken as 984 * an indication that memory is tighter. 985 */ 986 boolean mAllowLowerMemLevel = false; 987 988 /** 989 * The last computed memory level, for holding when we are in a state that 990 * processes are going away for other reasons. 991 */ 992 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 993 994 /** 995 * The last total number of process we have, to determine if changes actually look 996 * like a shrinking number of process due to lower RAM. 997 */ 998 int mLastNumProcesses; 999 1000 /** 1001 * The uptime of the last time we performed idle maintenance. 1002 */ 1003 long mLastIdleTime = SystemClock.uptimeMillis(); 1004 1005 /** 1006 * Total time spent with RAM that has been added in the past since the last idle time. 1007 */ 1008 long mLowRamTimeSinceLastIdle = 0; 1009 1010 /** 1011 * If RAM is currently low, when that horrible situation started. 1012 */ 1013 long mLowRamStartTime = 0; 1014 1015 /** 1016 * For reporting to battery stats the current top application. 1017 */ 1018 private String mCurResumedPackage = null; 1019 private int mCurResumedUid = -1; 1020 1021 /** 1022 * For reporting to battery stats the apps currently running foreground 1023 * service. The ProcessMap is package/uid tuples; each of these contain 1024 * an array of the currently foreground processes. 1025 */ 1026 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1027 = new ProcessMap<ArrayList<ProcessRecord>>(); 1028 1029 /** 1030 * This is set if we had to do a delayed dexopt of an app before launching 1031 * it, to increase the ANR timeouts in that case. 1032 */ 1033 boolean mDidDexOpt; 1034 1035 /** 1036 * Set if the systemServer made a call to enterSafeMode. 1037 */ 1038 boolean mSafeMode; 1039 1040 String mDebugApp = null; 1041 boolean mWaitForDebugger = false; 1042 boolean mDebugTransient = false; 1043 String mOrigDebugApp = null; 1044 boolean mOrigWaitForDebugger = false; 1045 boolean mAlwaysFinishActivities = false; 1046 IActivityController mController = null; 1047 String mProfileApp = null; 1048 ProcessRecord mProfileProc = null; 1049 String mProfileFile; 1050 ParcelFileDescriptor mProfileFd; 1051 int mSamplingInterval = 0; 1052 boolean mAutoStopProfiler = false; 1053 int mProfileType = 0; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 int mCurrentUserId = 0; 1111 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1112 1113 /** 1114 * Mapping from each known user ID to the profile group ID it is associated with. 1115 */ 1116 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1117 1118 private UserManagerService mUserManager; 1119 1120 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1121 final ProcessRecord mApp; 1122 final int mPid; 1123 final IApplicationThread mAppThread; 1124 1125 AppDeathRecipient(ProcessRecord app, int pid, 1126 IApplicationThread thread) { 1127 if (localLOGV) Slog.v( 1128 TAG, "New death recipient " + this 1129 + " for thread " + thread.asBinder()); 1130 mApp = app; 1131 mPid = pid; 1132 mAppThread = thread; 1133 } 1134 1135 @Override 1136 public void binderDied() { 1137 if (localLOGV) Slog.v( 1138 TAG, "Death received in " + this 1139 + " for thread " + mAppThread.asBinder()); 1140 synchronized(ActivityManagerService.this) { 1141 appDiedLocked(mApp, mPid, mAppThread); 1142 } 1143 } 1144 } 1145 1146 static final int SHOW_ERROR_MSG = 1; 1147 static final int SHOW_NOT_RESPONDING_MSG = 2; 1148 static final int SHOW_FACTORY_ERROR_MSG = 3; 1149 static final int UPDATE_CONFIGURATION_MSG = 4; 1150 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1151 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1152 static final int SERVICE_TIMEOUT_MSG = 12; 1153 static final int UPDATE_TIME_ZONE = 13; 1154 static final int SHOW_UID_ERROR_MSG = 14; 1155 static final int IM_FEELING_LUCKY_MSG = 15; 1156 static final int PROC_START_TIMEOUT_MSG = 20; 1157 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1158 static final int KILL_APPLICATION_MSG = 22; 1159 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1160 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1161 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1162 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1163 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1164 static final int CLEAR_DNS_CACHE_MSG = 28; 1165 static final int UPDATE_HTTP_PROXY_MSG = 29; 1166 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1167 static final int DISPATCH_PROCESSES_CHANGED = 31; 1168 static final int DISPATCH_PROCESS_DIED = 32; 1169 static final int REPORT_MEM_USAGE_MSG = 33; 1170 static final int REPORT_USER_SWITCH_MSG = 34; 1171 static final int CONTINUE_USER_SWITCH_MSG = 35; 1172 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1173 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1174 static final int PERSIST_URI_GRANTS_MSG = 38; 1175 static final int REQUEST_ALL_PSS_MSG = 39; 1176 static final int START_PROFILES_MSG = 40; 1177 static final int UPDATE_TIME = 41; 1178 static final int SYSTEM_USER_START_MSG = 42; 1179 static final int SYSTEM_USER_CURRENT_MSG = 43; 1180 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1181 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1182 static final int START_USER_SWITCH_MSG = 46; 1183 1184 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1185 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1186 static final int FIRST_COMPAT_MODE_MSG = 300; 1187 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1188 1189 AlertDialog mUidAlert; 1190 CompatModeDialog mCompatModeDialog; 1191 long mLastMemUsageReportTime = 0; 1192 1193 private LockToAppRequestDialog mLockToAppRequest; 1194 1195 /** 1196 * Flag whether the current user is a "monkey", i.e. whether 1197 * the UI is driven by a UI automation tool. 1198 */ 1199 private boolean mUserIsMonkey; 1200 1201 /** Flag whether the device has a Recents UI */ 1202 boolean mHasRecents; 1203 1204 /** The dimensions of the thumbnails in the Recents UI. */ 1205 int mThumbnailWidth; 1206 int mThumbnailHeight; 1207 1208 final ServiceThread mHandlerThread; 1209 final MainHandler mHandler; 1210 1211 final class MainHandler extends Handler { 1212 public MainHandler(Looper looper) { 1213 super(looper, null, true); 1214 } 1215 1216 @Override 1217 public void handleMessage(Message msg) { 1218 switch (msg.what) { 1219 case SHOW_ERROR_MSG: { 1220 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1221 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1222 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1223 synchronized (ActivityManagerService.this) { 1224 ProcessRecord proc = (ProcessRecord)data.get("app"); 1225 AppErrorResult res = (AppErrorResult) data.get("result"); 1226 if (proc != null && proc.crashDialog != null) { 1227 Slog.e(TAG, "App already has crash dialog: " + proc); 1228 if (res != null) { 1229 res.set(0); 1230 } 1231 return; 1232 } 1233 boolean isBackground = (UserHandle.getAppId(proc.uid) 1234 >= Process.FIRST_APPLICATION_UID 1235 && proc.pid != MY_PID); 1236 for (int userId : mCurrentProfileIds) { 1237 isBackground &= (proc.userId != userId); 1238 } 1239 if (isBackground && !showBackground) { 1240 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1241 if (res != null) { 1242 res.set(0); 1243 } 1244 return; 1245 } 1246 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1247 Dialog d = new AppErrorDialog(mContext, 1248 ActivityManagerService.this, res, proc); 1249 d.show(); 1250 proc.crashDialog = d; 1251 } else { 1252 // The device is asleep, so just pretend that the user 1253 // saw a crash dialog and hit "force quit". 1254 if (res != null) { 1255 res.set(0); 1256 } 1257 } 1258 } 1259 1260 ensureBootCompleted(); 1261 } break; 1262 case SHOW_NOT_RESPONDING_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1265 ProcessRecord proc = (ProcessRecord)data.get("app"); 1266 if (proc != null && proc.anrDialog != null) { 1267 Slog.e(TAG, "App already has anr dialog: " + proc); 1268 return; 1269 } 1270 1271 Intent intent = new Intent("android.intent.action.ANR"); 1272 if (!mProcessesReady) { 1273 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1274 | Intent.FLAG_RECEIVER_FOREGROUND); 1275 } 1276 broadcastIntentLocked(null, null, intent, 1277 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1278 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1279 1280 if (mShowDialogs) { 1281 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1282 mContext, proc, (ActivityRecord)data.get("activity"), 1283 msg.arg1 != 0); 1284 d.show(); 1285 proc.anrDialog = d; 1286 } else { 1287 // Just kill the app if there is no dialog to be shown. 1288 killAppAtUsersRequest(proc, null); 1289 } 1290 } 1291 1292 ensureBootCompleted(); 1293 } break; 1294 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1295 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1296 synchronized (ActivityManagerService.this) { 1297 ProcessRecord proc = (ProcessRecord) data.get("app"); 1298 if (proc == null) { 1299 Slog.e(TAG, "App not found when showing strict mode dialog."); 1300 break; 1301 } 1302 if (proc.crashDialog != null) { 1303 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1304 return; 1305 } 1306 AppErrorResult res = (AppErrorResult) data.get("result"); 1307 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1308 Dialog d = new StrictModeViolationDialog(mContext, 1309 ActivityManagerService.this, res, proc); 1310 d.show(); 1311 proc.crashDialog = d; 1312 } else { 1313 // The device is asleep, so just pretend that the user 1314 // saw a crash dialog and hit "force quit". 1315 res.set(0); 1316 } 1317 } 1318 ensureBootCompleted(); 1319 } break; 1320 case SHOW_FACTORY_ERROR_MSG: { 1321 Dialog d = new FactoryErrorDialog( 1322 mContext, msg.getData().getCharSequence("msg")); 1323 d.show(); 1324 ensureBootCompleted(); 1325 } break; 1326 case UPDATE_CONFIGURATION_MSG: { 1327 final ContentResolver resolver = mContext.getContentResolver(); 1328 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1329 } break; 1330 case GC_BACKGROUND_PROCESSES_MSG: { 1331 synchronized (ActivityManagerService.this) { 1332 performAppGcsIfAppropriateLocked(); 1333 } 1334 } break; 1335 case WAIT_FOR_DEBUGGER_MSG: { 1336 synchronized (ActivityManagerService.this) { 1337 ProcessRecord app = (ProcessRecord)msg.obj; 1338 if (msg.arg1 != 0) { 1339 if (!app.waitedForDebugger) { 1340 Dialog d = new AppWaitingForDebuggerDialog( 1341 ActivityManagerService.this, 1342 mContext, app); 1343 app.waitDialog = d; 1344 app.waitedForDebugger = true; 1345 d.show(); 1346 } 1347 } else { 1348 if (app.waitDialog != null) { 1349 app.waitDialog.dismiss(); 1350 app.waitDialog = null; 1351 } 1352 } 1353 } 1354 } break; 1355 case SERVICE_TIMEOUT_MSG: { 1356 if (mDidDexOpt) { 1357 mDidDexOpt = false; 1358 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1359 nmsg.obj = msg.obj; 1360 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1361 return; 1362 } 1363 mServices.serviceTimeout((ProcessRecord)msg.obj); 1364 } break; 1365 case UPDATE_TIME_ZONE: { 1366 synchronized (ActivityManagerService.this) { 1367 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1368 ProcessRecord r = mLruProcesses.get(i); 1369 if (r.thread != null) { 1370 try { 1371 r.thread.updateTimeZone(); 1372 } catch (RemoteException ex) { 1373 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1374 } 1375 } 1376 } 1377 } 1378 } break; 1379 case CLEAR_DNS_CACHE_MSG: { 1380 synchronized (ActivityManagerService.this) { 1381 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1382 ProcessRecord r = mLruProcesses.get(i); 1383 if (r.thread != null) { 1384 try { 1385 r.thread.clearDnsCache(); 1386 } catch (RemoteException ex) { 1387 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1388 } 1389 } 1390 } 1391 } 1392 } break; 1393 case UPDATE_HTTP_PROXY_MSG: { 1394 ProxyInfo proxy = (ProxyInfo)msg.obj; 1395 String host = ""; 1396 String port = ""; 1397 String exclList = ""; 1398 Uri pacFileUrl = Uri.EMPTY; 1399 if (proxy != null) { 1400 host = proxy.getHost(); 1401 port = Integer.toString(proxy.getPort()); 1402 exclList = proxy.getExclusionListAsString(); 1403 pacFileUrl = proxy.getPacFileUrl(); 1404 } 1405 synchronized (ActivityManagerService.this) { 1406 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1407 ProcessRecord r = mLruProcesses.get(i); 1408 if (r.thread != null) { 1409 try { 1410 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1411 } catch (RemoteException ex) { 1412 Slog.w(TAG, "Failed to update http proxy for: " + 1413 r.info.processName); 1414 } 1415 } 1416 } 1417 } 1418 } break; 1419 case SHOW_UID_ERROR_MSG: { 1420 String title = "System UIDs Inconsistent"; 1421 String text = "UIDs on the system are inconsistent, you need to wipe your" 1422 + " data partition or your device will be unstable."; 1423 Log.e(TAG, title + ": " + text); 1424 if (mShowDialogs) { 1425 // XXX This is a temporary dialog, no need to localize. 1426 AlertDialog d = new BaseErrorDialog(mContext); 1427 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1428 d.setCancelable(false); 1429 d.setTitle(title); 1430 d.setMessage(text); 1431 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1432 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1433 mUidAlert = d; 1434 d.show(); 1435 } 1436 } break; 1437 case IM_FEELING_LUCKY_MSG: { 1438 if (mUidAlert != null) { 1439 mUidAlert.dismiss(); 1440 mUidAlert = null; 1441 } 1442 } break; 1443 case PROC_START_TIMEOUT_MSG: { 1444 if (mDidDexOpt) { 1445 mDidDexOpt = false; 1446 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1447 nmsg.obj = msg.obj; 1448 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1449 return; 1450 } 1451 ProcessRecord app = (ProcessRecord)msg.obj; 1452 synchronized (ActivityManagerService.this) { 1453 processStartTimedOutLocked(app); 1454 } 1455 } break; 1456 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1457 synchronized (ActivityManagerService.this) { 1458 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1459 } 1460 } break; 1461 case KILL_APPLICATION_MSG: { 1462 synchronized (ActivityManagerService.this) { 1463 int appid = msg.arg1; 1464 boolean restart = (msg.arg2 == 1); 1465 Bundle bundle = (Bundle)msg.obj; 1466 String pkg = bundle.getString("pkg"); 1467 String reason = bundle.getString("reason"); 1468 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1469 false, UserHandle.USER_ALL, reason); 1470 } 1471 } break; 1472 case FINALIZE_PENDING_INTENT_MSG: { 1473 ((PendingIntentRecord)msg.obj).completeFinalize(); 1474 } break; 1475 case POST_HEAVY_NOTIFICATION_MSG: { 1476 INotificationManager inm = NotificationManager.getService(); 1477 if (inm == null) { 1478 return; 1479 } 1480 1481 ActivityRecord root = (ActivityRecord)msg.obj; 1482 ProcessRecord process = root.app; 1483 if (process == null) { 1484 return; 1485 } 1486 1487 try { 1488 Context context = mContext.createPackageContext(process.info.packageName, 0); 1489 String text = mContext.getString(R.string.heavy_weight_notification, 1490 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1491 Notification notification = new Notification(); 1492 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1493 notification.when = 0; 1494 notification.flags = Notification.FLAG_ONGOING_EVENT; 1495 notification.tickerText = text; 1496 notification.defaults = 0; // please be quiet 1497 notification.sound = null; 1498 notification.vibrate = null; 1499 notification.color = mContext.getResources().getColor( 1500 com.android.internal.R.color.system_notification_accent_color); 1501 notification.setLatestEventInfo(context, text, 1502 mContext.getText(R.string.heavy_weight_notification_detail), 1503 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1504 PendingIntent.FLAG_CANCEL_CURRENT, null, 1505 new UserHandle(root.userId))); 1506 1507 try { 1508 int[] outId = new int[1]; 1509 inm.enqueueNotificationWithTag("android", "android", null, 1510 R.string.heavy_weight_notification, 1511 notification, outId, root.userId); 1512 } catch (RuntimeException e) { 1513 Slog.w(ActivityManagerService.TAG, 1514 "Error showing notification for heavy-weight app", e); 1515 } catch (RemoteException e) { 1516 } 1517 } catch (NameNotFoundException e) { 1518 Slog.w(TAG, "Unable to create context for heavy notification", e); 1519 } 1520 } break; 1521 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1522 INotificationManager inm = NotificationManager.getService(); 1523 if (inm == null) { 1524 return; 1525 } 1526 try { 1527 inm.cancelNotificationWithTag("android", null, 1528 R.string.heavy_weight_notification, msg.arg1); 1529 } catch (RuntimeException e) { 1530 Slog.w(ActivityManagerService.TAG, 1531 "Error canceling notification for service", e); 1532 } catch (RemoteException e) { 1533 } 1534 } break; 1535 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1536 synchronized (ActivityManagerService.this) { 1537 checkExcessivePowerUsageLocked(true); 1538 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1539 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1540 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1541 } 1542 } break; 1543 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1544 synchronized (ActivityManagerService.this) { 1545 ActivityRecord ar = (ActivityRecord)msg.obj; 1546 if (mCompatModeDialog != null) { 1547 if (mCompatModeDialog.mAppInfo.packageName.equals( 1548 ar.info.applicationInfo.packageName)) { 1549 return; 1550 } 1551 mCompatModeDialog.dismiss(); 1552 mCompatModeDialog = null; 1553 } 1554 if (ar != null && false) { 1555 if (mCompatModePackages.getPackageAskCompatModeLocked( 1556 ar.packageName)) { 1557 int mode = mCompatModePackages.computeCompatModeLocked( 1558 ar.info.applicationInfo); 1559 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1560 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1561 mCompatModeDialog = new CompatModeDialog( 1562 ActivityManagerService.this, mContext, 1563 ar.info.applicationInfo); 1564 mCompatModeDialog.show(); 1565 } 1566 } 1567 } 1568 } 1569 break; 1570 } 1571 case DISPATCH_PROCESSES_CHANGED: { 1572 dispatchProcessesChanged(); 1573 break; 1574 } 1575 case DISPATCH_PROCESS_DIED: { 1576 final int pid = msg.arg1; 1577 final int uid = msg.arg2; 1578 dispatchProcessDied(pid, uid); 1579 break; 1580 } 1581 case REPORT_MEM_USAGE_MSG: { 1582 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1583 Thread thread = new Thread() { 1584 @Override public void run() { 1585 final SparseArray<ProcessMemInfo> infoMap 1586 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1587 for (int i=0, N=memInfos.size(); i<N; i++) { 1588 ProcessMemInfo mi = memInfos.get(i); 1589 infoMap.put(mi.pid, mi); 1590 } 1591 updateCpuStatsNow(); 1592 synchronized (mProcessCpuThread) { 1593 final int N = mProcessCpuTracker.countStats(); 1594 for (int i=0; i<N; i++) { 1595 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1596 if (st.vsize > 0) { 1597 long pss = Debug.getPss(st.pid, null); 1598 if (pss > 0) { 1599 if (infoMap.indexOfKey(st.pid) < 0) { 1600 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1601 ProcessList.NATIVE_ADJ, -1, "native", null); 1602 mi.pss = pss; 1603 memInfos.add(mi); 1604 } 1605 } 1606 } 1607 } 1608 } 1609 1610 long totalPss = 0; 1611 for (int i=0, N=memInfos.size(); i<N; i++) { 1612 ProcessMemInfo mi = memInfos.get(i); 1613 if (mi.pss == 0) { 1614 mi.pss = Debug.getPss(mi.pid, null); 1615 } 1616 totalPss += mi.pss; 1617 } 1618 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1619 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1620 if (lhs.oomAdj != rhs.oomAdj) { 1621 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1622 } 1623 if (lhs.pss != rhs.pss) { 1624 return lhs.pss < rhs.pss ? 1 : -1; 1625 } 1626 return 0; 1627 } 1628 }); 1629 1630 StringBuilder tag = new StringBuilder(128); 1631 StringBuilder stack = new StringBuilder(128); 1632 tag.append("Low on memory -- "); 1633 appendMemBucket(tag, totalPss, "total", false); 1634 appendMemBucket(stack, totalPss, "total", true); 1635 1636 StringBuilder logBuilder = new StringBuilder(1024); 1637 logBuilder.append("Low on memory:\n"); 1638 1639 boolean firstLine = true; 1640 int lastOomAdj = Integer.MIN_VALUE; 1641 for (int i=0, N=memInfos.size(); i<N; i++) { 1642 ProcessMemInfo mi = memInfos.get(i); 1643 1644 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1645 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1646 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1647 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1648 if (lastOomAdj != mi.oomAdj) { 1649 lastOomAdj = mi.oomAdj; 1650 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1651 tag.append(" / "); 1652 } 1653 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1654 if (firstLine) { 1655 stack.append(":"); 1656 firstLine = false; 1657 } 1658 stack.append("\n\t at "); 1659 } else { 1660 stack.append("$"); 1661 } 1662 } else { 1663 tag.append(" "); 1664 stack.append("$"); 1665 } 1666 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1667 appendMemBucket(tag, mi.pss, mi.name, false); 1668 } 1669 appendMemBucket(stack, mi.pss, mi.name, true); 1670 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1671 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1672 stack.append("("); 1673 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1674 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1675 stack.append(DUMP_MEM_OOM_LABEL[k]); 1676 stack.append(":"); 1677 stack.append(DUMP_MEM_OOM_ADJ[k]); 1678 } 1679 } 1680 stack.append(")"); 1681 } 1682 } 1683 1684 logBuilder.append(" "); 1685 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1686 logBuilder.append(' '); 1687 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1688 logBuilder.append(' '); 1689 ProcessList.appendRamKb(logBuilder, mi.pss); 1690 logBuilder.append(" kB: "); 1691 logBuilder.append(mi.name); 1692 logBuilder.append(" ("); 1693 logBuilder.append(mi.pid); 1694 logBuilder.append(") "); 1695 logBuilder.append(mi.adjType); 1696 logBuilder.append('\n'); 1697 if (mi.adjReason != null) { 1698 logBuilder.append(" "); 1699 logBuilder.append(mi.adjReason); 1700 logBuilder.append('\n'); 1701 } 1702 } 1703 1704 logBuilder.append(" "); 1705 ProcessList.appendRamKb(logBuilder, totalPss); 1706 logBuilder.append(" kB: TOTAL\n"); 1707 1708 long[] infos = new long[Debug.MEMINFO_COUNT]; 1709 Debug.getMemInfo(infos); 1710 logBuilder.append(" MemInfo: "); 1711 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1712 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1713 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1714 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1715 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1716 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1717 logBuilder.append(" ZRAM: "); 1718 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1719 logBuilder.append(" kB RAM, "); 1720 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1721 logBuilder.append(" kB swap total, "); 1722 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1723 logBuilder.append(" kB swap free\n"); 1724 } 1725 Slog.i(TAG, logBuilder.toString()); 1726 1727 StringBuilder dropBuilder = new StringBuilder(1024); 1728 /* 1729 StringWriter oomSw = new StringWriter(); 1730 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1731 StringWriter catSw = new StringWriter(); 1732 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1733 String[] emptyArgs = new String[] { }; 1734 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1735 oomPw.flush(); 1736 String oomString = oomSw.toString(); 1737 */ 1738 dropBuilder.append(stack); 1739 dropBuilder.append('\n'); 1740 dropBuilder.append('\n'); 1741 dropBuilder.append(logBuilder); 1742 dropBuilder.append('\n'); 1743 /* 1744 dropBuilder.append(oomString); 1745 dropBuilder.append('\n'); 1746 */ 1747 StringWriter catSw = new StringWriter(); 1748 synchronized (ActivityManagerService.this) { 1749 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1750 String[] emptyArgs = new String[] { }; 1751 catPw.println(); 1752 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1753 catPw.println(); 1754 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1755 false, false, null); 1756 catPw.println(); 1757 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1758 catPw.flush(); 1759 } 1760 dropBuilder.append(catSw.toString()); 1761 addErrorToDropBox("lowmem", null, "system_server", null, 1762 null, tag.toString(), dropBuilder.toString(), null, null); 1763 //Slog.i(TAG, "Sent to dropbox:"); 1764 //Slog.i(TAG, dropBuilder.toString()); 1765 synchronized (ActivityManagerService.this) { 1766 long now = SystemClock.uptimeMillis(); 1767 if (mLastMemUsageReportTime < now) { 1768 mLastMemUsageReportTime = now; 1769 } 1770 } 1771 } 1772 }; 1773 thread.start(); 1774 break; 1775 } 1776 case START_USER_SWITCH_MSG: { 1777 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1778 break; 1779 } 1780 case REPORT_USER_SWITCH_MSG: { 1781 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1782 break; 1783 } 1784 case CONTINUE_USER_SWITCH_MSG: { 1785 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1786 break; 1787 } 1788 case USER_SWITCH_TIMEOUT_MSG: { 1789 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1790 break; 1791 } 1792 case IMMERSIVE_MODE_LOCK_MSG: { 1793 final boolean nextState = (msg.arg1 != 0); 1794 if (mUpdateLock.isHeld() != nextState) { 1795 if (DEBUG_IMMERSIVE) { 1796 final ActivityRecord r = (ActivityRecord) msg.obj; 1797 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1798 } 1799 if (nextState) { 1800 mUpdateLock.acquire(); 1801 } else { 1802 mUpdateLock.release(); 1803 } 1804 } 1805 break; 1806 } 1807 case PERSIST_URI_GRANTS_MSG: { 1808 writeGrantedUriPermissions(); 1809 break; 1810 } 1811 case REQUEST_ALL_PSS_MSG: { 1812 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1813 break; 1814 } 1815 case START_PROFILES_MSG: { 1816 synchronized (ActivityManagerService.this) { 1817 startProfilesLocked(); 1818 } 1819 break; 1820 } 1821 case UPDATE_TIME: { 1822 synchronized (ActivityManagerService.this) { 1823 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1824 ProcessRecord r = mLruProcesses.get(i); 1825 if (r.thread != null) { 1826 try { 1827 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1828 } catch (RemoteException ex) { 1829 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1830 } 1831 } 1832 } 1833 } 1834 break; 1835 } 1836 case SYSTEM_USER_START_MSG: { 1837 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1838 Integer.toString(msg.arg1), msg.arg1); 1839 mSystemServiceManager.startUser(msg.arg1); 1840 break; 1841 } 1842 case SYSTEM_USER_CURRENT_MSG: { 1843 mBatteryStatsService.noteEvent( 1844 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1845 Integer.toString(msg.arg2), msg.arg2); 1846 mBatteryStatsService.noteEvent( 1847 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1848 Integer.toString(msg.arg1), msg.arg1); 1849 mSystemServiceManager.switchUser(msg.arg1); 1850 mLockToAppRequest.clearPrompt(); 1851 break; 1852 } 1853 case ENTER_ANIMATION_COMPLETE_MSG: { 1854 synchronized (ActivityManagerService.this) { 1855 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1856 if (r != null && r.app != null && r.app.thread != null) { 1857 try { 1858 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1859 } catch (RemoteException e) { 1860 } 1861 } 1862 } 1863 break; 1864 } 1865 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1866 enableScreenAfterBoot(); 1867 break; 1868 } 1869 } 1870 } 1871 }; 1872 1873 static final int COLLECT_PSS_BG_MSG = 1; 1874 1875 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1876 @Override 1877 public void handleMessage(Message msg) { 1878 switch (msg.what) { 1879 case COLLECT_PSS_BG_MSG: { 1880 long start = SystemClock.uptimeMillis(); 1881 MemInfoReader memInfo = null; 1882 synchronized (ActivityManagerService.this) { 1883 if (mFullPssPending) { 1884 mFullPssPending = false; 1885 memInfo = new MemInfoReader(); 1886 } 1887 } 1888 if (memInfo != null) { 1889 updateCpuStatsNow(); 1890 long nativeTotalPss = 0; 1891 synchronized (mProcessCpuThread) { 1892 final int N = mProcessCpuTracker.countStats(); 1893 for (int j=0; j<N; j++) { 1894 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1895 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1896 // This is definitely an application process; skip it. 1897 continue; 1898 } 1899 synchronized (mPidsSelfLocked) { 1900 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1901 // This is one of our own processes; skip it. 1902 continue; 1903 } 1904 } 1905 nativeTotalPss += Debug.getPss(st.pid, null); 1906 } 1907 } 1908 memInfo.readMemInfo(); 1909 synchronized (this) { 1910 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1911 + (SystemClock.uptimeMillis()-start) + "ms"); 1912 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1913 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1914 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1915 +memInfo.getSlabSizeKb(), 1916 nativeTotalPss); 1917 } 1918 } 1919 1920 int i=0, num=0; 1921 long[] tmp = new long[1]; 1922 do { 1923 ProcessRecord proc; 1924 int procState; 1925 int pid; 1926 synchronized (ActivityManagerService.this) { 1927 if (i >= mPendingPssProcesses.size()) { 1928 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1929 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1930 mPendingPssProcesses.clear(); 1931 return; 1932 } 1933 proc = mPendingPssProcesses.get(i); 1934 procState = proc.pssProcState; 1935 if (proc.thread != null && procState == proc.setProcState) { 1936 pid = proc.pid; 1937 } else { 1938 proc = null; 1939 pid = 0; 1940 } 1941 i++; 1942 } 1943 if (proc != null) { 1944 long pss = Debug.getPss(pid, tmp); 1945 synchronized (ActivityManagerService.this) { 1946 if (proc.thread != null && proc.setProcState == procState 1947 && proc.pid == pid) { 1948 num++; 1949 proc.lastPssTime = SystemClock.uptimeMillis(); 1950 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1951 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1952 + ": " + pss + " lastPss=" + proc.lastPss 1953 + " state=" + ProcessList.makeProcStateString(procState)); 1954 if (proc.initialIdlePss == 0) { 1955 proc.initialIdlePss = pss; 1956 } 1957 proc.lastPss = pss; 1958 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1959 proc.lastCachedPss = pss; 1960 } 1961 } 1962 } 1963 } 1964 } while (true); 1965 } 1966 } 1967 } 1968 }; 1969 1970 /** 1971 * Monitor for package changes and update our internal state. 1972 */ 1973 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1974 @Override 1975 public void onPackageRemoved(String packageName, int uid) { 1976 // Remove all tasks with activities in the specified package from the list of recent tasks 1977 synchronized (ActivityManagerService.this) { 1978 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1979 TaskRecord tr = mRecentTasks.get(i); 1980 ComponentName cn = tr.intent.getComponent(); 1981 if (cn != null && cn.getPackageName().equals(packageName)) { 1982 // If the package name matches, remove the task and kill the process 1983 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1984 } 1985 } 1986 } 1987 } 1988 1989 @Override 1990 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1991 onPackageModified(packageName); 1992 return true; 1993 } 1994 1995 @Override 1996 public void onPackageModified(String packageName) { 1997 final PackageManager pm = mContext.getPackageManager(); 1998 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1999 new ArrayList<Pair<Intent, Integer>>(); 2000 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2001 // Copy the list of recent tasks so that we don't hold onto the lock on 2002 // ActivityManagerService for long periods while checking if components exist. 2003 synchronized (ActivityManagerService.this) { 2004 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2005 TaskRecord tr = mRecentTasks.get(i); 2006 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2007 } 2008 } 2009 // Check the recent tasks and filter out all tasks with components that no longer exist. 2010 Intent tmpI = new Intent(); 2011 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2012 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2013 ComponentName cn = p.first.getComponent(); 2014 if (cn != null && cn.getPackageName().equals(packageName)) { 2015 try { 2016 // Add the task to the list to remove if the component no longer exists 2017 tmpI.setComponent(cn); 2018 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2019 tasksToRemove.add(p.second); 2020 } 2021 } catch (Exception e) {} 2022 } 2023 } 2024 // Prune all the tasks with removed components from the list of recent tasks 2025 synchronized (ActivityManagerService.this) { 2026 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2027 // Remove the task but don't kill the process (since other components in that 2028 // package may still be running and in the background) 2029 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2030 } 2031 } 2032 } 2033 2034 @Override 2035 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2036 // Force stop the specified packages 2037 if (packages != null) { 2038 for (String pkg : packages) { 2039 synchronized (ActivityManagerService.this) { 2040 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2041 "finished booting")) { 2042 return true; 2043 } 2044 } 2045 } 2046 } 2047 return false; 2048 } 2049 }; 2050 2051 public void setSystemProcess() { 2052 try { 2053 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2054 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2055 ServiceManager.addService("meminfo", new MemBinder(this)); 2056 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2057 ServiceManager.addService("dbinfo", new DbBinder(this)); 2058 if (MONITOR_CPU_USAGE) { 2059 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2060 } 2061 ServiceManager.addService("permission", new PermissionController(this)); 2062 2063 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2064 "android", STOCK_PM_FLAGS); 2065 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2066 2067 synchronized (this) { 2068 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2069 app.persistent = true; 2070 app.pid = MY_PID; 2071 app.maxAdj = ProcessList.SYSTEM_ADJ; 2072 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2073 mProcessNames.put(app.processName, app.uid, app); 2074 synchronized (mPidsSelfLocked) { 2075 mPidsSelfLocked.put(app.pid, app); 2076 } 2077 updateLruProcessLocked(app, false, null); 2078 updateOomAdjLocked(); 2079 } 2080 } catch (PackageManager.NameNotFoundException e) { 2081 throw new RuntimeException( 2082 "Unable to find android system package", e); 2083 } 2084 } 2085 2086 public void setWindowManager(WindowManagerService wm) { 2087 mWindowManager = wm; 2088 mStackSupervisor.setWindowManager(wm); 2089 } 2090 2091 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2092 mUsageStatsService = usageStatsManager; 2093 } 2094 2095 public void startObservingNativeCrashes() { 2096 final NativeCrashListener ncl = new NativeCrashListener(this); 2097 ncl.start(); 2098 } 2099 2100 public IAppOpsService getAppOpsService() { 2101 return mAppOpsService; 2102 } 2103 2104 static class MemBinder extends Binder { 2105 ActivityManagerService mActivityManagerService; 2106 MemBinder(ActivityManagerService activityManagerService) { 2107 mActivityManagerService = activityManagerService; 2108 } 2109 2110 @Override 2111 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2112 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2113 != PackageManager.PERMISSION_GRANTED) { 2114 pw.println("Permission Denial: can't dump meminfo from from pid=" 2115 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2116 + " without permission " + android.Manifest.permission.DUMP); 2117 return; 2118 } 2119 2120 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2121 } 2122 } 2123 2124 static class GraphicsBinder extends Binder { 2125 ActivityManagerService mActivityManagerService; 2126 GraphicsBinder(ActivityManagerService activityManagerService) { 2127 mActivityManagerService = activityManagerService; 2128 } 2129 2130 @Override 2131 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2132 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2133 != PackageManager.PERMISSION_GRANTED) { 2134 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2135 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2136 + " without permission " + android.Manifest.permission.DUMP); 2137 return; 2138 } 2139 2140 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2141 } 2142 } 2143 2144 static class DbBinder extends Binder { 2145 ActivityManagerService mActivityManagerService; 2146 DbBinder(ActivityManagerService activityManagerService) { 2147 mActivityManagerService = activityManagerService; 2148 } 2149 2150 @Override 2151 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2152 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2153 != PackageManager.PERMISSION_GRANTED) { 2154 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2155 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2156 + " without permission " + android.Manifest.permission.DUMP); 2157 return; 2158 } 2159 2160 mActivityManagerService.dumpDbInfo(fd, pw, args); 2161 } 2162 } 2163 2164 static class CpuBinder extends Binder { 2165 ActivityManagerService mActivityManagerService; 2166 CpuBinder(ActivityManagerService activityManagerService) { 2167 mActivityManagerService = activityManagerService; 2168 } 2169 2170 @Override 2171 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2172 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2173 != PackageManager.PERMISSION_GRANTED) { 2174 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2175 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2176 + " without permission " + android.Manifest.permission.DUMP); 2177 return; 2178 } 2179 2180 synchronized (mActivityManagerService.mProcessCpuThread) { 2181 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2182 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2183 SystemClock.uptimeMillis())); 2184 } 2185 } 2186 } 2187 2188 public static final class Lifecycle extends SystemService { 2189 private final ActivityManagerService mService; 2190 2191 public Lifecycle(Context context) { 2192 super(context); 2193 mService = new ActivityManagerService(context); 2194 } 2195 2196 @Override 2197 public void onStart() { 2198 mService.start(); 2199 } 2200 2201 public ActivityManagerService getService() { 2202 return mService; 2203 } 2204 } 2205 2206 // Note: This method is invoked on the main thread but may need to attach various 2207 // handlers to other threads. So take care to be explicit about the looper. 2208 public ActivityManagerService(Context systemContext) { 2209 mContext = systemContext; 2210 mFactoryTest = FactoryTest.getMode(); 2211 mSystemThread = ActivityThread.currentActivityThread(); 2212 2213 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2214 2215 mHandlerThread = new ServiceThread(TAG, 2216 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2217 mHandlerThread.start(); 2218 mHandler = new MainHandler(mHandlerThread.getLooper()); 2219 2220 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2221 "foreground", BROADCAST_FG_TIMEOUT, false); 2222 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2223 "background", BROADCAST_BG_TIMEOUT, true); 2224 mBroadcastQueues[0] = mFgBroadcastQueue; 2225 mBroadcastQueues[1] = mBgBroadcastQueue; 2226 2227 mServices = new ActiveServices(this); 2228 mProviderMap = new ProviderMap(this); 2229 2230 // TODO: Move creation of battery stats service outside of activity manager service. 2231 File dataDir = Environment.getDataDirectory(); 2232 File systemDir = new File(dataDir, "system"); 2233 systemDir.mkdirs(); 2234 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2235 mBatteryStatsService.getActiveStatistics().readLocked(); 2236 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2237 mOnBattery = DEBUG_POWER ? true 2238 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2239 mBatteryStatsService.getActiveStatistics().setCallback(this); 2240 2241 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2242 2243 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2244 2245 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2246 2247 // User 0 is the first and only user that runs at boot. 2248 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2249 mUserLru.add(Integer.valueOf(0)); 2250 updateStartedUserArrayLocked(); 2251 2252 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2253 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2254 2255 mConfiguration.setToDefaults(); 2256 mConfiguration.setLocale(Locale.getDefault()); 2257 2258 mConfigurationSeq = mConfiguration.seq = 1; 2259 mProcessCpuTracker.init(); 2260 2261 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2262 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2263 mStackSupervisor = new ActivityStackSupervisor(this); 2264 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2265 2266 mProcessCpuThread = new Thread("CpuTracker") { 2267 @Override 2268 public void run() { 2269 while (true) { 2270 try { 2271 try { 2272 synchronized(this) { 2273 final long now = SystemClock.uptimeMillis(); 2274 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2275 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2276 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2277 // + ", write delay=" + nextWriteDelay); 2278 if (nextWriteDelay < nextCpuDelay) { 2279 nextCpuDelay = nextWriteDelay; 2280 } 2281 if (nextCpuDelay > 0) { 2282 mProcessCpuMutexFree.set(true); 2283 this.wait(nextCpuDelay); 2284 } 2285 } 2286 } catch (InterruptedException e) { 2287 } 2288 updateCpuStatsNow(); 2289 } catch (Exception e) { 2290 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2291 } 2292 } 2293 } 2294 }; 2295 2296 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2297 2298 Watchdog.getInstance().addMonitor(this); 2299 Watchdog.getInstance().addThread(mHandler); 2300 } 2301 2302 public void setSystemServiceManager(SystemServiceManager mgr) { 2303 mSystemServiceManager = mgr; 2304 } 2305 2306 private void start() { 2307 Process.removeAllProcessGroups(); 2308 mProcessCpuThread.start(); 2309 2310 mBatteryStatsService.publish(mContext); 2311 mAppOpsService.publish(mContext); 2312 Slog.d("AppOps", "AppOpsService published"); 2313 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2314 } 2315 2316 public void initPowerManagement() { 2317 mStackSupervisor.initPowerManagement(); 2318 mBatteryStatsService.initPowerManagement(); 2319 } 2320 2321 @Override 2322 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2323 throws RemoteException { 2324 if (code == SYSPROPS_TRANSACTION) { 2325 // We need to tell all apps about the system property change. 2326 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2327 synchronized(this) { 2328 final int NP = mProcessNames.getMap().size(); 2329 for (int ip=0; ip<NP; ip++) { 2330 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2331 final int NA = apps.size(); 2332 for (int ia=0; ia<NA; ia++) { 2333 ProcessRecord app = apps.valueAt(ia); 2334 if (app.thread != null) { 2335 procs.add(app.thread.asBinder()); 2336 } 2337 } 2338 } 2339 } 2340 2341 int N = procs.size(); 2342 for (int i=0; i<N; i++) { 2343 Parcel data2 = Parcel.obtain(); 2344 try { 2345 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2346 } catch (RemoteException e) { 2347 } 2348 data2.recycle(); 2349 } 2350 } 2351 try { 2352 return super.onTransact(code, data, reply, flags); 2353 } catch (RuntimeException e) { 2354 // The activity manager only throws security exceptions, so let's 2355 // log all others. 2356 if (!(e instanceof SecurityException)) { 2357 Slog.wtf(TAG, "Activity Manager Crash", e); 2358 } 2359 throw e; 2360 } 2361 } 2362 2363 void updateCpuStats() { 2364 final long now = SystemClock.uptimeMillis(); 2365 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2366 return; 2367 } 2368 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2369 synchronized (mProcessCpuThread) { 2370 mProcessCpuThread.notify(); 2371 } 2372 } 2373 } 2374 2375 void updateCpuStatsNow() { 2376 synchronized (mProcessCpuThread) { 2377 mProcessCpuMutexFree.set(false); 2378 final long now = SystemClock.uptimeMillis(); 2379 boolean haveNewCpuStats = false; 2380 2381 if (MONITOR_CPU_USAGE && 2382 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2383 mLastCpuTime.set(now); 2384 haveNewCpuStats = true; 2385 mProcessCpuTracker.update(); 2386 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2387 //Slog.i(TAG, "Total CPU usage: " 2388 // + mProcessCpu.getTotalCpuPercent() + "%"); 2389 2390 // Slog the cpu usage if the property is set. 2391 if ("true".equals(SystemProperties.get("events.cpu"))) { 2392 int user = mProcessCpuTracker.getLastUserTime(); 2393 int system = mProcessCpuTracker.getLastSystemTime(); 2394 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2395 int irq = mProcessCpuTracker.getLastIrqTime(); 2396 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2397 int idle = mProcessCpuTracker.getLastIdleTime(); 2398 2399 int total = user + system + iowait + irq + softIrq + idle; 2400 if (total == 0) total = 1; 2401 2402 EventLog.writeEvent(EventLogTags.CPU, 2403 ((user+system+iowait+irq+softIrq) * 100) / total, 2404 (user * 100) / total, 2405 (system * 100) / total, 2406 (iowait * 100) / total, 2407 (irq * 100) / total, 2408 (softIrq * 100) / total); 2409 } 2410 } 2411 2412 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2413 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2414 synchronized(bstats) { 2415 synchronized(mPidsSelfLocked) { 2416 if (haveNewCpuStats) { 2417 if (mOnBattery) { 2418 int perc = bstats.startAddingCpuLocked(); 2419 int totalUTime = 0; 2420 int totalSTime = 0; 2421 final int N = mProcessCpuTracker.countStats(); 2422 for (int i=0; i<N; i++) { 2423 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2424 if (!st.working) { 2425 continue; 2426 } 2427 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2428 int otherUTime = (st.rel_utime*perc)/100; 2429 int otherSTime = (st.rel_stime*perc)/100; 2430 totalUTime += otherUTime; 2431 totalSTime += otherSTime; 2432 if (pr != null) { 2433 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2434 if (ps == null || !ps.isActive()) { 2435 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2436 pr.info.uid, pr.processName); 2437 } 2438 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2439 st.rel_stime-otherSTime); 2440 ps.addSpeedStepTimes(cpuSpeedTimes); 2441 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2442 } else { 2443 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2444 if (ps == null || !ps.isActive()) { 2445 st.batteryStats = ps = bstats.getProcessStatsLocked( 2446 bstats.mapUid(st.uid), st.name); 2447 } 2448 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2449 st.rel_stime-otherSTime); 2450 ps.addSpeedStepTimes(cpuSpeedTimes); 2451 } 2452 } 2453 bstats.finishAddingCpuLocked(perc, totalUTime, 2454 totalSTime, cpuSpeedTimes); 2455 } 2456 } 2457 } 2458 2459 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2460 mLastWriteTime = now; 2461 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2462 } 2463 } 2464 } 2465 } 2466 2467 @Override 2468 public void batteryNeedsCpuUpdate() { 2469 updateCpuStatsNow(); 2470 } 2471 2472 @Override 2473 public void batteryPowerChanged(boolean onBattery) { 2474 // When plugging in, update the CPU stats first before changing 2475 // the plug state. 2476 updateCpuStatsNow(); 2477 synchronized (this) { 2478 synchronized(mPidsSelfLocked) { 2479 mOnBattery = DEBUG_POWER ? true : onBattery; 2480 } 2481 } 2482 } 2483 2484 /** 2485 * Initialize the application bind args. These are passed to each 2486 * process when the bindApplication() IPC is sent to the process. They're 2487 * lazily setup to make sure the services are running when they're asked for. 2488 */ 2489 private HashMap<String, IBinder> getCommonServicesLocked() { 2490 if (mAppBindArgs == null) { 2491 mAppBindArgs = new HashMap<String, IBinder>(); 2492 2493 // Setup the application init args 2494 mAppBindArgs.put("package", ServiceManager.getService("package")); 2495 mAppBindArgs.put("window", ServiceManager.getService("window")); 2496 mAppBindArgs.put(Context.ALARM_SERVICE, 2497 ServiceManager.getService(Context.ALARM_SERVICE)); 2498 } 2499 return mAppBindArgs; 2500 } 2501 2502 final void setFocusedActivityLocked(ActivityRecord r) { 2503 if (mFocusedActivity != r) { 2504 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2505 mFocusedActivity = r; 2506 if (r.task != null && r.task.voiceInteractor != null) { 2507 startRunningVoiceLocked(); 2508 } else { 2509 finishRunningVoiceLocked(); 2510 } 2511 mStackSupervisor.setFocusedStack(r); 2512 if (r != null) { 2513 mWindowManager.setFocusedApp(r.appToken, true); 2514 } 2515 applyUpdateLockStateLocked(r); 2516 } 2517 } 2518 2519 final void clearFocusedActivity(ActivityRecord r) { 2520 if (mFocusedActivity == r) { 2521 mFocusedActivity = null; 2522 } 2523 } 2524 2525 @Override 2526 public void setFocusedStack(int stackId) { 2527 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2528 synchronized (ActivityManagerService.this) { 2529 ActivityStack stack = mStackSupervisor.getStack(stackId); 2530 if (stack != null) { 2531 ActivityRecord r = stack.topRunningActivityLocked(null); 2532 if (r != null) { 2533 setFocusedActivityLocked(r); 2534 } 2535 } 2536 } 2537 } 2538 2539 @Override 2540 public void notifyActivityDrawn(IBinder token) { 2541 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2542 synchronized (this) { 2543 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2544 if (r != null) { 2545 r.task.stack.notifyActivityDrawnLocked(r); 2546 } 2547 } 2548 } 2549 2550 final void applyUpdateLockStateLocked(ActivityRecord r) { 2551 // Modifications to the UpdateLock state are done on our handler, outside 2552 // the activity manager's locks. The new state is determined based on the 2553 // state *now* of the relevant activity record. The object is passed to 2554 // the handler solely for logging detail, not to be consulted/modified. 2555 final boolean nextState = r != null && r.immersive; 2556 mHandler.sendMessage( 2557 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2558 } 2559 2560 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2561 Message msg = Message.obtain(); 2562 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2563 msg.obj = r.task.askedCompatMode ? null : r; 2564 mHandler.sendMessage(msg); 2565 } 2566 2567 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2568 String what, Object obj, ProcessRecord srcApp) { 2569 app.lastActivityTime = now; 2570 2571 if (app.activities.size() > 0) { 2572 // Don't want to touch dependent processes that are hosting activities. 2573 return index; 2574 } 2575 2576 int lrui = mLruProcesses.lastIndexOf(app); 2577 if (lrui < 0) { 2578 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2579 + what + " " + obj + " from " + srcApp); 2580 return index; 2581 } 2582 2583 if (lrui >= index) { 2584 // Don't want to cause this to move dependent processes *back* in the 2585 // list as if they were less frequently used. 2586 return index; 2587 } 2588 2589 if (lrui >= mLruProcessActivityStart) { 2590 // Don't want to touch dependent processes that are hosting activities. 2591 return index; 2592 } 2593 2594 mLruProcesses.remove(lrui); 2595 if (index > 0) { 2596 index--; 2597 } 2598 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2599 + " in LRU list: " + app); 2600 mLruProcesses.add(index, app); 2601 return index; 2602 } 2603 2604 final void removeLruProcessLocked(ProcessRecord app) { 2605 int lrui = mLruProcesses.lastIndexOf(app); 2606 if (lrui >= 0) { 2607 if (lrui <= mLruProcessActivityStart) { 2608 mLruProcessActivityStart--; 2609 } 2610 if (lrui <= mLruProcessServiceStart) { 2611 mLruProcessServiceStart--; 2612 } 2613 mLruProcesses.remove(lrui); 2614 } 2615 } 2616 2617 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2618 ProcessRecord client) { 2619 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2620 || app.treatLikeActivity; 2621 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2622 if (!activityChange && hasActivity) { 2623 // The process has activities, so we are only allowing activity-based adjustments 2624 // to move it. It should be kept in the front of the list with other 2625 // processes that have activities, and we don't want those to change their 2626 // order except due to activity operations. 2627 return; 2628 } 2629 2630 mLruSeq++; 2631 final long now = SystemClock.uptimeMillis(); 2632 app.lastActivityTime = now; 2633 2634 // First a quick reject: if the app is already at the position we will 2635 // put it, then there is nothing to do. 2636 if (hasActivity) { 2637 final int N = mLruProcesses.size(); 2638 if (N > 0 && mLruProcesses.get(N-1) == app) { 2639 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2640 return; 2641 } 2642 } else { 2643 if (mLruProcessServiceStart > 0 2644 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2645 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2646 return; 2647 } 2648 } 2649 2650 int lrui = mLruProcesses.lastIndexOf(app); 2651 2652 if (app.persistent && lrui >= 0) { 2653 // We don't care about the position of persistent processes, as long as 2654 // they are in the list. 2655 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2656 return; 2657 } 2658 2659 /* In progress: compute new position first, so we can avoid doing work 2660 if the process is not actually going to move. Not yet working. 2661 int addIndex; 2662 int nextIndex; 2663 boolean inActivity = false, inService = false; 2664 if (hasActivity) { 2665 // Process has activities, put it at the very tipsy-top. 2666 addIndex = mLruProcesses.size(); 2667 nextIndex = mLruProcessServiceStart; 2668 inActivity = true; 2669 } else if (hasService) { 2670 // Process has services, put it at the top of the service list. 2671 addIndex = mLruProcessActivityStart; 2672 nextIndex = mLruProcessServiceStart; 2673 inActivity = true; 2674 inService = true; 2675 } else { 2676 // Process not otherwise of interest, it goes to the top of the non-service area. 2677 addIndex = mLruProcessServiceStart; 2678 if (client != null) { 2679 int clientIndex = mLruProcesses.lastIndexOf(client); 2680 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2681 + app); 2682 if (clientIndex >= 0 && addIndex > clientIndex) { 2683 addIndex = clientIndex; 2684 } 2685 } 2686 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2687 } 2688 2689 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2690 + mLruProcessActivityStart + "): " + app); 2691 */ 2692 2693 if (lrui >= 0) { 2694 if (lrui < mLruProcessActivityStart) { 2695 mLruProcessActivityStart--; 2696 } 2697 if (lrui < mLruProcessServiceStart) { 2698 mLruProcessServiceStart--; 2699 } 2700 /* 2701 if (addIndex > lrui) { 2702 addIndex--; 2703 } 2704 if (nextIndex > lrui) { 2705 nextIndex--; 2706 } 2707 */ 2708 mLruProcesses.remove(lrui); 2709 } 2710 2711 /* 2712 mLruProcesses.add(addIndex, app); 2713 if (inActivity) { 2714 mLruProcessActivityStart++; 2715 } 2716 if (inService) { 2717 mLruProcessActivityStart++; 2718 } 2719 */ 2720 2721 int nextIndex; 2722 if (hasActivity) { 2723 final int N = mLruProcesses.size(); 2724 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2725 // Process doesn't have activities, but has clients with 2726 // activities... move it up, but one below the top (the top 2727 // should always have a real activity). 2728 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2729 mLruProcesses.add(N-1, app); 2730 // To keep it from spamming the LRU list (by making a bunch of clients), 2731 // we will push down any other entries owned by the app. 2732 final int uid = app.info.uid; 2733 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2734 ProcessRecord subProc = mLruProcesses.get(i); 2735 if (subProc.info.uid == uid) { 2736 // We want to push this one down the list. If the process after 2737 // it is for the same uid, however, don't do so, because we don't 2738 // want them internally to be re-ordered. 2739 if (mLruProcesses.get(i-1).info.uid != uid) { 2740 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2741 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2742 ProcessRecord tmp = mLruProcesses.get(i); 2743 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2744 mLruProcesses.set(i-1, tmp); 2745 i--; 2746 } 2747 } else { 2748 // A gap, we can stop here. 2749 break; 2750 } 2751 } 2752 } else { 2753 // Process has activities, put it at the very tipsy-top. 2754 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2755 mLruProcesses.add(app); 2756 } 2757 nextIndex = mLruProcessServiceStart; 2758 } else if (hasService) { 2759 // Process has services, put it at the top of the service list. 2760 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2761 mLruProcesses.add(mLruProcessActivityStart, app); 2762 nextIndex = mLruProcessServiceStart; 2763 mLruProcessActivityStart++; 2764 } else { 2765 // Process not otherwise of interest, it goes to the top of the non-service area. 2766 int index = mLruProcessServiceStart; 2767 if (client != null) { 2768 // If there is a client, don't allow the process to be moved up higher 2769 // in the list than that client. 2770 int clientIndex = mLruProcesses.lastIndexOf(client); 2771 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2772 + " when updating " + app); 2773 if (clientIndex <= lrui) { 2774 // Don't allow the client index restriction to push it down farther in the 2775 // list than it already is. 2776 clientIndex = lrui; 2777 } 2778 if (clientIndex >= 0 && index > clientIndex) { 2779 index = clientIndex; 2780 } 2781 } 2782 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2783 mLruProcesses.add(index, app); 2784 nextIndex = index-1; 2785 mLruProcessActivityStart++; 2786 mLruProcessServiceStart++; 2787 } 2788 2789 // If the app is currently using a content provider or service, 2790 // bump those processes as well. 2791 for (int j=app.connections.size()-1; j>=0; j--) { 2792 ConnectionRecord cr = app.connections.valueAt(j); 2793 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2794 && cr.binding.service.app != null 2795 && cr.binding.service.app.lruSeq != mLruSeq 2796 && !cr.binding.service.app.persistent) { 2797 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2798 "service connection", cr, app); 2799 } 2800 } 2801 for (int j=app.conProviders.size()-1; j>=0; j--) { 2802 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2803 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2804 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2805 "provider reference", cpr, app); 2806 } 2807 } 2808 } 2809 2810 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2811 if (uid == Process.SYSTEM_UID) { 2812 // The system gets to run in any process. If there are multiple 2813 // processes with the same uid, just pick the first (this 2814 // should never happen). 2815 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2816 if (procs == null) return null; 2817 final int N = procs.size(); 2818 for (int i = 0; i < N; i++) { 2819 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2820 } 2821 } 2822 ProcessRecord proc = mProcessNames.get(processName, uid); 2823 if (false && proc != null && !keepIfLarge 2824 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2825 && proc.lastCachedPss >= 4000) { 2826 // Turn this condition on to cause killing to happen regularly, for testing. 2827 if (proc.baseProcessTracker != null) { 2828 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2829 } 2830 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2831 } else if (proc != null && !keepIfLarge 2832 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2833 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2834 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2835 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2836 if (proc.baseProcessTracker != null) { 2837 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2838 } 2839 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2840 } 2841 } 2842 return proc; 2843 } 2844 2845 void ensurePackageDexOpt(String packageName) { 2846 IPackageManager pm = AppGlobals.getPackageManager(); 2847 try { 2848 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2849 mDidDexOpt = true; 2850 } 2851 } catch (RemoteException e) { 2852 } 2853 } 2854 2855 boolean isNextTransitionForward() { 2856 int transit = mWindowManager.getPendingAppTransition(); 2857 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2858 || transit == AppTransition.TRANSIT_TASK_OPEN 2859 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2860 } 2861 2862 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2863 String processName, String abiOverride, int uid, Runnable crashHandler) { 2864 synchronized(this) { 2865 ApplicationInfo info = new ApplicationInfo(); 2866 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2867 // For isolated processes, the former contains the parent's uid and the latter the 2868 // actual uid of the isolated process. 2869 // In the special case introduced by this method (which is, starting an isolated 2870 // process directly from the SystemServer without an actual parent app process) the 2871 // closest thing to a parent's uid is SYSTEM_UID. 2872 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2873 // the |isolated| logic in the ProcessRecord constructor. 2874 info.uid = Process.SYSTEM_UID; 2875 info.processName = processName; 2876 info.className = entryPoint; 2877 info.packageName = "android"; 2878 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2879 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2880 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2881 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2882 crashHandler); 2883 return proc != null ? proc.pid : 0; 2884 } 2885 } 2886 2887 final ProcessRecord startProcessLocked(String processName, 2888 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2889 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2890 boolean isolated, boolean keepIfLarge) { 2891 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2892 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2893 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2894 null /* crashHandler */); 2895 } 2896 2897 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2898 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2899 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2900 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2901 long startTime = SystemClock.elapsedRealtime(); 2902 ProcessRecord app; 2903 if (!isolated) { 2904 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2905 checkTime(startTime, "startProcess: after getProcessRecord"); 2906 } else { 2907 // If this is an isolated process, it can't re-use an existing process. 2908 app = null; 2909 } 2910 // We don't have to do anything more if: 2911 // (1) There is an existing application record; and 2912 // (2) The caller doesn't think it is dead, OR there is no thread 2913 // object attached to it so we know it couldn't have crashed; and 2914 // (3) There is a pid assigned to it, so it is either starting or 2915 // already running. 2916 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2917 + " app=" + app + " knownToBeDead=" + knownToBeDead 2918 + " thread=" + (app != null ? app.thread : null) 2919 + " pid=" + (app != null ? app.pid : -1)); 2920 if (app != null && app.pid > 0) { 2921 if (!knownToBeDead || app.thread == null) { 2922 // We already have the app running, or are waiting for it to 2923 // come up (we have a pid but not yet its thread), so keep it. 2924 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2925 // If this is a new package in the process, add the package to the list 2926 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2927 checkTime(startTime, "startProcess: done, added package to proc"); 2928 return app; 2929 } 2930 2931 // An application record is attached to a previous process, 2932 // clean it up now. 2933 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2934 checkTime(startTime, "startProcess: bad proc running, killing"); 2935 Process.killProcessGroup(app.info.uid, app.pid); 2936 handleAppDiedLocked(app, true, true); 2937 checkTime(startTime, "startProcess: done killing old proc"); 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 checkTime(startTime, "startProcess: creating new process record"); 2974 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2975 app.crashHandler = crashHandler; 2976 if (app == null) { 2977 Slog.w(TAG, "Failed making new process record for " 2978 + processName + "/" + info.uid + " isolated=" + isolated); 2979 return null; 2980 } 2981 mProcessNames.put(processName, app.uid, app); 2982 if (isolated) { 2983 mIsolatedProcesses.put(app.uid, app); 2984 } 2985 checkTime(startTime, "startProcess: done creating new process record"); 2986 } else { 2987 // If this is a new package in the process, add the package to the list 2988 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2989 checkTime(startTime, "startProcess: added package to existing proc"); 2990 } 2991 2992 // If the system is not ready yet, then hold off on starting this 2993 // process until it is. 2994 if (!mProcessesReady 2995 && !isAllowedWhileBooting(info) 2996 && !allowWhileBooting) { 2997 if (!mProcessesOnHold.contains(app)) { 2998 mProcessesOnHold.add(app); 2999 } 3000 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3001 return app; 3002 } 3003 3004 startProcessLocked( 3005 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3006 checkTime(startTime, "startProcess: done starting proc!"); 3007 return (app.pid != 0) ? app : null; 3008 } 3009 3010 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3011 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3012 } 3013 3014 private final void startProcessLocked(ProcessRecord app, 3015 String hostingType, String hostingNameStr) { 3016 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3017 null /* entryPoint */, null /* entryPointArgs */); 3018 } 3019 3020 private final void startProcessLocked(ProcessRecord app, String hostingType, 3021 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3022 long startTime = SystemClock.elapsedRealtime(); 3023 if (app.pid > 0 && app.pid != MY_PID) { 3024 checkTime(startTime, "startProcess: removing from pids map"); 3025 synchronized (mPidsSelfLocked) { 3026 mPidsSelfLocked.remove(app.pid); 3027 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3028 } 3029 checkTime(startTime, "startProcess: done removing from pids map"); 3030 app.setPid(0); 3031 } 3032 3033 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3034 "startProcessLocked removing on hold: " + app); 3035 mProcessesOnHold.remove(app); 3036 3037 checkTime(startTime, "startProcess: starting to update cpu stats"); 3038 updateCpuStats(); 3039 checkTime(startTime, "startProcess: done updating cpu stats"); 3040 3041 try { 3042 int uid = app.uid; 3043 3044 int[] gids = null; 3045 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3046 if (!app.isolated) { 3047 int[] permGids = null; 3048 try { 3049 checkTime(startTime, "startProcess: getting gids from package manager"); 3050 final PackageManager pm = mContext.getPackageManager(); 3051 permGids = pm.getPackageGids(app.info.packageName); 3052 3053 if (Environment.isExternalStorageEmulated()) { 3054 checkTime(startTime, "startProcess: checking external storage perm"); 3055 if (pm.checkPermission( 3056 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3057 app.info.packageName) == PERMISSION_GRANTED) { 3058 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3059 } else { 3060 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3061 } 3062 } 3063 } catch (PackageManager.NameNotFoundException e) { 3064 Slog.w(TAG, "Unable to retrieve gids", e); 3065 } 3066 3067 /* 3068 * Add shared application and profile GIDs so applications can share some 3069 * resources like shared libraries and access user-wide resources 3070 */ 3071 if (permGids == null) { 3072 gids = new int[2]; 3073 } else { 3074 gids = new int[permGids.length + 2]; 3075 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3076 } 3077 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3078 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3079 } 3080 checkTime(startTime, "startProcess: building args"); 3081 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3082 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3083 && mTopComponent != null 3084 && app.processName.equals(mTopComponent.getPackageName())) { 3085 uid = 0; 3086 } 3087 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3088 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3089 uid = 0; 3090 } 3091 } 3092 int debugFlags = 0; 3093 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3094 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3095 // Also turn on CheckJNI for debuggable apps. It's quite 3096 // awkward to turn on otherwise. 3097 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3098 } 3099 // Run the app in safe mode if its manifest requests so or the 3100 // system is booted in safe mode. 3101 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3102 mSafeMode == true) { 3103 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3104 } 3105 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3106 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3107 } 3108 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3109 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3110 } 3111 if ("1".equals(SystemProperties.get("debug.assert"))) { 3112 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3113 } 3114 3115 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3116 if (requiredAbi == null) { 3117 requiredAbi = Build.SUPPORTED_ABIS[0]; 3118 } 3119 3120 // Start the process. It will either succeed and return a result containing 3121 // the PID of the new process, or else throw a RuntimeException. 3122 boolean isActivityProcess = (entryPoint == null); 3123 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3124 checkTime(startTime, "startProcess: asking zygote to start proc"); 3125 Process.ProcessStartResult startResult = Process.start(entryPoint, 3126 app.processName, uid, uid, gids, debugFlags, mountExternal, 3127 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3128 checkTime(startTime, "startProcess: returned from zygote!"); 3129 3130 checkTime(startTime, "startProcess: noting battery stats update"); 3131 if (app.isolated) { 3132 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3133 } 3134 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3135 checkTime(startTime, "startProcess: done updating battery stats"); 3136 3137 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3138 UserHandle.getUserId(uid), startResult.pid, uid, 3139 app.processName, hostingType, 3140 hostingNameStr != null ? hostingNameStr : ""); 3141 3142 if (app.persistent) { 3143 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3144 } 3145 3146 checkTime(startTime, "startProcess: building log message"); 3147 StringBuilder buf = mStringBuilder; 3148 buf.setLength(0); 3149 buf.append("Start proc "); 3150 buf.append(app.processName); 3151 if (!isActivityProcess) { 3152 buf.append(" ["); 3153 buf.append(entryPoint); 3154 buf.append("]"); 3155 } 3156 buf.append(" for "); 3157 buf.append(hostingType); 3158 if (hostingNameStr != null) { 3159 buf.append(" "); 3160 buf.append(hostingNameStr); 3161 } 3162 buf.append(": pid="); 3163 buf.append(startResult.pid); 3164 buf.append(" uid="); 3165 buf.append(uid); 3166 buf.append(" gids={"); 3167 if (gids != null) { 3168 for (int gi=0; gi<gids.length; gi++) { 3169 if (gi != 0) buf.append(", "); 3170 buf.append(gids[gi]); 3171 3172 } 3173 } 3174 buf.append("}"); 3175 if (requiredAbi != null) { 3176 buf.append(" abi="); 3177 buf.append(requiredAbi); 3178 } 3179 Slog.i(TAG, buf.toString()); 3180 app.setPid(startResult.pid); 3181 app.usingWrapper = startResult.usingWrapper; 3182 app.removed = false; 3183 app.killedByAm = false; 3184 checkTime(startTime, "startProcess: starting to update pids map"); 3185 synchronized (mPidsSelfLocked) { 3186 this.mPidsSelfLocked.put(startResult.pid, app); 3187 if (isActivityProcess) { 3188 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3189 msg.obj = app; 3190 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3191 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3192 } 3193 } 3194 checkTime(startTime, "startProcess: done updating pids map"); 3195 } catch (RuntimeException e) { 3196 // XXX do better error recovery. 3197 app.setPid(0); 3198 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3199 if (app.isolated) { 3200 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3201 } 3202 Slog.e(TAG, "Failure starting process " + app.processName, e); 3203 } 3204 } 3205 3206 void updateUsageStats(ActivityRecord component, boolean resumed) { 3207 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3208 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3209 if (resumed) { 3210 if (mUsageStatsService != null) { 3211 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3212 System.currentTimeMillis(), 3213 UsageEvents.Event.MOVE_TO_FOREGROUND); 3214 } 3215 synchronized (stats) { 3216 stats.noteActivityResumedLocked(component.app.uid); 3217 } 3218 } else { 3219 if (mUsageStatsService != null) { 3220 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3221 System.currentTimeMillis(), 3222 UsageEvents.Event.MOVE_TO_BACKGROUND); 3223 } 3224 synchronized (stats) { 3225 stats.noteActivityPausedLocked(component.app.uid); 3226 } 3227 } 3228 } 3229 3230 Intent getHomeIntent() { 3231 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3232 intent.setComponent(mTopComponent); 3233 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3234 intent.addCategory(Intent.CATEGORY_HOME); 3235 } 3236 return intent; 3237 } 3238 3239 boolean startHomeActivityLocked(int userId) { 3240 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3241 && mTopAction == null) { 3242 // We are running in factory test mode, but unable to find 3243 // the factory test app, so just sit around displaying the 3244 // error message and don't try to start anything. 3245 return false; 3246 } 3247 Intent intent = getHomeIntent(); 3248 ActivityInfo aInfo = 3249 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3250 if (aInfo != null) { 3251 intent.setComponent(new ComponentName( 3252 aInfo.applicationInfo.packageName, aInfo.name)); 3253 // Don't do this if the home app is currently being 3254 // instrumented. 3255 aInfo = new ActivityInfo(aInfo); 3256 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3257 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3258 aInfo.applicationInfo.uid, true); 3259 if (app == null || app.instrumentationClass == null) { 3260 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3261 mStackSupervisor.startHomeActivity(intent, aInfo); 3262 } 3263 } 3264 3265 return true; 3266 } 3267 3268 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3269 ActivityInfo ai = null; 3270 ComponentName comp = intent.getComponent(); 3271 try { 3272 if (comp != null) { 3273 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3274 } else { 3275 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3276 intent, 3277 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3278 flags, userId); 3279 3280 if (info != null) { 3281 ai = info.activityInfo; 3282 } 3283 } 3284 } catch (RemoteException e) { 3285 // ignore 3286 } 3287 3288 return ai; 3289 } 3290 3291 /** 3292 * Starts the "new version setup screen" if appropriate. 3293 */ 3294 void startSetupActivityLocked() { 3295 // Only do this once per boot. 3296 if (mCheckedForSetup) { 3297 return; 3298 } 3299 3300 // We will show this screen if the current one is a different 3301 // version than the last one shown, and we are not running in 3302 // low-level factory test mode. 3303 final ContentResolver resolver = mContext.getContentResolver(); 3304 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3305 Settings.Global.getInt(resolver, 3306 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3307 mCheckedForSetup = true; 3308 3309 // See if we should be showing the platform update setup UI. 3310 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3311 List<ResolveInfo> ris = mContext.getPackageManager() 3312 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3313 3314 // We don't allow third party apps to replace this. 3315 ResolveInfo ri = null; 3316 for (int i=0; ris != null && i<ris.size(); i++) { 3317 if ((ris.get(i).activityInfo.applicationInfo.flags 3318 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3319 ri = ris.get(i); 3320 break; 3321 } 3322 } 3323 3324 if (ri != null) { 3325 String vers = ri.activityInfo.metaData != null 3326 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3327 : null; 3328 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3329 vers = ri.activityInfo.applicationInfo.metaData.getString( 3330 Intent.METADATA_SETUP_VERSION); 3331 } 3332 String lastVers = Settings.Secure.getString( 3333 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3334 if (vers != null && !vers.equals(lastVers)) { 3335 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3336 intent.setComponent(new ComponentName( 3337 ri.activityInfo.packageName, ri.activityInfo.name)); 3338 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3339 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3340 null); 3341 } 3342 } 3343 } 3344 } 3345 3346 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3347 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3348 } 3349 3350 void enforceNotIsolatedCaller(String caller) { 3351 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3352 throw new SecurityException("Isolated process not allowed to call " + caller); 3353 } 3354 } 3355 3356 @Override 3357 public int getFrontActivityScreenCompatMode() { 3358 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3359 synchronized (this) { 3360 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3361 } 3362 } 3363 3364 @Override 3365 public void setFrontActivityScreenCompatMode(int mode) { 3366 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3367 "setFrontActivityScreenCompatMode"); 3368 synchronized (this) { 3369 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3370 } 3371 } 3372 3373 @Override 3374 public int getPackageScreenCompatMode(String packageName) { 3375 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3376 synchronized (this) { 3377 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3378 } 3379 } 3380 3381 @Override 3382 public void setPackageScreenCompatMode(String packageName, int mode) { 3383 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3384 "setPackageScreenCompatMode"); 3385 synchronized (this) { 3386 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3387 } 3388 } 3389 3390 @Override 3391 public boolean getPackageAskScreenCompat(String packageName) { 3392 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3393 synchronized (this) { 3394 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3395 } 3396 } 3397 3398 @Override 3399 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3400 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3401 "setPackageAskScreenCompat"); 3402 synchronized (this) { 3403 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3404 } 3405 } 3406 3407 private void dispatchProcessesChanged() { 3408 int N; 3409 synchronized (this) { 3410 N = mPendingProcessChanges.size(); 3411 if (mActiveProcessChanges.length < N) { 3412 mActiveProcessChanges = new ProcessChangeItem[N]; 3413 } 3414 mPendingProcessChanges.toArray(mActiveProcessChanges); 3415 mAvailProcessChanges.addAll(mPendingProcessChanges); 3416 mPendingProcessChanges.clear(); 3417 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3418 } 3419 3420 int i = mProcessObservers.beginBroadcast(); 3421 while (i > 0) { 3422 i--; 3423 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3424 if (observer != null) { 3425 try { 3426 for (int j=0; j<N; j++) { 3427 ProcessChangeItem item = mActiveProcessChanges[j]; 3428 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3429 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3430 + item.pid + " uid=" + item.uid + ": " 3431 + item.foregroundActivities); 3432 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3433 item.foregroundActivities); 3434 } 3435 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3436 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3437 + item.pid + " uid=" + item.uid + ": " + item.processState); 3438 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3439 } 3440 } 3441 } catch (RemoteException e) { 3442 } 3443 } 3444 } 3445 mProcessObservers.finishBroadcast(); 3446 } 3447 3448 private void dispatchProcessDied(int pid, int uid) { 3449 int i = mProcessObservers.beginBroadcast(); 3450 while (i > 0) { 3451 i--; 3452 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3453 if (observer != null) { 3454 try { 3455 observer.onProcessDied(pid, uid); 3456 } catch (RemoteException e) { 3457 } 3458 } 3459 } 3460 mProcessObservers.finishBroadcast(); 3461 } 3462 3463 @Override 3464 public final int startActivity(IApplicationThread caller, String callingPackage, 3465 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3466 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3467 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3468 resultWho, requestCode, startFlags, profilerInfo, options, 3469 UserHandle.getCallingUserId()); 3470 } 3471 3472 @Override 3473 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3474 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3475 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3476 enforceNotIsolatedCaller("startActivity"); 3477 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3478 false, ALLOW_FULL_ONLY, "startActivity", null); 3479 // TODO: Switch to user app stacks here. 3480 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3481 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3482 profilerInfo, null, null, options, userId, null, null); 3483 } 3484 3485 @Override 3486 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3487 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3488 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3489 3490 // This is very dangerous -- it allows you to perform a start activity (including 3491 // permission grants) as any app that may launch one of your own activities. So 3492 // we will only allow this to be done from activities that are part of the core framework, 3493 // and then only when they are running as the system. 3494 final ActivityRecord sourceRecord; 3495 final int targetUid; 3496 final String targetPackage; 3497 synchronized (this) { 3498 if (resultTo == null) { 3499 throw new SecurityException("Must be called from an activity"); 3500 } 3501 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3502 if (sourceRecord == null) { 3503 throw new SecurityException("Called with bad activity token: " + resultTo); 3504 } 3505 if (!sourceRecord.info.packageName.equals("android")) { 3506 throw new SecurityException( 3507 "Must be called from an activity that is declared in the android package"); 3508 } 3509 if (sourceRecord.app == null) { 3510 throw new SecurityException("Called without a process attached to activity"); 3511 } 3512 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3513 // This is still okay, as long as this activity is running under the 3514 // uid of the original calling activity. 3515 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3516 throw new SecurityException( 3517 "Calling activity in uid " + sourceRecord.app.uid 3518 + " must be system uid or original calling uid " 3519 + sourceRecord.launchedFromUid); 3520 } 3521 } 3522 targetUid = sourceRecord.launchedFromUid; 3523 targetPackage = sourceRecord.launchedFromPackage; 3524 } 3525 3526 // TODO: Switch to user app stacks here. 3527 try { 3528 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3529 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3530 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3531 return ret; 3532 } catch (SecurityException e) { 3533 // XXX need to figure out how to propagate to original app. 3534 // A SecurityException here is generally actually a fault of the original 3535 // calling activity (such as a fairly granting permissions), so propagate it 3536 // back to them. 3537 /* 3538 StringBuilder msg = new StringBuilder(); 3539 msg.append("While launching"); 3540 msg.append(intent.toString()); 3541 msg.append(": "); 3542 msg.append(e.getMessage()); 3543 */ 3544 throw e; 3545 } 3546 } 3547 3548 @Override 3549 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3550 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3551 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3552 enforceNotIsolatedCaller("startActivityAndWait"); 3553 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3554 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3555 WaitResult res = new WaitResult(); 3556 // TODO: Switch to user app stacks here. 3557 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3558 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3559 options, userId, null, null); 3560 return res; 3561 } 3562 3563 @Override 3564 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3565 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3566 int startFlags, Configuration config, Bundle options, int userId) { 3567 enforceNotIsolatedCaller("startActivityWithConfig"); 3568 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3569 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3570 // TODO: Switch to user app stacks here. 3571 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3572 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3573 null, null, config, options, userId, null, null); 3574 return ret; 3575 } 3576 3577 @Override 3578 public int startActivityIntentSender(IApplicationThread caller, 3579 IntentSender intent, Intent fillInIntent, String resolvedType, 3580 IBinder resultTo, String resultWho, int requestCode, 3581 int flagsMask, int flagsValues, Bundle options) { 3582 enforceNotIsolatedCaller("startActivityIntentSender"); 3583 // Refuse possible leaked file descriptors 3584 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3585 throw new IllegalArgumentException("File descriptors passed in Intent"); 3586 } 3587 3588 IIntentSender sender = intent.getTarget(); 3589 if (!(sender instanceof PendingIntentRecord)) { 3590 throw new IllegalArgumentException("Bad PendingIntent object"); 3591 } 3592 3593 PendingIntentRecord pir = (PendingIntentRecord)sender; 3594 3595 synchronized (this) { 3596 // If this is coming from the currently resumed activity, it is 3597 // effectively saying that app switches are allowed at this point. 3598 final ActivityStack stack = getFocusedStack(); 3599 if (stack.mResumedActivity != null && 3600 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3601 mAppSwitchesAllowedTime = 0; 3602 } 3603 } 3604 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3605 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3606 return ret; 3607 } 3608 3609 @Override 3610 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3611 Intent intent, String resolvedType, IVoiceInteractionSession session, 3612 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3613 Bundle options, int userId) { 3614 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3615 != PackageManager.PERMISSION_GRANTED) { 3616 String msg = "Permission Denial: startVoiceActivity() from pid=" 3617 + Binder.getCallingPid() 3618 + ", uid=" + Binder.getCallingUid() 3619 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3620 Slog.w(TAG, msg); 3621 throw new SecurityException(msg); 3622 } 3623 if (session == null || interactor == null) { 3624 throw new NullPointerException("null session or interactor"); 3625 } 3626 userId = handleIncomingUser(callingPid, callingUid, userId, 3627 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3628 // TODO: Switch to user app stacks here. 3629 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3630 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3631 null, options, userId, null, null); 3632 } 3633 3634 @Override 3635 public boolean startNextMatchingActivity(IBinder callingActivity, 3636 Intent intent, Bundle options) { 3637 // Refuse possible leaked file descriptors 3638 if (intent != null && intent.hasFileDescriptors() == true) { 3639 throw new IllegalArgumentException("File descriptors passed in Intent"); 3640 } 3641 3642 synchronized (this) { 3643 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3644 if (r == null) { 3645 ActivityOptions.abort(options); 3646 return false; 3647 } 3648 if (r.app == null || r.app.thread == null) { 3649 // The caller is not running... d'oh! 3650 ActivityOptions.abort(options); 3651 return false; 3652 } 3653 intent = new Intent(intent); 3654 // The caller is not allowed to change the data. 3655 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3656 // And we are resetting to find the next component... 3657 intent.setComponent(null); 3658 3659 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3660 3661 ActivityInfo aInfo = null; 3662 try { 3663 List<ResolveInfo> resolves = 3664 AppGlobals.getPackageManager().queryIntentActivities( 3665 intent, r.resolvedType, 3666 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3667 UserHandle.getCallingUserId()); 3668 3669 // Look for the original activity in the list... 3670 final int N = resolves != null ? resolves.size() : 0; 3671 for (int i=0; i<N; i++) { 3672 ResolveInfo rInfo = resolves.get(i); 3673 if (rInfo.activityInfo.packageName.equals(r.packageName) 3674 && rInfo.activityInfo.name.equals(r.info.name)) { 3675 // We found the current one... the next matching is 3676 // after it. 3677 i++; 3678 if (i<N) { 3679 aInfo = resolves.get(i).activityInfo; 3680 } 3681 if (debug) { 3682 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3683 + "/" + r.info.name); 3684 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3685 + "/" + aInfo.name); 3686 } 3687 break; 3688 } 3689 } 3690 } catch (RemoteException e) { 3691 } 3692 3693 if (aInfo == null) { 3694 // Nobody who is next! 3695 ActivityOptions.abort(options); 3696 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3697 return false; 3698 } 3699 3700 intent.setComponent(new ComponentName( 3701 aInfo.applicationInfo.packageName, aInfo.name)); 3702 intent.setFlags(intent.getFlags()&~( 3703 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3704 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3705 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3706 Intent.FLAG_ACTIVITY_NEW_TASK)); 3707 3708 // Okay now we need to start the new activity, replacing the 3709 // currently running activity. This is a little tricky because 3710 // we want to start the new one as if the current one is finished, 3711 // but not finish the current one first so that there is no flicker. 3712 // And thus... 3713 final boolean wasFinishing = r.finishing; 3714 r.finishing = true; 3715 3716 // Propagate reply information over to the new activity. 3717 final ActivityRecord resultTo = r.resultTo; 3718 final String resultWho = r.resultWho; 3719 final int requestCode = r.requestCode; 3720 r.resultTo = null; 3721 if (resultTo != null) { 3722 resultTo.removeResultsLocked(r, resultWho, requestCode); 3723 } 3724 3725 final long origId = Binder.clearCallingIdentity(); 3726 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3727 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3728 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3729 options, false, null, null, null); 3730 Binder.restoreCallingIdentity(origId); 3731 3732 r.finishing = wasFinishing; 3733 if (res != ActivityManager.START_SUCCESS) { 3734 return false; 3735 } 3736 return true; 3737 } 3738 } 3739 3740 @Override 3741 public final int startActivityFromRecents(int taskId, Bundle options) { 3742 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3743 String msg = "Permission Denial: startActivityFromRecents called without " + 3744 START_TASKS_FROM_RECENTS; 3745 Slog.w(TAG, msg); 3746 throw new SecurityException(msg); 3747 } 3748 return startActivityFromRecentsInner(taskId, options); 3749 } 3750 3751 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3752 final TaskRecord task; 3753 final int callingUid; 3754 final String callingPackage; 3755 final Intent intent; 3756 final int userId; 3757 synchronized (this) { 3758 task = recentTaskForIdLocked(taskId); 3759 if (task == null) { 3760 throw new IllegalArgumentException("Task " + taskId + " not found."); 3761 } 3762 callingUid = task.mCallingUid; 3763 callingPackage = task.mCallingPackage; 3764 intent = task.intent; 3765 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3766 userId = task.userId; 3767 } 3768 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3769 options, userId, null, task); 3770 } 3771 3772 final int startActivityInPackage(int uid, String callingPackage, 3773 Intent intent, String resolvedType, IBinder resultTo, 3774 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3775 IActivityContainer container, TaskRecord inTask) { 3776 3777 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3778 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3779 3780 // TODO: Switch to user app stacks here. 3781 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3782 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3783 null, null, null, options, userId, container, inTask); 3784 return ret; 3785 } 3786 3787 @Override 3788 public final int startActivities(IApplicationThread caller, String callingPackage, 3789 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3790 int userId) { 3791 enforceNotIsolatedCaller("startActivities"); 3792 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3793 false, ALLOW_FULL_ONLY, "startActivity", null); 3794 // TODO: Switch to user app stacks here. 3795 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3796 resolvedTypes, resultTo, options, userId); 3797 return ret; 3798 } 3799 3800 final int startActivitiesInPackage(int uid, String callingPackage, 3801 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3802 Bundle options, int userId) { 3803 3804 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3805 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3806 // TODO: Switch to user app stacks here. 3807 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3808 resultTo, options, userId); 3809 return ret; 3810 } 3811 3812 //explicitly remove thd old information in mRecentTasks when removing existing user. 3813 private void removeRecentTasksForUserLocked(int userId) { 3814 if(userId <= 0) { 3815 Slog.i(TAG, "Can't remove recent task on user " + userId); 3816 return; 3817 } 3818 3819 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3820 TaskRecord tr = mRecentTasks.get(i); 3821 if (tr.userId == userId) { 3822 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3823 + " when finishing user" + userId); 3824 mRecentTasks.remove(i); 3825 tr.removedFromRecents(mTaskPersister); 3826 } 3827 } 3828 3829 // Remove tasks from persistent storage. 3830 mTaskPersister.wakeup(null, true); 3831 } 3832 3833 /** 3834 * Update the recent tasks lists: make sure tasks should still be here (their 3835 * applications / activities still exist), update their availability, fixup ordering 3836 * of affiliations. 3837 */ 3838 void cleanupRecentTasksLocked(int userId) { 3839 if (mRecentTasks == null) { 3840 // Happens when called from the packagemanager broadcast before boot. 3841 return; 3842 } 3843 3844 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3845 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3846 final IPackageManager pm = AppGlobals.getPackageManager(); 3847 final ActivityInfo dummyAct = new ActivityInfo(); 3848 final ApplicationInfo dummyApp = new ApplicationInfo(); 3849 3850 int N = mRecentTasks.size(); 3851 3852 int[] users = userId == UserHandle.USER_ALL 3853 ? getUsersLocked() : new int[] { userId }; 3854 for (int user : users) { 3855 for (int i = 0; i < N; i++) { 3856 TaskRecord task = mRecentTasks.get(i); 3857 if (task.userId != user) { 3858 // Only look at tasks for the user ID of interest. 3859 continue; 3860 } 3861 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3862 // This situation is broken, and we should just get rid of it now. 3863 mRecentTasks.remove(i); 3864 task.removedFromRecents(mTaskPersister); 3865 i--; 3866 N--; 3867 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3868 continue; 3869 } 3870 // Check whether this activity is currently available. 3871 if (task.realActivity != null) { 3872 ActivityInfo ai = availActCache.get(task.realActivity); 3873 if (ai == null) { 3874 try { 3875 ai = pm.getActivityInfo(task.realActivity, 3876 PackageManager.GET_UNINSTALLED_PACKAGES 3877 | PackageManager.GET_DISABLED_COMPONENTS, user); 3878 } catch (RemoteException e) { 3879 // Will never happen. 3880 continue; 3881 } 3882 if (ai == null) { 3883 ai = dummyAct; 3884 } 3885 availActCache.put(task.realActivity, ai); 3886 } 3887 if (ai == dummyAct) { 3888 // This could be either because the activity no longer exists, or the 3889 // app is temporarily gone. For the former we want to remove the recents 3890 // entry; for the latter we want to mark it as unavailable. 3891 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3892 if (app == null) { 3893 try { 3894 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3895 PackageManager.GET_UNINSTALLED_PACKAGES 3896 | PackageManager.GET_DISABLED_COMPONENTS, user); 3897 } catch (RemoteException e) { 3898 // Will never happen. 3899 continue; 3900 } 3901 if (app == null) { 3902 app = dummyApp; 3903 } 3904 availAppCache.put(task.realActivity.getPackageName(), app); 3905 } 3906 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3907 // Doesn't exist any more! Good-bye. 3908 mRecentTasks.remove(i); 3909 task.removedFromRecents(mTaskPersister); 3910 i--; 3911 N--; 3912 Slog.w(TAG, "Removing no longer valid recent: " + task); 3913 continue; 3914 } else { 3915 // Otherwise just not available for now. 3916 if (task.isAvailable) { 3917 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3918 + task); 3919 } 3920 task.isAvailable = false; 3921 } 3922 } else { 3923 if (!ai.enabled || !ai.applicationInfo.enabled 3924 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3925 if (task.isAvailable) { 3926 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3927 + task + " (enabled=" + ai.enabled + "/" 3928 + ai.applicationInfo.enabled + " flags=" 3929 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3930 } 3931 task.isAvailable = false; 3932 } else { 3933 if (!task.isAvailable) { 3934 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3935 + task); 3936 } 3937 task.isAvailable = true; 3938 } 3939 } 3940 } 3941 } 3942 } 3943 3944 // Verify the affiliate chain for each task. 3945 for (int i = 0; i < N; ) { 3946 TaskRecord task = mRecentTasks.remove(i); 3947 if (mTmpRecents.contains(task)) { 3948 continue; 3949 } 3950 int affiliatedTaskId = task.mAffiliatedTaskId; 3951 while (true) { 3952 TaskRecord next = task.mNextAffiliate; 3953 if (next == null) { 3954 break; 3955 } 3956 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3957 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3958 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3959 task.setNextAffiliate(null); 3960 if (next.mPrevAffiliate == task) { 3961 next.setPrevAffiliate(null); 3962 } 3963 break; 3964 } 3965 if (next.mPrevAffiliate != task) { 3966 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3967 next.mPrevAffiliate + " task=" + task); 3968 next.setPrevAffiliate(null); 3969 task.setNextAffiliate(null); 3970 break; 3971 } 3972 if (!mRecentTasks.contains(next)) { 3973 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3974 task.setNextAffiliate(null); 3975 // We know that next.mPrevAffiliate is always task, from above, so clear 3976 // its previous affiliate. 3977 next.setPrevAffiliate(null); 3978 break; 3979 } 3980 task = next; 3981 } 3982 // task is now the end of the list 3983 do { 3984 mRecentTasks.remove(task); 3985 mRecentTasks.add(i++, task); 3986 mTmpRecents.add(task); 3987 task.inRecents = true; 3988 } while ((task = task.mPrevAffiliate) != null); 3989 } 3990 mTmpRecents.clear(); 3991 // mRecentTasks is now in sorted, affiliated order. 3992 } 3993 3994 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3995 int N = mRecentTasks.size(); 3996 TaskRecord top = task; 3997 int topIndex = taskIndex; 3998 while (top.mNextAffiliate != null && topIndex > 0) { 3999 top = top.mNextAffiliate; 4000 topIndex--; 4001 } 4002 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4003 + topIndex + " from intial " + taskIndex); 4004 // Find the end of the chain, doing a sanity check along the way. 4005 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4006 int endIndex = topIndex; 4007 TaskRecord prev = top; 4008 while (endIndex < N) { 4009 TaskRecord cur = mRecentTasks.get(endIndex); 4010 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4011 + endIndex + " " + cur); 4012 if (cur == top) { 4013 // Verify start of the chain. 4014 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4015 Slog.wtf(TAG, "Bad chain @" + endIndex 4016 + ": first task has next affiliate: " + prev); 4017 sane = false; 4018 break; 4019 } 4020 } else { 4021 // Verify middle of the chain's next points back to the one before. 4022 if (cur.mNextAffiliate != prev 4023 || cur.mNextAffiliateTaskId != prev.taskId) { 4024 Slog.wtf(TAG, "Bad chain @" + endIndex 4025 + ": middle task " + cur + " @" + endIndex 4026 + " has bad next affiliate " 4027 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4028 + ", expected " + prev); 4029 sane = false; 4030 break; 4031 } 4032 } 4033 if (cur.mPrevAffiliateTaskId == -1) { 4034 // Chain ends here. 4035 if (cur.mPrevAffiliate != null) { 4036 Slog.wtf(TAG, "Bad chain @" + endIndex 4037 + ": last task " + cur + " has previous affiliate " 4038 + cur.mPrevAffiliate); 4039 sane = false; 4040 } 4041 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4042 break; 4043 } else { 4044 // Verify middle of the chain's prev points to a valid item. 4045 if (cur.mPrevAffiliate == null) { 4046 Slog.wtf(TAG, "Bad chain @" + endIndex 4047 + ": task " + cur + " has previous affiliate " 4048 + cur.mPrevAffiliate + " but should be id " 4049 + cur.mPrevAffiliate); 4050 sane = false; 4051 break; 4052 } 4053 } 4054 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4055 Slog.wtf(TAG, "Bad chain @" + endIndex 4056 + ": task " + cur + " has affiliated id " 4057 + cur.mAffiliatedTaskId + " but should be " 4058 + task.mAffiliatedTaskId); 4059 sane = false; 4060 break; 4061 } 4062 prev = cur; 4063 endIndex++; 4064 if (endIndex >= N) { 4065 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4066 + ": last task " + prev); 4067 sane = false; 4068 break; 4069 } 4070 } 4071 if (sane) { 4072 if (endIndex < taskIndex) { 4073 Slog.wtf(TAG, "Bad chain @" + endIndex 4074 + ": did not extend to task " + task + " @" + taskIndex); 4075 sane = false; 4076 } 4077 } 4078 if (sane) { 4079 // All looks good, we can just move all of the affiliated tasks 4080 // to the top. 4081 for (int i=topIndex; i<=endIndex; i++) { 4082 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4083 + " from " + i + " to " + (i-topIndex)); 4084 TaskRecord cur = mRecentTasks.remove(i); 4085 mRecentTasks.add(i-topIndex, cur); 4086 } 4087 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4088 + " to " + endIndex); 4089 return true; 4090 } 4091 4092 // Whoops, couldn't do it. 4093 return false; 4094 } 4095 4096 final void addRecentTaskLocked(TaskRecord task) { 4097 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4098 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4099 4100 int N = mRecentTasks.size(); 4101 // Quick case: check if the top-most recent task is the same. 4102 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4103 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4104 return; 4105 } 4106 // Another quick case: check if this is part of a set of affiliated 4107 // tasks that are at the top. 4108 if (isAffiliated && N > 0 && task.inRecents 4109 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4110 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4111 + " at top when adding " + task); 4112 return; 4113 } 4114 // Another quick case: never add voice sessions. 4115 if (task.voiceSession != null) { 4116 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4117 return; 4118 } 4119 4120 boolean needAffiliationFix = false; 4121 4122 // Slightly less quick case: the task is already in recents, so all we need 4123 // to do is move it. 4124 if (task.inRecents) { 4125 int taskIndex = mRecentTasks.indexOf(task); 4126 if (taskIndex >= 0) { 4127 if (!isAffiliated) { 4128 // Simple case: this is not an affiliated task, so we just move it to the front. 4129 mRecentTasks.remove(taskIndex); 4130 mRecentTasks.add(0, task); 4131 notifyTaskPersisterLocked(task, false); 4132 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4133 + " from " + taskIndex); 4134 return; 4135 } else { 4136 // More complicated: need to keep all affiliated tasks together. 4137 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4138 // All went well. 4139 return; 4140 } 4141 4142 // Uh oh... something bad in the affiliation chain, try to rebuild 4143 // everything and then go through our general path of adding a new task. 4144 needAffiliationFix = true; 4145 } 4146 } else { 4147 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4148 needAffiliationFix = true; 4149 } 4150 } 4151 4152 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4153 trimRecentsForTask(task, true); 4154 4155 N = mRecentTasks.size(); 4156 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4157 final TaskRecord tr = mRecentTasks.remove(N - 1); 4158 tr.removedFromRecents(mTaskPersister); 4159 N--; 4160 } 4161 task.inRecents = true; 4162 if (!isAffiliated || needAffiliationFix) { 4163 // If this is a simple non-affiliated task, or we had some failure trying to 4164 // handle it as part of an affilated task, then just place it at the top. 4165 mRecentTasks.add(0, task); 4166 } else if (isAffiliated) { 4167 // If this is a new affiliated task, then move all of the affiliated tasks 4168 // to the front and insert this new one. 4169 TaskRecord other = task.mNextAffiliate; 4170 if (other == null) { 4171 other = task.mPrevAffiliate; 4172 } 4173 if (other != null) { 4174 int otherIndex = mRecentTasks.indexOf(other); 4175 if (otherIndex >= 0) { 4176 // Insert new task at appropriate location. 4177 int taskIndex; 4178 if (other == task.mNextAffiliate) { 4179 // We found the index of our next affiliation, which is who is 4180 // before us in the list, so add after that point. 4181 taskIndex = otherIndex+1; 4182 } else { 4183 // We found the index of our previous affiliation, which is who is 4184 // after us in the list, so add at their position. 4185 taskIndex = otherIndex; 4186 } 4187 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4188 + taskIndex + ": " + task); 4189 mRecentTasks.add(taskIndex, task); 4190 4191 // Now move everything to the front. 4192 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4193 // All went well. 4194 return; 4195 } 4196 4197 // Uh oh... something bad in the affiliation chain, try to rebuild 4198 // everything and then go through our general path of adding a new task. 4199 needAffiliationFix = true; 4200 } else { 4201 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4202 + other); 4203 needAffiliationFix = true; 4204 } 4205 } else { 4206 if (DEBUG_RECENTS) Slog.d(TAG, 4207 "addRecent: adding affiliated task without next/prev:" + task); 4208 needAffiliationFix = true; 4209 } 4210 } 4211 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4212 4213 if (needAffiliationFix) { 4214 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4215 cleanupRecentTasksLocked(task.userId); 4216 } 4217 } 4218 4219 /** 4220 * If needed, remove oldest existing entries in recents that are for the same kind 4221 * of task as the given one. 4222 */ 4223 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4224 int N = mRecentTasks.size(); 4225 final Intent intent = task.intent; 4226 final boolean document = intent != null && intent.isDocument(); 4227 4228 int maxRecents = task.maxRecents - 1; 4229 for (int i=0; i<N; i++) { 4230 final TaskRecord tr = mRecentTasks.get(i); 4231 if (task != tr) { 4232 if (task.userId != tr.userId) { 4233 continue; 4234 } 4235 if (i > MAX_RECENT_BITMAPS) { 4236 tr.freeLastThumbnail(); 4237 } 4238 final Intent trIntent = tr.intent; 4239 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4240 (intent == null || !intent.filterEquals(trIntent))) { 4241 continue; 4242 } 4243 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4244 if (document && trIsDocument) { 4245 // These are the same document activity (not necessarily the same doc). 4246 if (maxRecents > 0) { 4247 --maxRecents; 4248 continue; 4249 } 4250 // Hit the maximum number of documents for this task. Fall through 4251 // and remove this document from recents. 4252 } else if (document || trIsDocument) { 4253 // Only one of these is a document. Not the droid we're looking for. 4254 continue; 4255 } 4256 } 4257 4258 if (!doTrim) { 4259 // If the caller is not actually asking for a trim, just tell them we reached 4260 // a point where the trim would happen. 4261 return i; 4262 } 4263 4264 // Either task and tr are the same or, their affinities match or their intents match 4265 // and neither of them is a document, or they are documents using the same activity 4266 // and their maxRecents has been reached. 4267 tr.disposeThumbnail(); 4268 mRecentTasks.remove(i); 4269 if (task != tr) { 4270 tr.removedFromRecents(mTaskPersister); 4271 } 4272 i--; 4273 N--; 4274 if (task.intent == null) { 4275 // If the new recent task we are adding is not fully 4276 // specified, then replace it with the existing recent task. 4277 task = tr; 4278 } 4279 notifyTaskPersisterLocked(tr, false); 4280 } 4281 4282 return -1; 4283 } 4284 4285 @Override 4286 public void reportActivityFullyDrawn(IBinder token) { 4287 synchronized (this) { 4288 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4289 if (r == null) { 4290 return; 4291 } 4292 r.reportFullyDrawnLocked(); 4293 } 4294 } 4295 4296 @Override 4297 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4298 synchronized (this) { 4299 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4300 if (r == null) { 4301 return; 4302 } 4303 final long origId = Binder.clearCallingIdentity(); 4304 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4305 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4306 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4307 if (config != null) { 4308 r.frozenBeforeDestroy = true; 4309 if (!updateConfigurationLocked(config, r, false, false)) { 4310 mStackSupervisor.resumeTopActivitiesLocked(); 4311 } 4312 } 4313 Binder.restoreCallingIdentity(origId); 4314 } 4315 } 4316 4317 @Override 4318 public int getRequestedOrientation(IBinder token) { 4319 synchronized (this) { 4320 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4321 if (r == null) { 4322 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4323 } 4324 return mWindowManager.getAppOrientation(r.appToken); 4325 } 4326 } 4327 4328 /** 4329 * This is the internal entry point for handling Activity.finish(). 4330 * 4331 * @param token The Binder token referencing the Activity we want to finish. 4332 * @param resultCode Result code, if any, from this Activity. 4333 * @param resultData Result data (Intent), if any, from this Activity. 4334 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4335 * the root Activity in the task. 4336 * 4337 * @return Returns true if the activity successfully finished, or false if it is still running. 4338 */ 4339 @Override 4340 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4341 boolean finishTask) { 4342 // Refuse possible leaked file descriptors 4343 if (resultData != null && resultData.hasFileDescriptors() == true) { 4344 throw new IllegalArgumentException("File descriptors passed in Intent"); 4345 } 4346 4347 synchronized(this) { 4348 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4349 if (r == null) { 4350 return true; 4351 } 4352 // Keep track of the root activity of the task before we finish it 4353 TaskRecord tr = r.task; 4354 ActivityRecord rootR = tr.getRootActivity(); 4355 // Do not allow task to finish in Lock Task mode. 4356 if (tr == mStackSupervisor.mLockTaskModeTask) { 4357 if (rootR == r) { 4358 mStackSupervisor.showLockTaskToast(); 4359 return false; 4360 } 4361 } 4362 if (mController != null) { 4363 // Find the first activity that is not finishing. 4364 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4365 if (next != null) { 4366 // ask watcher if this is allowed 4367 boolean resumeOK = true; 4368 try { 4369 resumeOK = mController.activityResuming(next.packageName); 4370 } catch (RemoteException e) { 4371 mController = null; 4372 Watchdog.getInstance().setActivityController(null); 4373 } 4374 4375 if (!resumeOK) { 4376 return false; 4377 } 4378 } 4379 } 4380 final long origId = Binder.clearCallingIdentity(); 4381 try { 4382 boolean res; 4383 if (finishTask && r == rootR) { 4384 // If requested, remove the task that is associated to this activity only if it 4385 // was the root activity in the task. The result code and data is ignored because 4386 // we don't support returning them across task boundaries. 4387 res = removeTaskByIdLocked(tr.taskId, 0); 4388 } else { 4389 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4390 resultData, "app-request", true); 4391 } 4392 return res; 4393 } finally { 4394 Binder.restoreCallingIdentity(origId); 4395 } 4396 } 4397 } 4398 4399 @Override 4400 public final void finishHeavyWeightApp() { 4401 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4402 != PackageManager.PERMISSION_GRANTED) { 4403 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4404 + Binder.getCallingPid() 4405 + ", uid=" + Binder.getCallingUid() 4406 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4407 Slog.w(TAG, msg); 4408 throw new SecurityException(msg); 4409 } 4410 4411 synchronized(this) { 4412 if (mHeavyWeightProcess == null) { 4413 return; 4414 } 4415 4416 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4417 mHeavyWeightProcess.activities); 4418 for (int i=0; i<activities.size(); i++) { 4419 ActivityRecord r = activities.get(i); 4420 if (!r.finishing) { 4421 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4422 null, "finish-heavy", true); 4423 } 4424 } 4425 4426 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4427 mHeavyWeightProcess.userId, 0)); 4428 mHeavyWeightProcess = null; 4429 } 4430 } 4431 4432 @Override 4433 public void crashApplication(int uid, int initialPid, String packageName, 4434 String message) { 4435 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4436 != PackageManager.PERMISSION_GRANTED) { 4437 String msg = "Permission Denial: crashApplication() from pid=" 4438 + Binder.getCallingPid() 4439 + ", uid=" + Binder.getCallingUid() 4440 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4441 Slog.w(TAG, msg); 4442 throw new SecurityException(msg); 4443 } 4444 4445 synchronized(this) { 4446 ProcessRecord proc = null; 4447 4448 // Figure out which process to kill. We don't trust that initialPid 4449 // still has any relation to current pids, so must scan through the 4450 // list. 4451 synchronized (mPidsSelfLocked) { 4452 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4453 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4454 if (p.uid != uid) { 4455 continue; 4456 } 4457 if (p.pid == initialPid) { 4458 proc = p; 4459 break; 4460 } 4461 if (p.pkgList.containsKey(packageName)) { 4462 proc = p; 4463 } 4464 } 4465 } 4466 4467 if (proc == null) { 4468 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4469 + " initialPid=" + initialPid 4470 + " packageName=" + packageName); 4471 return; 4472 } 4473 4474 if (proc.thread != null) { 4475 if (proc.pid == Process.myPid()) { 4476 Log.w(TAG, "crashApplication: trying to crash self!"); 4477 return; 4478 } 4479 long ident = Binder.clearCallingIdentity(); 4480 try { 4481 proc.thread.scheduleCrash(message); 4482 } catch (RemoteException e) { 4483 } 4484 Binder.restoreCallingIdentity(ident); 4485 } 4486 } 4487 } 4488 4489 @Override 4490 public final void finishSubActivity(IBinder token, String resultWho, 4491 int requestCode) { 4492 synchronized(this) { 4493 final long origId = Binder.clearCallingIdentity(); 4494 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4495 if (r != null) { 4496 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4497 } 4498 Binder.restoreCallingIdentity(origId); 4499 } 4500 } 4501 4502 @Override 4503 public boolean finishActivityAffinity(IBinder token) { 4504 synchronized(this) { 4505 final long origId = Binder.clearCallingIdentity(); 4506 try { 4507 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4508 4509 ActivityRecord rootR = r.task.getRootActivity(); 4510 // Do not allow task to finish in Lock Task mode. 4511 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4512 if (rootR == r) { 4513 mStackSupervisor.showLockTaskToast(); 4514 return false; 4515 } 4516 } 4517 boolean res = false; 4518 if (r != null) { 4519 res = r.task.stack.finishActivityAffinityLocked(r); 4520 } 4521 return res; 4522 } finally { 4523 Binder.restoreCallingIdentity(origId); 4524 } 4525 } 4526 } 4527 4528 @Override 4529 public void finishVoiceTask(IVoiceInteractionSession session) { 4530 synchronized(this) { 4531 final long origId = Binder.clearCallingIdentity(); 4532 try { 4533 mStackSupervisor.finishVoiceTask(session); 4534 } finally { 4535 Binder.restoreCallingIdentity(origId); 4536 } 4537 } 4538 4539 } 4540 4541 @Override 4542 public boolean releaseActivityInstance(IBinder token) { 4543 synchronized(this) { 4544 final long origId = Binder.clearCallingIdentity(); 4545 try { 4546 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4547 if (r.task == null || r.task.stack == null) { 4548 return false; 4549 } 4550 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4551 } finally { 4552 Binder.restoreCallingIdentity(origId); 4553 } 4554 } 4555 } 4556 4557 @Override 4558 public void releaseSomeActivities(IApplicationThread appInt) { 4559 synchronized(this) { 4560 final long origId = Binder.clearCallingIdentity(); 4561 try { 4562 ProcessRecord app = getRecordForAppLocked(appInt); 4563 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4564 } finally { 4565 Binder.restoreCallingIdentity(origId); 4566 } 4567 } 4568 } 4569 4570 @Override 4571 public boolean willActivityBeVisible(IBinder token) { 4572 synchronized(this) { 4573 ActivityStack stack = ActivityRecord.getStackLocked(token); 4574 if (stack != null) { 4575 return stack.willActivityBeVisibleLocked(token); 4576 } 4577 return false; 4578 } 4579 } 4580 4581 @Override 4582 public void overridePendingTransition(IBinder token, String packageName, 4583 int enterAnim, int exitAnim) { 4584 synchronized(this) { 4585 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4586 if (self == null) { 4587 return; 4588 } 4589 4590 final long origId = Binder.clearCallingIdentity(); 4591 4592 if (self.state == ActivityState.RESUMED 4593 || self.state == ActivityState.PAUSING) { 4594 mWindowManager.overridePendingAppTransition(packageName, 4595 enterAnim, exitAnim, null); 4596 } 4597 4598 Binder.restoreCallingIdentity(origId); 4599 } 4600 } 4601 4602 /** 4603 * Main function for removing an existing process from the activity manager 4604 * as a result of that process going away. Clears out all connections 4605 * to the process. 4606 */ 4607 private final void handleAppDiedLocked(ProcessRecord app, 4608 boolean restarting, boolean allowRestart) { 4609 int pid = app.pid; 4610 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4611 if (!restarting) { 4612 removeLruProcessLocked(app); 4613 if (pid > 0) { 4614 ProcessList.remove(pid); 4615 } 4616 } 4617 4618 if (mProfileProc == app) { 4619 clearProfilerLocked(); 4620 } 4621 4622 // Remove this application's activities from active lists. 4623 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4624 4625 app.activities.clear(); 4626 4627 if (app.instrumentationClass != null) { 4628 Slog.w(TAG, "Crash of app " + app.processName 4629 + " running instrumentation " + app.instrumentationClass); 4630 Bundle info = new Bundle(); 4631 info.putString("shortMsg", "Process crashed."); 4632 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4633 } 4634 4635 if (!restarting) { 4636 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4637 // If there was nothing to resume, and we are not already 4638 // restarting this process, but there is a visible activity that 4639 // is hosted by the process... then make sure all visible 4640 // activities are running, taking care of restarting this 4641 // process. 4642 if (hasVisibleActivities) { 4643 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4644 } 4645 } 4646 } 4647 } 4648 4649 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4650 IBinder threadBinder = thread.asBinder(); 4651 // Find the application record. 4652 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4653 ProcessRecord rec = mLruProcesses.get(i); 4654 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4655 return i; 4656 } 4657 } 4658 return -1; 4659 } 4660 4661 final ProcessRecord getRecordForAppLocked( 4662 IApplicationThread thread) { 4663 if (thread == null) { 4664 return null; 4665 } 4666 4667 int appIndex = getLRURecordIndexForAppLocked(thread); 4668 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4669 } 4670 4671 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4672 // If there are no longer any background processes running, 4673 // and the app that died was not running instrumentation, 4674 // then tell everyone we are now low on memory. 4675 boolean haveBg = false; 4676 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4677 ProcessRecord rec = mLruProcesses.get(i); 4678 if (rec.thread != null 4679 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4680 haveBg = true; 4681 break; 4682 } 4683 } 4684 4685 if (!haveBg) { 4686 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4687 if (doReport) { 4688 long now = SystemClock.uptimeMillis(); 4689 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4690 doReport = false; 4691 } else { 4692 mLastMemUsageReportTime = now; 4693 } 4694 } 4695 final ArrayList<ProcessMemInfo> memInfos 4696 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4697 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4698 long now = SystemClock.uptimeMillis(); 4699 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4700 ProcessRecord rec = mLruProcesses.get(i); 4701 if (rec == dyingProc || rec.thread == null) { 4702 continue; 4703 } 4704 if (doReport) { 4705 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4706 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4707 } 4708 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4709 // The low memory report is overriding any current 4710 // state for a GC request. Make sure to do 4711 // heavy/important/visible/foreground processes first. 4712 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4713 rec.lastRequestedGc = 0; 4714 } else { 4715 rec.lastRequestedGc = rec.lastLowMemory; 4716 } 4717 rec.reportLowMemory = true; 4718 rec.lastLowMemory = now; 4719 mProcessesToGc.remove(rec); 4720 addProcessToGcListLocked(rec); 4721 } 4722 } 4723 if (doReport) { 4724 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4725 mHandler.sendMessage(msg); 4726 } 4727 scheduleAppGcsLocked(); 4728 } 4729 } 4730 4731 final void appDiedLocked(ProcessRecord app) { 4732 appDiedLocked(app, app.pid, app.thread); 4733 } 4734 4735 final void appDiedLocked(ProcessRecord app, int pid, 4736 IApplicationThread thread) { 4737 4738 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4739 synchronized (stats) { 4740 stats.noteProcessDiedLocked(app.info.uid, pid); 4741 } 4742 4743 Process.killProcessGroup(app.info.uid, pid); 4744 4745 // Clean up already done if the process has been re-started. 4746 if (app.pid == pid && app.thread != null && 4747 app.thread.asBinder() == thread.asBinder()) { 4748 boolean doLowMem = app.instrumentationClass == null; 4749 boolean doOomAdj = doLowMem; 4750 if (!app.killedByAm) { 4751 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4752 + ") has died."); 4753 mAllowLowerMemLevel = true; 4754 } else { 4755 // Note that we always want to do oom adj to update our state with the 4756 // new number of procs. 4757 mAllowLowerMemLevel = false; 4758 doLowMem = false; 4759 } 4760 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4761 if (DEBUG_CLEANUP) Slog.v( 4762 TAG, "Dying app: " + app + ", pid: " + pid 4763 + ", thread: " + thread.asBinder()); 4764 handleAppDiedLocked(app, false, true); 4765 4766 if (doOomAdj) { 4767 updateOomAdjLocked(); 4768 } 4769 if (doLowMem) { 4770 doLowMemReportIfNeededLocked(app); 4771 } 4772 } else if (app.pid != pid) { 4773 // A new process has already been started. 4774 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4775 + ") has died and restarted (pid " + app.pid + ")."); 4776 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4777 } else if (DEBUG_PROCESSES) { 4778 Slog.d(TAG, "Received spurious death notification for thread " 4779 + thread.asBinder()); 4780 } 4781 } 4782 4783 /** 4784 * If a stack trace dump file is configured, dump process stack traces. 4785 * @param clearTraces causes the dump file to be erased prior to the new 4786 * traces being written, if true; when false, the new traces will be 4787 * appended to any existing file content. 4788 * @param firstPids of dalvik VM processes to dump stack traces for first 4789 * @param lastPids of dalvik VM processes to dump stack traces for last 4790 * @param nativeProcs optional list of native process names to dump stack crawls 4791 * @return file containing stack traces, or null if no dump file is configured 4792 */ 4793 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4794 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4795 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4796 if (tracesPath == null || tracesPath.length() == 0) { 4797 return null; 4798 } 4799 4800 File tracesFile = new File(tracesPath); 4801 try { 4802 File tracesDir = tracesFile.getParentFile(); 4803 if (!tracesDir.exists()) { 4804 tracesFile.mkdirs(); 4805 if (!SELinux.restorecon(tracesDir)) { 4806 return null; 4807 } 4808 } 4809 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4810 4811 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4812 tracesFile.createNewFile(); 4813 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4814 } catch (IOException e) { 4815 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4816 return null; 4817 } 4818 4819 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4820 return tracesFile; 4821 } 4822 4823 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4824 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4825 // Use a FileObserver to detect when traces finish writing. 4826 // The order of traces is considered important to maintain for legibility. 4827 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4828 @Override 4829 public synchronized void onEvent(int event, String path) { notify(); } 4830 }; 4831 4832 try { 4833 observer.startWatching(); 4834 4835 // First collect all of the stacks of the most important pids. 4836 if (firstPids != null) { 4837 try { 4838 int num = firstPids.size(); 4839 for (int i = 0; i < num; i++) { 4840 synchronized (observer) { 4841 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4842 observer.wait(200); // Wait for write-close, give up after 200msec 4843 } 4844 } 4845 } catch (InterruptedException e) { 4846 Log.wtf(TAG, e); 4847 } 4848 } 4849 4850 // Next collect the stacks of the native pids 4851 if (nativeProcs != null) { 4852 int[] pids = Process.getPidsForCommands(nativeProcs); 4853 if (pids != null) { 4854 for (int pid : pids) { 4855 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4856 } 4857 } 4858 } 4859 4860 // Lastly, measure CPU usage. 4861 if (processCpuTracker != null) { 4862 processCpuTracker.init(); 4863 System.gc(); 4864 processCpuTracker.update(); 4865 try { 4866 synchronized (processCpuTracker) { 4867 processCpuTracker.wait(500); // measure over 1/2 second. 4868 } 4869 } catch (InterruptedException e) { 4870 } 4871 processCpuTracker.update(); 4872 4873 // We'll take the stack crawls of just the top apps using CPU. 4874 final int N = processCpuTracker.countWorkingStats(); 4875 int numProcs = 0; 4876 for (int i=0; i<N && numProcs<5; i++) { 4877 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4878 if (lastPids.indexOfKey(stats.pid) >= 0) { 4879 numProcs++; 4880 try { 4881 synchronized (observer) { 4882 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4883 observer.wait(200); // Wait for write-close, give up after 200msec 4884 } 4885 } catch (InterruptedException e) { 4886 Log.wtf(TAG, e); 4887 } 4888 4889 } 4890 } 4891 } 4892 } finally { 4893 observer.stopWatching(); 4894 } 4895 } 4896 4897 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4898 if (true || IS_USER_BUILD) { 4899 return; 4900 } 4901 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4902 if (tracesPath == null || tracesPath.length() == 0) { 4903 return; 4904 } 4905 4906 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4907 StrictMode.allowThreadDiskWrites(); 4908 try { 4909 final File tracesFile = new File(tracesPath); 4910 final File tracesDir = tracesFile.getParentFile(); 4911 final File tracesTmp = new File(tracesDir, "__tmp__"); 4912 try { 4913 if (!tracesDir.exists()) { 4914 tracesFile.mkdirs(); 4915 if (!SELinux.restorecon(tracesDir.getPath())) { 4916 return; 4917 } 4918 } 4919 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4920 4921 if (tracesFile.exists()) { 4922 tracesTmp.delete(); 4923 tracesFile.renameTo(tracesTmp); 4924 } 4925 StringBuilder sb = new StringBuilder(); 4926 Time tobj = new Time(); 4927 tobj.set(System.currentTimeMillis()); 4928 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4929 sb.append(": "); 4930 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4931 sb.append(" since "); 4932 sb.append(msg); 4933 FileOutputStream fos = new FileOutputStream(tracesFile); 4934 fos.write(sb.toString().getBytes()); 4935 if (app == null) { 4936 fos.write("\n*** No application process!".getBytes()); 4937 } 4938 fos.close(); 4939 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4940 } catch (IOException e) { 4941 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4942 return; 4943 } 4944 4945 if (app != null) { 4946 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4947 firstPids.add(app.pid); 4948 dumpStackTraces(tracesPath, firstPids, null, null, null); 4949 } 4950 4951 File lastTracesFile = null; 4952 File curTracesFile = null; 4953 for (int i=9; i>=0; i--) { 4954 String name = String.format(Locale.US, "slow%02d.txt", i); 4955 curTracesFile = new File(tracesDir, name); 4956 if (curTracesFile.exists()) { 4957 if (lastTracesFile != null) { 4958 curTracesFile.renameTo(lastTracesFile); 4959 } else { 4960 curTracesFile.delete(); 4961 } 4962 } 4963 lastTracesFile = curTracesFile; 4964 } 4965 tracesFile.renameTo(curTracesFile); 4966 if (tracesTmp.exists()) { 4967 tracesTmp.renameTo(tracesFile); 4968 } 4969 } finally { 4970 StrictMode.setThreadPolicy(oldPolicy); 4971 } 4972 } 4973 4974 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4975 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4976 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4977 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4978 4979 if (mController != null) { 4980 try { 4981 // 0 == continue, -1 = kill process immediately 4982 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4983 if (res < 0 && app.pid != MY_PID) { 4984 app.kill("anr", true); 4985 } 4986 } catch (RemoteException e) { 4987 mController = null; 4988 Watchdog.getInstance().setActivityController(null); 4989 } 4990 } 4991 4992 long anrTime = SystemClock.uptimeMillis(); 4993 if (MONITOR_CPU_USAGE) { 4994 updateCpuStatsNow(); 4995 } 4996 4997 synchronized (this) { 4998 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4999 if (mShuttingDown) { 5000 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5001 return; 5002 } else if (app.notResponding) { 5003 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5004 return; 5005 } else if (app.crashing) { 5006 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5007 return; 5008 } 5009 5010 // In case we come through here for the same app before completing 5011 // this one, mark as anring now so we will bail out. 5012 app.notResponding = true; 5013 5014 // Log the ANR to the event log. 5015 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5016 app.processName, app.info.flags, annotation); 5017 5018 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5019 firstPids.add(app.pid); 5020 5021 int parentPid = app.pid; 5022 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5023 if (parentPid != app.pid) firstPids.add(parentPid); 5024 5025 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5026 5027 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5028 ProcessRecord r = mLruProcesses.get(i); 5029 if (r != null && r.thread != null) { 5030 int pid = r.pid; 5031 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5032 if (r.persistent) { 5033 firstPids.add(pid); 5034 } else { 5035 lastPids.put(pid, Boolean.TRUE); 5036 } 5037 } 5038 } 5039 } 5040 } 5041 5042 // Log the ANR to the main log. 5043 StringBuilder info = new StringBuilder(); 5044 info.setLength(0); 5045 info.append("ANR in ").append(app.processName); 5046 if (activity != null && activity.shortComponentName != null) { 5047 info.append(" (").append(activity.shortComponentName).append(")"); 5048 } 5049 info.append("\n"); 5050 info.append("PID: ").append(app.pid).append("\n"); 5051 if (annotation != null) { 5052 info.append("Reason: ").append(annotation).append("\n"); 5053 } 5054 if (parent != null && parent != activity) { 5055 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5056 } 5057 5058 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5059 5060 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5061 NATIVE_STACKS_OF_INTEREST); 5062 5063 String cpuInfo = null; 5064 if (MONITOR_CPU_USAGE) { 5065 updateCpuStatsNow(); 5066 synchronized (mProcessCpuThread) { 5067 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5068 } 5069 info.append(processCpuTracker.printCurrentLoad()); 5070 info.append(cpuInfo); 5071 } 5072 5073 info.append(processCpuTracker.printCurrentState(anrTime)); 5074 5075 Slog.e(TAG, info.toString()); 5076 if (tracesFile == null) { 5077 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5078 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5079 } 5080 5081 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5082 cpuInfo, tracesFile, null); 5083 5084 if (mController != null) { 5085 try { 5086 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5087 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5088 if (res != 0) { 5089 if (res < 0 && app.pid != MY_PID) { 5090 app.kill("anr", true); 5091 } else { 5092 synchronized (this) { 5093 mServices.scheduleServiceTimeoutLocked(app); 5094 } 5095 } 5096 return; 5097 } 5098 } catch (RemoteException e) { 5099 mController = null; 5100 Watchdog.getInstance().setActivityController(null); 5101 } 5102 } 5103 5104 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5105 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5106 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5107 5108 synchronized (this) { 5109 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5110 app.kill("bg anr", true); 5111 return; 5112 } 5113 5114 // Set the app's notResponding state, and look up the errorReportReceiver 5115 makeAppNotRespondingLocked(app, 5116 activity != null ? activity.shortComponentName : null, 5117 annotation != null ? "ANR " + annotation : "ANR", 5118 info.toString()); 5119 5120 // Bring up the infamous App Not Responding dialog 5121 Message msg = Message.obtain(); 5122 HashMap<String, Object> map = new HashMap<String, Object>(); 5123 msg.what = SHOW_NOT_RESPONDING_MSG; 5124 msg.obj = map; 5125 msg.arg1 = aboveSystem ? 1 : 0; 5126 map.put("app", app); 5127 if (activity != null) { 5128 map.put("activity", activity); 5129 } 5130 5131 mHandler.sendMessage(msg); 5132 } 5133 } 5134 5135 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5136 if (!mLaunchWarningShown) { 5137 mLaunchWarningShown = true; 5138 mHandler.post(new Runnable() { 5139 @Override 5140 public void run() { 5141 synchronized (ActivityManagerService.this) { 5142 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5143 d.show(); 5144 mHandler.postDelayed(new Runnable() { 5145 @Override 5146 public void run() { 5147 synchronized (ActivityManagerService.this) { 5148 d.dismiss(); 5149 mLaunchWarningShown = false; 5150 } 5151 } 5152 }, 4000); 5153 } 5154 } 5155 }); 5156 } 5157 } 5158 5159 @Override 5160 public boolean clearApplicationUserData(final String packageName, 5161 final IPackageDataObserver observer, int userId) { 5162 enforceNotIsolatedCaller("clearApplicationUserData"); 5163 int uid = Binder.getCallingUid(); 5164 int pid = Binder.getCallingPid(); 5165 userId = handleIncomingUser(pid, uid, 5166 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5167 long callingId = Binder.clearCallingIdentity(); 5168 try { 5169 IPackageManager pm = AppGlobals.getPackageManager(); 5170 int pkgUid = -1; 5171 synchronized(this) { 5172 try { 5173 pkgUid = pm.getPackageUid(packageName, userId); 5174 } catch (RemoteException e) { 5175 } 5176 if (pkgUid == -1) { 5177 Slog.w(TAG, "Invalid packageName: " + packageName); 5178 if (observer != null) { 5179 try { 5180 observer.onRemoveCompleted(packageName, false); 5181 } catch (RemoteException e) { 5182 Slog.i(TAG, "Observer no longer exists."); 5183 } 5184 } 5185 return false; 5186 } 5187 if (uid == pkgUid || checkComponentPermission( 5188 android.Manifest.permission.CLEAR_APP_USER_DATA, 5189 pid, uid, -1, true) 5190 == PackageManager.PERMISSION_GRANTED) { 5191 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5192 } else { 5193 throw new SecurityException("PID " + pid + " does not have permission " 5194 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5195 + " of package " + packageName); 5196 } 5197 5198 // Remove all tasks match the cleared application package and user 5199 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5200 final TaskRecord tr = mRecentTasks.get(i); 5201 final String taskPackageName = 5202 tr.getBaseIntent().getComponent().getPackageName(); 5203 if (tr.userId != userId) continue; 5204 if (!taskPackageName.equals(packageName)) continue; 5205 removeTaskByIdLocked(tr.taskId, 0); 5206 } 5207 } 5208 5209 try { 5210 // Clear application user data 5211 pm.clearApplicationUserData(packageName, observer, userId); 5212 5213 synchronized(this) { 5214 // Remove all permissions granted from/to this package 5215 removeUriPermissionsForPackageLocked(packageName, userId, true); 5216 } 5217 5218 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5219 Uri.fromParts("package", packageName, null)); 5220 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5221 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5222 null, null, 0, null, null, null, false, false, userId); 5223 } catch (RemoteException e) { 5224 } 5225 } finally { 5226 Binder.restoreCallingIdentity(callingId); 5227 } 5228 return true; 5229 } 5230 5231 @Override 5232 public void killBackgroundProcesses(final String packageName, int userId) { 5233 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5234 != PackageManager.PERMISSION_GRANTED && 5235 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5236 != PackageManager.PERMISSION_GRANTED) { 5237 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5238 + Binder.getCallingPid() 5239 + ", uid=" + Binder.getCallingUid() 5240 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5241 Slog.w(TAG, msg); 5242 throw new SecurityException(msg); 5243 } 5244 5245 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5246 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5247 long callingId = Binder.clearCallingIdentity(); 5248 try { 5249 IPackageManager pm = AppGlobals.getPackageManager(); 5250 synchronized(this) { 5251 int appId = -1; 5252 try { 5253 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5254 } catch (RemoteException e) { 5255 } 5256 if (appId == -1) { 5257 Slog.w(TAG, "Invalid packageName: " + packageName); 5258 return; 5259 } 5260 killPackageProcessesLocked(packageName, appId, userId, 5261 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5262 } 5263 } finally { 5264 Binder.restoreCallingIdentity(callingId); 5265 } 5266 } 5267 5268 @Override 5269 public void killAllBackgroundProcesses() { 5270 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5271 != PackageManager.PERMISSION_GRANTED) { 5272 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5273 + Binder.getCallingPid() 5274 + ", uid=" + Binder.getCallingUid() 5275 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5276 Slog.w(TAG, msg); 5277 throw new SecurityException(msg); 5278 } 5279 5280 long callingId = Binder.clearCallingIdentity(); 5281 try { 5282 synchronized(this) { 5283 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5284 final int NP = mProcessNames.getMap().size(); 5285 for (int ip=0; ip<NP; ip++) { 5286 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5287 final int NA = apps.size(); 5288 for (int ia=0; ia<NA; ia++) { 5289 ProcessRecord app = apps.valueAt(ia); 5290 if (app.persistent) { 5291 // we don't kill persistent processes 5292 continue; 5293 } 5294 if (app.removed) { 5295 procs.add(app); 5296 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5297 app.removed = true; 5298 procs.add(app); 5299 } 5300 } 5301 } 5302 5303 int N = procs.size(); 5304 for (int i=0; i<N; i++) { 5305 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5306 } 5307 mAllowLowerMemLevel = true; 5308 updateOomAdjLocked(); 5309 doLowMemReportIfNeededLocked(null); 5310 } 5311 } finally { 5312 Binder.restoreCallingIdentity(callingId); 5313 } 5314 } 5315 5316 @Override 5317 public void forceStopPackage(final String packageName, int userId) { 5318 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5319 != PackageManager.PERMISSION_GRANTED) { 5320 String msg = "Permission Denial: forceStopPackage() from pid=" 5321 + Binder.getCallingPid() 5322 + ", uid=" + Binder.getCallingUid() 5323 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5324 Slog.w(TAG, msg); 5325 throw new SecurityException(msg); 5326 } 5327 final int callingPid = Binder.getCallingPid(); 5328 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5329 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5330 long callingId = Binder.clearCallingIdentity(); 5331 try { 5332 IPackageManager pm = AppGlobals.getPackageManager(); 5333 synchronized(this) { 5334 int[] users = userId == UserHandle.USER_ALL 5335 ? getUsersLocked() : new int[] { userId }; 5336 for (int user : users) { 5337 int pkgUid = -1; 5338 try { 5339 pkgUid = pm.getPackageUid(packageName, user); 5340 } catch (RemoteException e) { 5341 } 5342 if (pkgUid == -1) { 5343 Slog.w(TAG, "Invalid packageName: " + packageName); 5344 continue; 5345 } 5346 try { 5347 pm.setPackageStoppedState(packageName, true, user); 5348 } catch (RemoteException e) { 5349 } catch (IllegalArgumentException e) { 5350 Slog.w(TAG, "Failed trying to unstop package " 5351 + packageName + ": " + e); 5352 } 5353 if (isUserRunningLocked(user, false)) { 5354 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5355 } 5356 } 5357 } 5358 } finally { 5359 Binder.restoreCallingIdentity(callingId); 5360 } 5361 } 5362 5363 @Override 5364 public void addPackageDependency(String packageName) { 5365 synchronized (this) { 5366 int callingPid = Binder.getCallingPid(); 5367 if (callingPid == Process.myPid()) { 5368 // Yeah, um, no. 5369 Slog.w(TAG, "Can't addPackageDependency on system process"); 5370 return; 5371 } 5372 ProcessRecord proc; 5373 synchronized (mPidsSelfLocked) { 5374 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5375 } 5376 if (proc != null) { 5377 if (proc.pkgDeps == null) { 5378 proc.pkgDeps = new ArraySet<String>(1); 5379 } 5380 proc.pkgDeps.add(packageName); 5381 } 5382 } 5383 } 5384 5385 /* 5386 * The pkg name and app id have to be specified. 5387 */ 5388 @Override 5389 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5390 if (pkg == null) { 5391 return; 5392 } 5393 // Make sure the uid is valid. 5394 if (appid < 0) { 5395 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5396 return; 5397 } 5398 int callerUid = Binder.getCallingUid(); 5399 // Only the system server can kill an application 5400 if (callerUid == Process.SYSTEM_UID) { 5401 // Post an aysnc message to kill the application 5402 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5403 msg.arg1 = appid; 5404 msg.arg2 = 0; 5405 Bundle bundle = new Bundle(); 5406 bundle.putString("pkg", pkg); 5407 bundle.putString("reason", reason); 5408 msg.obj = bundle; 5409 mHandler.sendMessage(msg); 5410 } else { 5411 throw new SecurityException(callerUid + " cannot kill pkg: " + 5412 pkg); 5413 } 5414 } 5415 5416 @Override 5417 public void closeSystemDialogs(String reason) { 5418 enforceNotIsolatedCaller("closeSystemDialogs"); 5419 5420 final int pid = Binder.getCallingPid(); 5421 final int uid = Binder.getCallingUid(); 5422 final long origId = Binder.clearCallingIdentity(); 5423 try { 5424 synchronized (this) { 5425 // Only allow this from foreground processes, so that background 5426 // applications can't abuse it to prevent system UI from being shown. 5427 if (uid >= Process.FIRST_APPLICATION_UID) { 5428 ProcessRecord proc; 5429 synchronized (mPidsSelfLocked) { 5430 proc = mPidsSelfLocked.get(pid); 5431 } 5432 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5433 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5434 + " from background process " + proc); 5435 return; 5436 } 5437 } 5438 closeSystemDialogsLocked(reason); 5439 } 5440 } finally { 5441 Binder.restoreCallingIdentity(origId); 5442 } 5443 } 5444 5445 void closeSystemDialogsLocked(String reason) { 5446 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5447 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5448 | Intent.FLAG_RECEIVER_FOREGROUND); 5449 if (reason != null) { 5450 intent.putExtra("reason", reason); 5451 } 5452 mWindowManager.closeSystemDialogs(reason); 5453 5454 mStackSupervisor.closeSystemDialogsLocked(); 5455 5456 broadcastIntentLocked(null, null, intent, null, 5457 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5458 Process.SYSTEM_UID, UserHandle.USER_ALL); 5459 } 5460 5461 @Override 5462 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5463 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5464 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5465 for (int i=pids.length-1; i>=0; i--) { 5466 ProcessRecord proc; 5467 int oomAdj; 5468 synchronized (this) { 5469 synchronized (mPidsSelfLocked) { 5470 proc = mPidsSelfLocked.get(pids[i]); 5471 oomAdj = proc != null ? proc.setAdj : 0; 5472 } 5473 } 5474 infos[i] = new Debug.MemoryInfo(); 5475 Debug.getMemoryInfo(pids[i], infos[i]); 5476 if (proc != null) { 5477 synchronized (this) { 5478 if (proc.thread != null && proc.setAdj == oomAdj) { 5479 // Record this for posterity if the process has been stable. 5480 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5481 infos[i].getTotalUss(), false, proc.pkgList); 5482 } 5483 } 5484 } 5485 } 5486 return infos; 5487 } 5488 5489 @Override 5490 public long[] getProcessPss(int[] pids) { 5491 enforceNotIsolatedCaller("getProcessPss"); 5492 long[] pss = new long[pids.length]; 5493 for (int i=pids.length-1; i>=0; i--) { 5494 ProcessRecord proc; 5495 int oomAdj; 5496 synchronized (this) { 5497 synchronized (mPidsSelfLocked) { 5498 proc = mPidsSelfLocked.get(pids[i]); 5499 oomAdj = proc != null ? proc.setAdj : 0; 5500 } 5501 } 5502 long[] tmpUss = new long[1]; 5503 pss[i] = Debug.getPss(pids[i], tmpUss); 5504 if (proc != null) { 5505 synchronized (this) { 5506 if (proc.thread != null && proc.setAdj == oomAdj) { 5507 // Record this for posterity if the process has been stable. 5508 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5509 } 5510 } 5511 } 5512 } 5513 return pss; 5514 } 5515 5516 @Override 5517 public void killApplicationProcess(String processName, int uid) { 5518 if (processName == null) { 5519 return; 5520 } 5521 5522 int callerUid = Binder.getCallingUid(); 5523 // Only the system server can kill an application 5524 if (callerUid == Process.SYSTEM_UID) { 5525 synchronized (this) { 5526 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5527 if (app != null && app.thread != null) { 5528 try { 5529 app.thread.scheduleSuicide(); 5530 } catch (RemoteException e) { 5531 // If the other end already died, then our work here is done. 5532 } 5533 } else { 5534 Slog.w(TAG, "Process/uid not found attempting kill of " 5535 + processName + " / " + uid); 5536 } 5537 } 5538 } else { 5539 throw new SecurityException(callerUid + " cannot kill app process: " + 5540 processName); 5541 } 5542 } 5543 5544 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5545 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5546 false, true, false, false, UserHandle.getUserId(uid), reason); 5547 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5548 Uri.fromParts("package", packageName, null)); 5549 if (!mProcessesReady) { 5550 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5551 | Intent.FLAG_RECEIVER_FOREGROUND); 5552 } 5553 intent.putExtra(Intent.EXTRA_UID, uid); 5554 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5555 broadcastIntentLocked(null, null, intent, 5556 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5557 false, false, 5558 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5559 } 5560 5561 private void forceStopUserLocked(int userId, String reason) { 5562 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5563 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5564 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5565 | Intent.FLAG_RECEIVER_FOREGROUND); 5566 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5567 broadcastIntentLocked(null, null, intent, 5568 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5569 false, false, 5570 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5571 } 5572 5573 private final boolean killPackageProcessesLocked(String packageName, int appId, 5574 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5575 boolean doit, boolean evenPersistent, String reason) { 5576 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5577 5578 // Remove all processes this package may have touched: all with the 5579 // same UID (except for the system or root user), and all whose name 5580 // matches the package name. 5581 final int NP = mProcessNames.getMap().size(); 5582 for (int ip=0; ip<NP; ip++) { 5583 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5584 final int NA = apps.size(); 5585 for (int ia=0; ia<NA; ia++) { 5586 ProcessRecord app = apps.valueAt(ia); 5587 if (app.persistent && !evenPersistent) { 5588 // we don't kill persistent processes 5589 continue; 5590 } 5591 if (app.removed) { 5592 if (doit) { 5593 procs.add(app); 5594 } 5595 continue; 5596 } 5597 5598 // Skip process if it doesn't meet our oom adj requirement. 5599 if (app.setAdj < minOomAdj) { 5600 continue; 5601 } 5602 5603 // If no package is specified, we call all processes under the 5604 // give user id. 5605 if (packageName == null) { 5606 if (app.userId != userId) { 5607 continue; 5608 } 5609 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5610 continue; 5611 } 5612 // Package has been specified, we want to hit all processes 5613 // that match it. We need to qualify this by the processes 5614 // that are running under the specified app and user ID. 5615 } else { 5616 final boolean isDep = app.pkgDeps != null 5617 && app.pkgDeps.contains(packageName); 5618 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5619 continue; 5620 } 5621 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5622 continue; 5623 } 5624 if (!app.pkgList.containsKey(packageName) && !isDep) { 5625 continue; 5626 } 5627 } 5628 5629 // Process has passed all conditions, kill it! 5630 if (!doit) { 5631 return true; 5632 } 5633 app.removed = true; 5634 procs.add(app); 5635 } 5636 } 5637 5638 int N = procs.size(); 5639 for (int i=0; i<N; i++) { 5640 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5641 } 5642 updateOomAdjLocked(); 5643 return N > 0; 5644 } 5645 5646 private final boolean forceStopPackageLocked(String name, int appId, 5647 boolean callerWillRestart, boolean purgeCache, boolean doit, 5648 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5649 int i; 5650 int N; 5651 5652 if (userId == UserHandle.USER_ALL && name == null) { 5653 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5654 } 5655 5656 if (appId < 0 && name != null) { 5657 try { 5658 appId = UserHandle.getAppId( 5659 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5660 } catch (RemoteException e) { 5661 } 5662 } 5663 5664 if (doit) { 5665 if (name != null) { 5666 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5667 + " user=" + userId + ": " + reason); 5668 } else { 5669 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5670 } 5671 5672 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5673 for (int ip=pmap.size()-1; ip>=0; ip--) { 5674 SparseArray<Long> ba = pmap.valueAt(ip); 5675 for (i=ba.size()-1; i>=0; i--) { 5676 boolean remove = false; 5677 final int entUid = ba.keyAt(i); 5678 if (name != null) { 5679 if (userId == UserHandle.USER_ALL) { 5680 if (UserHandle.getAppId(entUid) == appId) { 5681 remove = true; 5682 } 5683 } else { 5684 if (entUid == UserHandle.getUid(userId, appId)) { 5685 remove = true; 5686 } 5687 } 5688 } else if (UserHandle.getUserId(entUid) == userId) { 5689 remove = true; 5690 } 5691 if (remove) { 5692 ba.removeAt(i); 5693 } 5694 } 5695 if (ba.size() == 0) { 5696 pmap.removeAt(ip); 5697 } 5698 } 5699 } 5700 5701 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5702 -100, callerWillRestart, true, doit, evenPersistent, 5703 name == null ? ("stop user " + userId) : ("stop " + name)); 5704 5705 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5706 if (!doit) { 5707 return true; 5708 } 5709 didSomething = true; 5710 } 5711 5712 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5713 if (!doit) { 5714 return true; 5715 } 5716 didSomething = true; 5717 } 5718 5719 if (name == null) { 5720 // Remove all sticky broadcasts from this user. 5721 mStickyBroadcasts.remove(userId); 5722 } 5723 5724 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5725 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5726 userId, providers)) { 5727 if (!doit) { 5728 return true; 5729 } 5730 didSomething = true; 5731 } 5732 N = providers.size(); 5733 for (i=0; i<N; i++) { 5734 removeDyingProviderLocked(null, providers.get(i), true); 5735 } 5736 5737 // Remove transient permissions granted from/to this package/user 5738 removeUriPermissionsForPackageLocked(name, userId, false); 5739 5740 if (name == null || uninstalling) { 5741 // Remove pending intents. For now we only do this when force 5742 // stopping users, because we have some problems when doing this 5743 // for packages -- app widgets are not currently cleaned up for 5744 // such packages, so they can be left with bad pending intents. 5745 if (mIntentSenderRecords.size() > 0) { 5746 Iterator<WeakReference<PendingIntentRecord>> it 5747 = mIntentSenderRecords.values().iterator(); 5748 while (it.hasNext()) { 5749 WeakReference<PendingIntentRecord> wpir = it.next(); 5750 if (wpir == null) { 5751 it.remove(); 5752 continue; 5753 } 5754 PendingIntentRecord pir = wpir.get(); 5755 if (pir == null) { 5756 it.remove(); 5757 continue; 5758 } 5759 if (name == null) { 5760 // Stopping user, remove all objects for the user. 5761 if (pir.key.userId != userId) { 5762 // Not the same user, skip it. 5763 continue; 5764 } 5765 } else { 5766 if (UserHandle.getAppId(pir.uid) != appId) { 5767 // Different app id, skip it. 5768 continue; 5769 } 5770 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5771 // Different user, skip it. 5772 continue; 5773 } 5774 if (!pir.key.packageName.equals(name)) { 5775 // Different package, skip it. 5776 continue; 5777 } 5778 } 5779 if (!doit) { 5780 return true; 5781 } 5782 didSomething = true; 5783 it.remove(); 5784 pir.canceled = true; 5785 if (pir.key.activity != null) { 5786 pir.key.activity.pendingResults.remove(pir.ref); 5787 } 5788 } 5789 } 5790 } 5791 5792 if (doit) { 5793 if (purgeCache && name != null) { 5794 AttributeCache ac = AttributeCache.instance(); 5795 if (ac != null) { 5796 ac.removePackage(name); 5797 } 5798 } 5799 if (mBooted) { 5800 mStackSupervisor.resumeTopActivitiesLocked(); 5801 mStackSupervisor.scheduleIdleLocked(); 5802 } 5803 } 5804 5805 return didSomething; 5806 } 5807 5808 private final boolean removeProcessLocked(ProcessRecord app, 5809 boolean callerWillRestart, boolean allowRestart, String reason) { 5810 final String name = app.processName; 5811 final int uid = app.uid; 5812 if (DEBUG_PROCESSES) Slog.d( 5813 TAG, "Force removing proc " + app.toShortString() + " (" + name 5814 + "/" + uid + ")"); 5815 5816 mProcessNames.remove(name, uid); 5817 mIsolatedProcesses.remove(app.uid); 5818 if (mHeavyWeightProcess == app) { 5819 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5820 mHeavyWeightProcess.userId, 0)); 5821 mHeavyWeightProcess = null; 5822 } 5823 boolean needRestart = false; 5824 if (app.pid > 0 && app.pid != MY_PID) { 5825 int pid = app.pid; 5826 synchronized (mPidsSelfLocked) { 5827 mPidsSelfLocked.remove(pid); 5828 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5829 } 5830 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5831 if (app.isolated) { 5832 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5833 } 5834 app.kill(reason, true); 5835 handleAppDiedLocked(app, true, allowRestart); 5836 removeLruProcessLocked(app); 5837 5838 if (app.persistent && !app.isolated) { 5839 if (!callerWillRestart) { 5840 addAppLocked(app.info, false, null /* ABI override */); 5841 } else { 5842 needRestart = true; 5843 } 5844 } 5845 } else { 5846 mRemovedProcesses.add(app); 5847 } 5848 5849 return needRestart; 5850 } 5851 5852 private final void processStartTimedOutLocked(ProcessRecord app) { 5853 final int pid = app.pid; 5854 boolean gone = false; 5855 synchronized (mPidsSelfLocked) { 5856 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5857 if (knownApp != null && knownApp.thread == null) { 5858 mPidsSelfLocked.remove(pid); 5859 gone = true; 5860 } 5861 } 5862 5863 if (gone) { 5864 Slog.w(TAG, "Process " + app + " failed to attach"); 5865 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5866 pid, app.uid, app.processName); 5867 mProcessNames.remove(app.processName, app.uid); 5868 mIsolatedProcesses.remove(app.uid); 5869 if (mHeavyWeightProcess == app) { 5870 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5871 mHeavyWeightProcess.userId, 0)); 5872 mHeavyWeightProcess = null; 5873 } 5874 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5875 if (app.isolated) { 5876 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5877 } 5878 // Take care of any launching providers waiting for this process. 5879 checkAppInLaunchingProvidersLocked(app, true); 5880 // Take care of any services that are waiting for the process. 5881 mServices.processStartTimedOutLocked(app); 5882 app.kill("start timeout", true); 5883 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5884 Slog.w(TAG, "Unattached app died before backup, skipping"); 5885 try { 5886 IBackupManager bm = IBackupManager.Stub.asInterface( 5887 ServiceManager.getService(Context.BACKUP_SERVICE)); 5888 bm.agentDisconnected(app.info.packageName); 5889 } catch (RemoteException e) { 5890 // Can't happen; the backup manager is local 5891 } 5892 } 5893 if (isPendingBroadcastProcessLocked(pid)) { 5894 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5895 skipPendingBroadcastLocked(pid); 5896 } 5897 } else { 5898 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5899 } 5900 } 5901 5902 private final boolean attachApplicationLocked(IApplicationThread thread, 5903 int pid) { 5904 5905 // Find the application record that is being attached... either via 5906 // the pid if we are running in multiple processes, or just pull the 5907 // next app record if we are emulating process with anonymous threads. 5908 ProcessRecord app; 5909 if (pid != MY_PID && pid >= 0) { 5910 synchronized (mPidsSelfLocked) { 5911 app = mPidsSelfLocked.get(pid); 5912 } 5913 } else { 5914 app = null; 5915 } 5916 5917 if (app == null) { 5918 Slog.w(TAG, "No pending application record for pid " + pid 5919 + " (IApplicationThread " + thread + "); dropping process"); 5920 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5921 if (pid > 0 && pid != MY_PID) { 5922 Process.killProcessQuiet(pid); 5923 //TODO: Process.killProcessGroup(app.info.uid, pid); 5924 } else { 5925 try { 5926 thread.scheduleExit(); 5927 } catch (Exception e) { 5928 // Ignore exceptions. 5929 } 5930 } 5931 return false; 5932 } 5933 5934 // If this application record is still attached to a previous 5935 // process, clean it up now. 5936 if (app.thread != null) { 5937 handleAppDiedLocked(app, true, true); 5938 } 5939 5940 // Tell the process all about itself. 5941 5942 if (localLOGV) Slog.v( 5943 TAG, "Binding process pid " + pid + " to record " + app); 5944 5945 final String processName = app.processName; 5946 try { 5947 AppDeathRecipient adr = new AppDeathRecipient( 5948 app, pid, thread); 5949 thread.asBinder().linkToDeath(adr, 0); 5950 app.deathRecipient = adr; 5951 } catch (RemoteException e) { 5952 app.resetPackageList(mProcessStats); 5953 startProcessLocked(app, "link fail", processName); 5954 return false; 5955 } 5956 5957 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5958 5959 app.makeActive(thread, mProcessStats); 5960 app.curAdj = app.setAdj = -100; 5961 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5962 app.forcingToForeground = null; 5963 updateProcessForegroundLocked(app, false, false); 5964 app.hasShownUi = false; 5965 app.debugging = false; 5966 app.cached = false; 5967 5968 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5969 5970 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5971 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5972 5973 if (!normalMode) { 5974 Slog.i(TAG, "Launching preboot mode app: " + app); 5975 } 5976 5977 if (localLOGV) Slog.v( 5978 TAG, "New app record " + app 5979 + " thread=" + thread.asBinder() + " pid=" + pid); 5980 try { 5981 int testMode = IApplicationThread.DEBUG_OFF; 5982 if (mDebugApp != null && mDebugApp.equals(processName)) { 5983 testMode = mWaitForDebugger 5984 ? IApplicationThread.DEBUG_WAIT 5985 : IApplicationThread.DEBUG_ON; 5986 app.debugging = true; 5987 if (mDebugTransient) { 5988 mDebugApp = mOrigDebugApp; 5989 mWaitForDebugger = mOrigWaitForDebugger; 5990 } 5991 } 5992 String profileFile = app.instrumentationProfileFile; 5993 ParcelFileDescriptor profileFd = null; 5994 int samplingInterval = 0; 5995 boolean profileAutoStop = false; 5996 if (mProfileApp != null && mProfileApp.equals(processName)) { 5997 mProfileProc = app; 5998 profileFile = mProfileFile; 5999 profileFd = mProfileFd; 6000 samplingInterval = mSamplingInterval; 6001 profileAutoStop = mAutoStopProfiler; 6002 } 6003 boolean enableOpenGlTrace = false; 6004 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6005 enableOpenGlTrace = true; 6006 mOpenGlTraceApp = null; 6007 } 6008 6009 // If the app is being launched for restore or full backup, set it up specially 6010 boolean isRestrictedBackupMode = false; 6011 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6012 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6013 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6014 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6015 } 6016 6017 ensurePackageDexOpt(app.instrumentationInfo != null 6018 ? app.instrumentationInfo.packageName 6019 : app.info.packageName); 6020 if (app.instrumentationClass != null) { 6021 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6022 } 6023 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6024 + processName + " with config " + mConfiguration); 6025 ApplicationInfo appInfo = app.instrumentationInfo != null 6026 ? app.instrumentationInfo : app.info; 6027 app.compat = compatibilityInfoForPackageLocked(appInfo); 6028 if (profileFd != null) { 6029 profileFd = profileFd.dup(); 6030 } 6031 ProfilerInfo profilerInfo = profileFile == null ? null 6032 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6033 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6034 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6035 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6036 isRestrictedBackupMode || !normalMode, app.persistent, 6037 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6038 mCoreSettingsObserver.getCoreSettingsLocked()); 6039 updateLruProcessLocked(app, false, null); 6040 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6041 } catch (Exception e) { 6042 // todo: Yikes! What should we do? For now we will try to 6043 // start another process, but that could easily get us in 6044 // an infinite loop of restarting processes... 6045 Slog.w(TAG, "Exception thrown during bind!", e); 6046 6047 app.resetPackageList(mProcessStats); 6048 app.unlinkDeathRecipient(); 6049 startProcessLocked(app, "bind fail", processName); 6050 return false; 6051 } 6052 6053 // Remove this record from the list of starting applications. 6054 mPersistentStartingProcesses.remove(app); 6055 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6056 "Attach application locked removing on hold: " + app); 6057 mProcessesOnHold.remove(app); 6058 6059 boolean badApp = false; 6060 boolean didSomething = false; 6061 6062 // See if the top visible activity is waiting to run in this process... 6063 if (normalMode) { 6064 try { 6065 if (mStackSupervisor.attachApplicationLocked(app)) { 6066 didSomething = true; 6067 } 6068 } catch (Exception e) { 6069 badApp = true; 6070 } 6071 } 6072 6073 // Find any services that should be running in this process... 6074 if (!badApp) { 6075 try { 6076 didSomething |= mServices.attachApplicationLocked(app, processName); 6077 } catch (Exception e) { 6078 badApp = true; 6079 } 6080 } 6081 6082 // Check if a next-broadcast receiver is in this process... 6083 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6084 try { 6085 didSomething |= sendPendingBroadcastsLocked(app); 6086 } catch (Exception e) { 6087 // If the app died trying to launch the receiver we declare it 'bad' 6088 badApp = true; 6089 } 6090 } 6091 6092 // Check whether the next backup agent is in this process... 6093 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6094 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6095 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6096 try { 6097 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6098 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6099 mBackupTarget.backupMode); 6100 } catch (Exception e) { 6101 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6102 e.printStackTrace(); 6103 } 6104 } 6105 6106 if (badApp) { 6107 // todo: Also need to kill application to deal with all 6108 // kinds of exceptions. 6109 handleAppDiedLocked(app, false, true); 6110 return false; 6111 } 6112 6113 if (!didSomething) { 6114 updateOomAdjLocked(); 6115 } 6116 6117 return true; 6118 } 6119 6120 @Override 6121 public final void attachApplication(IApplicationThread thread) { 6122 synchronized (this) { 6123 int callingPid = Binder.getCallingPid(); 6124 final long origId = Binder.clearCallingIdentity(); 6125 attachApplicationLocked(thread, callingPid); 6126 Binder.restoreCallingIdentity(origId); 6127 } 6128 } 6129 6130 @Override 6131 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6132 final long origId = Binder.clearCallingIdentity(); 6133 synchronized (this) { 6134 ActivityStack stack = ActivityRecord.getStackLocked(token); 6135 if (stack != null) { 6136 ActivityRecord r = 6137 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6138 if (stopProfiling) { 6139 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6140 try { 6141 mProfileFd.close(); 6142 } catch (IOException e) { 6143 } 6144 clearProfilerLocked(); 6145 } 6146 } 6147 } 6148 } 6149 Binder.restoreCallingIdentity(origId); 6150 } 6151 6152 void postEnableScreenAfterBootLocked() { 6153 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6154 } 6155 6156 void enableScreenAfterBoot() { 6157 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6158 SystemClock.uptimeMillis()); 6159 mWindowManager.enableScreenAfterBoot(); 6160 6161 synchronized (this) { 6162 updateEventDispatchingLocked(); 6163 } 6164 } 6165 6166 @Override 6167 public void showBootMessage(final CharSequence msg, final boolean always) { 6168 enforceNotIsolatedCaller("showBootMessage"); 6169 mWindowManager.showBootMessage(msg, always); 6170 } 6171 6172 @Override 6173 public void keyguardWaitingForActivityDrawn() { 6174 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6175 final long token = Binder.clearCallingIdentity(); 6176 try { 6177 synchronized (this) { 6178 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6179 mWindowManager.keyguardWaitingForActivityDrawn(); 6180 } 6181 } finally { 6182 Binder.restoreCallingIdentity(token); 6183 } 6184 } 6185 6186 final void finishBooting() { 6187 // Register receivers to handle package update events 6188 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6189 6190 // Let system services know. 6191 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6192 6193 synchronized (this) { 6194 // Ensure that any processes we had put on hold are now started 6195 // up. 6196 final int NP = mProcessesOnHold.size(); 6197 if (NP > 0) { 6198 ArrayList<ProcessRecord> procs = 6199 new ArrayList<ProcessRecord>(mProcessesOnHold); 6200 for (int ip=0; ip<NP; ip++) { 6201 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6202 + procs.get(ip)); 6203 startProcessLocked(procs.get(ip), "on-hold", null); 6204 } 6205 } 6206 6207 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6208 // Start looking for apps that are abusing wake locks. 6209 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6210 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6211 // Tell anyone interested that we are done booting! 6212 SystemProperties.set("sys.boot_completed", "1"); 6213 SystemProperties.set("dev.bootcomplete", "1"); 6214 for (int i=0; i<mStartedUsers.size(); i++) { 6215 UserStartedState uss = mStartedUsers.valueAt(i); 6216 if (uss.mState == UserStartedState.STATE_BOOTING) { 6217 uss.mState = UserStartedState.STATE_RUNNING; 6218 final int userId = mStartedUsers.keyAt(i); 6219 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6220 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6221 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6222 broadcastIntentLocked(null, null, intent, null, 6223 new IIntentReceiver.Stub() { 6224 @Override 6225 public void performReceive(Intent intent, int resultCode, 6226 String data, Bundle extras, boolean ordered, 6227 boolean sticky, int sendingUser) { 6228 synchronized (ActivityManagerService.this) { 6229 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6230 true, false); 6231 } 6232 } 6233 }, 6234 0, null, null, 6235 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6236 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6237 userId); 6238 } 6239 } 6240 scheduleStartProfilesLocked(); 6241 } 6242 } 6243 } 6244 6245 final void ensureBootCompleted() { 6246 boolean booting; 6247 boolean enableScreen; 6248 synchronized (this) { 6249 booting = mBooting; 6250 mBooting = false; 6251 enableScreen = !mBooted; 6252 mBooted = true; 6253 } 6254 6255 if (booting) { 6256 finishBooting(); 6257 } 6258 6259 if (enableScreen) { 6260 enableScreenAfterBoot(); 6261 } 6262 } 6263 6264 @Override 6265 public final void activityResumed(IBinder token) { 6266 final long origId = Binder.clearCallingIdentity(); 6267 synchronized(this) { 6268 ActivityStack stack = ActivityRecord.getStackLocked(token); 6269 if (stack != null) { 6270 ActivityRecord.activityResumedLocked(token); 6271 } 6272 } 6273 Binder.restoreCallingIdentity(origId); 6274 } 6275 6276 @Override 6277 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6278 final long origId = Binder.clearCallingIdentity(); 6279 synchronized(this) { 6280 ActivityStack stack = ActivityRecord.getStackLocked(token); 6281 if (stack != null) { 6282 stack.activityPausedLocked(token, false, persistentState); 6283 } 6284 } 6285 Binder.restoreCallingIdentity(origId); 6286 } 6287 6288 @Override 6289 public final void activityStopped(IBinder token, Bundle icicle, 6290 PersistableBundle persistentState, CharSequence description) { 6291 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6292 6293 // Refuse possible leaked file descriptors 6294 if (icicle != null && icicle.hasFileDescriptors()) { 6295 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6296 } 6297 6298 final long origId = Binder.clearCallingIdentity(); 6299 6300 synchronized (this) { 6301 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6302 if (r != null) { 6303 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6304 } 6305 } 6306 6307 trimApplications(); 6308 6309 Binder.restoreCallingIdentity(origId); 6310 } 6311 6312 @Override 6313 public final void activityDestroyed(IBinder token) { 6314 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6315 synchronized (this) { 6316 ActivityStack stack = ActivityRecord.getStackLocked(token); 6317 if (stack != null) { 6318 stack.activityDestroyedLocked(token); 6319 } 6320 } 6321 } 6322 6323 @Override 6324 public final void backgroundResourcesReleased(IBinder token) { 6325 final long origId = Binder.clearCallingIdentity(); 6326 try { 6327 synchronized (this) { 6328 ActivityStack stack = ActivityRecord.getStackLocked(token); 6329 if (stack != null) { 6330 stack.backgroundResourcesReleased(token); 6331 } 6332 } 6333 } finally { 6334 Binder.restoreCallingIdentity(origId); 6335 } 6336 } 6337 6338 @Override 6339 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6340 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6341 } 6342 6343 @Override 6344 public final void notifyEnterAnimationComplete(IBinder token) { 6345 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6346 } 6347 6348 @Override 6349 public String getCallingPackage(IBinder token) { 6350 synchronized (this) { 6351 ActivityRecord r = getCallingRecordLocked(token); 6352 return r != null ? r.info.packageName : null; 6353 } 6354 } 6355 6356 @Override 6357 public ComponentName getCallingActivity(IBinder token) { 6358 synchronized (this) { 6359 ActivityRecord r = getCallingRecordLocked(token); 6360 return r != null ? r.intent.getComponent() : null; 6361 } 6362 } 6363 6364 private ActivityRecord getCallingRecordLocked(IBinder token) { 6365 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6366 if (r == null) { 6367 return null; 6368 } 6369 return r.resultTo; 6370 } 6371 6372 @Override 6373 public ComponentName getActivityClassForToken(IBinder token) { 6374 synchronized(this) { 6375 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6376 if (r == null) { 6377 return null; 6378 } 6379 return r.intent.getComponent(); 6380 } 6381 } 6382 6383 @Override 6384 public String getPackageForToken(IBinder token) { 6385 synchronized(this) { 6386 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6387 if (r == null) { 6388 return null; 6389 } 6390 return r.packageName; 6391 } 6392 } 6393 6394 @Override 6395 public IIntentSender getIntentSender(int type, 6396 String packageName, IBinder token, String resultWho, 6397 int requestCode, Intent[] intents, String[] resolvedTypes, 6398 int flags, Bundle options, int userId) { 6399 enforceNotIsolatedCaller("getIntentSender"); 6400 // Refuse possible leaked file descriptors 6401 if (intents != null) { 6402 if (intents.length < 1) { 6403 throw new IllegalArgumentException("Intents array length must be >= 1"); 6404 } 6405 for (int i=0; i<intents.length; i++) { 6406 Intent intent = intents[i]; 6407 if (intent != null) { 6408 if (intent.hasFileDescriptors()) { 6409 throw new IllegalArgumentException("File descriptors passed in Intent"); 6410 } 6411 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6412 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6413 throw new IllegalArgumentException( 6414 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6415 } 6416 intents[i] = new Intent(intent); 6417 } 6418 } 6419 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6420 throw new IllegalArgumentException( 6421 "Intent array length does not match resolvedTypes length"); 6422 } 6423 } 6424 if (options != null) { 6425 if (options.hasFileDescriptors()) { 6426 throw new IllegalArgumentException("File descriptors passed in options"); 6427 } 6428 } 6429 6430 synchronized(this) { 6431 int callingUid = Binder.getCallingUid(); 6432 int origUserId = userId; 6433 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6434 type == ActivityManager.INTENT_SENDER_BROADCAST, 6435 ALLOW_NON_FULL, "getIntentSender", null); 6436 if (origUserId == UserHandle.USER_CURRENT) { 6437 // We don't want to evaluate this until the pending intent is 6438 // actually executed. However, we do want to always do the 6439 // security checking for it above. 6440 userId = UserHandle.USER_CURRENT; 6441 } 6442 try { 6443 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6444 int uid = AppGlobals.getPackageManager() 6445 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6446 if (!UserHandle.isSameApp(callingUid, uid)) { 6447 String msg = "Permission Denial: getIntentSender() from pid=" 6448 + Binder.getCallingPid() 6449 + ", uid=" + Binder.getCallingUid() 6450 + ", (need uid=" + uid + ")" 6451 + " is not allowed to send as package " + packageName; 6452 Slog.w(TAG, msg); 6453 throw new SecurityException(msg); 6454 } 6455 } 6456 6457 return getIntentSenderLocked(type, packageName, callingUid, userId, 6458 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6459 6460 } catch (RemoteException e) { 6461 throw new SecurityException(e); 6462 } 6463 } 6464 } 6465 6466 IIntentSender getIntentSenderLocked(int type, String packageName, 6467 int callingUid, int userId, IBinder token, String resultWho, 6468 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6469 Bundle options) { 6470 if (DEBUG_MU) 6471 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6472 ActivityRecord activity = null; 6473 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6474 activity = ActivityRecord.isInStackLocked(token); 6475 if (activity == null) { 6476 return null; 6477 } 6478 if (activity.finishing) { 6479 return null; 6480 } 6481 } 6482 6483 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6484 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6485 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6486 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6487 |PendingIntent.FLAG_UPDATE_CURRENT); 6488 6489 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6490 type, packageName, activity, resultWho, 6491 requestCode, intents, resolvedTypes, flags, options, userId); 6492 WeakReference<PendingIntentRecord> ref; 6493 ref = mIntentSenderRecords.get(key); 6494 PendingIntentRecord rec = ref != null ? ref.get() : null; 6495 if (rec != null) { 6496 if (!cancelCurrent) { 6497 if (updateCurrent) { 6498 if (rec.key.requestIntent != null) { 6499 rec.key.requestIntent.replaceExtras(intents != null ? 6500 intents[intents.length - 1] : null); 6501 } 6502 if (intents != null) { 6503 intents[intents.length-1] = rec.key.requestIntent; 6504 rec.key.allIntents = intents; 6505 rec.key.allResolvedTypes = resolvedTypes; 6506 } else { 6507 rec.key.allIntents = null; 6508 rec.key.allResolvedTypes = null; 6509 } 6510 } 6511 return rec; 6512 } 6513 rec.canceled = true; 6514 mIntentSenderRecords.remove(key); 6515 } 6516 if (noCreate) { 6517 return rec; 6518 } 6519 rec = new PendingIntentRecord(this, key, callingUid); 6520 mIntentSenderRecords.put(key, rec.ref); 6521 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6522 if (activity.pendingResults == null) { 6523 activity.pendingResults 6524 = new HashSet<WeakReference<PendingIntentRecord>>(); 6525 } 6526 activity.pendingResults.add(rec.ref); 6527 } 6528 return rec; 6529 } 6530 6531 @Override 6532 public void cancelIntentSender(IIntentSender sender) { 6533 if (!(sender instanceof PendingIntentRecord)) { 6534 return; 6535 } 6536 synchronized(this) { 6537 PendingIntentRecord rec = (PendingIntentRecord)sender; 6538 try { 6539 int uid = AppGlobals.getPackageManager() 6540 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6541 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6542 String msg = "Permission Denial: cancelIntentSender() from pid=" 6543 + Binder.getCallingPid() 6544 + ", uid=" + Binder.getCallingUid() 6545 + " is not allowed to cancel packges " 6546 + rec.key.packageName; 6547 Slog.w(TAG, msg); 6548 throw new SecurityException(msg); 6549 } 6550 } catch (RemoteException e) { 6551 throw new SecurityException(e); 6552 } 6553 cancelIntentSenderLocked(rec, true); 6554 } 6555 } 6556 6557 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6558 rec.canceled = true; 6559 mIntentSenderRecords.remove(rec.key); 6560 if (cleanActivity && rec.key.activity != null) { 6561 rec.key.activity.pendingResults.remove(rec.ref); 6562 } 6563 } 6564 6565 @Override 6566 public String getPackageForIntentSender(IIntentSender pendingResult) { 6567 if (!(pendingResult instanceof PendingIntentRecord)) { 6568 return null; 6569 } 6570 try { 6571 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6572 return res.key.packageName; 6573 } catch (ClassCastException e) { 6574 } 6575 return null; 6576 } 6577 6578 @Override 6579 public int getUidForIntentSender(IIntentSender sender) { 6580 if (sender instanceof PendingIntentRecord) { 6581 try { 6582 PendingIntentRecord res = (PendingIntentRecord)sender; 6583 return res.uid; 6584 } catch (ClassCastException e) { 6585 } 6586 } 6587 return -1; 6588 } 6589 6590 @Override 6591 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6592 if (!(pendingResult instanceof PendingIntentRecord)) { 6593 return false; 6594 } 6595 try { 6596 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6597 if (res.key.allIntents == null) { 6598 return false; 6599 } 6600 for (int i=0; i<res.key.allIntents.length; i++) { 6601 Intent intent = res.key.allIntents[i]; 6602 if (intent.getPackage() != null && intent.getComponent() != null) { 6603 return false; 6604 } 6605 } 6606 return true; 6607 } catch (ClassCastException e) { 6608 } 6609 return false; 6610 } 6611 6612 @Override 6613 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6614 if (!(pendingResult instanceof PendingIntentRecord)) { 6615 return false; 6616 } 6617 try { 6618 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6619 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6620 return true; 6621 } 6622 return false; 6623 } catch (ClassCastException e) { 6624 } 6625 return false; 6626 } 6627 6628 @Override 6629 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6630 if (!(pendingResult instanceof PendingIntentRecord)) { 6631 return null; 6632 } 6633 try { 6634 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6635 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6636 } catch (ClassCastException e) { 6637 } 6638 return null; 6639 } 6640 6641 @Override 6642 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6643 if (!(pendingResult instanceof PendingIntentRecord)) { 6644 return null; 6645 } 6646 try { 6647 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6648 Intent intent = res.key.requestIntent; 6649 if (intent != null) { 6650 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6651 || res.lastTagPrefix.equals(prefix))) { 6652 return res.lastTag; 6653 } 6654 res.lastTagPrefix = prefix; 6655 StringBuilder sb = new StringBuilder(128); 6656 if (prefix != null) { 6657 sb.append(prefix); 6658 } 6659 if (intent.getAction() != null) { 6660 sb.append(intent.getAction()); 6661 } else if (intent.getComponent() != null) { 6662 intent.getComponent().appendShortString(sb); 6663 } else { 6664 sb.append("?"); 6665 } 6666 return res.lastTag = sb.toString(); 6667 } 6668 } catch (ClassCastException e) { 6669 } 6670 return null; 6671 } 6672 6673 @Override 6674 public void setProcessLimit(int max) { 6675 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6676 "setProcessLimit()"); 6677 synchronized (this) { 6678 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6679 mProcessLimitOverride = max; 6680 } 6681 trimApplications(); 6682 } 6683 6684 @Override 6685 public int getProcessLimit() { 6686 synchronized (this) { 6687 return mProcessLimitOverride; 6688 } 6689 } 6690 6691 void foregroundTokenDied(ForegroundToken token) { 6692 synchronized (ActivityManagerService.this) { 6693 synchronized (mPidsSelfLocked) { 6694 ForegroundToken cur 6695 = mForegroundProcesses.get(token.pid); 6696 if (cur != token) { 6697 return; 6698 } 6699 mForegroundProcesses.remove(token.pid); 6700 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6701 if (pr == null) { 6702 return; 6703 } 6704 pr.forcingToForeground = null; 6705 updateProcessForegroundLocked(pr, false, false); 6706 } 6707 updateOomAdjLocked(); 6708 } 6709 } 6710 6711 @Override 6712 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6713 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6714 "setProcessForeground()"); 6715 synchronized(this) { 6716 boolean changed = false; 6717 6718 synchronized (mPidsSelfLocked) { 6719 ProcessRecord pr = mPidsSelfLocked.get(pid); 6720 if (pr == null && isForeground) { 6721 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6722 return; 6723 } 6724 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6725 if (oldToken != null) { 6726 oldToken.token.unlinkToDeath(oldToken, 0); 6727 mForegroundProcesses.remove(pid); 6728 if (pr != null) { 6729 pr.forcingToForeground = null; 6730 } 6731 changed = true; 6732 } 6733 if (isForeground && token != null) { 6734 ForegroundToken newToken = new ForegroundToken() { 6735 @Override 6736 public void binderDied() { 6737 foregroundTokenDied(this); 6738 } 6739 }; 6740 newToken.pid = pid; 6741 newToken.token = token; 6742 try { 6743 token.linkToDeath(newToken, 0); 6744 mForegroundProcesses.put(pid, newToken); 6745 pr.forcingToForeground = token; 6746 changed = true; 6747 } catch (RemoteException e) { 6748 // If the process died while doing this, we will later 6749 // do the cleanup with the process death link. 6750 } 6751 } 6752 } 6753 6754 if (changed) { 6755 updateOomAdjLocked(); 6756 } 6757 } 6758 } 6759 6760 // ========================================================= 6761 // PERMISSIONS 6762 // ========================================================= 6763 6764 static class PermissionController extends IPermissionController.Stub { 6765 ActivityManagerService mActivityManagerService; 6766 PermissionController(ActivityManagerService activityManagerService) { 6767 mActivityManagerService = activityManagerService; 6768 } 6769 6770 @Override 6771 public boolean checkPermission(String permission, int pid, int uid) { 6772 return mActivityManagerService.checkPermission(permission, pid, 6773 uid) == PackageManager.PERMISSION_GRANTED; 6774 } 6775 } 6776 6777 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6778 @Override 6779 public int checkComponentPermission(String permission, int pid, int uid, 6780 int owningUid, boolean exported) { 6781 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6782 owningUid, exported); 6783 } 6784 6785 @Override 6786 public Object getAMSLock() { 6787 return ActivityManagerService.this; 6788 } 6789 } 6790 6791 /** 6792 * This can be called with or without the global lock held. 6793 */ 6794 int checkComponentPermission(String permission, int pid, int uid, 6795 int owningUid, boolean exported) { 6796 // We might be performing an operation on behalf of an indirect binder 6797 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6798 // client identity accordingly before proceeding. 6799 Identity tlsIdentity = sCallerIdentity.get(); 6800 if (tlsIdentity != null) { 6801 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6802 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6803 uid = tlsIdentity.uid; 6804 pid = tlsIdentity.pid; 6805 } 6806 6807 if (pid == MY_PID) { 6808 return PackageManager.PERMISSION_GRANTED; 6809 } 6810 6811 return ActivityManager.checkComponentPermission(permission, uid, 6812 owningUid, exported); 6813 } 6814 6815 /** 6816 * As the only public entry point for permissions checking, this method 6817 * can enforce the semantic that requesting a check on a null global 6818 * permission is automatically denied. (Internally a null permission 6819 * string is used when calling {@link #checkComponentPermission} in cases 6820 * when only uid-based security is needed.) 6821 * 6822 * This can be called with or without the global lock held. 6823 */ 6824 @Override 6825 public int checkPermission(String permission, int pid, int uid) { 6826 if (permission == null) { 6827 return PackageManager.PERMISSION_DENIED; 6828 } 6829 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6830 } 6831 6832 /** 6833 * Binder IPC calls go through the public entry point. 6834 * This can be called with or without the global lock held. 6835 */ 6836 int checkCallingPermission(String permission) { 6837 return checkPermission(permission, 6838 Binder.getCallingPid(), 6839 UserHandle.getAppId(Binder.getCallingUid())); 6840 } 6841 6842 /** 6843 * This can be called with or without the global lock held. 6844 */ 6845 void enforceCallingPermission(String permission, String func) { 6846 if (checkCallingPermission(permission) 6847 == PackageManager.PERMISSION_GRANTED) { 6848 return; 6849 } 6850 6851 String msg = "Permission Denial: " + func + " from pid=" 6852 + Binder.getCallingPid() 6853 + ", uid=" + Binder.getCallingUid() 6854 + " requires " + permission; 6855 Slog.w(TAG, msg); 6856 throw new SecurityException(msg); 6857 } 6858 6859 /** 6860 * Determine if UID is holding permissions required to access {@link Uri} in 6861 * the given {@link ProviderInfo}. Final permission checking is always done 6862 * in {@link ContentProvider}. 6863 */ 6864 private final boolean checkHoldingPermissionsLocked( 6865 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6866 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6867 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6868 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6869 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6870 != PERMISSION_GRANTED) { 6871 return false; 6872 } 6873 } 6874 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6875 } 6876 6877 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6878 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6879 if (pi.applicationInfo.uid == uid) { 6880 return true; 6881 } else if (!pi.exported) { 6882 return false; 6883 } 6884 6885 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6886 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6887 try { 6888 // check if target holds top-level <provider> permissions 6889 if (!readMet && pi.readPermission != null && considerUidPermissions 6890 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6891 readMet = true; 6892 } 6893 if (!writeMet && pi.writePermission != null && considerUidPermissions 6894 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6895 writeMet = true; 6896 } 6897 6898 // track if unprotected read/write is allowed; any denied 6899 // <path-permission> below removes this ability 6900 boolean allowDefaultRead = pi.readPermission == null; 6901 boolean allowDefaultWrite = pi.writePermission == null; 6902 6903 // check if target holds any <path-permission> that match uri 6904 final PathPermission[] pps = pi.pathPermissions; 6905 if (pps != null) { 6906 final String path = grantUri.uri.getPath(); 6907 int i = pps.length; 6908 while (i > 0 && (!readMet || !writeMet)) { 6909 i--; 6910 PathPermission pp = pps[i]; 6911 if (pp.match(path)) { 6912 if (!readMet) { 6913 final String pprperm = pp.getReadPermission(); 6914 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6915 + pprperm + " for " + pp.getPath() 6916 + ": match=" + pp.match(path) 6917 + " check=" + pm.checkUidPermission(pprperm, uid)); 6918 if (pprperm != null) { 6919 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6920 == PERMISSION_GRANTED) { 6921 readMet = true; 6922 } else { 6923 allowDefaultRead = false; 6924 } 6925 } 6926 } 6927 if (!writeMet) { 6928 final String ppwperm = pp.getWritePermission(); 6929 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6930 + ppwperm + " for " + pp.getPath() 6931 + ": match=" + pp.match(path) 6932 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6933 if (ppwperm != null) { 6934 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6935 == PERMISSION_GRANTED) { 6936 writeMet = true; 6937 } else { 6938 allowDefaultWrite = false; 6939 } 6940 } 6941 } 6942 } 6943 } 6944 } 6945 6946 // grant unprotected <provider> read/write, if not blocked by 6947 // <path-permission> above 6948 if (allowDefaultRead) readMet = true; 6949 if (allowDefaultWrite) writeMet = true; 6950 6951 } catch (RemoteException e) { 6952 return false; 6953 } 6954 6955 return readMet && writeMet; 6956 } 6957 6958 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6959 ProviderInfo pi = null; 6960 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6961 if (cpr != null) { 6962 pi = cpr.info; 6963 } else { 6964 try { 6965 pi = AppGlobals.getPackageManager().resolveContentProvider( 6966 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6967 } catch (RemoteException ex) { 6968 } 6969 } 6970 return pi; 6971 } 6972 6973 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6974 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6975 if (targetUris != null) { 6976 return targetUris.get(grantUri); 6977 } 6978 return null; 6979 } 6980 6981 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6982 String targetPkg, int targetUid, GrantUri grantUri) { 6983 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6984 if (targetUris == null) { 6985 targetUris = Maps.newArrayMap(); 6986 mGrantedUriPermissions.put(targetUid, targetUris); 6987 } 6988 6989 UriPermission perm = targetUris.get(grantUri); 6990 if (perm == null) { 6991 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6992 targetUris.put(grantUri, perm); 6993 } 6994 6995 return perm; 6996 } 6997 6998 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6999 final int modeFlags) { 7000 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7001 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7002 : UriPermission.STRENGTH_OWNED; 7003 7004 // Root gets to do everything. 7005 if (uid == 0) { 7006 return true; 7007 } 7008 7009 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7010 if (perms == null) return false; 7011 7012 // First look for exact match 7013 final UriPermission exactPerm = perms.get(grantUri); 7014 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7015 return true; 7016 } 7017 7018 // No exact match, look for prefixes 7019 final int N = perms.size(); 7020 for (int i = 0; i < N; i++) { 7021 final UriPermission perm = perms.valueAt(i); 7022 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7023 && perm.getStrength(modeFlags) >= minStrength) { 7024 return true; 7025 } 7026 } 7027 7028 return false; 7029 } 7030 7031 /** 7032 * @param uri This uri must NOT contain an embedded userId. 7033 * @param userId The userId in which the uri is to be resolved. 7034 */ 7035 @Override 7036 public int checkUriPermission(Uri uri, int pid, int uid, 7037 final int modeFlags, int userId) { 7038 enforceNotIsolatedCaller("checkUriPermission"); 7039 7040 // Another redirected-binder-call permissions check as in 7041 // {@link checkComponentPermission}. 7042 Identity tlsIdentity = sCallerIdentity.get(); 7043 if (tlsIdentity != null) { 7044 uid = tlsIdentity.uid; 7045 pid = tlsIdentity.pid; 7046 } 7047 7048 // Our own process gets to do everything. 7049 if (pid == MY_PID) { 7050 return PackageManager.PERMISSION_GRANTED; 7051 } 7052 synchronized (this) { 7053 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7054 ? PackageManager.PERMISSION_GRANTED 7055 : PackageManager.PERMISSION_DENIED; 7056 } 7057 } 7058 7059 /** 7060 * Check if the targetPkg can be granted permission to access uri by 7061 * the callingUid using the given modeFlags. Throws a security exception 7062 * if callingUid is not allowed to do this. Returns the uid of the target 7063 * if the URI permission grant should be performed; returns -1 if it is not 7064 * needed (for example targetPkg already has permission to access the URI). 7065 * If you already know the uid of the target, you can supply it in 7066 * lastTargetUid else set that to -1. 7067 */ 7068 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7069 final int modeFlags, int lastTargetUid) { 7070 if (!Intent.isAccessUriMode(modeFlags)) { 7071 return -1; 7072 } 7073 7074 if (targetPkg != null) { 7075 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7076 "Checking grant " + targetPkg + " permission to " + grantUri); 7077 } 7078 7079 final IPackageManager pm = AppGlobals.getPackageManager(); 7080 7081 // If this is not a content: uri, we can't do anything with it. 7082 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7083 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7084 "Can't grant URI permission for non-content URI: " + grantUri); 7085 return -1; 7086 } 7087 7088 final String authority = grantUri.uri.getAuthority(); 7089 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7090 if (pi == null) { 7091 Slog.w(TAG, "No content provider found for permission check: " + 7092 grantUri.uri.toSafeString()); 7093 return -1; 7094 } 7095 7096 int targetUid = lastTargetUid; 7097 if (targetUid < 0 && targetPkg != null) { 7098 try { 7099 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7100 if (targetUid < 0) { 7101 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7102 "Can't grant URI permission no uid for: " + targetPkg); 7103 return -1; 7104 } 7105 } catch (RemoteException ex) { 7106 return -1; 7107 } 7108 } 7109 7110 if (targetUid >= 0) { 7111 // First... does the target actually need this permission? 7112 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7113 // No need to grant the target this permission. 7114 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7115 "Target " + targetPkg + " already has full permission to " + grantUri); 7116 return -1; 7117 } 7118 } else { 7119 // First... there is no target package, so can anyone access it? 7120 boolean allowed = pi.exported; 7121 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7122 if (pi.readPermission != null) { 7123 allowed = false; 7124 } 7125 } 7126 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7127 if (pi.writePermission != null) { 7128 allowed = false; 7129 } 7130 } 7131 if (allowed) { 7132 return -1; 7133 } 7134 } 7135 7136 /* There is a special cross user grant if: 7137 * - The target is on another user. 7138 * - Apps on the current user can access the uri without any uid permissions. 7139 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7140 * grant uri permissions. 7141 */ 7142 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7143 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7144 modeFlags, false /*without considering the uid permissions*/); 7145 7146 // Second... is the provider allowing granting of URI permissions? 7147 if (!specialCrossUserGrant) { 7148 if (!pi.grantUriPermissions) { 7149 throw new SecurityException("Provider " + pi.packageName 7150 + "/" + pi.name 7151 + " does not allow granting of Uri permissions (uri " 7152 + grantUri + ")"); 7153 } 7154 if (pi.uriPermissionPatterns != null) { 7155 final int N = pi.uriPermissionPatterns.length; 7156 boolean allowed = false; 7157 for (int i=0; i<N; i++) { 7158 if (pi.uriPermissionPatterns[i] != null 7159 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7160 allowed = true; 7161 break; 7162 } 7163 } 7164 if (!allowed) { 7165 throw new SecurityException("Provider " + pi.packageName 7166 + "/" + pi.name 7167 + " does not allow granting of permission to path of Uri " 7168 + grantUri); 7169 } 7170 } 7171 } 7172 7173 // Third... does the caller itself have permission to access 7174 // this uri? 7175 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7176 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7177 // Require they hold a strong enough Uri permission 7178 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7179 throw new SecurityException("Uid " + callingUid 7180 + " does not have permission to uri " + grantUri); 7181 } 7182 } 7183 } 7184 return targetUid; 7185 } 7186 7187 /** 7188 * @param uri This uri must NOT contain an embedded userId. 7189 * @param userId The userId in which the uri is to be resolved. 7190 */ 7191 @Override 7192 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7193 final int modeFlags, int userId) { 7194 enforceNotIsolatedCaller("checkGrantUriPermission"); 7195 synchronized(this) { 7196 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7197 new GrantUri(userId, uri, false), modeFlags, -1); 7198 } 7199 } 7200 7201 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7202 final int modeFlags, UriPermissionOwner owner) { 7203 if (!Intent.isAccessUriMode(modeFlags)) { 7204 return; 7205 } 7206 7207 // So here we are: the caller has the assumed permission 7208 // to the uri, and the target doesn't. Let's now give this to 7209 // the target. 7210 7211 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7212 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7213 7214 final String authority = grantUri.uri.getAuthority(); 7215 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7216 if (pi == null) { 7217 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7218 return; 7219 } 7220 7221 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7222 grantUri.prefix = true; 7223 } 7224 final UriPermission perm = findOrCreateUriPermissionLocked( 7225 pi.packageName, targetPkg, targetUid, grantUri); 7226 perm.grantModes(modeFlags, owner); 7227 } 7228 7229 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7230 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7231 if (targetPkg == null) { 7232 throw new NullPointerException("targetPkg"); 7233 } 7234 int targetUid; 7235 final IPackageManager pm = AppGlobals.getPackageManager(); 7236 try { 7237 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7238 } catch (RemoteException ex) { 7239 return; 7240 } 7241 7242 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7243 targetUid); 7244 if (targetUid < 0) { 7245 return; 7246 } 7247 7248 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7249 owner); 7250 } 7251 7252 static class NeededUriGrants extends ArrayList<GrantUri> { 7253 final String targetPkg; 7254 final int targetUid; 7255 final int flags; 7256 7257 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7258 this.targetPkg = targetPkg; 7259 this.targetUid = targetUid; 7260 this.flags = flags; 7261 } 7262 } 7263 7264 /** 7265 * Like checkGrantUriPermissionLocked, but takes an Intent. 7266 */ 7267 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7268 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7269 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7270 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7271 + " clip=" + (intent != null ? intent.getClipData() : null) 7272 + " from " + intent + "; flags=0x" 7273 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7274 7275 if (targetPkg == null) { 7276 throw new NullPointerException("targetPkg"); 7277 } 7278 7279 if (intent == null) { 7280 return null; 7281 } 7282 Uri data = intent.getData(); 7283 ClipData clip = intent.getClipData(); 7284 if (data == null && clip == null) { 7285 return null; 7286 } 7287 // Default userId for uris in the intent (if they don't specify it themselves) 7288 int contentUserHint = intent.getContentUserHint(); 7289 if (contentUserHint == UserHandle.USER_CURRENT) { 7290 contentUserHint = UserHandle.getUserId(callingUid); 7291 } 7292 final IPackageManager pm = AppGlobals.getPackageManager(); 7293 int targetUid; 7294 if (needed != null) { 7295 targetUid = needed.targetUid; 7296 } else { 7297 try { 7298 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7299 } catch (RemoteException ex) { 7300 return null; 7301 } 7302 if (targetUid < 0) { 7303 if (DEBUG_URI_PERMISSION) { 7304 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7305 + " on user " + targetUserId); 7306 } 7307 return null; 7308 } 7309 } 7310 if (data != null) { 7311 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7312 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7313 targetUid); 7314 if (targetUid > 0) { 7315 if (needed == null) { 7316 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7317 } 7318 needed.add(grantUri); 7319 } 7320 } 7321 if (clip != null) { 7322 for (int i=0; i<clip.getItemCount(); i++) { 7323 Uri uri = clip.getItemAt(i).getUri(); 7324 if (uri != null) { 7325 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7326 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7327 targetUid); 7328 if (targetUid > 0) { 7329 if (needed == null) { 7330 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7331 } 7332 needed.add(grantUri); 7333 } 7334 } else { 7335 Intent clipIntent = clip.getItemAt(i).getIntent(); 7336 if (clipIntent != null) { 7337 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7338 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7339 if (newNeeded != null) { 7340 needed = newNeeded; 7341 } 7342 } 7343 } 7344 } 7345 } 7346 7347 return needed; 7348 } 7349 7350 /** 7351 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7352 */ 7353 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7354 UriPermissionOwner owner) { 7355 if (needed != null) { 7356 for (int i=0; i<needed.size(); i++) { 7357 GrantUri grantUri = needed.get(i); 7358 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7359 grantUri, needed.flags, owner); 7360 } 7361 } 7362 } 7363 7364 void grantUriPermissionFromIntentLocked(int callingUid, 7365 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7366 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7367 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7368 if (needed == null) { 7369 return; 7370 } 7371 7372 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7373 } 7374 7375 /** 7376 * @param uri This uri must NOT contain an embedded userId. 7377 * @param userId The userId in which the uri is to be resolved. 7378 */ 7379 @Override 7380 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7381 final int modeFlags, int userId) { 7382 enforceNotIsolatedCaller("grantUriPermission"); 7383 GrantUri grantUri = new GrantUri(userId, uri, false); 7384 synchronized(this) { 7385 final ProcessRecord r = getRecordForAppLocked(caller); 7386 if (r == null) { 7387 throw new SecurityException("Unable to find app for caller " 7388 + caller 7389 + " when granting permission to uri " + grantUri); 7390 } 7391 if (targetPkg == null) { 7392 throw new IllegalArgumentException("null target"); 7393 } 7394 if (grantUri == null) { 7395 throw new IllegalArgumentException("null uri"); 7396 } 7397 7398 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7399 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7400 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7401 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7402 7403 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7404 UserHandle.getUserId(r.uid)); 7405 } 7406 } 7407 7408 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7409 if (perm.modeFlags == 0) { 7410 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7411 perm.targetUid); 7412 if (perms != null) { 7413 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7414 "Removing " + perm.targetUid + " permission to " + perm.uri); 7415 7416 perms.remove(perm.uri); 7417 if (perms.isEmpty()) { 7418 mGrantedUriPermissions.remove(perm.targetUid); 7419 } 7420 } 7421 } 7422 } 7423 7424 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7425 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7426 7427 final IPackageManager pm = AppGlobals.getPackageManager(); 7428 final String authority = grantUri.uri.getAuthority(); 7429 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7430 if (pi == null) { 7431 Slog.w(TAG, "No content provider found for permission revoke: " 7432 + grantUri.toSafeString()); 7433 return; 7434 } 7435 7436 // Does the caller have this permission on the URI? 7437 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7438 // Right now, if you are not the original owner of the permission, 7439 // you are not allowed to revoke it. 7440 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7441 throw new SecurityException("Uid " + callingUid 7442 + " does not have permission to uri " + grantUri); 7443 //} 7444 } 7445 7446 boolean persistChanged = false; 7447 7448 // Go through all of the permissions and remove any that match. 7449 int N = mGrantedUriPermissions.size(); 7450 for (int i = 0; i < N; i++) { 7451 final int targetUid = mGrantedUriPermissions.keyAt(i); 7452 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7453 7454 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7455 final UriPermission perm = it.next(); 7456 if (perm.uri.sourceUserId == grantUri.sourceUserId 7457 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7458 if (DEBUG_URI_PERMISSION) 7459 Slog.v(TAG, 7460 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7461 persistChanged |= perm.revokeModes( 7462 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7463 if (perm.modeFlags == 0) { 7464 it.remove(); 7465 } 7466 } 7467 } 7468 7469 if (perms.isEmpty()) { 7470 mGrantedUriPermissions.remove(targetUid); 7471 N--; 7472 i--; 7473 } 7474 } 7475 7476 if (persistChanged) { 7477 schedulePersistUriGrants(); 7478 } 7479 } 7480 7481 /** 7482 * @param uri This uri must NOT contain an embedded userId. 7483 * @param userId The userId in which the uri is to be resolved. 7484 */ 7485 @Override 7486 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7487 int userId) { 7488 enforceNotIsolatedCaller("revokeUriPermission"); 7489 synchronized(this) { 7490 final ProcessRecord r = getRecordForAppLocked(caller); 7491 if (r == null) { 7492 throw new SecurityException("Unable to find app for caller " 7493 + caller 7494 + " when revoking permission to uri " + uri); 7495 } 7496 if (uri == null) { 7497 Slog.w(TAG, "revokeUriPermission: null uri"); 7498 return; 7499 } 7500 7501 if (!Intent.isAccessUriMode(modeFlags)) { 7502 return; 7503 } 7504 7505 final IPackageManager pm = AppGlobals.getPackageManager(); 7506 final String authority = uri.getAuthority(); 7507 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7508 if (pi == null) { 7509 Slog.w(TAG, "No content provider found for permission revoke: " 7510 + uri.toSafeString()); 7511 return; 7512 } 7513 7514 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7515 } 7516 } 7517 7518 /** 7519 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7520 * given package. 7521 * 7522 * @param packageName Package name to match, or {@code null} to apply to all 7523 * packages. 7524 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7525 * to all users. 7526 * @param persistable If persistable grants should be removed. 7527 */ 7528 private void removeUriPermissionsForPackageLocked( 7529 String packageName, int userHandle, boolean persistable) { 7530 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7531 throw new IllegalArgumentException("Must narrow by either package or user"); 7532 } 7533 7534 boolean persistChanged = false; 7535 7536 int N = mGrantedUriPermissions.size(); 7537 for (int i = 0; i < N; i++) { 7538 final int targetUid = mGrantedUriPermissions.keyAt(i); 7539 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7540 7541 // Only inspect grants matching user 7542 if (userHandle == UserHandle.USER_ALL 7543 || userHandle == UserHandle.getUserId(targetUid)) { 7544 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7545 final UriPermission perm = it.next(); 7546 7547 // Only inspect grants matching package 7548 if (packageName == null || perm.sourcePkg.equals(packageName) 7549 || perm.targetPkg.equals(packageName)) { 7550 persistChanged |= perm.revokeModes( 7551 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7552 7553 // Only remove when no modes remain; any persisted grants 7554 // will keep this alive. 7555 if (perm.modeFlags == 0) { 7556 it.remove(); 7557 } 7558 } 7559 } 7560 7561 if (perms.isEmpty()) { 7562 mGrantedUriPermissions.remove(targetUid); 7563 N--; 7564 i--; 7565 } 7566 } 7567 } 7568 7569 if (persistChanged) { 7570 schedulePersistUriGrants(); 7571 } 7572 } 7573 7574 @Override 7575 public IBinder newUriPermissionOwner(String name) { 7576 enforceNotIsolatedCaller("newUriPermissionOwner"); 7577 synchronized(this) { 7578 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7579 return owner.getExternalTokenLocked(); 7580 } 7581 } 7582 7583 /** 7584 * @param uri This uri must NOT contain an embedded userId. 7585 * @param sourceUserId The userId in which the uri is to be resolved. 7586 * @param targetUserId The userId of the app that receives the grant. 7587 */ 7588 @Override 7589 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7590 final int modeFlags, int sourceUserId, int targetUserId) { 7591 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7592 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7593 synchronized(this) { 7594 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7595 if (owner == null) { 7596 throw new IllegalArgumentException("Unknown owner: " + token); 7597 } 7598 if (fromUid != Binder.getCallingUid()) { 7599 if (Binder.getCallingUid() != Process.myUid()) { 7600 // Only system code can grant URI permissions on behalf 7601 // of other users. 7602 throw new SecurityException("nice try"); 7603 } 7604 } 7605 if (targetPkg == null) { 7606 throw new IllegalArgumentException("null target"); 7607 } 7608 if (uri == null) { 7609 throw new IllegalArgumentException("null uri"); 7610 } 7611 7612 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7613 modeFlags, owner, targetUserId); 7614 } 7615 } 7616 7617 /** 7618 * @param uri This uri must NOT contain an embedded userId. 7619 * @param userId The userId in which the uri is to be resolved. 7620 */ 7621 @Override 7622 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7623 synchronized(this) { 7624 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7625 if (owner == null) { 7626 throw new IllegalArgumentException("Unknown owner: " + token); 7627 } 7628 7629 if (uri == null) { 7630 owner.removeUriPermissionsLocked(mode); 7631 } else { 7632 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7633 } 7634 } 7635 } 7636 7637 private void schedulePersistUriGrants() { 7638 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7639 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7640 10 * DateUtils.SECOND_IN_MILLIS); 7641 } 7642 } 7643 7644 private void writeGrantedUriPermissions() { 7645 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7646 7647 // Snapshot permissions so we can persist without lock 7648 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7649 synchronized (this) { 7650 final int size = mGrantedUriPermissions.size(); 7651 for (int i = 0; i < size; i++) { 7652 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7653 for (UriPermission perm : perms.values()) { 7654 if (perm.persistedModeFlags != 0) { 7655 persist.add(perm.snapshot()); 7656 } 7657 } 7658 } 7659 } 7660 7661 FileOutputStream fos = null; 7662 try { 7663 fos = mGrantFile.startWrite(); 7664 7665 XmlSerializer out = new FastXmlSerializer(); 7666 out.setOutput(fos, "utf-8"); 7667 out.startDocument(null, true); 7668 out.startTag(null, TAG_URI_GRANTS); 7669 for (UriPermission.Snapshot perm : persist) { 7670 out.startTag(null, TAG_URI_GRANT); 7671 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7672 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7673 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7674 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7675 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7676 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7677 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7678 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7679 out.endTag(null, TAG_URI_GRANT); 7680 } 7681 out.endTag(null, TAG_URI_GRANTS); 7682 out.endDocument(); 7683 7684 mGrantFile.finishWrite(fos); 7685 } catch (IOException e) { 7686 if (fos != null) { 7687 mGrantFile.failWrite(fos); 7688 } 7689 } 7690 } 7691 7692 private void readGrantedUriPermissionsLocked() { 7693 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7694 7695 final long now = System.currentTimeMillis(); 7696 7697 FileInputStream fis = null; 7698 try { 7699 fis = mGrantFile.openRead(); 7700 final XmlPullParser in = Xml.newPullParser(); 7701 in.setInput(fis, null); 7702 7703 int type; 7704 while ((type = in.next()) != END_DOCUMENT) { 7705 final String tag = in.getName(); 7706 if (type == START_TAG) { 7707 if (TAG_URI_GRANT.equals(tag)) { 7708 final int sourceUserId; 7709 final int targetUserId; 7710 final int userHandle = readIntAttribute(in, 7711 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7712 if (userHandle != UserHandle.USER_NULL) { 7713 // For backwards compatibility. 7714 sourceUserId = userHandle; 7715 targetUserId = userHandle; 7716 } else { 7717 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7718 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7719 } 7720 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7721 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7722 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7723 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7724 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7725 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7726 7727 // Sanity check that provider still belongs to source package 7728 final ProviderInfo pi = getProviderInfoLocked( 7729 uri.getAuthority(), sourceUserId); 7730 if (pi != null && sourcePkg.equals(pi.packageName)) { 7731 int targetUid = -1; 7732 try { 7733 targetUid = AppGlobals.getPackageManager() 7734 .getPackageUid(targetPkg, targetUserId); 7735 } catch (RemoteException e) { 7736 } 7737 if (targetUid != -1) { 7738 final UriPermission perm = findOrCreateUriPermissionLocked( 7739 sourcePkg, targetPkg, targetUid, 7740 new GrantUri(sourceUserId, uri, prefix)); 7741 perm.initPersistedModes(modeFlags, createdTime); 7742 } 7743 } else { 7744 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7745 + " but instead found " + pi); 7746 } 7747 } 7748 } 7749 } 7750 } catch (FileNotFoundException e) { 7751 // Missing grants is okay 7752 } catch (IOException e) { 7753 Log.wtf(TAG, "Failed reading Uri grants", e); 7754 } catch (XmlPullParserException e) { 7755 Log.wtf(TAG, "Failed reading Uri grants", e); 7756 } finally { 7757 IoUtils.closeQuietly(fis); 7758 } 7759 } 7760 7761 /** 7762 * @param uri This uri must NOT contain an embedded userId. 7763 * @param userId The userId in which the uri is to be resolved. 7764 */ 7765 @Override 7766 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7767 enforceNotIsolatedCaller("takePersistableUriPermission"); 7768 7769 Preconditions.checkFlagsArgument(modeFlags, 7770 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7771 7772 synchronized (this) { 7773 final int callingUid = Binder.getCallingUid(); 7774 boolean persistChanged = false; 7775 GrantUri grantUri = new GrantUri(userId, uri, false); 7776 7777 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7778 new GrantUri(userId, uri, false)); 7779 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7780 new GrantUri(userId, uri, true)); 7781 7782 final boolean exactValid = (exactPerm != null) 7783 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7784 final boolean prefixValid = (prefixPerm != null) 7785 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7786 7787 if (!(exactValid || prefixValid)) { 7788 throw new SecurityException("No persistable permission grants found for UID " 7789 + callingUid + " and Uri " + grantUri.toSafeString()); 7790 } 7791 7792 if (exactValid) { 7793 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7794 } 7795 if (prefixValid) { 7796 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7797 } 7798 7799 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7800 7801 if (persistChanged) { 7802 schedulePersistUriGrants(); 7803 } 7804 } 7805 } 7806 7807 /** 7808 * @param uri This uri must NOT contain an embedded userId. 7809 * @param userId The userId in which the uri is to be resolved. 7810 */ 7811 @Override 7812 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7813 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7814 7815 Preconditions.checkFlagsArgument(modeFlags, 7816 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7817 7818 synchronized (this) { 7819 final int callingUid = Binder.getCallingUid(); 7820 boolean persistChanged = false; 7821 7822 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7823 new GrantUri(userId, uri, false)); 7824 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7825 new GrantUri(userId, uri, true)); 7826 if (exactPerm == null && prefixPerm == null) { 7827 throw new SecurityException("No permission grants found for UID " + callingUid 7828 + " and Uri " + uri.toSafeString()); 7829 } 7830 7831 if (exactPerm != null) { 7832 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7833 removeUriPermissionIfNeededLocked(exactPerm); 7834 } 7835 if (prefixPerm != null) { 7836 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7837 removeUriPermissionIfNeededLocked(prefixPerm); 7838 } 7839 7840 if (persistChanged) { 7841 schedulePersistUriGrants(); 7842 } 7843 } 7844 } 7845 7846 /** 7847 * Prune any older {@link UriPermission} for the given UID until outstanding 7848 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7849 * 7850 * @return if any mutations occured that require persisting. 7851 */ 7852 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7853 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7854 if (perms == null) return false; 7855 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7856 7857 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7858 for (UriPermission perm : perms.values()) { 7859 if (perm.persistedModeFlags != 0) { 7860 persisted.add(perm); 7861 } 7862 } 7863 7864 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7865 if (trimCount <= 0) return false; 7866 7867 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7868 for (int i = 0; i < trimCount; i++) { 7869 final UriPermission perm = persisted.get(i); 7870 7871 if (DEBUG_URI_PERMISSION) { 7872 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7873 } 7874 7875 perm.releasePersistableModes(~0); 7876 removeUriPermissionIfNeededLocked(perm); 7877 } 7878 7879 return true; 7880 } 7881 7882 @Override 7883 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7884 String packageName, boolean incoming) { 7885 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7886 Preconditions.checkNotNull(packageName, "packageName"); 7887 7888 final int callingUid = Binder.getCallingUid(); 7889 final IPackageManager pm = AppGlobals.getPackageManager(); 7890 try { 7891 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7892 if (packageUid != callingUid) { 7893 throw new SecurityException( 7894 "Package " + packageName + " does not belong to calling UID " + callingUid); 7895 } 7896 } catch (RemoteException e) { 7897 throw new SecurityException("Failed to verify package name ownership"); 7898 } 7899 7900 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7901 synchronized (this) { 7902 if (incoming) { 7903 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7904 callingUid); 7905 if (perms == null) { 7906 Slog.w(TAG, "No permission grants found for " + packageName); 7907 } else { 7908 for (UriPermission perm : perms.values()) { 7909 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7910 result.add(perm.buildPersistedPublicApiObject()); 7911 } 7912 } 7913 } 7914 } else { 7915 final int size = mGrantedUriPermissions.size(); 7916 for (int i = 0; i < size; i++) { 7917 final ArrayMap<GrantUri, UriPermission> perms = 7918 mGrantedUriPermissions.valueAt(i); 7919 for (UriPermission perm : perms.values()) { 7920 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7921 result.add(perm.buildPersistedPublicApiObject()); 7922 } 7923 } 7924 } 7925 } 7926 } 7927 return new ParceledListSlice<android.content.UriPermission>(result); 7928 } 7929 7930 @Override 7931 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7932 synchronized (this) { 7933 ProcessRecord app = 7934 who != null ? getRecordForAppLocked(who) : null; 7935 if (app == null) return; 7936 7937 Message msg = Message.obtain(); 7938 msg.what = WAIT_FOR_DEBUGGER_MSG; 7939 msg.obj = app; 7940 msg.arg1 = waiting ? 1 : 0; 7941 mHandler.sendMessage(msg); 7942 } 7943 } 7944 7945 @Override 7946 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7947 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7948 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7949 outInfo.availMem = Process.getFreeMemory(); 7950 outInfo.totalMem = Process.getTotalMemory(); 7951 outInfo.threshold = homeAppMem; 7952 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7953 outInfo.hiddenAppThreshold = cachedAppMem; 7954 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7955 ProcessList.SERVICE_ADJ); 7956 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7957 ProcessList.VISIBLE_APP_ADJ); 7958 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7959 ProcessList.FOREGROUND_APP_ADJ); 7960 } 7961 7962 // ========================================================= 7963 // TASK MANAGEMENT 7964 // ========================================================= 7965 7966 @Override 7967 public List<IAppTask> getAppTasks(String callingPackage) { 7968 int callingUid = Binder.getCallingUid(); 7969 long ident = Binder.clearCallingIdentity(); 7970 7971 synchronized(this) { 7972 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7973 try { 7974 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7975 7976 final int N = mRecentTasks.size(); 7977 for (int i = 0; i < N; i++) { 7978 TaskRecord tr = mRecentTasks.get(i); 7979 // Skip tasks that do not match the caller. We don't need to verify 7980 // callingPackage, because we are also limiting to callingUid and know 7981 // that will limit to the correct security sandbox. 7982 if (tr.effectiveUid != callingUid) { 7983 continue; 7984 } 7985 Intent intent = tr.getBaseIntent(); 7986 if (intent == null || 7987 !callingPackage.equals(intent.getComponent().getPackageName())) { 7988 continue; 7989 } 7990 ActivityManager.RecentTaskInfo taskInfo = 7991 createRecentTaskInfoFromTaskRecord(tr); 7992 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7993 list.add(taskImpl); 7994 } 7995 } finally { 7996 Binder.restoreCallingIdentity(ident); 7997 } 7998 return list; 7999 } 8000 } 8001 8002 @Override 8003 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8004 final int callingUid = Binder.getCallingUid(); 8005 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8006 8007 synchronized(this) { 8008 if (localLOGV) Slog.v( 8009 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8010 8011 final boolean allowed = checkCallingPermission( 8012 android.Manifest.permission.GET_TASKS) 8013 == PackageManager.PERMISSION_GRANTED; 8014 if (!allowed) { 8015 Slog.w(TAG, "getTasks: caller " + callingUid 8016 + " does not hold GET_TASKS; limiting output"); 8017 } 8018 8019 // TODO: Improve with MRU list from all ActivityStacks. 8020 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8021 } 8022 8023 return list; 8024 } 8025 8026 TaskRecord getMostRecentTask() { 8027 return mRecentTasks.get(0); 8028 } 8029 8030 /** 8031 * Creates a new RecentTaskInfo from a TaskRecord. 8032 */ 8033 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8034 // Update the task description to reflect any changes in the task stack 8035 tr.updateTaskDescription(); 8036 8037 // Compose the recent task info 8038 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8039 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8040 rti.persistentId = tr.taskId; 8041 rti.baseIntent = new Intent(tr.getBaseIntent()); 8042 rti.origActivity = tr.origActivity; 8043 rti.description = tr.lastDescription; 8044 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8045 rti.userId = tr.userId; 8046 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8047 rti.firstActiveTime = tr.firstActiveTime; 8048 rti.lastActiveTime = tr.lastActiveTime; 8049 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8050 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8051 return rti; 8052 } 8053 8054 @Override 8055 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8056 final int callingUid = Binder.getCallingUid(); 8057 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8058 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8059 8060 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8061 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8062 synchronized (this) { 8063 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8064 == PackageManager.PERMISSION_GRANTED; 8065 if (!allowed) { 8066 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8067 + " does not hold GET_TASKS; limiting output"); 8068 } 8069 final boolean detailed = checkCallingPermission( 8070 android.Manifest.permission.GET_DETAILED_TASKS) 8071 == PackageManager.PERMISSION_GRANTED; 8072 8073 final int N = mRecentTasks.size(); 8074 ArrayList<ActivityManager.RecentTaskInfo> res 8075 = new ArrayList<ActivityManager.RecentTaskInfo>( 8076 maxNum < N ? maxNum : N); 8077 8078 final Set<Integer> includedUsers; 8079 if (includeProfiles) { 8080 includedUsers = getProfileIdsLocked(userId); 8081 } else { 8082 includedUsers = new HashSet<Integer>(); 8083 } 8084 includedUsers.add(Integer.valueOf(userId)); 8085 8086 for (int i=0; i<N && maxNum > 0; i++) { 8087 TaskRecord tr = mRecentTasks.get(i); 8088 // Only add calling user or related users recent tasks 8089 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8090 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8091 continue; 8092 } 8093 8094 // Return the entry if desired by the caller. We always return 8095 // the first entry, because callers always expect this to be the 8096 // foreground app. We may filter others if the caller has 8097 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8098 // we should exclude the entry. 8099 8100 if (i == 0 8101 || withExcluded 8102 || (tr.intent == null) 8103 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8104 == 0)) { 8105 if (!allowed) { 8106 // If the caller doesn't have the GET_TASKS permission, then only 8107 // allow them to see a small subset of tasks -- their own and home. 8108 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8109 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8110 continue; 8111 } 8112 } 8113 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8114 if (tr.stack != null && tr.stack.isHomeStack()) { 8115 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8116 continue; 8117 } 8118 } 8119 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8120 // Don't include auto remove tasks that are finished or finishing. 8121 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8122 + tr); 8123 continue; 8124 } 8125 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8126 && !tr.isAvailable) { 8127 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8128 continue; 8129 } 8130 8131 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8132 if (!detailed) { 8133 rti.baseIntent.replaceExtras((Bundle)null); 8134 } 8135 8136 res.add(rti); 8137 maxNum--; 8138 } 8139 } 8140 return res; 8141 } 8142 } 8143 8144 private TaskRecord recentTaskForIdLocked(int id) { 8145 final int N = mRecentTasks.size(); 8146 for (int i=0; i<N; i++) { 8147 TaskRecord tr = mRecentTasks.get(i); 8148 if (tr.taskId == id) { 8149 return tr; 8150 } 8151 } 8152 return null; 8153 } 8154 8155 @Override 8156 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8157 synchronized (this) { 8158 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8159 "getTaskThumbnail()"); 8160 TaskRecord tr = recentTaskForIdLocked(id); 8161 if (tr != null) { 8162 return tr.getTaskThumbnailLocked(); 8163 } 8164 } 8165 return null; 8166 } 8167 8168 @Override 8169 public int addAppTask(IBinder activityToken, Intent intent, 8170 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8171 final int callingUid = Binder.getCallingUid(); 8172 final long callingIdent = Binder.clearCallingIdentity(); 8173 8174 try { 8175 synchronized (this) { 8176 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8177 if (r == null) { 8178 throw new IllegalArgumentException("Activity does not exist; token=" 8179 + activityToken); 8180 } 8181 ComponentName comp = intent.getComponent(); 8182 if (comp == null) { 8183 throw new IllegalArgumentException("Intent " + intent 8184 + " must specify explicit component"); 8185 } 8186 if (thumbnail.getWidth() != mThumbnailWidth 8187 || thumbnail.getHeight() != mThumbnailHeight) { 8188 throw new IllegalArgumentException("Bad thumbnail size: got " 8189 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8190 + mThumbnailWidth + "x" + mThumbnailHeight); 8191 } 8192 if (intent.getSelector() != null) { 8193 intent.setSelector(null); 8194 } 8195 if (intent.getSourceBounds() != null) { 8196 intent.setSourceBounds(null); 8197 } 8198 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8199 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8200 // The caller has added this as an auto-remove task... that makes no 8201 // sense, so turn off auto-remove. 8202 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8203 } 8204 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8205 // Must be a new task. 8206 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8207 } 8208 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8209 mLastAddedTaskActivity = null; 8210 } 8211 ActivityInfo ainfo = mLastAddedTaskActivity; 8212 if (ainfo == null) { 8213 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8214 comp, 0, UserHandle.getUserId(callingUid)); 8215 if (ainfo.applicationInfo.uid != callingUid) { 8216 throw new SecurityException( 8217 "Can't add task for another application: target uid=" 8218 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8219 } 8220 } 8221 8222 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8223 intent, description); 8224 8225 int trimIdx = trimRecentsForTask(task, false); 8226 if (trimIdx >= 0) { 8227 // If this would have caused a trim, then we'll abort because that 8228 // means it would be added at the end of the list but then just removed. 8229 return -1; 8230 } 8231 8232 final int N = mRecentTasks.size(); 8233 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8234 final TaskRecord tr = mRecentTasks.remove(N - 1); 8235 tr.removedFromRecents(mTaskPersister); 8236 } 8237 8238 task.inRecents = true; 8239 mRecentTasks.add(task); 8240 r.task.stack.addTask(task, false, false); 8241 8242 task.setLastThumbnail(thumbnail); 8243 task.freeLastThumbnail(); 8244 8245 return task.taskId; 8246 } 8247 } finally { 8248 Binder.restoreCallingIdentity(callingIdent); 8249 } 8250 } 8251 8252 @Override 8253 public Point getAppTaskThumbnailSize() { 8254 synchronized (this) { 8255 return new Point(mThumbnailWidth, mThumbnailHeight); 8256 } 8257 } 8258 8259 @Override 8260 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8261 synchronized (this) { 8262 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8263 if (r != null) { 8264 r.taskDescription = td; 8265 r.task.updateTaskDescription(); 8266 } 8267 } 8268 } 8269 8270 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8271 mRecentTasks.remove(tr); 8272 tr.removedFromRecents(mTaskPersister); 8273 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8274 Intent baseIntent = new Intent( 8275 tr.intent != null ? tr.intent : tr.affinityIntent); 8276 ComponentName component = baseIntent.getComponent(); 8277 if (component == null) { 8278 Slog.w(TAG, "Now component for base intent of task: " + tr); 8279 return; 8280 } 8281 8282 // Find any running services associated with this app. 8283 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8284 8285 if (killProcesses) { 8286 // Find any running processes associated with this app. 8287 final String pkg = component.getPackageName(); 8288 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8289 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8290 for (int i=0; i<pmap.size(); i++) { 8291 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8292 for (int j=0; j<uids.size(); j++) { 8293 ProcessRecord proc = uids.valueAt(j); 8294 if (proc.userId != tr.userId) { 8295 continue; 8296 } 8297 if (!proc.pkgList.containsKey(pkg)) { 8298 continue; 8299 } 8300 procs.add(proc); 8301 } 8302 } 8303 8304 // Kill the running processes. 8305 for (int i=0; i<procs.size(); i++) { 8306 ProcessRecord pr = procs.get(i); 8307 if (pr == mHomeProcess) { 8308 // Don't kill the home process along with tasks from the same package. 8309 continue; 8310 } 8311 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8312 pr.kill("remove task", true); 8313 } else { 8314 pr.waitingToKill = "remove task"; 8315 } 8316 } 8317 } 8318 } 8319 8320 /** 8321 * Removes the task with the specified task id. 8322 * 8323 * @param taskId Identifier of the task to be removed. 8324 * @param flags Additional operational flags. May be 0 or 8325 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8326 * @return Returns true if the given task was found and removed. 8327 */ 8328 private boolean removeTaskByIdLocked(int taskId, int flags) { 8329 TaskRecord tr = recentTaskForIdLocked(taskId); 8330 if (tr != null) { 8331 tr.removeTaskActivitiesLocked(); 8332 cleanUpRemovedTaskLocked(tr, flags); 8333 if (tr.isPersistable) { 8334 notifyTaskPersisterLocked(null, true); 8335 } 8336 return true; 8337 } 8338 return false; 8339 } 8340 8341 @Override 8342 public boolean removeTask(int taskId, int flags) { 8343 synchronized (this) { 8344 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8345 "removeTask()"); 8346 long ident = Binder.clearCallingIdentity(); 8347 try { 8348 return removeTaskByIdLocked(taskId, flags); 8349 } finally { 8350 Binder.restoreCallingIdentity(ident); 8351 } 8352 } 8353 } 8354 8355 /** 8356 * TODO: Add mController hook 8357 */ 8358 @Override 8359 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8360 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8361 "moveTaskToFront()"); 8362 8363 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8364 synchronized(this) { 8365 moveTaskToFrontLocked(taskId, flags, options); 8366 } 8367 } 8368 8369 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8370 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8371 Binder.getCallingUid(), "Task to front")) { 8372 ActivityOptions.abort(options); 8373 return; 8374 } 8375 final long origId = Binder.clearCallingIdentity(); 8376 try { 8377 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8378 if (task == null) { 8379 return; 8380 } 8381 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8382 mStackSupervisor.showLockTaskToast(); 8383 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8384 return; 8385 } 8386 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8387 if (prev != null && prev.isRecentsActivity()) { 8388 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8389 } 8390 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8391 } finally { 8392 Binder.restoreCallingIdentity(origId); 8393 } 8394 ActivityOptions.abort(options); 8395 } 8396 8397 @Override 8398 public void moveTaskToBack(int taskId) { 8399 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8400 "moveTaskToBack()"); 8401 8402 synchronized(this) { 8403 TaskRecord tr = recentTaskForIdLocked(taskId); 8404 if (tr != null) { 8405 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8406 ActivityStack stack = tr.stack; 8407 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8408 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8409 Binder.getCallingUid(), "Task to back")) { 8410 return; 8411 } 8412 } 8413 final long origId = Binder.clearCallingIdentity(); 8414 try { 8415 stack.moveTaskToBackLocked(taskId, null); 8416 } finally { 8417 Binder.restoreCallingIdentity(origId); 8418 } 8419 } 8420 } 8421 } 8422 8423 /** 8424 * Moves an activity, and all of the other activities within the same task, to the bottom 8425 * of the history stack. The activity's order within the task is unchanged. 8426 * 8427 * @param token A reference to the activity we wish to move 8428 * @param nonRoot If false then this only works if the activity is the root 8429 * of a task; if true it will work for any activity in a task. 8430 * @return Returns true if the move completed, false if not. 8431 */ 8432 @Override 8433 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8434 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8435 synchronized(this) { 8436 final long origId = Binder.clearCallingIdentity(); 8437 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8438 if (taskId >= 0) { 8439 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8440 } 8441 Binder.restoreCallingIdentity(origId); 8442 } 8443 return false; 8444 } 8445 8446 @Override 8447 public void moveTaskBackwards(int task) { 8448 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8449 "moveTaskBackwards()"); 8450 8451 synchronized(this) { 8452 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8453 Binder.getCallingUid(), "Task backwards")) { 8454 return; 8455 } 8456 final long origId = Binder.clearCallingIdentity(); 8457 moveTaskBackwardsLocked(task); 8458 Binder.restoreCallingIdentity(origId); 8459 } 8460 } 8461 8462 private final void moveTaskBackwardsLocked(int task) { 8463 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8464 } 8465 8466 @Override 8467 public IBinder getHomeActivityToken() throws RemoteException { 8468 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8469 "getHomeActivityToken()"); 8470 synchronized (this) { 8471 return mStackSupervisor.getHomeActivityToken(); 8472 } 8473 } 8474 8475 @Override 8476 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8477 IActivityContainerCallback callback) throws RemoteException { 8478 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8479 "createActivityContainer()"); 8480 synchronized (this) { 8481 if (parentActivityToken == null) { 8482 throw new IllegalArgumentException("parent token must not be null"); 8483 } 8484 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8485 if (r == null) { 8486 return null; 8487 } 8488 if (callback == null) { 8489 throw new IllegalArgumentException("callback must not be null"); 8490 } 8491 return mStackSupervisor.createActivityContainer(r, callback); 8492 } 8493 } 8494 8495 @Override 8496 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8497 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8498 "deleteActivityContainer()"); 8499 synchronized (this) { 8500 mStackSupervisor.deleteActivityContainer(container); 8501 } 8502 } 8503 8504 @Override 8505 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8506 throws RemoteException { 8507 synchronized (this) { 8508 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8509 if (stack != null) { 8510 return stack.mActivityContainer; 8511 } 8512 return null; 8513 } 8514 } 8515 8516 @Override 8517 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8518 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8519 "moveTaskToStack()"); 8520 if (stackId == HOME_STACK_ID) { 8521 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8522 new RuntimeException("here").fillInStackTrace()); 8523 } 8524 synchronized (this) { 8525 long ident = Binder.clearCallingIdentity(); 8526 try { 8527 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8528 + stackId + " toTop=" + toTop); 8529 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8530 } finally { 8531 Binder.restoreCallingIdentity(ident); 8532 } 8533 } 8534 } 8535 8536 @Override 8537 public void resizeStack(int stackBoxId, Rect bounds) { 8538 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8539 "resizeStackBox()"); 8540 long ident = Binder.clearCallingIdentity(); 8541 try { 8542 mWindowManager.resizeStack(stackBoxId, bounds); 8543 } finally { 8544 Binder.restoreCallingIdentity(ident); 8545 } 8546 } 8547 8548 @Override 8549 public List<StackInfo> getAllStackInfos() { 8550 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8551 "getAllStackInfos()"); 8552 long ident = Binder.clearCallingIdentity(); 8553 try { 8554 synchronized (this) { 8555 return mStackSupervisor.getAllStackInfosLocked(); 8556 } 8557 } finally { 8558 Binder.restoreCallingIdentity(ident); 8559 } 8560 } 8561 8562 @Override 8563 public StackInfo getStackInfo(int stackId) { 8564 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8565 "getStackInfo()"); 8566 long ident = Binder.clearCallingIdentity(); 8567 try { 8568 synchronized (this) { 8569 return mStackSupervisor.getStackInfoLocked(stackId); 8570 } 8571 } finally { 8572 Binder.restoreCallingIdentity(ident); 8573 } 8574 } 8575 8576 @Override 8577 public boolean isInHomeStack(int taskId) { 8578 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8579 "getStackInfo()"); 8580 long ident = Binder.clearCallingIdentity(); 8581 try { 8582 synchronized (this) { 8583 TaskRecord tr = recentTaskForIdLocked(taskId); 8584 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8585 } 8586 } finally { 8587 Binder.restoreCallingIdentity(ident); 8588 } 8589 } 8590 8591 @Override 8592 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8593 synchronized(this) { 8594 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8595 } 8596 } 8597 8598 private boolean isLockTaskAuthorized(String pkg) { 8599 final DevicePolicyManager dpm = (DevicePolicyManager) 8600 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8601 try { 8602 int uid = mContext.getPackageManager().getPackageUid(pkg, 8603 Binder.getCallingUserHandle().getIdentifier()); 8604 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8605 } catch (NameNotFoundException e) { 8606 return false; 8607 } 8608 } 8609 8610 void startLockTaskMode(TaskRecord task) { 8611 final String pkg; 8612 synchronized (this) { 8613 pkg = task.intent.getComponent().getPackageName(); 8614 } 8615 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8616 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8617 final TaskRecord taskRecord = task; 8618 mHandler.post(new Runnable() { 8619 @Override 8620 public void run() { 8621 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8622 } 8623 }); 8624 return; 8625 } 8626 long ident = Binder.clearCallingIdentity(); 8627 try { 8628 synchronized (this) { 8629 // Since we lost lock on task, make sure it is still there. 8630 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8631 if (task != null) { 8632 if (!isSystemInitiated 8633 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8634 throw new IllegalArgumentException("Invalid task, not in foreground"); 8635 } 8636 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8637 } 8638 } 8639 } finally { 8640 Binder.restoreCallingIdentity(ident); 8641 } 8642 } 8643 8644 @Override 8645 public void startLockTaskMode(int taskId) { 8646 final TaskRecord task; 8647 long ident = Binder.clearCallingIdentity(); 8648 try { 8649 synchronized (this) { 8650 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8651 } 8652 } finally { 8653 Binder.restoreCallingIdentity(ident); 8654 } 8655 if (task != null) { 8656 startLockTaskMode(task); 8657 } 8658 } 8659 8660 @Override 8661 public void startLockTaskMode(IBinder token) { 8662 final TaskRecord task; 8663 long ident = Binder.clearCallingIdentity(); 8664 try { 8665 synchronized (this) { 8666 final ActivityRecord r = ActivityRecord.forToken(token); 8667 if (r == null) { 8668 return; 8669 } 8670 task = r.task; 8671 } 8672 } finally { 8673 Binder.restoreCallingIdentity(ident); 8674 } 8675 if (task != null) { 8676 startLockTaskMode(task); 8677 } 8678 } 8679 8680 @Override 8681 public void startLockTaskModeOnCurrent() throws RemoteException { 8682 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8683 ActivityRecord r = null; 8684 synchronized (this) { 8685 r = mStackSupervisor.topRunningActivityLocked(); 8686 } 8687 startLockTaskMode(r.task); 8688 } 8689 8690 @Override 8691 public void stopLockTaskMode() { 8692 // Verify that the user matches the package of the intent for the TaskRecord 8693 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8694 // and stopLockTaskMode. 8695 final int callingUid = Binder.getCallingUid(); 8696 if (callingUid != Process.SYSTEM_UID) { 8697 try { 8698 String pkg = 8699 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8700 int uid = mContext.getPackageManager().getPackageUid(pkg, 8701 Binder.getCallingUserHandle().getIdentifier()); 8702 if (uid != callingUid) { 8703 throw new SecurityException("Invalid uid, expected " + uid); 8704 } 8705 } catch (NameNotFoundException e) { 8706 Log.d(TAG, "stopLockTaskMode " + e); 8707 return; 8708 } 8709 } 8710 long ident = Binder.clearCallingIdentity(); 8711 try { 8712 Log.d(TAG, "stopLockTaskMode"); 8713 // Stop lock task 8714 synchronized (this) { 8715 mStackSupervisor.setLockTaskModeLocked(null, false); 8716 } 8717 } finally { 8718 Binder.restoreCallingIdentity(ident); 8719 } 8720 } 8721 8722 @Override 8723 public void stopLockTaskModeOnCurrent() throws RemoteException { 8724 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8725 long ident = Binder.clearCallingIdentity(); 8726 try { 8727 stopLockTaskMode(); 8728 } finally { 8729 Binder.restoreCallingIdentity(ident); 8730 } 8731 } 8732 8733 @Override 8734 public boolean isInLockTaskMode() { 8735 synchronized (this) { 8736 return mStackSupervisor.isInLockTaskMode(); 8737 } 8738 } 8739 8740 // ========================================================= 8741 // CONTENT PROVIDERS 8742 // ========================================================= 8743 8744 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8745 List<ProviderInfo> providers = null; 8746 try { 8747 providers = AppGlobals.getPackageManager(). 8748 queryContentProviders(app.processName, app.uid, 8749 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8750 } catch (RemoteException ex) { 8751 } 8752 if (DEBUG_MU) 8753 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8754 int userId = app.userId; 8755 if (providers != null) { 8756 int N = providers.size(); 8757 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8758 for (int i=0; i<N; i++) { 8759 ProviderInfo cpi = 8760 (ProviderInfo)providers.get(i); 8761 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8762 cpi.name, cpi.flags); 8763 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8764 // This is a singleton provider, but a user besides the 8765 // default user is asking to initialize a process it runs 8766 // in... well, no, it doesn't actually run in this process, 8767 // it runs in the process of the default user. Get rid of it. 8768 providers.remove(i); 8769 N--; 8770 i--; 8771 continue; 8772 } 8773 8774 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8775 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8776 if (cpr == null) { 8777 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8778 mProviderMap.putProviderByClass(comp, cpr); 8779 } 8780 if (DEBUG_MU) 8781 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8782 app.pubProviders.put(cpi.name, cpr); 8783 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8784 // Don't add this if it is a platform component that is marked 8785 // to run in multiple processes, because this is actually 8786 // part of the framework so doesn't make sense to track as a 8787 // separate apk in the process. 8788 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8789 mProcessStats); 8790 } 8791 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8792 } 8793 } 8794 return providers; 8795 } 8796 8797 /** 8798 * Check if {@link ProcessRecord} has a possible chance at accessing the 8799 * given {@link ProviderInfo}. Final permission checking is always done 8800 * in {@link ContentProvider}. 8801 */ 8802 private final String checkContentProviderPermissionLocked( 8803 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8804 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8805 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8806 boolean checkedGrants = false; 8807 if (checkUser) { 8808 // Looking for cross-user grants before enforcing the typical cross-users permissions 8809 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8810 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8811 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8812 return null; 8813 } 8814 checkedGrants = true; 8815 } 8816 userId = handleIncomingUser(callingPid, callingUid, userId, 8817 false, ALLOW_NON_FULL, 8818 "checkContentProviderPermissionLocked " + cpi.authority, null); 8819 if (userId != tmpTargetUserId) { 8820 // When we actually went to determine the final targer user ID, this ended 8821 // up different than our initial check for the authority. This is because 8822 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8823 // SELF. So we need to re-check the grants again. 8824 checkedGrants = false; 8825 } 8826 } 8827 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8828 cpi.applicationInfo.uid, cpi.exported) 8829 == PackageManager.PERMISSION_GRANTED) { 8830 return null; 8831 } 8832 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8833 cpi.applicationInfo.uid, cpi.exported) 8834 == PackageManager.PERMISSION_GRANTED) { 8835 return null; 8836 } 8837 8838 PathPermission[] pps = cpi.pathPermissions; 8839 if (pps != null) { 8840 int i = pps.length; 8841 while (i > 0) { 8842 i--; 8843 PathPermission pp = pps[i]; 8844 String pprperm = pp.getReadPermission(); 8845 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8846 cpi.applicationInfo.uid, cpi.exported) 8847 == PackageManager.PERMISSION_GRANTED) { 8848 return null; 8849 } 8850 String ppwperm = pp.getWritePermission(); 8851 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8852 cpi.applicationInfo.uid, cpi.exported) 8853 == PackageManager.PERMISSION_GRANTED) { 8854 return null; 8855 } 8856 } 8857 } 8858 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8859 return null; 8860 } 8861 8862 String msg; 8863 if (!cpi.exported) { 8864 msg = "Permission Denial: opening provider " + cpi.name 8865 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8866 + ", uid=" + callingUid + ") that is not exported from uid " 8867 + cpi.applicationInfo.uid; 8868 } else { 8869 msg = "Permission Denial: opening provider " + cpi.name 8870 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8871 + ", uid=" + callingUid + ") requires " 8872 + cpi.readPermission + " or " + cpi.writePermission; 8873 } 8874 Slog.w(TAG, msg); 8875 return msg; 8876 } 8877 8878 /** 8879 * Returns if the ContentProvider has granted a uri to callingUid 8880 */ 8881 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8882 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8883 if (perms != null) { 8884 for (int i=perms.size()-1; i>=0; i--) { 8885 GrantUri grantUri = perms.keyAt(i); 8886 if (grantUri.sourceUserId == userId || !checkUser) { 8887 if (matchesProvider(grantUri.uri, cpi)) { 8888 return true; 8889 } 8890 } 8891 } 8892 } 8893 return false; 8894 } 8895 8896 /** 8897 * Returns true if the uri authority is one of the authorities specified in the provider. 8898 */ 8899 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8900 String uriAuth = uri.getAuthority(); 8901 String cpiAuth = cpi.authority; 8902 if (cpiAuth.indexOf(';') == -1) { 8903 return cpiAuth.equals(uriAuth); 8904 } 8905 String[] cpiAuths = cpiAuth.split(";"); 8906 int length = cpiAuths.length; 8907 for (int i = 0; i < length; i++) { 8908 if (cpiAuths[i].equals(uriAuth)) return true; 8909 } 8910 return false; 8911 } 8912 8913 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8914 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8915 if (r != null) { 8916 for (int i=0; i<r.conProviders.size(); i++) { 8917 ContentProviderConnection conn = r.conProviders.get(i); 8918 if (conn.provider == cpr) { 8919 if (DEBUG_PROVIDER) Slog.v(TAG, 8920 "Adding provider requested by " 8921 + r.processName + " from process " 8922 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8923 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8924 if (stable) { 8925 conn.stableCount++; 8926 conn.numStableIncs++; 8927 } else { 8928 conn.unstableCount++; 8929 conn.numUnstableIncs++; 8930 } 8931 return conn; 8932 } 8933 } 8934 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8935 if (stable) { 8936 conn.stableCount = 1; 8937 conn.numStableIncs = 1; 8938 } else { 8939 conn.unstableCount = 1; 8940 conn.numUnstableIncs = 1; 8941 } 8942 cpr.connections.add(conn); 8943 r.conProviders.add(conn); 8944 return conn; 8945 } 8946 cpr.addExternalProcessHandleLocked(externalProcessToken); 8947 return null; 8948 } 8949 8950 boolean decProviderCountLocked(ContentProviderConnection conn, 8951 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8952 if (conn != null) { 8953 cpr = conn.provider; 8954 if (DEBUG_PROVIDER) Slog.v(TAG, 8955 "Removing provider requested by " 8956 + conn.client.processName + " from process " 8957 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8958 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8959 if (stable) { 8960 conn.stableCount--; 8961 } else { 8962 conn.unstableCount--; 8963 } 8964 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8965 cpr.connections.remove(conn); 8966 conn.client.conProviders.remove(conn); 8967 return true; 8968 } 8969 return false; 8970 } 8971 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8972 return false; 8973 } 8974 8975 private void checkTime(long startTime, String where) { 8976 long now = SystemClock.elapsedRealtime(); 8977 if ((now-startTime) > 1000) { 8978 // If we are taking more than a second, log about it. 8979 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 8980 } 8981 } 8982 8983 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8984 String name, IBinder token, boolean stable, int userId) { 8985 ContentProviderRecord cpr; 8986 ContentProviderConnection conn = null; 8987 ProviderInfo cpi = null; 8988 8989 synchronized(this) { 8990 long startTime = SystemClock.elapsedRealtime(); 8991 8992 ProcessRecord r = null; 8993 if (caller != null) { 8994 r = getRecordForAppLocked(caller); 8995 if (r == null) { 8996 throw new SecurityException( 8997 "Unable to find app for caller " + caller 8998 + " (pid=" + Binder.getCallingPid() 8999 + ") when getting content provider " + name); 9000 } 9001 } 9002 9003 boolean checkCrossUser = true; 9004 9005 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9006 9007 // First check if this content provider has been published... 9008 cpr = mProviderMap.getProviderByName(name, userId); 9009 // If that didn't work, check if it exists for user 0 and then 9010 // verify that it's a singleton provider before using it. 9011 if (cpr == null && userId != UserHandle.USER_OWNER) { 9012 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9013 if (cpr != null) { 9014 cpi = cpr.info; 9015 if (isSingleton(cpi.processName, cpi.applicationInfo, 9016 cpi.name, cpi.flags) 9017 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9018 userId = UserHandle.USER_OWNER; 9019 checkCrossUser = false; 9020 } else { 9021 cpr = null; 9022 cpi = null; 9023 } 9024 } 9025 } 9026 9027 boolean providerRunning = cpr != null; 9028 if (providerRunning) { 9029 cpi = cpr.info; 9030 String msg; 9031 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9032 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9033 != null) { 9034 throw new SecurityException(msg); 9035 } 9036 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9037 9038 if (r != null && cpr.canRunHere(r)) { 9039 // This provider has been published or is in the process 9040 // of being published... but it is also allowed to run 9041 // in the caller's process, so don't make a connection 9042 // and just let the caller instantiate its own instance. 9043 ContentProviderHolder holder = cpr.newHolder(null); 9044 // don't give caller the provider object, it needs 9045 // to make its own. 9046 holder.provider = null; 9047 return holder; 9048 } 9049 9050 final long origId = Binder.clearCallingIdentity(); 9051 9052 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9053 9054 // In this case the provider instance already exists, so we can 9055 // return it right away. 9056 conn = incProviderCountLocked(r, cpr, token, stable); 9057 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9058 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9059 // If this is a perceptible app accessing the provider, 9060 // make sure to count it as being accessed and thus 9061 // back up on the LRU list. This is good because 9062 // content providers are often expensive to start. 9063 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9064 updateLruProcessLocked(cpr.proc, false, null); 9065 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9066 } 9067 } 9068 9069 if (cpr.proc != null) { 9070 if (false) { 9071 if (cpr.name.flattenToShortString().equals( 9072 "com.android.providers.calendar/.CalendarProvider2")) { 9073 Slog.v(TAG, "****************** KILLING " 9074 + cpr.name.flattenToShortString()); 9075 Process.killProcess(cpr.proc.pid); 9076 } 9077 } 9078 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9079 boolean success = updateOomAdjLocked(cpr.proc); 9080 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9081 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9082 // NOTE: there is still a race here where a signal could be 9083 // pending on the process even though we managed to update its 9084 // adj level. Not sure what to do about this, but at least 9085 // the race is now smaller. 9086 if (!success) { 9087 // Uh oh... it looks like the provider's process 9088 // has been killed on us. We need to wait for a new 9089 // process to be started, and make sure its death 9090 // doesn't kill our process. 9091 Slog.i(TAG, 9092 "Existing provider " + cpr.name.flattenToShortString() 9093 + " is crashing; detaching " + r); 9094 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9095 checkTime(startTime, "getContentProviderImpl: before appDied"); 9096 appDiedLocked(cpr.proc); 9097 checkTime(startTime, "getContentProviderImpl: after appDied"); 9098 if (!lastRef) { 9099 // This wasn't the last ref our process had on 9100 // the provider... we have now been killed, bail. 9101 return null; 9102 } 9103 providerRunning = false; 9104 conn = null; 9105 } 9106 } 9107 9108 Binder.restoreCallingIdentity(origId); 9109 } 9110 9111 boolean singleton; 9112 if (!providerRunning) { 9113 try { 9114 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9115 cpi = AppGlobals.getPackageManager(). 9116 resolveContentProvider(name, 9117 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9118 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9119 } catch (RemoteException ex) { 9120 } 9121 if (cpi == null) { 9122 return null; 9123 } 9124 // If the provider is a singleton AND 9125 // (it's a call within the same user || the provider is a 9126 // privileged app) 9127 // Then allow connecting to the singleton provider 9128 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9129 cpi.name, cpi.flags) 9130 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9131 if (singleton) { 9132 userId = UserHandle.USER_OWNER; 9133 } 9134 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9135 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9136 9137 String msg; 9138 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9139 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9140 != null) { 9141 throw new SecurityException(msg); 9142 } 9143 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9144 9145 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9146 && !cpi.processName.equals("system")) { 9147 // If this content provider does not run in the system 9148 // process, and the system is not yet ready to run other 9149 // processes, then fail fast instead of hanging. 9150 throw new IllegalArgumentException( 9151 "Attempt to launch content provider before system ready"); 9152 } 9153 9154 // Make sure that the user who owns this provider is started. If not, 9155 // we don't want to allow it to run. 9156 if (mStartedUsers.get(userId) == null) { 9157 Slog.w(TAG, "Unable to launch app " 9158 + cpi.applicationInfo.packageName + "/" 9159 + cpi.applicationInfo.uid + " for provider " 9160 + name + ": user " + userId + " is stopped"); 9161 return null; 9162 } 9163 9164 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9165 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9166 cpr = mProviderMap.getProviderByClass(comp, userId); 9167 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9168 final boolean firstClass = cpr == null; 9169 if (firstClass) { 9170 try { 9171 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9172 ApplicationInfo ai = 9173 AppGlobals.getPackageManager(). 9174 getApplicationInfo( 9175 cpi.applicationInfo.packageName, 9176 STOCK_PM_FLAGS, userId); 9177 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9178 if (ai == null) { 9179 Slog.w(TAG, "No package info for content provider " 9180 + cpi.name); 9181 return null; 9182 } 9183 ai = getAppInfoForUser(ai, userId); 9184 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9185 } catch (RemoteException ex) { 9186 // pm is in same process, this will never happen. 9187 } 9188 } 9189 9190 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9191 9192 if (r != null && cpr.canRunHere(r)) { 9193 // If this is a multiprocess provider, then just return its 9194 // info and allow the caller to instantiate it. Only do 9195 // this if the provider is the same user as the caller's 9196 // process, or can run as root (so can be in any process). 9197 return cpr.newHolder(null); 9198 } 9199 9200 if (DEBUG_PROVIDER) { 9201 RuntimeException e = new RuntimeException("here"); 9202 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9203 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9204 } 9205 9206 // This is single process, and our app is now connecting to it. 9207 // See if we are already in the process of launching this 9208 // provider. 9209 final int N = mLaunchingProviders.size(); 9210 int i; 9211 for (i=0; i<N; i++) { 9212 if (mLaunchingProviders.get(i) == cpr) { 9213 break; 9214 } 9215 } 9216 9217 // If the provider is not already being launched, then get it 9218 // started. 9219 if (i >= N) { 9220 final long origId = Binder.clearCallingIdentity(); 9221 9222 try { 9223 // Content provider is now in use, its package can't be stopped. 9224 try { 9225 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9226 AppGlobals.getPackageManager().setPackageStoppedState( 9227 cpr.appInfo.packageName, false, userId); 9228 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9229 } catch (RemoteException e) { 9230 } catch (IllegalArgumentException e) { 9231 Slog.w(TAG, "Failed trying to unstop package " 9232 + cpr.appInfo.packageName + ": " + e); 9233 } 9234 9235 // Use existing process if already started 9236 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9237 ProcessRecord proc = getProcessRecordLocked( 9238 cpi.processName, cpr.appInfo.uid, false); 9239 if (proc != null && proc.thread != null) { 9240 if (DEBUG_PROVIDER) { 9241 Slog.d(TAG, "Installing in existing process " + proc); 9242 } 9243 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9244 proc.pubProviders.put(cpi.name, cpr); 9245 try { 9246 proc.thread.scheduleInstallProvider(cpi); 9247 } catch (RemoteException e) { 9248 } 9249 } else { 9250 checkTime(startTime, "getContentProviderImpl: before start process"); 9251 proc = startProcessLocked(cpi.processName, 9252 cpr.appInfo, false, 0, "content provider", 9253 new ComponentName(cpi.applicationInfo.packageName, 9254 cpi.name), false, false, false); 9255 checkTime(startTime, "getContentProviderImpl: after start process"); 9256 if (proc == null) { 9257 Slog.w(TAG, "Unable to launch app " 9258 + cpi.applicationInfo.packageName + "/" 9259 + cpi.applicationInfo.uid + " for provider " 9260 + name + ": process is bad"); 9261 return null; 9262 } 9263 } 9264 cpr.launchingApp = proc; 9265 mLaunchingProviders.add(cpr); 9266 } finally { 9267 Binder.restoreCallingIdentity(origId); 9268 } 9269 } 9270 9271 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9272 9273 // Make sure the provider is published (the same provider class 9274 // may be published under multiple names). 9275 if (firstClass) { 9276 mProviderMap.putProviderByClass(comp, cpr); 9277 } 9278 9279 mProviderMap.putProviderByName(name, cpr); 9280 conn = incProviderCountLocked(r, cpr, token, stable); 9281 if (conn != null) { 9282 conn.waiting = true; 9283 } 9284 } 9285 checkTime(startTime, "getContentProviderImpl: done!"); 9286 } 9287 9288 // Wait for the provider to be published... 9289 synchronized (cpr) { 9290 while (cpr.provider == null) { 9291 if (cpr.launchingApp == null) { 9292 Slog.w(TAG, "Unable to launch app " 9293 + cpi.applicationInfo.packageName + "/" 9294 + cpi.applicationInfo.uid + " for provider " 9295 + name + ": launching app became null"); 9296 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9297 UserHandle.getUserId(cpi.applicationInfo.uid), 9298 cpi.applicationInfo.packageName, 9299 cpi.applicationInfo.uid, name); 9300 return null; 9301 } 9302 try { 9303 if (DEBUG_MU) { 9304 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9305 + cpr.launchingApp); 9306 } 9307 if (conn != null) { 9308 conn.waiting = true; 9309 } 9310 cpr.wait(); 9311 } catch (InterruptedException ex) { 9312 } finally { 9313 if (conn != null) { 9314 conn.waiting = false; 9315 } 9316 } 9317 } 9318 } 9319 return cpr != null ? cpr.newHolder(conn) : null; 9320 } 9321 9322 @Override 9323 public final ContentProviderHolder getContentProvider( 9324 IApplicationThread caller, String name, int userId, boolean stable) { 9325 enforceNotIsolatedCaller("getContentProvider"); 9326 if (caller == null) { 9327 String msg = "null IApplicationThread when getting content provider " 9328 + name; 9329 Slog.w(TAG, msg); 9330 throw new SecurityException(msg); 9331 } 9332 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9333 // with cross-user grant. 9334 return getContentProviderImpl(caller, name, null, stable, userId); 9335 } 9336 9337 public ContentProviderHolder getContentProviderExternal( 9338 String name, int userId, IBinder token) { 9339 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9340 "Do not have permission in call getContentProviderExternal()"); 9341 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9342 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9343 return getContentProviderExternalUnchecked(name, token, userId); 9344 } 9345 9346 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9347 IBinder token, int userId) { 9348 return getContentProviderImpl(null, name, token, true, userId); 9349 } 9350 9351 /** 9352 * Drop a content provider from a ProcessRecord's bookkeeping 9353 */ 9354 public void removeContentProvider(IBinder connection, boolean stable) { 9355 enforceNotIsolatedCaller("removeContentProvider"); 9356 long ident = Binder.clearCallingIdentity(); 9357 try { 9358 synchronized (this) { 9359 ContentProviderConnection conn; 9360 try { 9361 conn = (ContentProviderConnection)connection; 9362 } catch (ClassCastException e) { 9363 String msg ="removeContentProvider: " + connection 9364 + " not a ContentProviderConnection"; 9365 Slog.w(TAG, msg); 9366 throw new IllegalArgumentException(msg); 9367 } 9368 if (conn == null) { 9369 throw new NullPointerException("connection is null"); 9370 } 9371 if (decProviderCountLocked(conn, null, null, stable)) { 9372 updateOomAdjLocked(); 9373 } 9374 } 9375 } finally { 9376 Binder.restoreCallingIdentity(ident); 9377 } 9378 } 9379 9380 public void removeContentProviderExternal(String name, IBinder token) { 9381 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9382 "Do not have permission in call removeContentProviderExternal()"); 9383 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9384 } 9385 9386 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9387 synchronized (this) { 9388 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9389 if(cpr == null) { 9390 //remove from mProvidersByClass 9391 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9392 return; 9393 } 9394 9395 //update content provider record entry info 9396 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9397 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9398 if (localCpr.hasExternalProcessHandles()) { 9399 if (localCpr.removeExternalProcessHandleLocked(token)) { 9400 updateOomAdjLocked(); 9401 } else { 9402 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9403 + " with no external reference for token: " 9404 + token + "."); 9405 } 9406 } else { 9407 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9408 + " with no external references."); 9409 } 9410 } 9411 } 9412 9413 public final void publishContentProviders(IApplicationThread caller, 9414 List<ContentProviderHolder> providers) { 9415 if (providers == null) { 9416 return; 9417 } 9418 9419 enforceNotIsolatedCaller("publishContentProviders"); 9420 synchronized (this) { 9421 final ProcessRecord r = getRecordForAppLocked(caller); 9422 if (DEBUG_MU) 9423 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9424 if (r == null) { 9425 throw new SecurityException( 9426 "Unable to find app for caller " + caller 9427 + " (pid=" + Binder.getCallingPid() 9428 + ") when publishing content providers"); 9429 } 9430 9431 final long origId = Binder.clearCallingIdentity(); 9432 9433 final int N = providers.size(); 9434 for (int i=0; i<N; i++) { 9435 ContentProviderHolder src = providers.get(i); 9436 if (src == null || src.info == null || src.provider == null) { 9437 continue; 9438 } 9439 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9440 if (DEBUG_MU) 9441 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9442 if (dst != null) { 9443 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9444 mProviderMap.putProviderByClass(comp, dst); 9445 String names[] = dst.info.authority.split(";"); 9446 for (int j = 0; j < names.length; j++) { 9447 mProviderMap.putProviderByName(names[j], dst); 9448 } 9449 9450 int NL = mLaunchingProviders.size(); 9451 int j; 9452 for (j=0; j<NL; j++) { 9453 if (mLaunchingProviders.get(j) == dst) { 9454 mLaunchingProviders.remove(j); 9455 j--; 9456 NL--; 9457 } 9458 } 9459 synchronized (dst) { 9460 dst.provider = src.provider; 9461 dst.proc = r; 9462 dst.notifyAll(); 9463 } 9464 updateOomAdjLocked(r); 9465 } 9466 } 9467 9468 Binder.restoreCallingIdentity(origId); 9469 } 9470 } 9471 9472 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9473 ContentProviderConnection conn; 9474 try { 9475 conn = (ContentProviderConnection)connection; 9476 } catch (ClassCastException e) { 9477 String msg ="refContentProvider: " + connection 9478 + " not a ContentProviderConnection"; 9479 Slog.w(TAG, msg); 9480 throw new IllegalArgumentException(msg); 9481 } 9482 if (conn == null) { 9483 throw new NullPointerException("connection is null"); 9484 } 9485 9486 synchronized (this) { 9487 if (stable > 0) { 9488 conn.numStableIncs += stable; 9489 } 9490 stable = conn.stableCount + stable; 9491 if (stable < 0) { 9492 throw new IllegalStateException("stableCount < 0: " + stable); 9493 } 9494 9495 if (unstable > 0) { 9496 conn.numUnstableIncs += unstable; 9497 } 9498 unstable = conn.unstableCount + unstable; 9499 if (unstable < 0) { 9500 throw new IllegalStateException("unstableCount < 0: " + unstable); 9501 } 9502 9503 if ((stable+unstable) <= 0) { 9504 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9505 + stable + " unstable=" + unstable); 9506 } 9507 conn.stableCount = stable; 9508 conn.unstableCount = unstable; 9509 return !conn.dead; 9510 } 9511 } 9512 9513 public void unstableProviderDied(IBinder connection) { 9514 ContentProviderConnection conn; 9515 try { 9516 conn = (ContentProviderConnection)connection; 9517 } catch (ClassCastException e) { 9518 String msg ="refContentProvider: " + connection 9519 + " not a ContentProviderConnection"; 9520 Slog.w(TAG, msg); 9521 throw new IllegalArgumentException(msg); 9522 } 9523 if (conn == null) { 9524 throw new NullPointerException("connection is null"); 9525 } 9526 9527 // Safely retrieve the content provider associated with the connection. 9528 IContentProvider provider; 9529 synchronized (this) { 9530 provider = conn.provider.provider; 9531 } 9532 9533 if (provider == null) { 9534 // Um, yeah, we're way ahead of you. 9535 return; 9536 } 9537 9538 // Make sure the caller is being honest with us. 9539 if (provider.asBinder().pingBinder()) { 9540 // Er, no, still looks good to us. 9541 synchronized (this) { 9542 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9543 + " says " + conn + " died, but we don't agree"); 9544 return; 9545 } 9546 } 9547 9548 // Well look at that! It's dead! 9549 synchronized (this) { 9550 if (conn.provider.provider != provider) { 9551 // But something changed... good enough. 9552 return; 9553 } 9554 9555 ProcessRecord proc = conn.provider.proc; 9556 if (proc == null || proc.thread == null) { 9557 // Seems like the process is already cleaned up. 9558 return; 9559 } 9560 9561 // As far as we're concerned, this is just like receiving a 9562 // death notification... just a bit prematurely. 9563 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9564 + ") early provider death"); 9565 final long ident = Binder.clearCallingIdentity(); 9566 try { 9567 appDiedLocked(proc); 9568 } finally { 9569 Binder.restoreCallingIdentity(ident); 9570 } 9571 } 9572 } 9573 9574 @Override 9575 public void appNotRespondingViaProvider(IBinder connection) { 9576 enforceCallingPermission( 9577 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9578 9579 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9580 if (conn == null) { 9581 Slog.w(TAG, "ContentProviderConnection is null"); 9582 return; 9583 } 9584 9585 final ProcessRecord host = conn.provider.proc; 9586 if (host == null) { 9587 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9588 return; 9589 } 9590 9591 final long token = Binder.clearCallingIdentity(); 9592 try { 9593 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9594 } finally { 9595 Binder.restoreCallingIdentity(token); 9596 } 9597 } 9598 9599 public final void installSystemProviders() { 9600 List<ProviderInfo> providers; 9601 synchronized (this) { 9602 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9603 providers = generateApplicationProvidersLocked(app); 9604 if (providers != null) { 9605 for (int i=providers.size()-1; i>=0; i--) { 9606 ProviderInfo pi = (ProviderInfo)providers.get(i); 9607 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9608 Slog.w(TAG, "Not installing system proc provider " + pi.name 9609 + ": not system .apk"); 9610 providers.remove(i); 9611 } 9612 } 9613 } 9614 } 9615 if (providers != null) { 9616 mSystemThread.installSystemProviders(providers); 9617 } 9618 9619 mCoreSettingsObserver = new CoreSettingsObserver(this); 9620 9621 //mUsageStatsService.monitorPackages(); 9622 } 9623 9624 /** 9625 * Allows apps to retrieve the MIME type of a URI. 9626 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9627 * users, then it does not need permission to access the ContentProvider. 9628 * Either, it needs cross-user uri grants. 9629 * 9630 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9631 * 9632 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9633 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9634 */ 9635 public String getProviderMimeType(Uri uri, int userId) { 9636 enforceNotIsolatedCaller("getProviderMimeType"); 9637 final String name = uri.getAuthority(); 9638 int callingUid = Binder.getCallingUid(); 9639 int callingPid = Binder.getCallingPid(); 9640 long ident = 0; 9641 boolean clearedIdentity = false; 9642 userId = unsafeConvertIncomingUser(userId); 9643 if (UserHandle.getUserId(callingUid) != userId) { 9644 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9645 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9646 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9647 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9648 clearedIdentity = true; 9649 ident = Binder.clearCallingIdentity(); 9650 } 9651 } 9652 ContentProviderHolder holder = null; 9653 try { 9654 holder = getContentProviderExternalUnchecked(name, null, userId); 9655 if (holder != null) { 9656 return holder.provider.getType(uri); 9657 } 9658 } catch (RemoteException e) { 9659 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9660 return null; 9661 } finally { 9662 // We need to clear the identity to call removeContentProviderExternalUnchecked 9663 if (!clearedIdentity) { 9664 ident = Binder.clearCallingIdentity(); 9665 } 9666 try { 9667 if (holder != null) { 9668 removeContentProviderExternalUnchecked(name, null, userId); 9669 } 9670 } finally { 9671 Binder.restoreCallingIdentity(ident); 9672 } 9673 } 9674 9675 return null; 9676 } 9677 9678 // ========================================================= 9679 // GLOBAL MANAGEMENT 9680 // ========================================================= 9681 9682 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9683 boolean isolated, int isolatedUid) { 9684 String proc = customProcess != null ? customProcess : info.processName; 9685 BatteryStatsImpl.Uid.Proc ps = null; 9686 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9687 int uid = info.uid; 9688 if (isolated) { 9689 if (isolatedUid == 0) { 9690 int userId = UserHandle.getUserId(uid); 9691 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9692 while (true) { 9693 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9694 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9695 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9696 } 9697 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9698 mNextIsolatedProcessUid++; 9699 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9700 // No process for this uid, use it. 9701 break; 9702 } 9703 stepsLeft--; 9704 if (stepsLeft <= 0) { 9705 return null; 9706 } 9707 } 9708 } else { 9709 // Special case for startIsolatedProcess (internal only), where 9710 // the uid of the isolated process is specified by the caller. 9711 uid = isolatedUid; 9712 } 9713 } 9714 return new ProcessRecord(stats, info, proc, uid); 9715 } 9716 9717 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9718 String abiOverride) { 9719 ProcessRecord app; 9720 if (!isolated) { 9721 app = getProcessRecordLocked(info.processName, info.uid, true); 9722 } else { 9723 app = null; 9724 } 9725 9726 if (app == null) { 9727 app = newProcessRecordLocked(info, null, isolated, 0); 9728 mProcessNames.put(info.processName, app.uid, app); 9729 if (isolated) { 9730 mIsolatedProcesses.put(app.uid, app); 9731 } 9732 updateLruProcessLocked(app, false, null); 9733 updateOomAdjLocked(); 9734 } 9735 9736 // This package really, really can not be stopped. 9737 try { 9738 AppGlobals.getPackageManager().setPackageStoppedState( 9739 info.packageName, false, UserHandle.getUserId(app.uid)); 9740 } catch (RemoteException e) { 9741 } catch (IllegalArgumentException e) { 9742 Slog.w(TAG, "Failed trying to unstop package " 9743 + info.packageName + ": " + e); 9744 } 9745 9746 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9747 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9748 app.persistent = true; 9749 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9750 } 9751 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9752 mPersistentStartingProcesses.add(app); 9753 startProcessLocked(app, "added application", app.processName, abiOverride, 9754 null /* entryPoint */, null /* entryPointArgs */); 9755 } 9756 9757 return app; 9758 } 9759 9760 public void unhandledBack() { 9761 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9762 "unhandledBack()"); 9763 9764 synchronized(this) { 9765 final long origId = Binder.clearCallingIdentity(); 9766 try { 9767 getFocusedStack().unhandledBackLocked(); 9768 } finally { 9769 Binder.restoreCallingIdentity(origId); 9770 } 9771 } 9772 } 9773 9774 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9775 enforceNotIsolatedCaller("openContentUri"); 9776 final int userId = UserHandle.getCallingUserId(); 9777 String name = uri.getAuthority(); 9778 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9779 ParcelFileDescriptor pfd = null; 9780 if (cph != null) { 9781 // We record the binder invoker's uid in thread-local storage before 9782 // going to the content provider to open the file. Later, in the code 9783 // that handles all permissions checks, we look for this uid and use 9784 // that rather than the Activity Manager's own uid. The effect is that 9785 // we do the check against the caller's permissions even though it looks 9786 // to the content provider like the Activity Manager itself is making 9787 // the request. 9788 sCallerIdentity.set(new Identity( 9789 Binder.getCallingPid(), Binder.getCallingUid())); 9790 try { 9791 pfd = cph.provider.openFile(null, uri, "r", null); 9792 } catch (FileNotFoundException e) { 9793 // do nothing; pfd will be returned null 9794 } finally { 9795 // Ensure that whatever happens, we clean up the identity state 9796 sCallerIdentity.remove(); 9797 } 9798 9799 // We've got the fd now, so we're done with the provider. 9800 removeContentProviderExternalUnchecked(name, null, userId); 9801 } else { 9802 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9803 } 9804 return pfd; 9805 } 9806 9807 // Actually is sleeping or shutting down or whatever else in the future 9808 // is an inactive state. 9809 public boolean isSleepingOrShuttingDown() { 9810 return mSleeping || mShuttingDown; 9811 } 9812 9813 public boolean isSleeping() { 9814 return mSleeping; 9815 } 9816 9817 void goingToSleep() { 9818 synchronized(this) { 9819 mWentToSleep = true; 9820 updateEventDispatchingLocked(); 9821 goToSleepIfNeededLocked(); 9822 } 9823 } 9824 9825 void finishRunningVoiceLocked() { 9826 if (mRunningVoice) { 9827 mRunningVoice = false; 9828 goToSleepIfNeededLocked(); 9829 } 9830 } 9831 9832 void goToSleepIfNeededLocked() { 9833 if (mWentToSleep && !mRunningVoice) { 9834 if (!mSleeping) { 9835 mSleeping = true; 9836 mStackSupervisor.goingToSleepLocked(); 9837 9838 // Initialize the wake times of all processes. 9839 checkExcessivePowerUsageLocked(false); 9840 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9841 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9842 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9843 } 9844 } 9845 } 9846 9847 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9848 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9849 // Never persist the home stack. 9850 return; 9851 } 9852 mTaskPersister.wakeup(task, flush); 9853 } 9854 9855 @Override 9856 public boolean shutdown(int timeout) { 9857 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9858 != PackageManager.PERMISSION_GRANTED) { 9859 throw new SecurityException("Requires permission " 9860 + android.Manifest.permission.SHUTDOWN); 9861 } 9862 9863 boolean timedout = false; 9864 9865 synchronized(this) { 9866 mShuttingDown = true; 9867 updateEventDispatchingLocked(); 9868 timedout = mStackSupervisor.shutdownLocked(timeout); 9869 } 9870 9871 mAppOpsService.shutdown(); 9872 if (mUsageStatsService != null) { 9873 mUsageStatsService.prepareShutdown(); 9874 } 9875 mBatteryStatsService.shutdown(); 9876 synchronized (this) { 9877 mProcessStats.shutdownLocked(); 9878 } 9879 notifyTaskPersisterLocked(null, true); 9880 9881 return timedout; 9882 } 9883 9884 public final void activitySlept(IBinder token) { 9885 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9886 9887 final long origId = Binder.clearCallingIdentity(); 9888 9889 synchronized (this) { 9890 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9891 if (r != null) { 9892 mStackSupervisor.activitySleptLocked(r); 9893 } 9894 } 9895 9896 Binder.restoreCallingIdentity(origId); 9897 } 9898 9899 void logLockScreen(String msg) { 9900 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9901 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9902 mWentToSleep + " mSleeping=" + mSleeping); 9903 } 9904 9905 private void comeOutOfSleepIfNeededLocked() { 9906 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9907 if (mSleeping) { 9908 mSleeping = false; 9909 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9910 } 9911 } 9912 } 9913 9914 void wakingUp() { 9915 synchronized(this) { 9916 mWentToSleep = false; 9917 updateEventDispatchingLocked(); 9918 comeOutOfSleepIfNeededLocked(); 9919 } 9920 } 9921 9922 void startRunningVoiceLocked() { 9923 if (!mRunningVoice) { 9924 mRunningVoice = true; 9925 comeOutOfSleepIfNeededLocked(); 9926 } 9927 } 9928 9929 private void updateEventDispatchingLocked() { 9930 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9931 } 9932 9933 public void setLockScreenShown(boolean shown) { 9934 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9935 != PackageManager.PERMISSION_GRANTED) { 9936 throw new SecurityException("Requires permission " 9937 + android.Manifest.permission.DEVICE_POWER); 9938 } 9939 9940 synchronized(this) { 9941 long ident = Binder.clearCallingIdentity(); 9942 try { 9943 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9944 mLockScreenShown = shown; 9945 comeOutOfSleepIfNeededLocked(); 9946 } finally { 9947 Binder.restoreCallingIdentity(ident); 9948 } 9949 } 9950 } 9951 9952 @Override 9953 public void stopAppSwitches() { 9954 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9955 != PackageManager.PERMISSION_GRANTED) { 9956 throw new SecurityException("Requires permission " 9957 + android.Manifest.permission.STOP_APP_SWITCHES); 9958 } 9959 9960 synchronized(this) { 9961 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9962 + APP_SWITCH_DELAY_TIME; 9963 mDidAppSwitch = false; 9964 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9965 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9966 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9967 } 9968 } 9969 9970 public void resumeAppSwitches() { 9971 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9972 != PackageManager.PERMISSION_GRANTED) { 9973 throw new SecurityException("Requires permission " 9974 + android.Manifest.permission.STOP_APP_SWITCHES); 9975 } 9976 9977 synchronized(this) { 9978 // Note that we don't execute any pending app switches... we will 9979 // let those wait until either the timeout, or the next start 9980 // activity request. 9981 mAppSwitchesAllowedTime = 0; 9982 } 9983 } 9984 9985 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9986 String name) { 9987 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9988 return true; 9989 } 9990 9991 final int perm = checkComponentPermission( 9992 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9993 callingUid, -1, true); 9994 if (perm == PackageManager.PERMISSION_GRANTED) { 9995 return true; 9996 } 9997 9998 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9999 return false; 10000 } 10001 10002 public void setDebugApp(String packageName, boolean waitForDebugger, 10003 boolean persistent) { 10004 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10005 "setDebugApp()"); 10006 10007 long ident = Binder.clearCallingIdentity(); 10008 try { 10009 // Note that this is not really thread safe if there are multiple 10010 // callers into it at the same time, but that's not a situation we 10011 // care about. 10012 if (persistent) { 10013 final ContentResolver resolver = mContext.getContentResolver(); 10014 Settings.Global.putString( 10015 resolver, Settings.Global.DEBUG_APP, 10016 packageName); 10017 Settings.Global.putInt( 10018 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10019 waitForDebugger ? 1 : 0); 10020 } 10021 10022 synchronized (this) { 10023 if (!persistent) { 10024 mOrigDebugApp = mDebugApp; 10025 mOrigWaitForDebugger = mWaitForDebugger; 10026 } 10027 mDebugApp = packageName; 10028 mWaitForDebugger = waitForDebugger; 10029 mDebugTransient = !persistent; 10030 if (packageName != null) { 10031 forceStopPackageLocked(packageName, -1, false, false, true, true, 10032 false, UserHandle.USER_ALL, "set debug app"); 10033 } 10034 } 10035 } finally { 10036 Binder.restoreCallingIdentity(ident); 10037 } 10038 } 10039 10040 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10041 synchronized (this) { 10042 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10043 if (!isDebuggable) { 10044 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10045 throw new SecurityException("Process not debuggable: " + app.packageName); 10046 } 10047 } 10048 10049 mOpenGlTraceApp = processName; 10050 } 10051 } 10052 10053 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10054 synchronized (this) { 10055 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10056 if (!isDebuggable) { 10057 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10058 throw new SecurityException("Process not debuggable: " + app.packageName); 10059 } 10060 } 10061 mProfileApp = processName; 10062 mProfileFile = profilerInfo.profileFile; 10063 if (mProfileFd != null) { 10064 try { 10065 mProfileFd.close(); 10066 } catch (IOException e) { 10067 } 10068 mProfileFd = null; 10069 } 10070 mProfileFd = profilerInfo.profileFd; 10071 mSamplingInterval = profilerInfo.samplingInterval; 10072 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10073 mProfileType = 0; 10074 } 10075 } 10076 10077 @Override 10078 public void setAlwaysFinish(boolean enabled) { 10079 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10080 "setAlwaysFinish()"); 10081 10082 Settings.Global.putInt( 10083 mContext.getContentResolver(), 10084 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10085 10086 synchronized (this) { 10087 mAlwaysFinishActivities = enabled; 10088 } 10089 } 10090 10091 @Override 10092 public void setActivityController(IActivityController controller) { 10093 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10094 "setActivityController()"); 10095 synchronized (this) { 10096 mController = controller; 10097 Watchdog.getInstance().setActivityController(controller); 10098 } 10099 } 10100 10101 @Override 10102 public void setUserIsMonkey(boolean userIsMonkey) { 10103 synchronized (this) { 10104 synchronized (mPidsSelfLocked) { 10105 final int callingPid = Binder.getCallingPid(); 10106 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10107 if (precessRecord == null) { 10108 throw new SecurityException("Unknown process: " + callingPid); 10109 } 10110 if (precessRecord.instrumentationUiAutomationConnection == null) { 10111 throw new SecurityException("Only an instrumentation process " 10112 + "with a UiAutomation can call setUserIsMonkey"); 10113 } 10114 } 10115 mUserIsMonkey = userIsMonkey; 10116 } 10117 } 10118 10119 @Override 10120 public boolean isUserAMonkey() { 10121 synchronized (this) { 10122 // If there is a controller also implies the user is a monkey. 10123 return (mUserIsMonkey || mController != null); 10124 } 10125 } 10126 10127 public void requestBugReport() { 10128 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10129 SystemProperties.set("ctl.start", "bugreport"); 10130 } 10131 10132 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10133 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10134 } 10135 10136 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10137 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10138 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10139 } 10140 return KEY_DISPATCHING_TIMEOUT; 10141 } 10142 10143 @Override 10144 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10145 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10146 != PackageManager.PERMISSION_GRANTED) { 10147 throw new SecurityException("Requires permission " 10148 + android.Manifest.permission.FILTER_EVENTS); 10149 } 10150 ProcessRecord proc; 10151 long timeout; 10152 synchronized (this) { 10153 synchronized (mPidsSelfLocked) { 10154 proc = mPidsSelfLocked.get(pid); 10155 } 10156 timeout = getInputDispatchingTimeoutLocked(proc); 10157 } 10158 10159 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10160 return -1; 10161 } 10162 10163 return timeout; 10164 } 10165 10166 /** 10167 * Handle input dispatching timeouts. 10168 * Returns whether input dispatching should be aborted or not. 10169 */ 10170 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10171 final ActivityRecord activity, final ActivityRecord parent, 10172 final boolean aboveSystem, String reason) { 10173 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10174 != PackageManager.PERMISSION_GRANTED) { 10175 throw new SecurityException("Requires permission " 10176 + android.Manifest.permission.FILTER_EVENTS); 10177 } 10178 10179 final String annotation; 10180 if (reason == null) { 10181 annotation = "Input dispatching timed out"; 10182 } else { 10183 annotation = "Input dispatching timed out (" + reason + ")"; 10184 } 10185 10186 if (proc != null) { 10187 synchronized (this) { 10188 if (proc.debugging) { 10189 return false; 10190 } 10191 10192 if (mDidDexOpt) { 10193 // Give more time since we were dexopting. 10194 mDidDexOpt = false; 10195 return false; 10196 } 10197 10198 if (proc.instrumentationClass != null) { 10199 Bundle info = new Bundle(); 10200 info.putString("shortMsg", "keyDispatchingTimedOut"); 10201 info.putString("longMsg", annotation); 10202 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10203 return true; 10204 } 10205 } 10206 mHandler.post(new Runnable() { 10207 @Override 10208 public void run() { 10209 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10210 } 10211 }); 10212 } 10213 10214 return true; 10215 } 10216 10217 public Bundle getAssistContextExtras(int requestType) { 10218 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10219 "getAssistContextExtras()"); 10220 PendingAssistExtras pae; 10221 Bundle extras = new Bundle(); 10222 synchronized (this) { 10223 ActivityRecord activity = getFocusedStack().mResumedActivity; 10224 if (activity == null) { 10225 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10226 return null; 10227 } 10228 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10229 if (activity.app == null || activity.app.thread == null) { 10230 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10231 return extras; 10232 } 10233 if (activity.app.pid == Binder.getCallingPid()) { 10234 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10235 return extras; 10236 } 10237 pae = new PendingAssistExtras(activity); 10238 try { 10239 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10240 requestType); 10241 mPendingAssistExtras.add(pae); 10242 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10243 } catch (RemoteException e) { 10244 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10245 return extras; 10246 } 10247 } 10248 synchronized (pae) { 10249 while (!pae.haveResult) { 10250 try { 10251 pae.wait(); 10252 } catch (InterruptedException e) { 10253 } 10254 } 10255 if (pae.result != null) { 10256 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10257 } 10258 } 10259 synchronized (this) { 10260 mPendingAssistExtras.remove(pae); 10261 mHandler.removeCallbacks(pae); 10262 } 10263 return extras; 10264 } 10265 10266 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10267 PendingAssistExtras pae = (PendingAssistExtras)token; 10268 synchronized (pae) { 10269 pae.result = extras; 10270 pae.haveResult = true; 10271 pae.notifyAll(); 10272 } 10273 } 10274 10275 public void registerProcessObserver(IProcessObserver observer) { 10276 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10277 "registerProcessObserver()"); 10278 synchronized (this) { 10279 mProcessObservers.register(observer); 10280 } 10281 } 10282 10283 @Override 10284 public void unregisterProcessObserver(IProcessObserver observer) { 10285 synchronized (this) { 10286 mProcessObservers.unregister(observer); 10287 } 10288 } 10289 10290 @Override 10291 public boolean convertFromTranslucent(IBinder token) { 10292 final long origId = Binder.clearCallingIdentity(); 10293 try { 10294 synchronized (this) { 10295 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10296 if (r == null) { 10297 return false; 10298 } 10299 if (r.changeWindowTranslucency(true)) { 10300 mWindowManager.setAppFullscreen(token, true); 10301 r.task.stack.releaseBackgroundResources(); 10302 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10303 return true; 10304 } 10305 return false; 10306 } 10307 } finally { 10308 Binder.restoreCallingIdentity(origId); 10309 } 10310 } 10311 10312 @Override 10313 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10314 final long origId = Binder.clearCallingIdentity(); 10315 try { 10316 synchronized (this) { 10317 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10318 if (r == null) { 10319 return false; 10320 } 10321 int index = r.task.mActivities.lastIndexOf(r); 10322 if (index > 0) { 10323 ActivityRecord under = r.task.mActivities.get(index - 1); 10324 under.returningOptions = options; 10325 } 10326 if (r.changeWindowTranslucency(false)) { 10327 r.task.stack.convertToTranslucent(r); 10328 mWindowManager.setAppFullscreen(token, false); 10329 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10330 return true; 10331 } else { 10332 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10333 return false; 10334 } 10335 } 10336 } finally { 10337 Binder.restoreCallingIdentity(origId); 10338 } 10339 } 10340 10341 @Override 10342 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10343 final long origId = Binder.clearCallingIdentity(); 10344 try { 10345 synchronized (this) { 10346 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10347 if (r != null) { 10348 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10349 } 10350 } 10351 return false; 10352 } finally { 10353 Binder.restoreCallingIdentity(origId); 10354 } 10355 } 10356 10357 @Override 10358 public boolean isBackgroundVisibleBehind(IBinder token) { 10359 final long origId = Binder.clearCallingIdentity(); 10360 try { 10361 synchronized (this) { 10362 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10363 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10364 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10365 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10366 return visible; 10367 } 10368 } finally { 10369 Binder.restoreCallingIdentity(origId); 10370 } 10371 } 10372 10373 @Override 10374 public ActivityOptions getActivityOptions(IBinder token) { 10375 final long origId = Binder.clearCallingIdentity(); 10376 try { 10377 synchronized (this) { 10378 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10379 if (r != null) { 10380 final ActivityOptions activityOptions = r.pendingOptions; 10381 r.pendingOptions = null; 10382 return activityOptions; 10383 } 10384 return null; 10385 } 10386 } finally { 10387 Binder.restoreCallingIdentity(origId); 10388 } 10389 } 10390 10391 @Override 10392 public void setImmersive(IBinder token, boolean immersive) { 10393 synchronized(this) { 10394 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10395 if (r == null) { 10396 throw new IllegalArgumentException(); 10397 } 10398 r.immersive = immersive; 10399 10400 // update associated state if we're frontmost 10401 if (r == mFocusedActivity) { 10402 if (DEBUG_IMMERSIVE) { 10403 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10404 } 10405 applyUpdateLockStateLocked(r); 10406 } 10407 } 10408 } 10409 10410 @Override 10411 public boolean isImmersive(IBinder token) { 10412 synchronized (this) { 10413 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10414 if (r == null) { 10415 throw new IllegalArgumentException(); 10416 } 10417 return r.immersive; 10418 } 10419 } 10420 10421 public boolean isTopActivityImmersive() { 10422 enforceNotIsolatedCaller("startActivity"); 10423 synchronized (this) { 10424 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10425 return (r != null) ? r.immersive : false; 10426 } 10427 } 10428 10429 @Override 10430 public boolean isTopOfTask(IBinder token) { 10431 synchronized (this) { 10432 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10433 if (r == null) { 10434 throw new IllegalArgumentException(); 10435 } 10436 return r.task.getTopActivity() == r; 10437 } 10438 } 10439 10440 public final void enterSafeMode() { 10441 synchronized(this) { 10442 // It only makes sense to do this before the system is ready 10443 // and started launching other packages. 10444 if (!mSystemReady) { 10445 try { 10446 AppGlobals.getPackageManager().enterSafeMode(); 10447 } catch (RemoteException e) { 10448 } 10449 } 10450 10451 mSafeMode = true; 10452 } 10453 } 10454 10455 public final void showSafeModeOverlay() { 10456 View v = LayoutInflater.from(mContext).inflate( 10457 com.android.internal.R.layout.safe_mode, null); 10458 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10459 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10460 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10461 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10462 lp.gravity = Gravity.BOTTOM | Gravity.START; 10463 lp.format = v.getBackground().getOpacity(); 10464 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10465 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10466 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10467 ((WindowManager)mContext.getSystemService( 10468 Context.WINDOW_SERVICE)).addView(v, lp); 10469 } 10470 10471 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10472 if (!(sender instanceof PendingIntentRecord)) { 10473 return; 10474 } 10475 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10476 synchronized (stats) { 10477 if (mBatteryStatsService.isOnBattery()) { 10478 mBatteryStatsService.enforceCallingPermission(); 10479 PendingIntentRecord rec = (PendingIntentRecord)sender; 10480 int MY_UID = Binder.getCallingUid(); 10481 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10482 BatteryStatsImpl.Uid.Pkg pkg = 10483 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10484 sourcePkg != null ? sourcePkg : rec.key.packageName); 10485 pkg.incWakeupsLocked(); 10486 } 10487 } 10488 } 10489 10490 public boolean killPids(int[] pids, String pReason, boolean secure) { 10491 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10492 throw new SecurityException("killPids only available to the system"); 10493 } 10494 String reason = (pReason == null) ? "Unknown" : pReason; 10495 // XXX Note: don't acquire main activity lock here, because the window 10496 // manager calls in with its locks held. 10497 10498 boolean killed = false; 10499 synchronized (mPidsSelfLocked) { 10500 int[] types = new int[pids.length]; 10501 int worstType = 0; 10502 for (int i=0; i<pids.length; i++) { 10503 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10504 if (proc != null) { 10505 int type = proc.setAdj; 10506 types[i] = type; 10507 if (type > worstType) { 10508 worstType = type; 10509 } 10510 } 10511 } 10512 10513 // If the worst oom_adj is somewhere in the cached proc LRU range, 10514 // then constrain it so we will kill all cached procs. 10515 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10516 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10517 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10518 } 10519 10520 // If this is not a secure call, don't let it kill processes that 10521 // are important. 10522 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10523 worstType = ProcessList.SERVICE_ADJ; 10524 } 10525 10526 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10527 for (int i=0; i<pids.length; i++) { 10528 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10529 if (proc == null) { 10530 continue; 10531 } 10532 int adj = proc.setAdj; 10533 if (adj >= worstType && !proc.killedByAm) { 10534 proc.kill(reason, true); 10535 killed = true; 10536 } 10537 } 10538 } 10539 return killed; 10540 } 10541 10542 @Override 10543 public void killUid(int uid, String reason) { 10544 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10545 throw new SecurityException("killUid only available to the system"); 10546 } 10547 synchronized (this) { 10548 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10549 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10550 reason != null ? reason : "kill uid"); 10551 } 10552 } 10553 10554 @Override 10555 public boolean killProcessesBelowForeground(String reason) { 10556 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10557 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10558 } 10559 10560 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10561 } 10562 10563 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10564 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10565 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10566 } 10567 10568 boolean killed = false; 10569 synchronized (mPidsSelfLocked) { 10570 final int size = mPidsSelfLocked.size(); 10571 for (int i = 0; i < size; i++) { 10572 final int pid = mPidsSelfLocked.keyAt(i); 10573 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10574 if (proc == null) continue; 10575 10576 final int adj = proc.setAdj; 10577 if (adj > belowAdj && !proc.killedByAm) { 10578 proc.kill(reason, true); 10579 killed = true; 10580 } 10581 } 10582 } 10583 return killed; 10584 } 10585 10586 @Override 10587 public void hang(final IBinder who, boolean allowRestart) { 10588 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10589 != PackageManager.PERMISSION_GRANTED) { 10590 throw new SecurityException("Requires permission " 10591 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10592 } 10593 10594 final IBinder.DeathRecipient death = new DeathRecipient() { 10595 @Override 10596 public void binderDied() { 10597 synchronized (this) { 10598 notifyAll(); 10599 } 10600 } 10601 }; 10602 10603 try { 10604 who.linkToDeath(death, 0); 10605 } catch (RemoteException e) { 10606 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10607 return; 10608 } 10609 10610 synchronized (this) { 10611 Watchdog.getInstance().setAllowRestart(allowRestart); 10612 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10613 synchronized (death) { 10614 while (who.isBinderAlive()) { 10615 try { 10616 death.wait(); 10617 } catch (InterruptedException e) { 10618 } 10619 } 10620 } 10621 Watchdog.getInstance().setAllowRestart(true); 10622 } 10623 } 10624 10625 @Override 10626 public void restart() { 10627 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10628 != PackageManager.PERMISSION_GRANTED) { 10629 throw new SecurityException("Requires permission " 10630 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10631 } 10632 10633 Log.i(TAG, "Sending shutdown broadcast..."); 10634 10635 BroadcastReceiver br = new BroadcastReceiver() { 10636 @Override public void onReceive(Context context, Intent intent) { 10637 // Now the broadcast is done, finish up the low-level shutdown. 10638 Log.i(TAG, "Shutting down activity manager..."); 10639 shutdown(10000); 10640 Log.i(TAG, "Shutdown complete, restarting!"); 10641 Process.killProcess(Process.myPid()); 10642 System.exit(10); 10643 } 10644 }; 10645 10646 // First send the high-level shut down broadcast. 10647 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10648 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10649 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10650 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10651 mContext.sendOrderedBroadcastAsUser(intent, 10652 UserHandle.ALL, null, br, mHandler, 0, null, null); 10653 */ 10654 br.onReceive(mContext, intent); 10655 } 10656 10657 private long getLowRamTimeSinceIdle(long now) { 10658 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10659 } 10660 10661 @Override 10662 public void performIdleMaintenance() { 10663 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10664 != PackageManager.PERMISSION_GRANTED) { 10665 throw new SecurityException("Requires permission " 10666 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10667 } 10668 10669 synchronized (this) { 10670 final long now = SystemClock.uptimeMillis(); 10671 final long timeSinceLastIdle = now - mLastIdleTime; 10672 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10673 mLastIdleTime = now; 10674 mLowRamTimeSinceLastIdle = 0; 10675 if (mLowRamStartTime != 0) { 10676 mLowRamStartTime = now; 10677 } 10678 10679 StringBuilder sb = new StringBuilder(128); 10680 sb.append("Idle maintenance over "); 10681 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10682 sb.append(" low RAM for "); 10683 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10684 Slog.i(TAG, sb.toString()); 10685 10686 // If at least 1/3 of our time since the last idle period has been spent 10687 // with RAM low, then we want to kill processes. 10688 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10689 10690 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10691 ProcessRecord proc = mLruProcesses.get(i); 10692 if (proc.notCachedSinceIdle) { 10693 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10694 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10695 if (doKilling && proc.initialIdlePss != 0 10696 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10697 proc.kill("idle maint (pss " + proc.lastPss 10698 + " from " + proc.initialIdlePss + ")", true); 10699 } 10700 } 10701 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10702 proc.notCachedSinceIdle = true; 10703 proc.initialIdlePss = 0; 10704 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10705 isSleeping(), now); 10706 } 10707 } 10708 10709 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10710 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10711 } 10712 } 10713 10714 private void retrieveSettings() { 10715 final ContentResolver resolver = mContext.getContentResolver(); 10716 String debugApp = Settings.Global.getString( 10717 resolver, Settings.Global.DEBUG_APP); 10718 boolean waitForDebugger = Settings.Global.getInt( 10719 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10720 boolean alwaysFinishActivities = Settings.Global.getInt( 10721 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10722 boolean forceRtl = Settings.Global.getInt( 10723 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10724 // Transfer any global setting for forcing RTL layout, into a System Property 10725 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10726 10727 Configuration configuration = new Configuration(); 10728 Settings.System.getConfiguration(resolver, configuration); 10729 if (forceRtl) { 10730 // This will take care of setting the correct layout direction flags 10731 configuration.setLayoutDirection(configuration.locale); 10732 } 10733 10734 synchronized (this) { 10735 mDebugApp = mOrigDebugApp = debugApp; 10736 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10737 mAlwaysFinishActivities = alwaysFinishActivities; 10738 // This happens before any activities are started, so we can 10739 // change mConfiguration in-place. 10740 updateConfigurationLocked(configuration, null, false, true); 10741 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10742 } 10743 } 10744 10745 /** Loads resources after the current configuration has been set. */ 10746 private void loadResourcesOnSystemReady() { 10747 final Resources res = mContext.getResources(); 10748 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10749 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10750 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10751 } 10752 10753 public boolean testIsSystemReady() { 10754 // no need to synchronize(this) just to read & return the value 10755 return mSystemReady; 10756 } 10757 10758 private static File getCalledPreBootReceiversFile() { 10759 File dataDir = Environment.getDataDirectory(); 10760 File systemDir = new File(dataDir, "system"); 10761 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10762 return fname; 10763 } 10764 10765 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10766 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10767 File file = getCalledPreBootReceiversFile(); 10768 FileInputStream fis = null; 10769 try { 10770 fis = new FileInputStream(file); 10771 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10772 int fvers = dis.readInt(); 10773 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10774 String vers = dis.readUTF(); 10775 String codename = dis.readUTF(); 10776 String build = dis.readUTF(); 10777 if (android.os.Build.VERSION.RELEASE.equals(vers) 10778 && android.os.Build.VERSION.CODENAME.equals(codename) 10779 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10780 int num = dis.readInt(); 10781 while (num > 0) { 10782 num--; 10783 String pkg = dis.readUTF(); 10784 String cls = dis.readUTF(); 10785 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10786 } 10787 } 10788 } 10789 } catch (FileNotFoundException e) { 10790 } catch (IOException e) { 10791 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10792 } finally { 10793 if (fis != null) { 10794 try { 10795 fis.close(); 10796 } catch (IOException e) { 10797 } 10798 } 10799 } 10800 return lastDoneReceivers; 10801 } 10802 10803 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10804 File file = getCalledPreBootReceiversFile(); 10805 FileOutputStream fos = null; 10806 DataOutputStream dos = null; 10807 try { 10808 fos = new FileOutputStream(file); 10809 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10810 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10811 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10812 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10813 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10814 dos.writeInt(list.size()); 10815 for (int i=0; i<list.size(); i++) { 10816 dos.writeUTF(list.get(i).getPackageName()); 10817 dos.writeUTF(list.get(i).getClassName()); 10818 } 10819 } catch (IOException e) { 10820 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10821 file.delete(); 10822 } finally { 10823 FileUtils.sync(fos); 10824 if (dos != null) { 10825 try { 10826 dos.close(); 10827 } catch (IOException e) { 10828 // TODO Auto-generated catch block 10829 e.printStackTrace(); 10830 } 10831 } 10832 } 10833 } 10834 10835 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10836 ArrayList<ComponentName> doneReceivers, int userId) { 10837 boolean waitingUpdate = false; 10838 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10839 List<ResolveInfo> ris = null; 10840 try { 10841 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10842 intent, null, 0, userId); 10843 } catch (RemoteException e) { 10844 } 10845 if (ris != null) { 10846 for (int i=ris.size()-1; i>=0; i--) { 10847 if ((ris.get(i).activityInfo.applicationInfo.flags 10848 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10849 ris.remove(i); 10850 } 10851 } 10852 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10853 10854 // For User 0, load the version number. When delivering to a new user, deliver 10855 // to all receivers. 10856 if (userId == UserHandle.USER_OWNER) { 10857 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10858 for (int i=0; i<ris.size(); i++) { 10859 ActivityInfo ai = ris.get(i).activityInfo; 10860 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10861 if (lastDoneReceivers.contains(comp)) { 10862 // We already did the pre boot receiver for this app with the current 10863 // platform version, so don't do it again... 10864 ris.remove(i); 10865 i--; 10866 // ...however, do keep it as one that has been done, so we don't 10867 // forget about it when rewriting the file of last done receivers. 10868 doneReceivers.add(comp); 10869 } 10870 } 10871 } 10872 10873 // If primary user, send broadcast to all available users, else just to userId 10874 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10875 : new int[] { userId }; 10876 for (int i = 0; i < ris.size(); i++) { 10877 ActivityInfo ai = ris.get(i).activityInfo; 10878 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10879 doneReceivers.add(comp); 10880 intent.setComponent(comp); 10881 for (int j=0; j<users.length; j++) { 10882 IIntentReceiver finisher = null; 10883 // On last receiver and user, set up a completion callback 10884 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10885 finisher = new IIntentReceiver.Stub() { 10886 public void performReceive(Intent intent, int resultCode, 10887 String data, Bundle extras, boolean ordered, 10888 boolean sticky, int sendingUser) { 10889 // The raw IIntentReceiver interface is called 10890 // with the AM lock held, so redispatch to 10891 // execute our code without the lock. 10892 mHandler.post(onFinishCallback); 10893 } 10894 }; 10895 } 10896 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10897 + " for user " + users[j]); 10898 broadcastIntentLocked(null, null, intent, null, finisher, 10899 0, null, null, null, AppOpsManager.OP_NONE, 10900 true, false, MY_PID, Process.SYSTEM_UID, 10901 users[j]); 10902 if (finisher != null) { 10903 waitingUpdate = true; 10904 } 10905 } 10906 } 10907 } 10908 10909 return waitingUpdate; 10910 } 10911 10912 public void systemReady(final Runnable goingCallback) { 10913 synchronized(this) { 10914 if (mSystemReady) { 10915 // If we're done calling all the receivers, run the next "boot phase" passed in 10916 // by the SystemServer 10917 if (goingCallback != null) { 10918 goingCallback.run(); 10919 } 10920 return; 10921 } 10922 10923 // Make sure we have the current profile info, since it is needed for 10924 // security checks. 10925 updateCurrentProfileIdsLocked(); 10926 10927 if (mRecentTasks == null) { 10928 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10929 if (!mRecentTasks.isEmpty()) { 10930 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10931 } 10932 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10933 mTaskPersister.startPersisting(); 10934 } 10935 10936 // Check to see if there are any update receivers to run. 10937 if (!mDidUpdate) { 10938 if (mWaitingUpdate) { 10939 return; 10940 } 10941 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10942 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10943 public void run() { 10944 synchronized (ActivityManagerService.this) { 10945 mDidUpdate = true; 10946 } 10947 writeLastDonePreBootReceivers(doneReceivers); 10948 showBootMessage(mContext.getText( 10949 R.string.android_upgrading_complete), 10950 false); 10951 systemReady(goingCallback); 10952 } 10953 }, doneReceivers, UserHandle.USER_OWNER); 10954 10955 if (mWaitingUpdate) { 10956 return; 10957 } 10958 mDidUpdate = true; 10959 } 10960 10961 mAppOpsService.systemReady(); 10962 mSystemReady = true; 10963 } 10964 10965 ArrayList<ProcessRecord> procsToKill = null; 10966 synchronized(mPidsSelfLocked) { 10967 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10968 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10969 if (!isAllowedWhileBooting(proc.info)){ 10970 if (procsToKill == null) { 10971 procsToKill = new ArrayList<ProcessRecord>(); 10972 } 10973 procsToKill.add(proc); 10974 } 10975 } 10976 } 10977 10978 synchronized(this) { 10979 if (procsToKill != null) { 10980 for (int i=procsToKill.size()-1; i>=0; i--) { 10981 ProcessRecord proc = procsToKill.get(i); 10982 Slog.i(TAG, "Removing system update proc: " + proc); 10983 removeProcessLocked(proc, true, false, "system update done"); 10984 } 10985 } 10986 10987 // Now that we have cleaned up any update processes, we 10988 // are ready to start launching real processes and know that 10989 // we won't trample on them any more. 10990 mProcessesReady = true; 10991 } 10992 10993 Slog.i(TAG, "System now ready"); 10994 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10995 SystemClock.uptimeMillis()); 10996 10997 synchronized(this) { 10998 // Make sure we have no pre-ready processes sitting around. 10999 11000 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11001 ResolveInfo ri = mContext.getPackageManager() 11002 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11003 STOCK_PM_FLAGS); 11004 CharSequence errorMsg = null; 11005 if (ri != null) { 11006 ActivityInfo ai = ri.activityInfo; 11007 ApplicationInfo app = ai.applicationInfo; 11008 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11009 mTopAction = Intent.ACTION_FACTORY_TEST; 11010 mTopData = null; 11011 mTopComponent = new ComponentName(app.packageName, 11012 ai.name); 11013 } else { 11014 errorMsg = mContext.getResources().getText( 11015 com.android.internal.R.string.factorytest_not_system); 11016 } 11017 } else { 11018 errorMsg = mContext.getResources().getText( 11019 com.android.internal.R.string.factorytest_no_action); 11020 } 11021 if (errorMsg != null) { 11022 mTopAction = null; 11023 mTopData = null; 11024 mTopComponent = null; 11025 Message msg = Message.obtain(); 11026 msg.what = SHOW_FACTORY_ERROR_MSG; 11027 msg.getData().putCharSequence("msg", errorMsg); 11028 mHandler.sendMessage(msg); 11029 } 11030 } 11031 } 11032 11033 retrieveSettings(); 11034 loadResourcesOnSystemReady(); 11035 11036 synchronized (this) { 11037 readGrantedUriPermissionsLocked(); 11038 } 11039 11040 if (goingCallback != null) goingCallback.run(); 11041 11042 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11043 Integer.toString(mCurrentUserId), mCurrentUserId); 11044 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11045 Integer.toString(mCurrentUserId), mCurrentUserId); 11046 mSystemServiceManager.startUser(mCurrentUserId); 11047 11048 synchronized (this) { 11049 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11050 try { 11051 List apps = AppGlobals.getPackageManager(). 11052 getPersistentApplications(STOCK_PM_FLAGS); 11053 if (apps != null) { 11054 int N = apps.size(); 11055 int i; 11056 for (i=0; i<N; i++) { 11057 ApplicationInfo info 11058 = (ApplicationInfo)apps.get(i); 11059 if (info != null && 11060 !info.packageName.equals("android")) { 11061 addAppLocked(info, false, null /* ABI override */); 11062 } 11063 } 11064 } 11065 } catch (RemoteException ex) { 11066 // pm is in same process, this will never happen. 11067 } 11068 } 11069 11070 // Start up initial activity. 11071 mBooting = true; 11072 11073 try { 11074 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11075 Message msg = Message.obtain(); 11076 msg.what = SHOW_UID_ERROR_MSG; 11077 mHandler.sendMessage(msg); 11078 } 11079 } catch (RemoteException e) { 11080 } 11081 11082 long ident = Binder.clearCallingIdentity(); 11083 try { 11084 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11085 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11086 | Intent.FLAG_RECEIVER_FOREGROUND); 11087 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11088 broadcastIntentLocked(null, null, intent, 11089 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11090 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11091 intent = new Intent(Intent.ACTION_USER_STARTING); 11092 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11093 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11094 broadcastIntentLocked(null, null, intent, 11095 null, new IIntentReceiver.Stub() { 11096 @Override 11097 public void performReceive(Intent intent, int resultCode, String data, 11098 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11099 throws RemoteException { 11100 } 11101 }, 0, null, null, 11102 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11103 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11104 } catch (Throwable t) { 11105 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11106 } finally { 11107 Binder.restoreCallingIdentity(ident); 11108 } 11109 mStackSupervisor.resumeTopActivitiesLocked(); 11110 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11111 } 11112 } 11113 11114 private boolean makeAppCrashingLocked(ProcessRecord app, 11115 String shortMsg, String longMsg, String stackTrace) { 11116 app.crashing = true; 11117 app.crashingReport = generateProcessError(app, 11118 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11119 startAppProblemLocked(app); 11120 app.stopFreezingAllLocked(); 11121 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11122 } 11123 11124 private void makeAppNotRespondingLocked(ProcessRecord app, 11125 String activity, String shortMsg, String longMsg) { 11126 app.notResponding = true; 11127 app.notRespondingReport = generateProcessError(app, 11128 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11129 activity, shortMsg, longMsg, null); 11130 startAppProblemLocked(app); 11131 app.stopFreezingAllLocked(); 11132 } 11133 11134 /** 11135 * Generate a process error record, suitable for attachment to a ProcessRecord. 11136 * 11137 * @param app The ProcessRecord in which the error occurred. 11138 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11139 * ActivityManager.AppErrorStateInfo 11140 * @param activity The activity associated with the crash, if known. 11141 * @param shortMsg Short message describing the crash. 11142 * @param longMsg Long message describing the crash. 11143 * @param stackTrace Full crash stack trace, may be null. 11144 * 11145 * @return Returns a fully-formed AppErrorStateInfo record. 11146 */ 11147 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11148 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11149 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11150 11151 report.condition = condition; 11152 report.processName = app.processName; 11153 report.pid = app.pid; 11154 report.uid = app.info.uid; 11155 report.tag = activity; 11156 report.shortMsg = shortMsg; 11157 report.longMsg = longMsg; 11158 report.stackTrace = stackTrace; 11159 11160 return report; 11161 } 11162 11163 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11164 synchronized (this) { 11165 app.crashing = false; 11166 app.crashingReport = null; 11167 app.notResponding = false; 11168 app.notRespondingReport = null; 11169 if (app.anrDialog == fromDialog) { 11170 app.anrDialog = null; 11171 } 11172 if (app.waitDialog == fromDialog) { 11173 app.waitDialog = null; 11174 } 11175 if (app.pid > 0 && app.pid != MY_PID) { 11176 handleAppCrashLocked(app, null, null, null); 11177 app.kill("user request after error", true); 11178 } 11179 } 11180 } 11181 11182 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11183 String stackTrace) { 11184 long now = SystemClock.uptimeMillis(); 11185 11186 Long crashTime; 11187 if (!app.isolated) { 11188 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11189 } else { 11190 crashTime = null; 11191 } 11192 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11193 // This process loses! 11194 Slog.w(TAG, "Process " + app.info.processName 11195 + " has crashed too many times: killing!"); 11196 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11197 app.userId, app.info.processName, app.uid); 11198 mStackSupervisor.handleAppCrashLocked(app); 11199 if (!app.persistent) { 11200 // We don't want to start this process again until the user 11201 // explicitly does so... but for persistent process, we really 11202 // need to keep it running. If a persistent process is actually 11203 // repeatedly crashing, then badness for everyone. 11204 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11205 app.info.processName); 11206 if (!app.isolated) { 11207 // XXX We don't have a way to mark isolated processes 11208 // as bad, since they don't have a peristent identity. 11209 mBadProcesses.put(app.info.processName, app.uid, 11210 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11211 mProcessCrashTimes.remove(app.info.processName, app.uid); 11212 } 11213 app.bad = true; 11214 app.removed = true; 11215 // Don't let services in this process be restarted and potentially 11216 // annoy the user repeatedly. Unless it is persistent, since those 11217 // processes run critical code. 11218 removeProcessLocked(app, false, false, "crash"); 11219 mStackSupervisor.resumeTopActivitiesLocked(); 11220 return false; 11221 } 11222 mStackSupervisor.resumeTopActivitiesLocked(); 11223 } else { 11224 mStackSupervisor.finishTopRunningActivityLocked(app); 11225 } 11226 11227 // Bump up the crash count of any services currently running in the proc. 11228 for (int i=app.services.size()-1; i>=0; i--) { 11229 // Any services running in the application need to be placed 11230 // back in the pending list. 11231 ServiceRecord sr = app.services.valueAt(i); 11232 sr.crashCount++; 11233 } 11234 11235 // If the crashing process is what we consider to be the "home process" and it has been 11236 // replaced by a third-party app, clear the package preferred activities from packages 11237 // with a home activity running in the process to prevent a repeatedly crashing app 11238 // from blocking the user to manually clear the list. 11239 final ArrayList<ActivityRecord> activities = app.activities; 11240 if (app == mHomeProcess && activities.size() > 0 11241 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11242 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11243 final ActivityRecord r = activities.get(activityNdx); 11244 if (r.isHomeActivity()) { 11245 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11246 try { 11247 ActivityThread.getPackageManager() 11248 .clearPackagePreferredActivities(r.packageName); 11249 } catch (RemoteException c) { 11250 // pm is in same process, this will never happen. 11251 } 11252 } 11253 } 11254 } 11255 11256 if (!app.isolated) { 11257 // XXX Can't keep track of crash times for isolated processes, 11258 // because they don't have a perisistent identity. 11259 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11260 } 11261 11262 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11263 return true; 11264 } 11265 11266 void startAppProblemLocked(ProcessRecord app) { 11267 // If this app is not running under the current user, then we 11268 // can't give it a report button because that would require 11269 // launching the report UI under a different user. 11270 app.errorReportReceiver = null; 11271 11272 for (int userId : mCurrentProfileIds) { 11273 if (app.userId == userId) { 11274 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11275 mContext, app.info.packageName, app.info.flags); 11276 } 11277 } 11278 skipCurrentReceiverLocked(app); 11279 } 11280 11281 void skipCurrentReceiverLocked(ProcessRecord app) { 11282 for (BroadcastQueue queue : mBroadcastQueues) { 11283 queue.skipCurrentReceiverLocked(app); 11284 } 11285 } 11286 11287 /** 11288 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11289 * The application process will exit immediately after this call returns. 11290 * @param app object of the crashing app, null for the system server 11291 * @param crashInfo describing the exception 11292 */ 11293 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11294 ProcessRecord r = findAppProcess(app, "Crash"); 11295 final String processName = app == null ? "system_server" 11296 : (r == null ? "unknown" : r.processName); 11297 11298 handleApplicationCrashInner("crash", r, processName, crashInfo); 11299 } 11300 11301 /* Native crash reporting uses this inner version because it needs to be somewhat 11302 * decoupled from the AM-managed cleanup lifecycle 11303 */ 11304 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11305 ApplicationErrorReport.CrashInfo crashInfo) { 11306 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11307 UserHandle.getUserId(Binder.getCallingUid()), processName, 11308 r == null ? -1 : r.info.flags, 11309 crashInfo.exceptionClassName, 11310 crashInfo.exceptionMessage, 11311 crashInfo.throwFileName, 11312 crashInfo.throwLineNumber); 11313 11314 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11315 11316 crashApplication(r, crashInfo); 11317 } 11318 11319 public void handleApplicationStrictModeViolation( 11320 IBinder app, 11321 int violationMask, 11322 StrictMode.ViolationInfo info) { 11323 ProcessRecord r = findAppProcess(app, "StrictMode"); 11324 if (r == null) { 11325 return; 11326 } 11327 11328 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11329 Integer stackFingerprint = info.hashCode(); 11330 boolean logIt = true; 11331 synchronized (mAlreadyLoggedViolatedStacks) { 11332 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11333 logIt = false; 11334 // TODO: sub-sample into EventLog for these, with 11335 // the info.durationMillis? Then we'd get 11336 // the relative pain numbers, without logging all 11337 // the stack traces repeatedly. We'd want to do 11338 // likewise in the client code, which also does 11339 // dup suppression, before the Binder call. 11340 } else { 11341 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11342 mAlreadyLoggedViolatedStacks.clear(); 11343 } 11344 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11345 } 11346 } 11347 if (logIt) { 11348 logStrictModeViolationToDropBox(r, info); 11349 } 11350 } 11351 11352 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11353 AppErrorResult result = new AppErrorResult(); 11354 synchronized (this) { 11355 final long origId = Binder.clearCallingIdentity(); 11356 11357 Message msg = Message.obtain(); 11358 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11359 HashMap<String, Object> data = new HashMap<String, Object>(); 11360 data.put("result", result); 11361 data.put("app", r); 11362 data.put("violationMask", violationMask); 11363 data.put("info", info); 11364 msg.obj = data; 11365 mHandler.sendMessage(msg); 11366 11367 Binder.restoreCallingIdentity(origId); 11368 } 11369 int res = result.get(); 11370 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11371 } 11372 } 11373 11374 // Depending on the policy in effect, there could be a bunch of 11375 // these in quick succession so we try to batch these together to 11376 // minimize disk writes, number of dropbox entries, and maximize 11377 // compression, by having more fewer, larger records. 11378 private void logStrictModeViolationToDropBox( 11379 ProcessRecord process, 11380 StrictMode.ViolationInfo info) { 11381 if (info == null) { 11382 return; 11383 } 11384 final boolean isSystemApp = process == null || 11385 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11386 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11387 final String processName = process == null ? "unknown" : process.processName; 11388 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11389 final DropBoxManager dbox = (DropBoxManager) 11390 mContext.getSystemService(Context.DROPBOX_SERVICE); 11391 11392 // Exit early if the dropbox isn't configured to accept this report type. 11393 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11394 11395 boolean bufferWasEmpty; 11396 boolean needsFlush; 11397 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11398 synchronized (sb) { 11399 bufferWasEmpty = sb.length() == 0; 11400 appendDropBoxProcessHeaders(process, processName, sb); 11401 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11402 sb.append("System-App: ").append(isSystemApp).append("\n"); 11403 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11404 if (info.violationNumThisLoop != 0) { 11405 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11406 } 11407 if (info.numAnimationsRunning != 0) { 11408 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11409 } 11410 if (info.broadcastIntentAction != null) { 11411 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11412 } 11413 if (info.durationMillis != -1) { 11414 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11415 } 11416 if (info.numInstances != -1) { 11417 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11418 } 11419 if (info.tags != null) { 11420 for (String tag : info.tags) { 11421 sb.append("Span-Tag: ").append(tag).append("\n"); 11422 } 11423 } 11424 sb.append("\n"); 11425 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11426 sb.append(info.crashInfo.stackTrace); 11427 } 11428 sb.append("\n"); 11429 11430 // Only buffer up to ~64k. Various logging bits truncate 11431 // things at 128k. 11432 needsFlush = (sb.length() > 64 * 1024); 11433 } 11434 11435 // Flush immediately if the buffer's grown too large, or this 11436 // is a non-system app. Non-system apps are isolated with a 11437 // different tag & policy and not batched. 11438 // 11439 // Batching is useful during internal testing with 11440 // StrictMode settings turned up high. Without batching, 11441 // thousands of separate files could be created on boot. 11442 if (!isSystemApp || needsFlush) { 11443 new Thread("Error dump: " + dropboxTag) { 11444 @Override 11445 public void run() { 11446 String report; 11447 synchronized (sb) { 11448 report = sb.toString(); 11449 sb.delete(0, sb.length()); 11450 sb.trimToSize(); 11451 } 11452 if (report.length() != 0) { 11453 dbox.addText(dropboxTag, report); 11454 } 11455 } 11456 }.start(); 11457 return; 11458 } 11459 11460 // System app batching: 11461 if (!bufferWasEmpty) { 11462 // An existing dropbox-writing thread is outstanding, so 11463 // we don't need to start it up. The existing thread will 11464 // catch the buffer appends we just did. 11465 return; 11466 } 11467 11468 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11469 // (After this point, we shouldn't access AMS internal data structures.) 11470 new Thread("Error dump: " + dropboxTag) { 11471 @Override 11472 public void run() { 11473 // 5 second sleep to let stacks arrive and be batched together 11474 try { 11475 Thread.sleep(5000); // 5 seconds 11476 } catch (InterruptedException e) {} 11477 11478 String errorReport; 11479 synchronized (mStrictModeBuffer) { 11480 errorReport = mStrictModeBuffer.toString(); 11481 if (errorReport.length() == 0) { 11482 return; 11483 } 11484 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11485 mStrictModeBuffer.trimToSize(); 11486 } 11487 dbox.addText(dropboxTag, errorReport); 11488 } 11489 }.start(); 11490 } 11491 11492 /** 11493 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11494 * @param app object of the crashing app, null for the system server 11495 * @param tag reported by the caller 11496 * @param system whether this wtf is coming from the system 11497 * @param crashInfo describing the context of the error 11498 * @return true if the process should exit immediately (WTF is fatal) 11499 */ 11500 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11501 final ApplicationErrorReport.CrashInfo crashInfo) { 11502 final ProcessRecord r = findAppProcess(app, "WTF"); 11503 final String processName = app == null ? "system_server" 11504 : (r == null ? "unknown" : r.processName); 11505 11506 EventLog.writeEvent(EventLogTags.AM_WTF, 11507 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11508 processName, 11509 r == null ? -1 : r.info.flags, 11510 tag, crashInfo.exceptionMessage); 11511 11512 if (system) { 11513 // If this is coming from the system, we could very well have low-level 11514 // system locks held, so we want to do this all asynchronously. And we 11515 // never want this to become fatal, so there is that too. 11516 mHandler.post(new Runnable() { 11517 @Override public void run() { 11518 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11519 crashInfo); 11520 } 11521 }); 11522 return false; 11523 } 11524 11525 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11526 11527 if (r != null && r.pid != Process.myPid() && 11528 Settings.Global.getInt(mContext.getContentResolver(), 11529 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11530 crashApplication(r, crashInfo); 11531 return true; 11532 } else { 11533 return false; 11534 } 11535 } 11536 11537 /** 11538 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11539 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11540 */ 11541 private ProcessRecord findAppProcess(IBinder app, String reason) { 11542 if (app == null) { 11543 return null; 11544 } 11545 11546 synchronized (this) { 11547 final int NP = mProcessNames.getMap().size(); 11548 for (int ip=0; ip<NP; ip++) { 11549 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11550 final int NA = apps.size(); 11551 for (int ia=0; ia<NA; ia++) { 11552 ProcessRecord p = apps.valueAt(ia); 11553 if (p.thread != null && p.thread.asBinder() == app) { 11554 return p; 11555 } 11556 } 11557 } 11558 11559 Slog.w(TAG, "Can't find mystery application for " + reason 11560 + " from pid=" + Binder.getCallingPid() 11561 + " uid=" + Binder.getCallingUid() + ": " + app); 11562 return null; 11563 } 11564 } 11565 11566 /** 11567 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11568 * to append various headers to the dropbox log text. 11569 */ 11570 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11571 StringBuilder sb) { 11572 // Watchdog thread ends up invoking this function (with 11573 // a null ProcessRecord) to add the stack file to dropbox. 11574 // Do not acquire a lock on this (am) in such cases, as it 11575 // could cause a potential deadlock, if and when watchdog 11576 // is invoked due to unavailability of lock on am and it 11577 // would prevent watchdog from killing system_server. 11578 if (process == null) { 11579 sb.append("Process: ").append(processName).append("\n"); 11580 return; 11581 } 11582 // Note: ProcessRecord 'process' is guarded by the service 11583 // instance. (notably process.pkgList, which could otherwise change 11584 // concurrently during execution of this method) 11585 synchronized (this) { 11586 sb.append("Process: ").append(processName).append("\n"); 11587 int flags = process.info.flags; 11588 IPackageManager pm = AppGlobals.getPackageManager(); 11589 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11590 for (int ip=0; ip<process.pkgList.size(); ip++) { 11591 String pkg = process.pkgList.keyAt(ip); 11592 sb.append("Package: ").append(pkg); 11593 try { 11594 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11595 if (pi != null) { 11596 sb.append(" v").append(pi.versionCode); 11597 if (pi.versionName != null) { 11598 sb.append(" (").append(pi.versionName).append(")"); 11599 } 11600 } 11601 } catch (RemoteException e) { 11602 Slog.e(TAG, "Error getting package info: " + pkg, e); 11603 } 11604 sb.append("\n"); 11605 } 11606 } 11607 } 11608 11609 private static String processClass(ProcessRecord process) { 11610 if (process == null || process.pid == MY_PID) { 11611 return "system_server"; 11612 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11613 return "system_app"; 11614 } else { 11615 return "data_app"; 11616 } 11617 } 11618 11619 /** 11620 * Write a description of an error (crash, WTF, ANR) to the drop box. 11621 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11622 * @param process which caused the error, null means the system server 11623 * @param activity which triggered the error, null if unknown 11624 * @param parent activity related to the error, null if unknown 11625 * @param subject line related to the error, null if absent 11626 * @param report in long form describing the error, null if absent 11627 * @param logFile to include in the report, null if none 11628 * @param crashInfo giving an application stack trace, null if absent 11629 */ 11630 public void addErrorToDropBox(String eventType, 11631 ProcessRecord process, String processName, ActivityRecord activity, 11632 ActivityRecord parent, String subject, 11633 final String report, final File logFile, 11634 final ApplicationErrorReport.CrashInfo crashInfo) { 11635 // NOTE -- this must never acquire the ActivityManagerService lock, 11636 // otherwise the watchdog may be prevented from resetting the system. 11637 11638 final String dropboxTag = processClass(process) + "_" + eventType; 11639 final DropBoxManager dbox = (DropBoxManager) 11640 mContext.getSystemService(Context.DROPBOX_SERVICE); 11641 11642 // Exit early if the dropbox isn't configured to accept this report type. 11643 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11644 11645 final StringBuilder sb = new StringBuilder(1024); 11646 appendDropBoxProcessHeaders(process, processName, sb); 11647 if (activity != null) { 11648 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11649 } 11650 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11651 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11652 } 11653 if (parent != null && parent != activity) { 11654 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11655 } 11656 if (subject != null) { 11657 sb.append("Subject: ").append(subject).append("\n"); 11658 } 11659 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11660 if (Debug.isDebuggerConnected()) { 11661 sb.append("Debugger: Connected\n"); 11662 } 11663 sb.append("\n"); 11664 11665 // Do the rest in a worker thread to avoid blocking the caller on I/O 11666 // (After this point, we shouldn't access AMS internal data structures.) 11667 Thread worker = new Thread("Error dump: " + dropboxTag) { 11668 @Override 11669 public void run() { 11670 if (report != null) { 11671 sb.append(report); 11672 } 11673 if (logFile != null) { 11674 try { 11675 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11676 "\n\n[[TRUNCATED]]")); 11677 } catch (IOException e) { 11678 Slog.e(TAG, "Error reading " + logFile, e); 11679 } 11680 } 11681 if (crashInfo != null && crashInfo.stackTrace != null) { 11682 sb.append(crashInfo.stackTrace); 11683 } 11684 11685 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11686 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11687 if (lines > 0) { 11688 sb.append("\n"); 11689 11690 // Merge several logcat streams, and take the last N lines 11691 InputStreamReader input = null; 11692 try { 11693 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11694 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11695 "-b", "crash", 11696 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11697 11698 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11699 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11700 input = new InputStreamReader(logcat.getInputStream()); 11701 11702 int num; 11703 char[] buf = new char[8192]; 11704 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11705 } catch (IOException e) { 11706 Slog.e(TAG, "Error running logcat", e); 11707 } finally { 11708 if (input != null) try { input.close(); } catch (IOException e) {} 11709 } 11710 } 11711 11712 dbox.addText(dropboxTag, sb.toString()); 11713 } 11714 }; 11715 11716 if (process == null) { 11717 // If process is null, we are being called from some internal code 11718 // and may be about to die -- run this synchronously. 11719 worker.run(); 11720 } else { 11721 worker.start(); 11722 } 11723 } 11724 11725 /** 11726 * Bring up the "unexpected error" dialog box for a crashing app. 11727 * Deal with edge cases (intercepts from instrumented applications, 11728 * ActivityController, error intent receivers, that sort of thing). 11729 * @param r the application crashing 11730 * @param crashInfo describing the failure 11731 */ 11732 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11733 long timeMillis = System.currentTimeMillis(); 11734 String shortMsg = crashInfo.exceptionClassName; 11735 String longMsg = crashInfo.exceptionMessage; 11736 String stackTrace = crashInfo.stackTrace; 11737 if (shortMsg != null && longMsg != null) { 11738 longMsg = shortMsg + ": " + longMsg; 11739 } else if (shortMsg != null) { 11740 longMsg = shortMsg; 11741 } 11742 11743 AppErrorResult result = new AppErrorResult(); 11744 synchronized (this) { 11745 if (mController != null) { 11746 try { 11747 String name = r != null ? r.processName : null; 11748 int pid = r != null ? r.pid : Binder.getCallingPid(); 11749 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11750 if (!mController.appCrashed(name, pid, 11751 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11752 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11753 && "Native crash".equals(crashInfo.exceptionClassName)) { 11754 Slog.w(TAG, "Skip killing native crashed app " + name 11755 + "(" + pid + ") during testing"); 11756 } else { 11757 Slog.w(TAG, "Force-killing crashed app " + name 11758 + " at watcher's request"); 11759 if (r != null) { 11760 r.kill("crash", true); 11761 } else { 11762 // Huh. 11763 Process.killProcess(pid); 11764 Process.killProcessGroup(uid, pid); 11765 } 11766 } 11767 return; 11768 } 11769 } catch (RemoteException e) { 11770 mController = null; 11771 Watchdog.getInstance().setActivityController(null); 11772 } 11773 } 11774 11775 final long origId = Binder.clearCallingIdentity(); 11776 11777 // If this process is running instrumentation, finish it. 11778 if (r != null && r.instrumentationClass != null) { 11779 Slog.w(TAG, "Error in app " + r.processName 11780 + " running instrumentation " + r.instrumentationClass + ":"); 11781 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11782 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11783 Bundle info = new Bundle(); 11784 info.putString("shortMsg", shortMsg); 11785 info.putString("longMsg", longMsg); 11786 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11787 Binder.restoreCallingIdentity(origId); 11788 return; 11789 } 11790 11791 // If we can't identify the process or it's already exceeded its crash quota, 11792 // quit right away without showing a crash dialog. 11793 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11794 Binder.restoreCallingIdentity(origId); 11795 return; 11796 } 11797 11798 Message msg = Message.obtain(); 11799 msg.what = SHOW_ERROR_MSG; 11800 HashMap data = new HashMap(); 11801 data.put("result", result); 11802 data.put("app", r); 11803 msg.obj = data; 11804 mHandler.sendMessage(msg); 11805 11806 Binder.restoreCallingIdentity(origId); 11807 } 11808 11809 int res = result.get(); 11810 11811 Intent appErrorIntent = null; 11812 synchronized (this) { 11813 if (r != null && !r.isolated) { 11814 // XXX Can't keep track of crash time for isolated processes, 11815 // since they don't have a persistent identity. 11816 mProcessCrashTimes.put(r.info.processName, r.uid, 11817 SystemClock.uptimeMillis()); 11818 } 11819 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11820 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11821 } 11822 } 11823 11824 if (appErrorIntent != null) { 11825 try { 11826 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11827 } catch (ActivityNotFoundException e) { 11828 Slog.w(TAG, "bug report receiver dissappeared", e); 11829 } 11830 } 11831 } 11832 11833 Intent createAppErrorIntentLocked(ProcessRecord r, 11834 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11835 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11836 if (report == null) { 11837 return null; 11838 } 11839 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11840 result.setComponent(r.errorReportReceiver); 11841 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11842 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11843 return result; 11844 } 11845 11846 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11847 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11848 if (r.errorReportReceiver == null) { 11849 return null; 11850 } 11851 11852 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11853 return null; 11854 } 11855 11856 ApplicationErrorReport report = new ApplicationErrorReport(); 11857 report.packageName = r.info.packageName; 11858 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11859 report.processName = r.processName; 11860 report.time = timeMillis; 11861 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11862 11863 if (r.crashing || r.forceCrashReport) { 11864 report.type = ApplicationErrorReport.TYPE_CRASH; 11865 report.crashInfo = crashInfo; 11866 } else if (r.notResponding) { 11867 report.type = ApplicationErrorReport.TYPE_ANR; 11868 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11869 11870 report.anrInfo.activity = r.notRespondingReport.tag; 11871 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11872 report.anrInfo.info = r.notRespondingReport.longMsg; 11873 } 11874 11875 return report; 11876 } 11877 11878 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11879 enforceNotIsolatedCaller("getProcessesInErrorState"); 11880 // assume our apps are happy - lazy create the list 11881 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11882 11883 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11884 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11885 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11886 11887 synchronized (this) { 11888 11889 // iterate across all processes 11890 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11891 ProcessRecord app = mLruProcesses.get(i); 11892 if (!allUsers && app.userId != userId) { 11893 continue; 11894 } 11895 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11896 // This one's in trouble, so we'll generate a report for it 11897 // crashes are higher priority (in case there's a crash *and* an anr) 11898 ActivityManager.ProcessErrorStateInfo report = null; 11899 if (app.crashing) { 11900 report = app.crashingReport; 11901 } else if (app.notResponding) { 11902 report = app.notRespondingReport; 11903 } 11904 11905 if (report != null) { 11906 if (errList == null) { 11907 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11908 } 11909 errList.add(report); 11910 } else { 11911 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11912 " crashing = " + app.crashing + 11913 " notResponding = " + app.notResponding); 11914 } 11915 } 11916 } 11917 } 11918 11919 return errList; 11920 } 11921 11922 static int procStateToImportance(int procState, int memAdj, 11923 ActivityManager.RunningAppProcessInfo currApp) { 11924 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11925 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11926 currApp.lru = memAdj; 11927 } else { 11928 currApp.lru = 0; 11929 } 11930 return imp; 11931 } 11932 11933 private void fillInProcMemInfo(ProcessRecord app, 11934 ActivityManager.RunningAppProcessInfo outInfo) { 11935 outInfo.pid = app.pid; 11936 outInfo.uid = app.info.uid; 11937 if (mHeavyWeightProcess == app) { 11938 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11939 } 11940 if (app.persistent) { 11941 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11942 } 11943 if (app.activities.size() > 0) { 11944 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11945 } 11946 outInfo.lastTrimLevel = app.trimMemoryLevel; 11947 int adj = app.curAdj; 11948 int procState = app.curProcState; 11949 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11950 outInfo.importanceReasonCode = app.adjTypeCode; 11951 outInfo.processState = app.curProcState; 11952 } 11953 11954 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11955 enforceNotIsolatedCaller("getRunningAppProcesses"); 11956 // Lazy instantiation of list 11957 List<ActivityManager.RunningAppProcessInfo> runList = null; 11958 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11959 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11960 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11961 synchronized (this) { 11962 // Iterate across all processes 11963 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11964 ProcessRecord app = mLruProcesses.get(i); 11965 if (!allUsers && app.userId != userId) { 11966 continue; 11967 } 11968 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11969 // Generate process state info for running application 11970 ActivityManager.RunningAppProcessInfo currApp = 11971 new ActivityManager.RunningAppProcessInfo(app.processName, 11972 app.pid, app.getPackageList()); 11973 fillInProcMemInfo(app, currApp); 11974 if (app.adjSource instanceof ProcessRecord) { 11975 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11976 currApp.importanceReasonImportance = 11977 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11978 app.adjSourceProcState); 11979 } else if (app.adjSource instanceof ActivityRecord) { 11980 ActivityRecord r = (ActivityRecord)app.adjSource; 11981 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11982 } 11983 if (app.adjTarget instanceof ComponentName) { 11984 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11985 } 11986 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11987 // + " lru=" + currApp.lru); 11988 if (runList == null) { 11989 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11990 } 11991 runList.add(currApp); 11992 } 11993 } 11994 } 11995 return runList; 11996 } 11997 11998 public List<ApplicationInfo> getRunningExternalApplications() { 11999 enforceNotIsolatedCaller("getRunningExternalApplications"); 12000 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12001 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12002 if (runningApps != null && runningApps.size() > 0) { 12003 Set<String> extList = new HashSet<String>(); 12004 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12005 if (app.pkgList != null) { 12006 for (String pkg : app.pkgList) { 12007 extList.add(pkg); 12008 } 12009 } 12010 } 12011 IPackageManager pm = AppGlobals.getPackageManager(); 12012 for (String pkg : extList) { 12013 try { 12014 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12015 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12016 retList.add(info); 12017 } 12018 } catch (RemoteException e) { 12019 } 12020 } 12021 } 12022 return retList; 12023 } 12024 12025 @Override 12026 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12027 enforceNotIsolatedCaller("getMyMemoryState"); 12028 synchronized (this) { 12029 ProcessRecord proc; 12030 synchronized (mPidsSelfLocked) { 12031 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12032 } 12033 fillInProcMemInfo(proc, outInfo); 12034 } 12035 } 12036 12037 @Override 12038 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12039 if (checkCallingPermission(android.Manifest.permission.DUMP) 12040 != PackageManager.PERMISSION_GRANTED) { 12041 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12042 + Binder.getCallingPid() 12043 + ", uid=" + Binder.getCallingUid() 12044 + " without permission " 12045 + android.Manifest.permission.DUMP); 12046 return; 12047 } 12048 12049 boolean dumpAll = false; 12050 boolean dumpClient = false; 12051 String dumpPackage = null; 12052 12053 int opti = 0; 12054 while (opti < args.length) { 12055 String opt = args[opti]; 12056 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12057 break; 12058 } 12059 opti++; 12060 if ("-a".equals(opt)) { 12061 dumpAll = true; 12062 } else if ("-c".equals(opt)) { 12063 dumpClient = true; 12064 } else if ("-h".equals(opt)) { 12065 pw.println("Activity manager dump options:"); 12066 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12067 pw.println(" cmd may be one of:"); 12068 pw.println(" a[ctivities]: activity stack state"); 12069 pw.println(" r[recents]: recent activities state"); 12070 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12071 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12072 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12073 pw.println(" o[om]: out of memory management"); 12074 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12075 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12076 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12077 pw.println(" service [COMP_SPEC]: service client-side state"); 12078 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12079 pw.println(" all: dump all activities"); 12080 pw.println(" top: dump the top activity"); 12081 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12082 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12083 pw.println(" a partial substring in a component name, a"); 12084 pw.println(" hex object identifier."); 12085 pw.println(" -a: include all available server state."); 12086 pw.println(" -c: include client state."); 12087 return; 12088 } else { 12089 pw.println("Unknown argument: " + opt + "; use -h for help"); 12090 } 12091 } 12092 12093 long origId = Binder.clearCallingIdentity(); 12094 boolean more = false; 12095 // Is the caller requesting to dump a particular piece of data? 12096 if (opti < args.length) { 12097 String cmd = args[opti]; 12098 opti++; 12099 if ("activities".equals(cmd) || "a".equals(cmd)) { 12100 synchronized (this) { 12101 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12102 } 12103 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12104 synchronized (this) { 12105 dumpRecentsLocked(fd, pw, args, opti, true, null); 12106 } 12107 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12108 String[] newArgs; 12109 String name; 12110 if (opti >= args.length) { 12111 name = null; 12112 newArgs = EMPTY_STRING_ARRAY; 12113 } else { 12114 name = args[opti]; 12115 opti++; 12116 newArgs = new String[args.length - opti]; 12117 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12118 args.length - opti); 12119 } 12120 synchronized (this) { 12121 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12122 } 12123 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12124 String[] newArgs; 12125 String name; 12126 if (opti >= args.length) { 12127 name = null; 12128 newArgs = EMPTY_STRING_ARRAY; 12129 } else { 12130 name = args[opti]; 12131 opti++; 12132 newArgs = new String[args.length - opti]; 12133 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12134 args.length - opti); 12135 } 12136 synchronized (this) { 12137 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12138 } 12139 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12140 String[] newArgs; 12141 String name; 12142 if (opti >= args.length) { 12143 name = null; 12144 newArgs = EMPTY_STRING_ARRAY; 12145 } else { 12146 name = args[opti]; 12147 opti++; 12148 newArgs = new String[args.length - opti]; 12149 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12150 args.length - opti); 12151 } 12152 synchronized (this) { 12153 dumpProcessesLocked(fd, pw, args, opti, true, name); 12154 } 12155 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12156 synchronized (this) { 12157 dumpOomLocked(fd, pw, args, opti, true); 12158 } 12159 } else if ("provider".equals(cmd)) { 12160 String[] newArgs; 12161 String name; 12162 if (opti >= args.length) { 12163 name = null; 12164 newArgs = EMPTY_STRING_ARRAY; 12165 } else { 12166 name = args[opti]; 12167 opti++; 12168 newArgs = new String[args.length - opti]; 12169 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12170 } 12171 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12172 pw.println("No providers match: " + name); 12173 pw.println("Use -h for help."); 12174 } 12175 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12176 synchronized (this) { 12177 dumpProvidersLocked(fd, pw, args, opti, true, null); 12178 } 12179 } else if ("service".equals(cmd)) { 12180 String[] newArgs; 12181 String name; 12182 if (opti >= args.length) { 12183 name = null; 12184 newArgs = EMPTY_STRING_ARRAY; 12185 } else { 12186 name = args[opti]; 12187 opti++; 12188 newArgs = new String[args.length - opti]; 12189 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12190 args.length - opti); 12191 } 12192 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12193 pw.println("No services match: " + name); 12194 pw.println("Use -h for help."); 12195 } 12196 } else if ("package".equals(cmd)) { 12197 String[] newArgs; 12198 if (opti >= args.length) { 12199 pw.println("package: no package name specified"); 12200 pw.println("Use -h for help."); 12201 } else { 12202 dumpPackage = args[opti]; 12203 opti++; 12204 newArgs = new String[args.length - opti]; 12205 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12206 args.length - opti); 12207 args = newArgs; 12208 opti = 0; 12209 more = true; 12210 } 12211 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12212 synchronized (this) { 12213 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12214 } 12215 } else { 12216 // Dumping a single activity? 12217 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12218 pw.println("Bad activity command, or no activities match: " + cmd); 12219 pw.println("Use -h for help."); 12220 } 12221 } 12222 if (!more) { 12223 Binder.restoreCallingIdentity(origId); 12224 return; 12225 } 12226 } 12227 12228 // No piece of data specified, dump everything. 12229 synchronized (this) { 12230 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12231 pw.println(); 12232 if (dumpAll) { 12233 pw.println("-------------------------------------------------------------------------------"); 12234 } 12235 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12236 pw.println(); 12237 if (dumpAll) { 12238 pw.println("-------------------------------------------------------------------------------"); 12239 } 12240 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12241 pw.println(); 12242 if (dumpAll) { 12243 pw.println("-------------------------------------------------------------------------------"); 12244 } 12245 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12246 pw.println(); 12247 if (dumpAll) { 12248 pw.println("-------------------------------------------------------------------------------"); 12249 } 12250 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12251 pw.println(); 12252 if (dumpAll) { 12253 pw.println("-------------------------------------------------------------------------------"); 12254 } 12255 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12256 pw.println(); 12257 if (dumpAll) { 12258 pw.println("-------------------------------------------------------------------------------"); 12259 } 12260 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12261 } 12262 Binder.restoreCallingIdentity(origId); 12263 } 12264 12265 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12266 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12267 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12268 12269 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12270 dumpPackage); 12271 boolean needSep = printedAnything; 12272 12273 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12274 dumpPackage, needSep, " mFocusedActivity: "); 12275 if (printed) { 12276 printedAnything = true; 12277 needSep = false; 12278 } 12279 12280 if (dumpPackage == null) { 12281 if (needSep) { 12282 pw.println(); 12283 } 12284 needSep = true; 12285 printedAnything = true; 12286 mStackSupervisor.dump(pw, " "); 12287 } 12288 12289 if (!printedAnything) { 12290 pw.println(" (nothing)"); 12291 } 12292 } 12293 12294 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12295 int opti, boolean dumpAll, String dumpPackage) { 12296 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12297 12298 boolean printedAnything = false; 12299 12300 if (mRecentTasks.size() > 0) { 12301 boolean printedHeader = false; 12302 12303 final int N = mRecentTasks.size(); 12304 for (int i=0; i<N; i++) { 12305 TaskRecord tr = mRecentTasks.get(i); 12306 if (dumpPackage != null) { 12307 if (tr.realActivity == null || 12308 !dumpPackage.equals(tr.realActivity)) { 12309 continue; 12310 } 12311 } 12312 if (!printedHeader) { 12313 pw.println(" Recent tasks:"); 12314 printedHeader = true; 12315 printedAnything = true; 12316 } 12317 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12318 pw.println(tr); 12319 if (dumpAll) { 12320 mRecentTasks.get(i).dump(pw, " "); 12321 } 12322 } 12323 } 12324 12325 if (!printedAnything) { 12326 pw.println(" (nothing)"); 12327 } 12328 } 12329 12330 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12331 int opti, boolean dumpAll, String dumpPackage) { 12332 boolean needSep = false; 12333 boolean printedAnything = false; 12334 int numPers = 0; 12335 12336 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12337 12338 if (dumpAll) { 12339 final int NP = mProcessNames.getMap().size(); 12340 for (int ip=0; ip<NP; ip++) { 12341 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12342 final int NA = procs.size(); 12343 for (int ia=0; ia<NA; ia++) { 12344 ProcessRecord r = procs.valueAt(ia); 12345 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12346 continue; 12347 } 12348 if (!needSep) { 12349 pw.println(" All known processes:"); 12350 needSep = true; 12351 printedAnything = true; 12352 } 12353 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12354 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12355 pw.print(" "); pw.println(r); 12356 r.dump(pw, " "); 12357 if (r.persistent) { 12358 numPers++; 12359 } 12360 } 12361 } 12362 } 12363 12364 if (mIsolatedProcesses.size() > 0) { 12365 boolean printed = false; 12366 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12367 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12368 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12369 continue; 12370 } 12371 if (!printed) { 12372 if (needSep) { 12373 pw.println(); 12374 } 12375 pw.println(" Isolated process list (sorted by uid):"); 12376 printedAnything = true; 12377 printed = true; 12378 needSep = true; 12379 } 12380 pw.println(String.format("%sIsolated #%2d: %s", 12381 " ", i, r.toString())); 12382 } 12383 } 12384 12385 if (mLruProcesses.size() > 0) { 12386 if (needSep) { 12387 pw.println(); 12388 } 12389 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12390 pw.print(" total, non-act at "); 12391 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12392 pw.print(", non-svc at "); 12393 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12394 pw.println("):"); 12395 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12396 needSep = true; 12397 printedAnything = true; 12398 } 12399 12400 if (dumpAll || dumpPackage != null) { 12401 synchronized (mPidsSelfLocked) { 12402 boolean printed = false; 12403 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12404 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12405 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12406 continue; 12407 } 12408 if (!printed) { 12409 if (needSep) pw.println(); 12410 needSep = true; 12411 pw.println(" PID mappings:"); 12412 printed = true; 12413 printedAnything = true; 12414 } 12415 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12416 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12417 } 12418 } 12419 } 12420 12421 if (mForegroundProcesses.size() > 0) { 12422 synchronized (mPidsSelfLocked) { 12423 boolean printed = false; 12424 for (int i=0; i<mForegroundProcesses.size(); i++) { 12425 ProcessRecord r = mPidsSelfLocked.get( 12426 mForegroundProcesses.valueAt(i).pid); 12427 if (dumpPackage != null && (r == null 12428 || !r.pkgList.containsKey(dumpPackage))) { 12429 continue; 12430 } 12431 if (!printed) { 12432 if (needSep) pw.println(); 12433 needSep = true; 12434 pw.println(" Foreground Processes:"); 12435 printed = true; 12436 printedAnything = true; 12437 } 12438 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12439 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12440 } 12441 } 12442 } 12443 12444 if (mPersistentStartingProcesses.size() > 0) { 12445 if (needSep) pw.println(); 12446 needSep = true; 12447 printedAnything = true; 12448 pw.println(" Persisent processes that are starting:"); 12449 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12450 "Starting Norm", "Restarting PERS", dumpPackage); 12451 } 12452 12453 if (mRemovedProcesses.size() > 0) { 12454 if (needSep) pw.println(); 12455 needSep = true; 12456 printedAnything = true; 12457 pw.println(" Processes that are being removed:"); 12458 dumpProcessList(pw, this, mRemovedProcesses, " ", 12459 "Removed Norm", "Removed PERS", dumpPackage); 12460 } 12461 12462 if (mProcessesOnHold.size() > 0) { 12463 if (needSep) pw.println(); 12464 needSep = true; 12465 printedAnything = true; 12466 pw.println(" Processes that are on old until the system is ready:"); 12467 dumpProcessList(pw, this, mProcessesOnHold, " ", 12468 "OnHold Norm", "OnHold PERS", dumpPackage); 12469 } 12470 12471 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12472 12473 if (mProcessCrashTimes.getMap().size() > 0) { 12474 boolean printed = false; 12475 long now = SystemClock.uptimeMillis(); 12476 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12477 final int NP = pmap.size(); 12478 for (int ip=0; ip<NP; ip++) { 12479 String pname = pmap.keyAt(ip); 12480 SparseArray<Long> uids = pmap.valueAt(ip); 12481 final int N = uids.size(); 12482 for (int i=0; i<N; i++) { 12483 int puid = uids.keyAt(i); 12484 ProcessRecord r = mProcessNames.get(pname, puid); 12485 if (dumpPackage != null && (r == null 12486 || !r.pkgList.containsKey(dumpPackage))) { 12487 continue; 12488 } 12489 if (!printed) { 12490 if (needSep) pw.println(); 12491 needSep = true; 12492 pw.println(" Time since processes crashed:"); 12493 printed = true; 12494 printedAnything = true; 12495 } 12496 pw.print(" Process "); pw.print(pname); 12497 pw.print(" uid "); pw.print(puid); 12498 pw.print(": last crashed "); 12499 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12500 pw.println(" ago"); 12501 } 12502 } 12503 } 12504 12505 if (mBadProcesses.getMap().size() > 0) { 12506 boolean printed = false; 12507 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12508 final int NP = pmap.size(); 12509 for (int ip=0; ip<NP; ip++) { 12510 String pname = pmap.keyAt(ip); 12511 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12512 final int N = uids.size(); 12513 for (int i=0; i<N; i++) { 12514 int puid = uids.keyAt(i); 12515 ProcessRecord r = mProcessNames.get(pname, puid); 12516 if (dumpPackage != null && (r == null 12517 || !r.pkgList.containsKey(dumpPackage))) { 12518 continue; 12519 } 12520 if (!printed) { 12521 if (needSep) pw.println(); 12522 needSep = true; 12523 pw.println(" Bad processes:"); 12524 printedAnything = true; 12525 } 12526 BadProcessInfo info = uids.valueAt(i); 12527 pw.print(" Bad process "); pw.print(pname); 12528 pw.print(" uid "); pw.print(puid); 12529 pw.print(": crashed at time "); pw.println(info.time); 12530 if (info.shortMsg != null) { 12531 pw.print(" Short msg: "); pw.println(info.shortMsg); 12532 } 12533 if (info.longMsg != null) { 12534 pw.print(" Long msg: "); pw.println(info.longMsg); 12535 } 12536 if (info.stack != null) { 12537 pw.println(" Stack:"); 12538 int lastPos = 0; 12539 for (int pos=0; pos<info.stack.length(); pos++) { 12540 if (info.stack.charAt(pos) == '\n') { 12541 pw.print(" "); 12542 pw.write(info.stack, lastPos, pos-lastPos); 12543 pw.println(); 12544 lastPos = pos+1; 12545 } 12546 } 12547 if (lastPos < info.stack.length()) { 12548 pw.print(" "); 12549 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12550 pw.println(); 12551 } 12552 } 12553 } 12554 } 12555 } 12556 12557 if (dumpPackage == null) { 12558 pw.println(); 12559 needSep = false; 12560 pw.println(" mStartedUsers:"); 12561 for (int i=0; i<mStartedUsers.size(); i++) { 12562 UserStartedState uss = mStartedUsers.valueAt(i); 12563 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12564 pw.print(": "); uss.dump("", pw); 12565 } 12566 pw.print(" mStartedUserArray: ["); 12567 for (int i=0; i<mStartedUserArray.length; i++) { 12568 if (i > 0) pw.print(", "); 12569 pw.print(mStartedUserArray[i]); 12570 } 12571 pw.println("]"); 12572 pw.print(" mUserLru: ["); 12573 for (int i=0; i<mUserLru.size(); i++) { 12574 if (i > 0) pw.print(", "); 12575 pw.print(mUserLru.get(i)); 12576 } 12577 pw.println("]"); 12578 if (dumpAll) { 12579 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12580 } 12581 synchronized (mUserProfileGroupIdsSelfLocked) { 12582 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12583 pw.println(" mUserProfileGroupIds:"); 12584 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12585 pw.print(" User #"); 12586 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12587 pw.print(" -> profile #"); 12588 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12589 } 12590 } 12591 } 12592 } 12593 if (mHomeProcess != null && (dumpPackage == null 12594 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12595 if (needSep) { 12596 pw.println(); 12597 needSep = false; 12598 } 12599 pw.println(" mHomeProcess: " + mHomeProcess); 12600 } 12601 if (mPreviousProcess != null && (dumpPackage == null 12602 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12603 if (needSep) { 12604 pw.println(); 12605 needSep = false; 12606 } 12607 pw.println(" mPreviousProcess: " + mPreviousProcess); 12608 } 12609 if (dumpAll) { 12610 StringBuilder sb = new StringBuilder(128); 12611 sb.append(" mPreviousProcessVisibleTime: "); 12612 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12613 pw.println(sb); 12614 } 12615 if (mHeavyWeightProcess != null && (dumpPackage == null 12616 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12617 if (needSep) { 12618 pw.println(); 12619 needSep = false; 12620 } 12621 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12622 } 12623 if (dumpPackage == null) { 12624 pw.println(" mConfiguration: " + mConfiguration); 12625 } 12626 if (dumpAll) { 12627 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12628 if (mCompatModePackages.getPackages().size() > 0) { 12629 boolean printed = false; 12630 for (Map.Entry<String, Integer> entry 12631 : mCompatModePackages.getPackages().entrySet()) { 12632 String pkg = entry.getKey(); 12633 int mode = entry.getValue(); 12634 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12635 continue; 12636 } 12637 if (!printed) { 12638 pw.println(" mScreenCompatPackages:"); 12639 printed = true; 12640 } 12641 pw.print(" "); pw.print(pkg); pw.print(": "); 12642 pw.print(mode); pw.println(); 12643 } 12644 } 12645 } 12646 if (dumpPackage == null) { 12647 if (mSleeping || mWentToSleep || mLockScreenShown) { 12648 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12649 + " mLockScreenShown " + mLockScreenShown); 12650 } 12651 if (mShuttingDown || mRunningVoice) { 12652 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12653 } 12654 } 12655 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12656 || mOrigWaitForDebugger) { 12657 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12658 || dumpPackage.equals(mOrigDebugApp)) { 12659 if (needSep) { 12660 pw.println(); 12661 needSep = false; 12662 } 12663 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12664 + " mDebugTransient=" + mDebugTransient 12665 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12666 } 12667 } 12668 if (mOpenGlTraceApp != null) { 12669 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12670 if (needSep) { 12671 pw.println(); 12672 needSep = false; 12673 } 12674 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12675 } 12676 } 12677 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12678 || mProfileFd != null) { 12679 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12680 if (needSep) { 12681 pw.println(); 12682 needSep = false; 12683 } 12684 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12685 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12686 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12687 + mAutoStopProfiler); 12688 pw.println(" mProfileType=" + mProfileType); 12689 } 12690 } 12691 if (dumpPackage == null) { 12692 if (mAlwaysFinishActivities || mController != null) { 12693 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12694 + " mController=" + mController); 12695 } 12696 if (dumpAll) { 12697 pw.println(" Total persistent processes: " + numPers); 12698 pw.println(" mProcessesReady=" + mProcessesReady 12699 + " mSystemReady=" + mSystemReady); 12700 pw.println(" mBooting=" + mBooting 12701 + " mBooted=" + mBooted 12702 + " mFactoryTest=" + mFactoryTest); 12703 pw.print(" mLastPowerCheckRealtime="); 12704 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12705 pw.println(""); 12706 pw.print(" mLastPowerCheckUptime="); 12707 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12708 pw.println(""); 12709 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12710 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12711 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12712 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12713 + " (" + mLruProcesses.size() + " total)" 12714 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12715 + " mNumServiceProcs=" + mNumServiceProcs 12716 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12717 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12718 + " mLastMemoryLevel" + mLastMemoryLevel 12719 + " mLastNumProcesses" + mLastNumProcesses); 12720 long now = SystemClock.uptimeMillis(); 12721 pw.print(" mLastIdleTime="); 12722 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12723 pw.print(" mLowRamSinceLastIdle="); 12724 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12725 pw.println(); 12726 } 12727 } 12728 12729 if (!printedAnything) { 12730 pw.println(" (nothing)"); 12731 } 12732 } 12733 12734 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12735 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12736 if (mProcessesToGc.size() > 0) { 12737 boolean printed = false; 12738 long now = SystemClock.uptimeMillis(); 12739 for (int i=0; i<mProcessesToGc.size(); i++) { 12740 ProcessRecord proc = mProcessesToGc.get(i); 12741 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12742 continue; 12743 } 12744 if (!printed) { 12745 if (needSep) pw.println(); 12746 needSep = true; 12747 pw.println(" Processes that are waiting to GC:"); 12748 printed = true; 12749 } 12750 pw.print(" Process "); pw.println(proc); 12751 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12752 pw.print(", last gced="); 12753 pw.print(now-proc.lastRequestedGc); 12754 pw.print(" ms ago, last lowMem="); 12755 pw.print(now-proc.lastLowMemory); 12756 pw.println(" ms ago"); 12757 12758 } 12759 } 12760 return needSep; 12761 } 12762 12763 void printOomLevel(PrintWriter pw, String name, int adj) { 12764 pw.print(" "); 12765 if (adj >= 0) { 12766 pw.print(' '); 12767 if (adj < 10) pw.print(' '); 12768 } else { 12769 if (adj > -10) pw.print(' '); 12770 } 12771 pw.print(adj); 12772 pw.print(": "); 12773 pw.print(name); 12774 pw.print(" ("); 12775 pw.print(mProcessList.getMemLevel(adj)/1024); 12776 pw.println(" kB)"); 12777 } 12778 12779 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12780 int opti, boolean dumpAll) { 12781 boolean needSep = false; 12782 12783 if (mLruProcesses.size() > 0) { 12784 if (needSep) pw.println(); 12785 needSep = true; 12786 pw.println(" OOM levels:"); 12787 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12788 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12789 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12790 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12791 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12792 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12793 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12794 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12795 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12796 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12797 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12798 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12799 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12800 12801 if (needSep) pw.println(); 12802 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12803 pw.print(" total, non-act at "); 12804 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12805 pw.print(", non-svc at "); 12806 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12807 pw.println("):"); 12808 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12809 needSep = true; 12810 } 12811 12812 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12813 12814 pw.println(); 12815 pw.println(" mHomeProcess: " + mHomeProcess); 12816 pw.println(" mPreviousProcess: " + mPreviousProcess); 12817 if (mHeavyWeightProcess != null) { 12818 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12819 } 12820 12821 return true; 12822 } 12823 12824 /** 12825 * There are three ways to call this: 12826 * - no provider specified: dump all the providers 12827 * - a flattened component name that matched an existing provider was specified as the 12828 * first arg: dump that one provider 12829 * - the first arg isn't the flattened component name of an existing provider: 12830 * dump all providers whose component contains the first arg as a substring 12831 */ 12832 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12833 int opti, boolean dumpAll) { 12834 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12835 } 12836 12837 static class ItemMatcher { 12838 ArrayList<ComponentName> components; 12839 ArrayList<String> strings; 12840 ArrayList<Integer> objects; 12841 boolean all; 12842 12843 ItemMatcher() { 12844 all = true; 12845 } 12846 12847 void build(String name) { 12848 ComponentName componentName = ComponentName.unflattenFromString(name); 12849 if (componentName != null) { 12850 if (components == null) { 12851 components = new ArrayList<ComponentName>(); 12852 } 12853 components.add(componentName); 12854 all = false; 12855 } else { 12856 int objectId = 0; 12857 // Not a '/' separated full component name; maybe an object ID? 12858 try { 12859 objectId = Integer.parseInt(name, 16); 12860 if (objects == null) { 12861 objects = new ArrayList<Integer>(); 12862 } 12863 objects.add(objectId); 12864 all = false; 12865 } catch (RuntimeException e) { 12866 // Not an integer; just do string match. 12867 if (strings == null) { 12868 strings = new ArrayList<String>(); 12869 } 12870 strings.add(name); 12871 all = false; 12872 } 12873 } 12874 } 12875 12876 int build(String[] args, int opti) { 12877 for (; opti<args.length; opti++) { 12878 String name = args[opti]; 12879 if ("--".equals(name)) { 12880 return opti+1; 12881 } 12882 build(name); 12883 } 12884 return opti; 12885 } 12886 12887 boolean match(Object object, ComponentName comp) { 12888 if (all) { 12889 return true; 12890 } 12891 if (components != null) { 12892 for (int i=0; i<components.size(); i++) { 12893 if (components.get(i).equals(comp)) { 12894 return true; 12895 } 12896 } 12897 } 12898 if (objects != null) { 12899 for (int i=0; i<objects.size(); i++) { 12900 if (System.identityHashCode(object) == objects.get(i)) { 12901 return true; 12902 } 12903 } 12904 } 12905 if (strings != null) { 12906 String flat = comp.flattenToString(); 12907 for (int i=0; i<strings.size(); i++) { 12908 if (flat.contains(strings.get(i))) { 12909 return true; 12910 } 12911 } 12912 } 12913 return false; 12914 } 12915 } 12916 12917 /** 12918 * There are three things that cmd can be: 12919 * - a flattened component name that matches an existing activity 12920 * - the cmd arg isn't the flattened component name of an existing activity: 12921 * dump all activity whose component contains the cmd as a substring 12922 * - A hex number of the ActivityRecord object instance. 12923 */ 12924 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12925 int opti, boolean dumpAll) { 12926 ArrayList<ActivityRecord> activities; 12927 12928 synchronized (this) { 12929 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12930 } 12931 12932 if (activities.size() <= 0) { 12933 return false; 12934 } 12935 12936 String[] newArgs = new String[args.length - opti]; 12937 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12938 12939 TaskRecord lastTask = null; 12940 boolean needSep = false; 12941 for (int i=activities.size()-1; i>=0; i--) { 12942 ActivityRecord r = activities.get(i); 12943 if (needSep) { 12944 pw.println(); 12945 } 12946 needSep = true; 12947 synchronized (this) { 12948 if (lastTask != r.task) { 12949 lastTask = r.task; 12950 pw.print("TASK "); pw.print(lastTask.affinity); 12951 pw.print(" id="); pw.println(lastTask.taskId); 12952 if (dumpAll) { 12953 lastTask.dump(pw, " "); 12954 } 12955 } 12956 } 12957 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12958 } 12959 return true; 12960 } 12961 12962 /** 12963 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12964 * there is a thread associated with the activity. 12965 */ 12966 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12967 final ActivityRecord r, String[] args, boolean dumpAll) { 12968 String innerPrefix = prefix + " "; 12969 synchronized (this) { 12970 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12971 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12972 pw.print(" pid="); 12973 if (r.app != null) pw.println(r.app.pid); 12974 else pw.println("(not running)"); 12975 if (dumpAll) { 12976 r.dump(pw, innerPrefix); 12977 } 12978 } 12979 if (r.app != null && r.app.thread != null) { 12980 // flush anything that is already in the PrintWriter since the thread is going 12981 // to write to the file descriptor directly 12982 pw.flush(); 12983 try { 12984 TransferPipe tp = new TransferPipe(); 12985 try { 12986 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12987 r.appToken, innerPrefix, args); 12988 tp.go(fd); 12989 } finally { 12990 tp.kill(); 12991 } 12992 } catch (IOException e) { 12993 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12994 } catch (RemoteException e) { 12995 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12996 } 12997 } 12998 } 12999 13000 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13001 int opti, boolean dumpAll, String dumpPackage) { 13002 boolean needSep = false; 13003 boolean onlyHistory = false; 13004 boolean printedAnything = false; 13005 13006 if ("history".equals(dumpPackage)) { 13007 if (opti < args.length && "-s".equals(args[opti])) { 13008 dumpAll = false; 13009 } 13010 onlyHistory = true; 13011 dumpPackage = null; 13012 } 13013 13014 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13015 if (!onlyHistory && dumpAll) { 13016 if (mRegisteredReceivers.size() > 0) { 13017 boolean printed = false; 13018 Iterator it = mRegisteredReceivers.values().iterator(); 13019 while (it.hasNext()) { 13020 ReceiverList r = (ReceiverList)it.next(); 13021 if (dumpPackage != null && (r.app == null || 13022 !dumpPackage.equals(r.app.info.packageName))) { 13023 continue; 13024 } 13025 if (!printed) { 13026 pw.println(" Registered Receivers:"); 13027 needSep = true; 13028 printed = true; 13029 printedAnything = true; 13030 } 13031 pw.print(" * "); pw.println(r); 13032 r.dump(pw, " "); 13033 } 13034 } 13035 13036 if (mReceiverResolver.dump(pw, needSep ? 13037 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13038 " ", dumpPackage, false)) { 13039 needSep = true; 13040 printedAnything = true; 13041 } 13042 } 13043 13044 for (BroadcastQueue q : mBroadcastQueues) { 13045 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13046 printedAnything |= needSep; 13047 } 13048 13049 needSep = true; 13050 13051 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13052 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13053 if (needSep) { 13054 pw.println(); 13055 } 13056 needSep = true; 13057 printedAnything = true; 13058 pw.print(" Sticky broadcasts for user "); 13059 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13060 StringBuilder sb = new StringBuilder(128); 13061 for (Map.Entry<String, ArrayList<Intent>> ent 13062 : mStickyBroadcasts.valueAt(user).entrySet()) { 13063 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13064 if (dumpAll) { 13065 pw.println(":"); 13066 ArrayList<Intent> intents = ent.getValue(); 13067 final int N = intents.size(); 13068 for (int i=0; i<N; i++) { 13069 sb.setLength(0); 13070 sb.append(" Intent: "); 13071 intents.get(i).toShortString(sb, false, true, false, false); 13072 pw.println(sb.toString()); 13073 Bundle bundle = intents.get(i).getExtras(); 13074 if (bundle != null) { 13075 pw.print(" "); 13076 pw.println(bundle.toString()); 13077 } 13078 } 13079 } else { 13080 pw.println(""); 13081 } 13082 } 13083 } 13084 } 13085 13086 if (!onlyHistory && dumpAll) { 13087 pw.println(); 13088 for (BroadcastQueue queue : mBroadcastQueues) { 13089 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13090 + queue.mBroadcastsScheduled); 13091 } 13092 pw.println(" mHandler:"); 13093 mHandler.dump(new PrintWriterPrinter(pw), " "); 13094 needSep = true; 13095 printedAnything = true; 13096 } 13097 13098 if (!printedAnything) { 13099 pw.println(" (nothing)"); 13100 } 13101 } 13102 13103 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13104 int opti, boolean dumpAll, String dumpPackage) { 13105 boolean needSep; 13106 boolean printedAnything = false; 13107 13108 ItemMatcher matcher = new ItemMatcher(); 13109 matcher.build(args, opti); 13110 13111 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13112 13113 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13114 printedAnything |= needSep; 13115 13116 if (mLaunchingProviders.size() > 0) { 13117 boolean printed = false; 13118 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13119 ContentProviderRecord r = mLaunchingProviders.get(i); 13120 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13121 continue; 13122 } 13123 if (!printed) { 13124 if (needSep) pw.println(); 13125 needSep = true; 13126 pw.println(" Launching content providers:"); 13127 printed = true; 13128 printedAnything = true; 13129 } 13130 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13131 pw.println(r); 13132 } 13133 } 13134 13135 if (mGrantedUriPermissions.size() > 0) { 13136 boolean printed = false; 13137 int dumpUid = -2; 13138 if (dumpPackage != null) { 13139 try { 13140 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13141 } catch (NameNotFoundException e) { 13142 dumpUid = -1; 13143 } 13144 } 13145 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13146 int uid = mGrantedUriPermissions.keyAt(i); 13147 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13148 continue; 13149 } 13150 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13151 if (!printed) { 13152 if (needSep) pw.println(); 13153 needSep = true; 13154 pw.println(" Granted Uri Permissions:"); 13155 printed = true; 13156 printedAnything = true; 13157 } 13158 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13159 for (UriPermission perm : perms.values()) { 13160 pw.print(" "); pw.println(perm); 13161 if (dumpAll) { 13162 perm.dump(pw, " "); 13163 } 13164 } 13165 } 13166 } 13167 13168 if (!printedAnything) { 13169 pw.println(" (nothing)"); 13170 } 13171 } 13172 13173 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13174 int opti, boolean dumpAll, String dumpPackage) { 13175 boolean printed = false; 13176 13177 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13178 13179 if (mIntentSenderRecords.size() > 0) { 13180 Iterator<WeakReference<PendingIntentRecord>> it 13181 = mIntentSenderRecords.values().iterator(); 13182 while (it.hasNext()) { 13183 WeakReference<PendingIntentRecord> ref = it.next(); 13184 PendingIntentRecord rec = ref != null ? ref.get(): null; 13185 if (dumpPackage != null && (rec == null 13186 || !dumpPackage.equals(rec.key.packageName))) { 13187 continue; 13188 } 13189 printed = true; 13190 if (rec != null) { 13191 pw.print(" * "); pw.println(rec); 13192 if (dumpAll) { 13193 rec.dump(pw, " "); 13194 } 13195 } else { 13196 pw.print(" * "); pw.println(ref); 13197 } 13198 } 13199 } 13200 13201 if (!printed) { 13202 pw.println(" (nothing)"); 13203 } 13204 } 13205 13206 private static final int dumpProcessList(PrintWriter pw, 13207 ActivityManagerService service, List list, 13208 String prefix, String normalLabel, String persistentLabel, 13209 String dumpPackage) { 13210 int numPers = 0; 13211 final int N = list.size()-1; 13212 for (int i=N; i>=0; i--) { 13213 ProcessRecord r = (ProcessRecord)list.get(i); 13214 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13215 continue; 13216 } 13217 pw.println(String.format("%s%s #%2d: %s", 13218 prefix, (r.persistent ? persistentLabel : normalLabel), 13219 i, r.toString())); 13220 if (r.persistent) { 13221 numPers++; 13222 } 13223 } 13224 return numPers; 13225 } 13226 13227 private static final boolean dumpProcessOomList(PrintWriter pw, 13228 ActivityManagerService service, List<ProcessRecord> origList, 13229 String prefix, String normalLabel, String persistentLabel, 13230 boolean inclDetails, String dumpPackage) { 13231 13232 ArrayList<Pair<ProcessRecord, Integer>> list 13233 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13234 for (int i=0; i<origList.size(); i++) { 13235 ProcessRecord r = origList.get(i); 13236 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13237 continue; 13238 } 13239 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13240 } 13241 13242 if (list.size() <= 0) { 13243 return false; 13244 } 13245 13246 Comparator<Pair<ProcessRecord, Integer>> comparator 13247 = new Comparator<Pair<ProcessRecord, Integer>>() { 13248 @Override 13249 public int compare(Pair<ProcessRecord, Integer> object1, 13250 Pair<ProcessRecord, Integer> object2) { 13251 if (object1.first.setAdj != object2.first.setAdj) { 13252 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13253 } 13254 if (object1.second.intValue() != object2.second.intValue()) { 13255 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13256 } 13257 return 0; 13258 } 13259 }; 13260 13261 Collections.sort(list, comparator); 13262 13263 final long curRealtime = SystemClock.elapsedRealtime(); 13264 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13265 final long curUptime = SystemClock.uptimeMillis(); 13266 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13267 13268 for (int i=list.size()-1; i>=0; i--) { 13269 ProcessRecord r = list.get(i).first; 13270 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13271 char schedGroup; 13272 switch (r.setSchedGroup) { 13273 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13274 schedGroup = 'B'; 13275 break; 13276 case Process.THREAD_GROUP_DEFAULT: 13277 schedGroup = 'F'; 13278 break; 13279 default: 13280 schedGroup = '?'; 13281 break; 13282 } 13283 char foreground; 13284 if (r.foregroundActivities) { 13285 foreground = 'A'; 13286 } else if (r.foregroundServices) { 13287 foreground = 'S'; 13288 } else { 13289 foreground = ' '; 13290 } 13291 String procState = ProcessList.makeProcStateString(r.curProcState); 13292 pw.print(prefix); 13293 pw.print(r.persistent ? persistentLabel : normalLabel); 13294 pw.print(" #"); 13295 int num = (origList.size()-1)-list.get(i).second; 13296 if (num < 10) pw.print(' '); 13297 pw.print(num); 13298 pw.print(": "); 13299 pw.print(oomAdj); 13300 pw.print(' '); 13301 pw.print(schedGroup); 13302 pw.print('/'); 13303 pw.print(foreground); 13304 pw.print('/'); 13305 pw.print(procState); 13306 pw.print(" trm:"); 13307 if (r.trimMemoryLevel < 10) pw.print(' '); 13308 pw.print(r.trimMemoryLevel); 13309 pw.print(' '); 13310 pw.print(r.toShortString()); 13311 pw.print(" ("); 13312 pw.print(r.adjType); 13313 pw.println(')'); 13314 if (r.adjSource != null || r.adjTarget != null) { 13315 pw.print(prefix); 13316 pw.print(" "); 13317 if (r.adjTarget instanceof ComponentName) { 13318 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13319 } else if (r.adjTarget != null) { 13320 pw.print(r.adjTarget.toString()); 13321 } else { 13322 pw.print("{null}"); 13323 } 13324 pw.print("<="); 13325 if (r.adjSource instanceof ProcessRecord) { 13326 pw.print("Proc{"); 13327 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13328 pw.println("}"); 13329 } else if (r.adjSource != null) { 13330 pw.println(r.adjSource.toString()); 13331 } else { 13332 pw.println("{null}"); 13333 } 13334 } 13335 if (inclDetails) { 13336 pw.print(prefix); 13337 pw.print(" "); 13338 pw.print("oom: max="); pw.print(r.maxAdj); 13339 pw.print(" curRaw="); pw.print(r.curRawAdj); 13340 pw.print(" setRaw="); pw.print(r.setRawAdj); 13341 pw.print(" cur="); pw.print(r.curAdj); 13342 pw.print(" set="); pw.println(r.setAdj); 13343 pw.print(prefix); 13344 pw.print(" "); 13345 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13346 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13347 pw.print(" lastPss="); pw.print(r.lastPss); 13348 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13349 pw.print(prefix); 13350 pw.print(" "); 13351 pw.print("cached="); pw.print(r.cached); 13352 pw.print(" empty="); pw.print(r.empty); 13353 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13354 13355 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13356 if (r.lastWakeTime != 0) { 13357 long wtime; 13358 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13359 synchronized (stats) { 13360 wtime = stats.getProcessWakeTime(r.info.uid, 13361 r.pid, curRealtime); 13362 } 13363 long timeUsed = wtime - r.lastWakeTime; 13364 pw.print(prefix); 13365 pw.print(" "); 13366 pw.print("keep awake over "); 13367 TimeUtils.formatDuration(realtimeSince, pw); 13368 pw.print(" used "); 13369 TimeUtils.formatDuration(timeUsed, pw); 13370 pw.print(" ("); 13371 pw.print((timeUsed*100)/realtimeSince); 13372 pw.println("%)"); 13373 } 13374 if (r.lastCpuTime != 0) { 13375 long timeUsed = r.curCpuTime - r.lastCpuTime; 13376 pw.print(prefix); 13377 pw.print(" "); 13378 pw.print("run cpu over "); 13379 TimeUtils.formatDuration(uptimeSince, pw); 13380 pw.print(" used "); 13381 TimeUtils.formatDuration(timeUsed, pw); 13382 pw.print(" ("); 13383 pw.print((timeUsed*100)/uptimeSince); 13384 pw.println("%)"); 13385 } 13386 } 13387 } 13388 } 13389 return true; 13390 } 13391 13392 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13393 ArrayList<ProcessRecord> procs; 13394 synchronized (this) { 13395 if (args != null && args.length > start 13396 && args[start].charAt(0) != '-') { 13397 procs = new ArrayList<ProcessRecord>(); 13398 int pid = -1; 13399 try { 13400 pid = Integer.parseInt(args[start]); 13401 } catch (NumberFormatException e) { 13402 } 13403 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13404 ProcessRecord proc = mLruProcesses.get(i); 13405 if (proc.pid == pid) { 13406 procs.add(proc); 13407 } else if (proc.processName.equals(args[start])) { 13408 procs.add(proc); 13409 } 13410 } 13411 if (procs.size() <= 0) { 13412 return null; 13413 } 13414 } else { 13415 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13416 } 13417 } 13418 return procs; 13419 } 13420 13421 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13422 PrintWriter pw, String[] args) { 13423 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13424 if (procs == null) { 13425 pw.println("No process found for: " + args[0]); 13426 return; 13427 } 13428 13429 long uptime = SystemClock.uptimeMillis(); 13430 long realtime = SystemClock.elapsedRealtime(); 13431 pw.println("Applications Graphics Acceleration Info:"); 13432 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13433 13434 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13435 ProcessRecord r = procs.get(i); 13436 if (r.thread != null) { 13437 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13438 pw.flush(); 13439 try { 13440 TransferPipe tp = new TransferPipe(); 13441 try { 13442 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13443 tp.go(fd); 13444 } finally { 13445 tp.kill(); 13446 } 13447 } catch (IOException e) { 13448 pw.println("Failure while dumping the app: " + r); 13449 pw.flush(); 13450 } catch (RemoteException e) { 13451 pw.println("Got a RemoteException while dumping the app " + r); 13452 pw.flush(); 13453 } 13454 } 13455 } 13456 } 13457 13458 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13459 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13460 if (procs == null) { 13461 pw.println("No process found for: " + args[0]); 13462 return; 13463 } 13464 13465 pw.println("Applications Database Info:"); 13466 13467 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13468 ProcessRecord r = procs.get(i); 13469 if (r.thread != null) { 13470 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13471 pw.flush(); 13472 try { 13473 TransferPipe tp = new TransferPipe(); 13474 try { 13475 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13476 tp.go(fd); 13477 } finally { 13478 tp.kill(); 13479 } 13480 } catch (IOException e) { 13481 pw.println("Failure while dumping the app: " + r); 13482 pw.flush(); 13483 } catch (RemoteException e) { 13484 pw.println("Got a RemoteException while dumping the app " + r); 13485 pw.flush(); 13486 } 13487 } 13488 } 13489 } 13490 13491 final static class MemItem { 13492 final boolean isProc; 13493 final String label; 13494 final String shortLabel; 13495 final long pss; 13496 final int id; 13497 final boolean hasActivities; 13498 ArrayList<MemItem> subitems; 13499 13500 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13501 boolean _hasActivities) { 13502 isProc = true; 13503 label = _label; 13504 shortLabel = _shortLabel; 13505 pss = _pss; 13506 id = _id; 13507 hasActivities = _hasActivities; 13508 } 13509 13510 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13511 isProc = false; 13512 label = _label; 13513 shortLabel = _shortLabel; 13514 pss = _pss; 13515 id = _id; 13516 hasActivities = false; 13517 } 13518 } 13519 13520 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13521 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13522 if (sort && !isCompact) { 13523 Collections.sort(items, new Comparator<MemItem>() { 13524 @Override 13525 public int compare(MemItem lhs, MemItem rhs) { 13526 if (lhs.pss < rhs.pss) { 13527 return 1; 13528 } else if (lhs.pss > rhs.pss) { 13529 return -1; 13530 } 13531 return 0; 13532 } 13533 }); 13534 } 13535 13536 for (int i=0; i<items.size(); i++) { 13537 MemItem mi = items.get(i); 13538 if (!isCompact) { 13539 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13540 } else if (mi.isProc) { 13541 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13542 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13543 pw.println(mi.hasActivities ? ",a" : ",e"); 13544 } else { 13545 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13546 pw.println(mi.pss); 13547 } 13548 if (mi.subitems != null) { 13549 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13550 true, isCompact); 13551 } 13552 } 13553 } 13554 13555 // These are in KB. 13556 static final long[] DUMP_MEM_BUCKETS = new long[] { 13557 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13558 120*1024, 160*1024, 200*1024, 13559 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13560 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13561 }; 13562 13563 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13564 boolean stackLike) { 13565 int start = label.lastIndexOf('.'); 13566 if (start >= 0) start++; 13567 else start = 0; 13568 int end = label.length(); 13569 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13570 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13571 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13572 out.append(bucket); 13573 out.append(stackLike ? "MB." : "MB "); 13574 out.append(label, start, end); 13575 return; 13576 } 13577 } 13578 out.append(memKB/1024); 13579 out.append(stackLike ? "MB." : "MB "); 13580 out.append(label, start, end); 13581 } 13582 13583 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13584 ProcessList.NATIVE_ADJ, 13585 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13586 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13587 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13588 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13589 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13590 }; 13591 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13592 "Native", 13593 "System", "Persistent", "Foreground", 13594 "Visible", "Perceptible", 13595 "Heavy Weight", "Backup", 13596 "A Services", "Home", 13597 "Previous", "B Services", "Cached" 13598 }; 13599 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13600 "native", 13601 "sys", "pers", "fore", 13602 "vis", "percept", 13603 "heavy", "backup", 13604 "servicea", "home", 13605 "prev", "serviceb", "cached" 13606 }; 13607 13608 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13609 long realtime, boolean isCheckinRequest, boolean isCompact) { 13610 if (isCheckinRequest || isCompact) { 13611 // short checkin version 13612 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13613 } else { 13614 pw.println("Applications Memory Usage (kB):"); 13615 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13616 } 13617 } 13618 13619 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13620 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13621 boolean dumpDetails = false; 13622 boolean dumpFullDetails = false; 13623 boolean dumpDalvik = false; 13624 boolean oomOnly = false; 13625 boolean isCompact = false; 13626 boolean localOnly = false; 13627 13628 int opti = 0; 13629 while (opti < args.length) { 13630 String opt = args[opti]; 13631 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13632 break; 13633 } 13634 opti++; 13635 if ("-a".equals(opt)) { 13636 dumpDetails = true; 13637 dumpFullDetails = true; 13638 dumpDalvik = true; 13639 } else if ("-d".equals(opt)) { 13640 dumpDalvik = true; 13641 } else if ("-c".equals(opt)) { 13642 isCompact = true; 13643 } else if ("--oom".equals(opt)) { 13644 oomOnly = true; 13645 } else if ("--local".equals(opt)) { 13646 localOnly = true; 13647 } else if ("-h".equals(opt)) { 13648 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13649 pw.println(" -a: include all available information for each process."); 13650 pw.println(" -d: include dalvik details when dumping process details."); 13651 pw.println(" -c: dump in a compact machine-parseable representation."); 13652 pw.println(" --oom: only show processes organized by oom adj."); 13653 pw.println(" --local: only collect details locally, don't call process."); 13654 pw.println("If [process] is specified it can be the name or "); 13655 pw.println("pid of a specific process to dump."); 13656 return; 13657 } else { 13658 pw.println("Unknown argument: " + opt + "; use -h for help"); 13659 } 13660 } 13661 13662 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13663 long uptime = SystemClock.uptimeMillis(); 13664 long realtime = SystemClock.elapsedRealtime(); 13665 final long[] tmpLong = new long[1]; 13666 13667 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13668 if (procs == null) { 13669 // No Java processes. Maybe they want to print a native process. 13670 if (args != null && args.length > opti 13671 && args[opti].charAt(0) != '-') { 13672 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13673 = new ArrayList<ProcessCpuTracker.Stats>(); 13674 updateCpuStatsNow(); 13675 int findPid = -1; 13676 try { 13677 findPid = Integer.parseInt(args[opti]); 13678 } catch (NumberFormatException e) { 13679 } 13680 synchronized (mProcessCpuThread) { 13681 final int N = mProcessCpuTracker.countStats(); 13682 for (int i=0; i<N; i++) { 13683 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13684 if (st.pid == findPid || (st.baseName != null 13685 && st.baseName.equals(args[opti]))) { 13686 nativeProcs.add(st); 13687 } 13688 } 13689 } 13690 if (nativeProcs.size() > 0) { 13691 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13692 isCompact); 13693 Debug.MemoryInfo mi = null; 13694 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13695 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13696 final int pid = r.pid; 13697 if (!isCheckinRequest && dumpDetails) { 13698 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13699 } 13700 if (mi == null) { 13701 mi = new Debug.MemoryInfo(); 13702 } 13703 if (dumpDetails || (!brief && !oomOnly)) { 13704 Debug.getMemoryInfo(pid, mi); 13705 } else { 13706 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13707 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13708 } 13709 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13710 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13711 if (isCheckinRequest) { 13712 pw.println(); 13713 } 13714 } 13715 return; 13716 } 13717 } 13718 pw.println("No process found for: " + args[opti]); 13719 return; 13720 } 13721 13722 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13723 dumpDetails = true; 13724 } 13725 13726 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13727 13728 String[] innerArgs = new String[args.length-opti]; 13729 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13730 13731 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13732 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13733 long nativePss=0, dalvikPss=0, otherPss=0; 13734 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13735 13736 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13737 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13738 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13739 13740 long totalPss = 0; 13741 long cachedPss = 0; 13742 13743 Debug.MemoryInfo mi = null; 13744 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13745 final ProcessRecord r = procs.get(i); 13746 final IApplicationThread thread; 13747 final int pid; 13748 final int oomAdj; 13749 final boolean hasActivities; 13750 synchronized (this) { 13751 thread = r.thread; 13752 pid = r.pid; 13753 oomAdj = r.getSetAdjWithServices(); 13754 hasActivities = r.activities.size() > 0; 13755 } 13756 if (thread != null) { 13757 if (!isCheckinRequest && dumpDetails) { 13758 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13759 } 13760 if (mi == null) { 13761 mi = new Debug.MemoryInfo(); 13762 } 13763 if (dumpDetails || (!brief && !oomOnly)) { 13764 Debug.getMemoryInfo(pid, mi); 13765 } else { 13766 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13767 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13768 } 13769 if (dumpDetails) { 13770 if (localOnly) { 13771 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13772 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13773 if (isCheckinRequest) { 13774 pw.println(); 13775 } 13776 } else { 13777 try { 13778 pw.flush(); 13779 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13780 dumpDalvik, innerArgs); 13781 } catch (RemoteException e) { 13782 if (!isCheckinRequest) { 13783 pw.println("Got RemoteException!"); 13784 pw.flush(); 13785 } 13786 } 13787 } 13788 } 13789 13790 final long myTotalPss = mi.getTotalPss(); 13791 final long myTotalUss = mi.getTotalUss(); 13792 13793 synchronized (this) { 13794 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13795 // Record this for posterity if the process has been stable. 13796 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13797 } 13798 } 13799 13800 if (!isCheckinRequest && mi != null) { 13801 totalPss += myTotalPss; 13802 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13803 (hasActivities ? " / activities)" : ")"), 13804 r.processName, myTotalPss, pid, hasActivities); 13805 procMems.add(pssItem); 13806 procMemsMap.put(pid, pssItem); 13807 13808 nativePss += mi.nativePss; 13809 dalvikPss += mi.dalvikPss; 13810 otherPss += mi.otherPss; 13811 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13812 long mem = mi.getOtherPss(j); 13813 miscPss[j] += mem; 13814 otherPss -= mem; 13815 } 13816 13817 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13818 cachedPss += myTotalPss; 13819 } 13820 13821 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13822 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13823 || oomIndex == (oomPss.length-1)) { 13824 oomPss[oomIndex] += myTotalPss; 13825 if (oomProcs[oomIndex] == null) { 13826 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13827 } 13828 oomProcs[oomIndex].add(pssItem); 13829 break; 13830 } 13831 } 13832 } 13833 } 13834 } 13835 13836 long nativeProcTotalPss = 0; 13837 13838 if (!isCheckinRequest && procs.size() > 1) { 13839 // If we are showing aggregations, also look for native processes to 13840 // include so that our aggregations are more accurate. 13841 updateCpuStatsNow(); 13842 synchronized (mProcessCpuThread) { 13843 final int N = mProcessCpuTracker.countStats(); 13844 for (int i=0; i<N; i++) { 13845 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13846 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13847 if (mi == null) { 13848 mi = new Debug.MemoryInfo(); 13849 } 13850 if (!brief && !oomOnly) { 13851 Debug.getMemoryInfo(st.pid, mi); 13852 } else { 13853 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13854 mi.nativePrivateDirty = (int)tmpLong[0]; 13855 } 13856 13857 final long myTotalPss = mi.getTotalPss(); 13858 totalPss += myTotalPss; 13859 nativeProcTotalPss += myTotalPss; 13860 13861 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13862 st.name, myTotalPss, st.pid, false); 13863 procMems.add(pssItem); 13864 13865 nativePss += mi.nativePss; 13866 dalvikPss += mi.dalvikPss; 13867 otherPss += mi.otherPss; 13868 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13869 long mem = mi.getOtherPss(j); 13870 miscPss[j] += mem; 13871 otherPss -= mem; 13872 } 13873 oomPss[0] += myTotalPss; 13874 if (oomProcs[0] == null) { 13875 oomProcs[0] = new ArrayList<MemItem>(); 13876 } 13877 oomProcs[0].add(pssItem); 13878 } 13879 } 13880 } 13881 13882 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13883 13884 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13885 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13886 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13887 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13888 String label = Debug.MemoryInfo.getOtherLabel(j); 13889 catMems.add(new MemItem(label, label, miscPss[j], j)); 13890 } 13891 13892 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13893 for (int j=0; j<oomPss.length; j++) { 13894 if (oomPss[j] != 0) { 13895 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13896 : DUMP_MEM_OOM_LABEL[j]; 13897 MemItem item = new MemItem(label, label, oomPss[j], 13898 DUMP_MEM_OOM_ADJ[j]); 13899 item.subitems = oomProcs[j]; 13900 oomMems.add(item); 13901 } 13902 } 13903 13904 if (!brief && !oomOnly && !isCompact) { 13905 pw.println(); 13906 pw.println("Total PSS by process:"); 13907 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13908 pw.println(); 13909 } 13910 if (!isCompact) { 13911 pw.println("Total PSS by OOM adjustment:"); 13912 } 13913 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13914 if (!brief && !oomOnly) { 13915 PrintWriter out = categoryPw != null ? categoryPw : pw; 13916 if (!isCompact) { 13917 out.println(); 13918 out.println("Total PSS by category:"); 13919 } 13920 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13921 } 13922 if (!isCompact) { 13923 pw.println(); 13924 } 13925 MemInfoReader memInfo = new MemInfoReader(); 13926 memInfo.readMemInfo(); 13927 if (nativeProcTotalPss > 0) { 13928 synchronized (this) { 13929 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13930 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13931 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13932 nativeProcTotalPss); 13933 } 13934 } 13935 if (!brief) { 13936 if (!isCompact) { 13937 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13938 pw.print(" kB (status "); 13939 switch (mLastMemoryLevel) { 13940 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13941 pw.println("normal)"); 13942 break; 13943 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13944 pw.println("moderate)"); 13945 break; 13946 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13947 pw.println("low)"); 13948 break; 13949 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13950 pw.println("critical)"); 13951 break; 13952 default: 13953 pw.print(mLastMemoryLevel); 13954 pw.println(")"); 13955 break; 13956 } 13957 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13958 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13959 pw.print(cachedPss); pw.print(" cached pss + "); 13960 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13961 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13962 } else { 13963 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13964 pw.print(cachedPss + memInfo.getCachedSizeKb() 13965 + memInfo.getFreeSizeKb()); pw.print(","); 13966 pw.println(totalPss - cachedPss); 13967 } 13968 } 13969 if (!isCompact) { 13970 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13971 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13972 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13973 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13974 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13975 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13976 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13977 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13978 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13979 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13980 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13981 } 13982 if (!brief) { 13983 if (memInfo.getZramTotalSizeKb() != 0) { 13984 if (!isCompact) { 13985 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13986 pw.print(" kB physical used for "); 13987 pw.print(memInfo.getSwapTotalSizeKb() 13988 - memInfo.getSwapFreeSizeKb()); 13989 pw.print(" kB in swap ("); 13990 pw.print(memInfo.getSwapTotalSizeKb()); 13991 pw.println(" kB total swap)"); 13992 } else { 13993 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13994 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13995 pw.println(memInfo.getSwapFreeSizeKb()); 13996 } 13997 } 13998 final int[] SINGLE_LONG_FORMAT = new int[] { 13999 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14000 }; 14001 long[] longOut = new long[1]; 14002 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14003 SINGLE_LONG_FORMAT, null, longOut, null); 14004 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14005 longOut[0] = 0; 14006 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14007 SINGLE_LONG_FORMAT, null, longOut, null); 14008 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14009 longOut[0] = 0; 14010 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14011 SINGLE_LONG_FORMAT, null, longOut, null); 14012 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14013 longOut[0] = 0; 14014 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14015 SINGLE_LONG_FORMAT, null, longOut, null); 14016 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14017 if (!isCompact) { 14018 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14019 pw.print(" KSM: "); pw.print(sharing); 14020 pw.print(" kB saved from shared "); 14021 pw.print(shared); pw.println(" kB"); 14022 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14023 pw.print(voltile); pw.println(" kB volatile"); 14024 } 14025 pw.print(" Tuning: "); 14026 pw.print(ActivityManager.staticGetMemoryClass()); 14027 pw.print(" (large "); 14028 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14029 pw.print("), oom "); 14030 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14031 pw.print(" kB"); 14032 pw.print(", restore limit "); 14033 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14034 pw.print(" kB"); 14035 if (ActivityManager.isLowRamDeviceStatic()) { 14036 pw.print(" (low-ram)"); 14037 } 14038 if (ActivityManager.isHighEndGfx()) { 14039 pw.print(" (high-end-gfx)"); 14040 } 14041 pw.println(); 14042 } else { 14043 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14044 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14045 pw.println(voltile); 14046 pw.print("tuning,"); 14047 pw.print(ActivityManager.staticGetMemoryClass()); 14048 pw.print(','); 14049 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14050 pw.print(','); 14051 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14052 if (ActivityManager.isLowRamDeviceStatic()) { 14053 pw.print(",low-ram"); 14054 } 14055 if (ActivityManager.isHighEndGfx()) { 14056 pw.print(",high-end-gfx"); 14057 } 14058 pw.println(); 14059 } 14060 } 14061 } 14062 } 14063 14064 /** 14065 * Searches array of arguments for the specified string 14066 * @param args array of argument strings 14067 * @param value value to search for 14068 * @return true if the value is contained in the array 14069 */ 14070 private static boolean scanArgs(String[] args, String value) { 14071 if (args != null) { 14072 for (String arg : args) { 14073 if (value.equals(arg)) { 14074 return true; 14075 } 14076 } 14077 } 14078 return false; 14079 } 14080 14081 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14082 ContentProviderRecord cpr, boolean always) { 14083 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14084 14085 if (!inLaunching || always) { 14086 synchronized (cpr) { 14087 cpr.launchingApp = null; 14088 cpr.notifyAll(); 14089 } 14090 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14091 String names[] = cpr.info.authority.split(";"); 14092 for (int j = 0; j < names.length; j++) { 14093 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14094 } 14095 } 14096 14097 for (int i=0; i<cpr.connections.size(); i++) { 14098 ContentProviderConnection conn = cpr.connections.get(i); 14099 if (conn.waiting) { 14100 // If this connection is waiting for the provider, then we don't 14101 // need to mess with its process unless we are always removing 14102 // or for some reason the provider is not currently launching. 14103 if (inLaunching && !always) { 14104 continue; 14105 } 14106 } 14107 ProcessRecord capp = conn.client; 14108 conn.dead = true; 14109 if (conn.stableCount > 0) { 14110 if (!capp.persistent && capp.thread != null 14111 && capp.pid != 0 14112 && capp.pid != MY_PID) { 14113 capp.kill("depends on provider " 14114 + cpr.name.flattenToShortString() 14115 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14116 } 14117 } else if (capp.thread != null && conn.provider.provider != null) { 14118 try { 14119 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14120 } catch (RemoteException e) { 14121 } 14122 // In the protocol here, we don't expect the client to correctly 14123 // clean up this connection, we'll just remove it. 14124 cpr.connections.remove(i); 14125 conn.client.conProviders.remove(conn); 14126 } 14127 } 14128 14129 if (inLaunching && always) { 14130 mLaunchingProviders.remove(cpr); 14131 } 14132 return inLaunching; 14133 } 14134 14135 /** 14136 * Main code for cleaning up a process when it has gone away. This is 14137 * called both as a result of the process dying, or directly when stopping 14138 * a process when running in single process mode. 14139 */ 14140 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14141 boolean restarting, boolean allowRestart, int index) { 14142 if (index >= 0) { 14143 removeLruProcessLocked(app); 14144 ProcessList.remove(app.pid); 14145 } 14146 14147 mProcessesToGc.remove(app); 14148 mPendingPssProcesses.remove(app); 14149 14150 // Dismiss any open dialogs. 14151 if (app.crashDialog != null && !app.forceCrashReport) { 14152 app.crashDialog.dismiss(); 14153 app.crashDialog = null; 14154 } 14155 if (app.anrDialog != null) { 14156 app.anrDialog.dismiss(); 14157 app.anrDialog = null; 14158 } 14159 if (app.waitDialog != null) { 14160 app.waitDialog.dismiss(); 14161 app.waitDialog = null; 14162 } 14163 14164 app.crashing = false; 14165 app.notResponding = false; 14166 14167 app.resetPackageList(mProcessStats); 14168 app.unlinkDeathRecipient(); 14169 app.makeInactive(mProcessStats); 14170 app.waitingToKill = null; 14171 app.forcingToForeground = null; 14172 updateProcessForegroundLocked(app, false, false); 14173 app.foregroundActivities = false; 14174 app.hasShownUi = false; 14175 app.treatLikeActivity = false; 14176 app.hasAboveClient = false; 14177 app.hasClientActivities = false; 14178 14179 mServices.killServicesLocked(app, allowRestart); 14180 14181 boolean restart = false; 14182 14183 // Remove published content providers. 14184 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14185 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14186 final boolean always = app.bad || !allowRestart; 14187 if (removeDyingProviderLocked(app, cpr, always) || always) { 14188 // We left the provider in the launching list, need to 14189 // restart it. 14190 restart = true; 14191 } 14192 14193 cpr.provider = null; 14194 cpr.proc = null; 14195 } 14196 app.pubProviders.clear(); 14197 14198 // Take care of any launching providers waiting for this process. 14199 if (checkAppInLaunchingProvidersLocked(app, false)) { 14200 restart = true; 14201 } 14202 14203 // Unregister from connected content providers. 14204 if (!app.conProviders.isEmpty()) { 14205 for (int i=0; i<app.conProviders.size(); i++) { 14206 ContentProviderConnection conn = app.conProviders.get(i); 14207 conn.provider.connections.remove(conn); 14208 } 14209 app.conProviders.clear(); 14210 } 14211 14212 // At this point there may be remaining entries in mLaunchingProviders 14213 // where we were the only one waiting, so they are no longer of use. 14214 // Look for these and clean up if found. 14215 // XXX Commented out for now. Trying to figure out a way to reproduce 14216 // the actual situation to identify what is actually going on. 14217 if (false) { 14218 for (int i=0; i<mLaunchingProviders.size(); i++) { 14219 ContentProviderRecord cpr = (ContentProviderRecord) 14220 mLaunchingProviders.get(i); 14221 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14222 synchronized (cpr) { 14223 cpr.launchingApp = null; 14224 cpr.notifyAll(); 14225 } 14226 } 14227 } 14228 } 14229 14230 skipCurrentReceiverLocked(app); 14231 14232 // Unregister any receivers. 14233 for (int i=app.receivers.size()-1; i>=0; i--) { 14234 removeReceiverLocked(app.receivers.valueAt(i)); 14235 } 14236 app.receivers.clear(); 14237 14238 // If the app is undergoing backup, tell the backup manager about it 14239 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14240 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14241 + mBackupTarget.appInfo + " died during backup"); 14242 try { 14243 IBackupManager bm = IBackupManager.Stub.asInterface( 14244 ServiceManager.getService(Context.BACKUP_SERVICE)); 14245 bm.agentDisconnected(app.info.packageName); 14246 } catch (RemoteException e) { 14247 // can't happen; backup manager is local 14248 } 14249 } 14250 14251 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14252 ProcessChangeItem item = mPendingProcessChanges.get(i); 14253 if (item.pid == app.pid) { 14254 mPendingProcessChanges.remove(i); 14255 mAvailProcessChanges.add(item); 14256 } 14257 } 14258 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14259 14260 // If the caller is restarting this app, then leave it in its 14261 // current lists and let the caller take care of it. 14262 if (restarting) { 14263 return; 14264 } 14265 14266 if (!app.persistent || app.isolated) { 14267 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14268 "Removing non-persistent process during cleanup: " + app); 14269 mProcessNames.remove(app.processName, app.uid); 14270 mIsolatedProcesses.remove(app.uid); 14271 if (mHeavyWeightProcess == app) { 14272 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14273 mHeavyWeightProcess.userId, 0)); 14274 mHeavyWeightProcess = null; 14275 } 14276 } else if (!app.removed) { 14277 // This app is persistent, so we need to keep its record around. 14278 // If it is not already on the pending app list, add it there 14279 // and start a new process for it. 14280 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14281 mPersistentStartingProcesses.add(app); 14282 restart = true; 14283 } 14284 } 14285 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14286 "Clean-up removing on hold: " + app); 14287 mProcessesOnHold.remove(app); 14288 14289 if (app == mHomeProcess) { 14290 mHomeProcess = null; 14291 } 14292 if (app == mPreviousProcess) { 14293 mPreviousProcess = null; 14294 } 14295 14296 if (restart && !app.isolated) { 14297 // We have components that still need to be running in the 14298 // process, so re-launch it. 14299 mProcessNames.put(app.processName, app.uid, app); 14300 startProcessLocked(app, "restart", app.processName); 14301 } else if (app.pid > 0 && app.pid != MY_PID) { 14302 // Goodbye! 14303 boolean removed; 14304 synchronized (mPidsSelfLocked) { 14305 mPidsSelfLocked.remove(app.pid); 14306 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14307 } 14308 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14309 if (app.isolated) { 14310 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14311 } 14312 app.setPid(0); 14313 } 14314 } 14315 14316 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14317 // Look through the content providers we are waiting to have launched, 14318 // and if any run in this process then either schedule a restart of 14319 // the process or kill the client waiting for it if this process has 14320 // gone bad. 14321 int NL = mLaunchingProviders.size(); 14322 boolean restart = false; 14323 for (int i=0; i<NL; i++) { 14324 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14325 if (cpr.launchingApp == app) { 14326 if (!alwaysBad && !app.bad) { 14327 restart = true; 14328 } else { 14329 removeDyingProviderLocked(app, cpr, true); 14330 // cpr should have been removed from mLaunchingProviders 14331 NL = mLaunchingProviders.size(); 14332 i--; 14333 } 14334 } 14335 } 14336 return restart; 14337 } 14338 14339 // ========================================================= 14340 // SERVICES 14341 // ========================================================= 14342 14343 @Override 14344 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14345 int flags) { 14346 enforceNotIsolatedCaller("getServices"); 14347 synchronized (this) { 14348 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14349 } 14350 } 14351 14352 @Override 14353 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14354 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14355 synchronized (this) { 14356 return mServices.getRunningServiceControlPanelLocked(name); 14357 } 14358 } 14359 14360 @Override 14361 public ComponentName startService(IApplicationThread caller, Intent service, 14362 String resolvedType, int userId) { 14363 enforceNotIsolatedCaller("startService"); 14364 // Refuse possible leaked file descriptors 14365 if (service != null && service.hasFileDescriptors() == true) { 14366 throw new IllegalArgumentException("File descriptors passed in Intent"); 14367 } 14368 14369 if (DEBUG_SERVICE) 14370 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14371 synchronized(this) { 14372 final int callingPid = Binder.getCallingPid(); 14373 final int callingUid = Binder.getCallingUid(); 14374 final long origId = Binder.clearCallingIdentity(); 14375 ComponentName res = mServices.startServiceLocked(caller, service, 14376 resolvedType, callingPid, callingUid, userId); 14377 Binder.restoreCallingIdentity(origId); 14378 return res; 14379 } 14380 } 14381 14382 ComponentName startServiceInPackage(int uid, 14383 Intent service, String resolvedType, int userId) { 14384 synchronized(this) { 14385 if (DEBUG_SERVICE) 14386 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14387 final long origId = Binder.clearCallingIdentity(); 14388 ComponentName res = mServices.startServiceLocked(null, service, 14389 resolvedType, -1, uid, userId); 14390 Binder.restoreCallingIdentity(origId); 14391 return res; 14392 } 14393 } 14394 14395 @Override 14396 public int stopService(IApplicationThread caller, Intent service, 14397 String resolvedType, int userId) { 14398 enforceNotIsolatedCaller("stopService"); 14399 // Refuse possible leaked file descriptors 14400 if (service != null && service.hasFileDescriptors() == true) { 14401 throw new IllegalArgumentException("File descriptors passed in Intent"); 14402 } 14403 14404 synchronized(this) { 14405 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14406 } 14407 } 14408 14409 @Override 14410 public IBinder peekService(Intent service, String resolvedType) { 14411 enforceNotIsolatedCaller("peekService"); 14412 // Refuse possible leaked file descriptors 14413 if (service != null && service.hasFileDescriptors() == true) { 14414 throw new IllegalArgumentException("File descriptors passed in Intent"); 14415 } 14416 synchronized(this) { 14417 return mServices.peekServiceLocked(service, resolvedType); 14418 } 14419 } 14420 14421 @Override 14422 public boolean stopServiceToken(ComponentName className, IBinder token, 14423 int startId) { 14424 synchronized(this) { 14425 return mServices.stopServiceTokenLocked(className, token, startId); 14426 } 14427 } 14428 14429 @Override 14430 public void setServiceForeground(ComponentName className, IBinder token, 14431 int id, Notification notification, boolean removeNotification) { 14432 synchronized(this) { 14433 mServices.setServiceForegroundLocked(className, token, id, notification, 14434 removeNotification); 14435 } 14436 } 14437 14438 @Override 14439 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14440 boolean requireFull, String name, String callerPackage) { 14441 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14442 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14443 } 14444 14445 int unsafeConvertIncomingUser(int userId) { 14446 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14447 ? mCurrentUserId : userId; 14448 } 14449 14450 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14451 int allowMode, String name, String callerPackage) { 14452 final int callingUserId = UserHandle.getUserId(callingUid); 14453 if (callingUserId == userId) { 14454 return userId; 14455 } 14456 14457 // Note that we may be accessing mCurrentUserId outside of a lock... 14458 // shouldn't be a big deal, if this is being called outside 14459 // of a locked context there is intrinsically a race with 14460 // the value the caller will receive and someone else changing it. 14461 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14462 // we will switch to the calling user if access to the current user fails. 14463 int targetUserId = unsafeConvertIncomingUser(userId); 14464 14465 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14466 final boolean allow; 14467 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14468 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14469 // If the caller has this permission, they always pass go. And collect $200. 14470 allow = true; 14471 } else if (allowMode == ALLOW_FULL_ONLY) { 14472 // We require full access, sucks to be you. 14473 allow = false; 14474 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14475 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14476 // If the caller does not have either permission, they are always doomed. 14477 allow = false; 14478 } else if (allowMode == ALLOW_NON_FULL) { 14479 // We are blanket allowing non-full access, you lucky caller! 14480 allow = true; 14481 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14482 // We may or may not allow this depending on whether the two users are 14483 // in the same profile. 14484 synchronized (mUserProfileGroupIdsSelfLocked) { 14485 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14486 UserInfo.NO_PROFILE_GROUP_ID); 14487 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14488 UserInfo.NO_PROFILE_GROUP_ID); 14489 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14490 && callingProfile == targetProfile; 14491 } 14492 } else { 14493 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14494 } 14495 if (!allow) { 14496 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14497 // In this case, they would like to just execute as their 14498 // owner user instead of failing. 14499 targetUserId = callingUserId; 14500 } else { 14501 StringBuilder builder = new StringBuilder(128); 14502 builder.append("Permission Denial: "); 14503 builder.append(name); 14504 if (callerPackage != null) { 14505 builder.append(" from "); 14506 builder.append(callerPackage); 14507 } 14508 builder.append(" asks to run as user "); 14509 builder.append(userId); 14510 builder.append(" but is calling from user "); 14511 builder.append(UserHandle.getUserId(callingUid)); 14512 builder.append("; this requires "); 14513 builder.append(INTERACT_ACROSS_USERS_FULL); 14514 if (allowMode != ALLOW_FULL_ONLY) { 14515 builder.append(" or "); 14516 builder.append(INTERACT_ACROSS_USERS); 14517 } 14518 String msg = builder.toString(); 14519 Slog.w(TAG, msg); 14520 throw new SecurityException(msg); 14521 } 14522 } 14523 } 14524 if (!allowAll && targetUserId < 0) { 14525 throw new IllegalArgumentException( 14526 "Call does not support special user #" + targetUserId); 14527 } 14528 return targetUserId; 14529 } 14530 14531 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14532 String className, int flags) { 14533 boolean result = false; 14534 // For apps that don't have pre-defined UIDs, check for permission 14535 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14536 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14537 if (ActivityManager.checkUidPermission( 14538 INTERACT_ACROSS_USERS, 14539 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14540 ComponentName comp = new ComponentName(aInfo.packageName, className); 14541 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14542 + " requests FLAG_SINGLE_USER, but app does not hold " 14543 + INTERACT_ACROSS_USERS; 14544 Slog.w(TAG, msg); 14545 throw new SecurityException(msg); 14546 } 14547 // Permission passed 14548 result = true; 14549 } 14550 } else if ("system".equals(componentProcessName)) { 14551 result = true; 14552 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14553 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14554 // Phone app is allowed to export singleuser providers. 14555 result = true; 14556 } else { 14557 // App with pre-defined UID, check if it's a persistent app 14558 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14559 } 14560 if (DEBUG_MU) { 14561 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14562 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14563 } 14564 return result; 14565 } 14566 14567 /** 14568 * Checks to see if the caller is in the same app as the singleton 14569 * component, or the component is in a special app. It allows special apps 14570 * to export singleton components but prevents exporting singleton 14571 * components for regular apps. 14572 */ 14573 boolean isValidSingletonCall(int callingUid, int componentUid) { 14574 int componentAppId = UserHandle.getAppId(componentUid); 14575 return UserHandle.isSameApp(callingUid, componentUid) 14576 || componentAppId == Process.SYSTEM_UID 14577 || componentAppId == Process.PHONE_UID 14578 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14579 == PackageManager.PERMISSION_GRANTED; 14580 } 14581 14582 public int bindService(IApplicationThread caller, IBinder token, 14583 Intent service, String resolvedType, 14584 IServiceConnection connection, int flags, int userId) { 14585 enforceNotIsolatedCaller("bindService"); 14586 // Refuse possible leaked file descriptors 14587 if (service != null && service.hasFileDescriptors() == true) { 14588 throw new IllegalArgumentException("File descriptors passed in Intent"); 14589 } 14590 14591 synchronized(this) { 14592 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14593 connection, flags, userId); 14594 } 14595 } 14596 14597 public boolean unbindService(IServiceConnection connection) { 14598 synchronized (this) { 14599 return mServices.unbindServiceLocked(connection); 14600 } 14601 } 14602 14603 public void publishService(IBinder token, Intent intent, IBinder service) { 14604 // Refuse possible leaked file descriptors 14605 if (intent != null && intent.hasFileDescriptors() == true) { 14606 throw new IllegalArgumentException("File descriptors passed in Intent"); 14607 } 14608 14609 synchronized(this) { 14610 if (!(token instanceof ServiceRecord)) { 14611 throw new IllegalArgumentException("Invalid service token"); 14612 } 14613 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14614 } 14615 } 14616 14617 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14618 // Refuse possible leaked file descriptors 14619 if (intent != null && intent.hasFileDescriptors() == true) { 14620 throw new IllegalArgumentException("File descriptors passed in Intent"); 14621 } 14622 14623 synchronized(this) { 14624 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14625 } 14626 } 14627 14628 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14629 synchronized(this) { 14630 if (!(token instanceof ServiceRecord)) { 14631 throw new IllegalArgumentException("Invalid service token"); 14632 } 14633 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14634 } 14635 } 14636 14637 // ========================================================= 14638 // BACKUP AND RESTORE 14639 // ========================================================= 14640 14641 // Cause the target app to be launched if necessary and its backup agent 14642 // instantiated. The backup agent will invoke backupAgentCreated() on the 14643 // activity manager to announce its creation. 14644 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14645 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14646 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14647 14648 synchronized(this) { 14649 // !!! TODO: currently no check here that we're already bound 14650 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14651 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14652 synchronized (stats) { 14653 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14654 } 14655 14656 // Backup agent is now in use, its package can't be stopped. 14657 try { 14658 AppGlobals.getPackageManager().setPackageStoppedState( 14659 app.packageName, false, UserHandle.getUserId(app.uid)); 14660 } catch (RemoteException e) { 14661 } catch (IllegalArgumentException e) { 14662 Slog.w(TAG, "Failed trying to unstop package " 14663 + app.packageName + ": " + e); 14664 } 14665 14666 BackupRecord r = new BackupRecord(ss, app, backupMode); 14667 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14668 ? new ComponentName(app.packageName, app.backupAgentName) 14669 : new ComponentName("android", "FullBackupAgent"); 14670 // startProcessLocked() returns existing proc's record if it's already running 14671 ProcessRecord proc = startProcessLocked(app.processName, app, 14672 false, 0, "backup", hostingName, false, false, false); 14673 if (proc == null) { 14674 Slog.e(TAG, "Unable to start backup agent process " + r); 14675 return false; 14676 } 14677 14678 r.app = proc; 14679 mBackupTarget = r; 14680 mBackupAppName = app.packageName; 14681 14682 // Try not to kill the process during backup 14683 updateOomAdjLocked(proc); 14684 14685 // If the process is already attached, schedule the creation of the backup agent now. 14686 // If it is not yet live, this will be done when it attaches to the framework. 14687 if (proc.thread != null) { 14688 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14689 try { 14690 proc.thread.scheduleCreateBackupAgent(app, 14691 compatibilityInfoForPackageLocked(app), backupMode); 14692 } catch (RemoteException e) { 14693 // Will time out on the backup manager side 14694 } 14695 } else { 14696 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14697 } 14698 // Invariants: at this point, the target app process exists and the application 14699 // is either already running or in the process of coming up. mBackupTarget and 14700 // mBackupAppName describe the app, so that when it binds back to the AM we 14701 // know that it's scheduled for a backup-agent operation. 14702 } 14703 14704 return true; 14705 } 14706 14707 @Override 14708 public void clearPendingBackup() { 14709 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14710 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14711 14712 synchronized (this) { 14713 mBackupTarget = null; 14714 mBackupAppName = null; 14715 } 14716 } 14717 14718 // A backup agent has just come up 14719 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14720 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14721 + " = " + agent); 14722 14723 synchronized(this) { 14724 if (!agentPackageName.equals(mBackupAppName)) { 14725 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14726 return; 14727 } 14728 } 14729 14730 long oldIdent = Binder.clearCallingIdentity(); 14731 try { 14732 IBackupManager bm = IBackupManager.Stub.asInterface( 14733 ServiceManager.getService(Context.BACKUP_SERVICE)); 14734 bm.agentConnected(agentPackageName, agent); 14735 } catch (RemoteException e) { 14736 // can't happen; the backup manager service is local 14737 } catch (Exception e) { 14738 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14739 e.printStackTrace(); 14740 } finally { 14741 Binder.restoreCallingIdentity(oldIdent); 14742 } 14743 } 14744 14745 // done with this agent 14746 public void unbindBackupAgent(ApplicationInfo appInfo) { 14747 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14748 if (appInfo == null) { 14749 Slog.w(TAG, "unbind backup agent for null app"); 14750 return; 14751 } 14752 14753 synchronized(this) { 14754 try { 14755 if (mBackupAppName == null) { 14756 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14757 return; 14758 } 14759 14760 if (!mBackupAppName.equals(appInfo.packageName)) { 14761 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14762 return; 14763 } 14764 14765 // Not backing this app up any more; reset its OOM adjustment 14766 final ProcessRecord proc = mBackupTarget.app; 14767 updateOomAdjLocked(proc); 14768 14769 // If the app crashed during backup, 'thread' will be null here 14770 if (proc.thread != null) { 14771 try { 14772 proc.thread.scheduleDestroyBackupAgent(appInfo, 14773 compatibilityInfoForPackageLocked(appInfo)); 14774 } catch (Exception e) { 14775 Slog.e(TAG, "Exception when unbinding backup agent:"); 14776 e.printStackTrace(); 14777 } 14778 } 14779 } finally { 14780 mBackupTarget = null; 14781 mBackupAppName = null; 14782 } 14783 } 14784 } 14785 // ========================================================= 14786 // BROADCASTS 14787 // ========================================================= 14788 14789 private final List getStickiesLocked(String action, IntentFilter filter, 14790 List cur, int userId) { 14791 final ContentResolver resolver = mContext.getContentResolver(); 14792 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14793 if (stickies == null) { 14794 return cur; 14795 } 14796 final ArrayList<Intent> list = stickies.get(action); 14797 if (list == null) { 14798 return cur; 14799 } 14800 int N = list.size(); 14801 for (int i=0; i<N; i++) { 14802 Intent intent = list.get(i); 14803 if (filter.match(resolver, intent, true, TAG) >= 0) { 14804 if (cur == null) { 14805 cur = new ArrayList<Intent>(); 14806 } 14807 cur.add(intent); 14808 } 14809 } 14810 return cur; 14811 } 14812 14813 boolean isPendingBroadcastProcessLocked(int pid) { 14814 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14815 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14816 } 14817 14818 void skipPendingBroadcastLocked(int pid) { 14819 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14820 for (BroadcastQueue queue : mBroadcastQueues) { 14821 queue.skipPendingBroadcastLocked(pid); 14822 } 14823 } 14824 14825 // The app just attached; send any pending broadcasts that it should receive 14826 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14827 boolean didSomething = false; 14828 for (BroadcastQueue queue : mBroadcastQueues) { 14829 didSomething |= queue.sendPendingBroadcastsLocked(app); 14830 } 14831 return didSomething; 14832 } 14833 14834 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14835 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14836 enforceNotIsolatedCaller("registerReceiver"); 14837 int callingUid; 14838 int callingPid; 14839 synchronized(this) { 14840 ProcessRecord callerApp = null; 14841 if (caller != null) { 14842 callerApp = getRecordForAppLocked(caller); 14843 if (callerApp == null) { 14844 throw new SecurityException( 14845 "Unable to find app for caller " + caller 14846 + " (pid=" + Binder.getCallingPid() 14847 + ") when registering receiver " + receiver); 14848 } 14849 if (callerApp.info.uid != Process.SYSTEM_UID && 14850 !callerApp.pkgList.containsKey(callerPackage) && 14851 !"android".equals(callerPackage)) { 14852 throw new SecurityException("Given caller package " + callerPackage 14853 + " is not running in process " + callerApp); 14854 } 14855 callingUid = callerApp.info.uid; 14856 callingPid = callerApp.pid; 14857 } else { 14858 callerPackage = null; 14859 callingUid = Binder.getCallingUid(); 14860 callingPid = Binder.getCallingPid(); 14861 } 14862 14863 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14864 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14865 14866 List allSticky = null; 14867 14868 // Look for any matching sticky broadcasts... 14869 Iterator actions = filter.actionsIterator(); 14870 if (actions != null) { 14871 while (actions.hasNext()) { 14872 String action = (String)actions.next(); 14873 allSticky = getStickiesLocked(action, filter, allSticky, 14874 UserHandle.USER_ALL); 14875 allSticky = getStickiesLocked(action, filter, allSticky, 14876 UserHandle.getUserId(callingUid)); 14877 } 14878 } else { 14879 allSticky = getStickiesLocked(null, filter, allSticky, 14880 UserHandle.USER_ALL); 14881 allSticky = getStickiesLocked(null, filter, allSticky, 14882 UserHandle.getUserId(callingUid)); 14883 } 14884 14885 // The first sticky in the list is returned directly back to 14886 // the client. 14887 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14888 14889 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14890 + ": " + sticky); 14891 14892 if (receiver == null) { 14893 return sticky; 14894 } 14895 14896 ReceiverList rl 14897 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14898 if (rl == null) { 14899 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14900 userId, receiver); 14901 if (rl.app != null) { 14902 rl.app.receivers.add(rl); 14903 } else { 14904 try { 14905 receiver.asBinder().linkToDeath(rl, 0); 14906 } catch (RemoteException e) { 14907 return sticky; 14908 } 14909 rl.linkedToDeath = true; 14910 } 14911 mRegisteredReceivers.put(receiver.asBinder(), rl); 14912 } else if (rl.uid != callingUid) { 14913 throw new IllegalArgumentException( 14914 "Receiver requested to register for uid " + callingUid 14915 + " was previously registered for uid " + rl.uid); 14916 } else if (rl.pid != callingPid) { 14917 throw new IllegalArgumentException( 14918 "Receiver requested to register for pid " + callingPid 14919 + " was previously registered for pid " + rl.pid); 14920 } else if (rl.userId != userId) { 14921 throw new IllegalArgumentException( 14922 "Receiver requested to register for user " + userId 14923 + " was previously registered for user " + rl.userId); 14924 } 14925 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14926 permission, callingUid, userId); 14927 rl.add(bf); 14928 if (!bf.debugCheck()) { 14929 Slog.w(TAG, "==> For Dynamic broadast"); 14930 } 14931 mReceiverResolver.addFilter(bf); 14932 14933 // Enqueue broadcasts for all existing stickies that match 14934 // this filter. 14935 if (allSticky != null) { 14936 ArrayList receivers = new ArrayList(); 14937 receivers.add(bf); 14938 14939 int N = allSticky.size(); 14940 for (int i=0; i<N; i++) { 14941 Intent intent = (Intent)allSticky.get(i); 14942 BroadcastQueue queue = broadcastQueueForIntent(intent); 14943 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14944 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14945 null, null, false, true, true, -1); 14946 queue.enqueueParallelBroadcastLocked(r); 14947 queue.scheduleBroadcastsLocked(); 14948 } 14949 } 14950 14951 return sticky; 14952 } 14953 } 14954 14955 public void unregisterReceiver(IIntentReceiver receiver) { 14956 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14957 14958 final long origId = Binder.clearCallingIdentity(); 14959 try { 14960 boolean doTrim = false; 14961 14962 synchronized(this) { 14963 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14964 if (rl != null) { 14965 if (rl.curBroadcast != null) { 14966 BroadcastRecord r = rl.curBroadcast; 14967 final boolean doNext = finishReceiverLocked( 14968 receiver.asBinder(), r.resultCode, r.resultData, 14969 r.resultExtras, r.resultAbort); 14970 if (doNext) { 14971 doTrim = true; 14972 r.queue.processNextBroadcast(false); 14973 } 14974 } 14975 14976 if (rl.app != null) { 14977 rl.app.receivers.remove(rl); 14978 } 14979 removeReceiverLocked(rl); 14980 if (rl.linkedToDeath) { 14981 rl.linkedToDeath = false; 14982 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14983 } 14984 } 14985 } 14986 14987 // If we actually concluded any broadcasts, we might now be able 14988 // to trim the recipients' apps from our working set 14989 if (doTrim) { 14990 trimApplications(); 14991 return; 14992 } 14993 14994 } finally { 14995 Binder.restoreCallingIdentity(origId); 14996 } 14997 } 14998 14999 void removeReceiverLocked(ReceiverList rl) { 15000 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15001 int N = rl.size(); 15002 for (int i=0; i<N; i++) { 15003 mReceiverResolver.removeFilter(rl.get(i)); 15004 } 15005 } 15006 15007 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15008 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15009 ProcessRecord r = mLruProcesses.get(i); 15010 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15011 try { 15012 r.thread.dispatchPackageBroadcast(cmd, packages); 15013 } catch (RemoteException ex) { 15014 } 15015 } 15016 } 15017 } 15018 15019 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15020 int[] users) { 15021 List<ResolveInfo> receivers = null; 15022 try { 15023 HashSet<ComponentName> singleUserReceivers = null; 15024 boolean scannedFirstReceivers = false; 15025 for (int user : users) { 15026 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15027 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15028 if (user != 0 && newReceivers != null) { 15029 // If this is not the primary user, we need to check for 15030 // any receivers that should be filtered out. 15031 for (int i=0; i<newReceivers.size(); i++) { 15032 ResolveInfo ri = newReceivers.get(i); 15033 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15034 newReceivers.remove(i); 15035 i--; 15036 } 15037 } 15038 } 15039 if (newReceivers != null && newReceivers.size() == 0) { 15040 newReceivers = null; 15041 } 15042 if (receivers == null) { 15043 receivers = newReceivers; 15044 } else if (newReceivers != null) { 15045 // We need to concatenate the additional receivers 15046 // found with what we have do far. This would be easy, 15047 // but we also need to de-dup any receivers that are 15048 // singleUser. 15049 if (!scannedFirstReceivers) { 15050 // Collect any single user receivers we had already retrieved. 15051 scannedFirstReceivers = true; 15052 for (int i=0; i<receivers.size(); i++) { 15053 ResolveInfo ri = receivers.get(i); 15054 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15055 ComponentName cn = new ComponentName( 15056 ri.activityInfo.packageName, ri.activityInfo.name); 15057 if (singleUserReceivers == null) { 15058 singleUserReceivers = new HashSet<ComponentName>(); 15059 } 15060 singleUserReceivers.add(cn); 15061 } 15062 } 15063 } 15064 // Add the new results to the existing results, tracking 15065 // and de-dupping single user receivers. 15066 for (int i=0; i<newReceivers.size(); i++) { 15067 ResolveInfo ri = newReceivers.get(i); 15068 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15069 ComponentName cn = new ComponentName( 15070 ri.activityInfo.packageName, ri.activityInfo.name); 15071 if (singleUserReceivers == null) { 15072 singleUserReceivers = new HashSet<ComponentName>(); 15073 } 15074 if (!singleUserReceivers.contains(cn)) { 15075 singleUserReceivers.add(cn); 15076 receivers.add(ri); 15077 } 15078 } else { 15079 receivers.add(ri); 15080 } 15081 } 15082 } 15083 } 15084 } catch (RemoteException ex) { 15085 // pm is in same process, this will never happen. 15086 } 15087 return receivers; 15088 } 15089 15090 private final int broadcastIntentLocked(ProcessRecord callerApp, 15091 String callerPackage, Intent intent, String resolvedType, 15092 IIntentReceiver resultTo, int resultCode, String resultData, 15093 Bundle map, String requiredPermission, int appOp, 15094 boolean ordered, boolean sticky, int callingPid, int callingUid, 15095 int userId) { 15096 intent = new Intent(intent); 15097 15098 // By default broadcasts do not go to stopped apps. 15099 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15100 15101 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15102 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15103 + " ordered=" + ordered + " userid=" + userId); 15104 if ((resultTo != null) && !ordered) { 15105 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15106 } 15107 15108 userId = handleIncomingUser(callingPid, callingUid, userId, 15109 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15110 15111 // Make sure that the user who is receiving this broadcast is started. 15112 // If not, we will just skip it. 15113 15114 15115 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15116 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15117 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15118 Slog.w(TAG, "Skipping broadcast of " + intent 15119 + ": user " + userId + " is stopped"); 15120 return ActivityManager.BROADCAST_SUCCESS; 15121 } 15122 } 15123 15124 /* 15125 * Prevent non-system code (defined here to be non-persistent 15126 * processes) from sending protected broadcasts. 15127 */ 15128 int callingAppId = UserHandle.getAppId(callingUid); 15129 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15130 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15131 || callingAppId == Process.NFC_UID || callingUid == 0) { 15132 // Always okay. 15133 } else if (callerApp == null || !callerApp.persistent) { 15134 try { 15135 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15136 intent.getAction())) { 15137 String msg = "Permission Denial: not allowed to send broadcast " 15138 + intent.getAction() + " from pid=" 15139 + callingPid + ", uid=" + callingUid; 15140 Slog.w(TAG, msg); 15141 throw new SecurityException(msg); 15142 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15143 // Special case for compatibility: we don't want apps to send this, 15144 // but historically it has not been protected and apps may be using it 15145 // to poke their own app widget. So, instead of making it protected, 15146 // just limit it to the caller. 15147 if (callerApp == null) { 15148 String msg = "Permission Denial: not allowed to send broadcast " 15149 + intent.getAction() + " from unknown caller."; 15150 Slog.w(TAG, msg); 15151 throw new SecurityException(msg); 15152 } else if (intent.getComponent() != null) { 15153 // They are good enough to send to an explicit component... verify 15154 // it is being sent to the calling app. 15155 if (!intent.getComponent().getPackageName().equals( 15156 callerApp.info.packageName)) { 15157 String msg = "Permission Denial: not allowed to send broadcast " 15158 + intent.getAction() + " to " 15159 + intent.getComponent().getPackageName() + " from " 15160 + callerApp.info.packageName; 15161 Slog.w(TAG, msg); 15162 throw new SecurityException(msg); 15163 } 15164 } else { 15165 // Limit broadcast to their own package. 15166 intent.setPackage(callerApp.info.packageName); 15167 } 15168 } 15169 } catch (RemoteException e) { 15170 Slog.w(TAG, "Remote exception", e); 15171 return ActivityManager.BROADCAST_SUCCESS; 15172 } 15173 } 15174 15175 // Handle special intents: if this broadcast is from the package 15176 // manager about a package being removed, we need to remove all of 15177 // its activities from the history stack. 15178 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15179 intent.getAction()); 15180 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15181 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15182 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15183 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15184 || uidRemoved) { 15185 if (checkComponentPermission( 15186 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15187 callingPid, callingUid, -1, true) 15188 == PackageManager.PERMISSION_GRANTED) { 15189 if (uidRemoved) { 15190 final Bundle intentExtras = intent.getExtras(); 15191 final int uid = intentExtras != null 15192 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15193 if (uid >= 0) { 15194 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15195 synchronized (bs) { 15196 bs.removeUidStatsLocked(uid); 15197 } 15198 mAppOpsService.uidRemoved(uid); 15199 } 15200 } else { 15201 // If resources are unavailable just force stop all 15202 // those packages and flush the attribute cache as well. 15203 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15204 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15205 if (list != null && (list.length > 0)) { 15206 for (String pkg : list) { 15207 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15208 "storage unmount"); 15209 } 15210 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15211 sendPackageBroadcastLocked( 15212 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15213 } 15214 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15215 intent.getAction())) { 15216 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15217 } else { 15218 Uri data = intent.getData(); 15219 String ssp; 15220 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15221 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15222 intent.getAction()); 15223 boolean fullUninstall = removed && 15224 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15225 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15226 forceStopPackageLocked(ssp, UserHandle.getAppId( 15227 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15228 false, fullUninstall, userId, 15229 removed ? "pkg removed" : "pkg changed"); 15230 } 15231 if (removed) { 15232 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15233 new String[] {ssp}, userId); 15234 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15235 mAppOpsService.packageRemoved( 15236 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15237 15238 // Remove all permissions granted from/to this package 15239 removeUriPermissionsForPackageLocked(ssp, userId, true); 15240 } 15241 } 15242 } 15243 } 15244 } 15245 } else { 15246 String msg = "Permission Denial: " + intent.getAction() 15247 + " broadcast from " + callerPackage + " (pid=" + callingPid 15248 + ", uid=" + callingUid + ")" 15249 + " requires " 15250 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15251 Slog.w(TAG, msg); 15252 throw new SecurityException(msg); 15253 } 15254 15255 // Special case for adding a package: by default turn on compatibility 15256 // mode. 15257 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15258 Uri data = intent.getData(); 15259 String ssp; 15260 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15261 mCompatModePackages.handlePackageAddedLocked(ssp, 15262 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15263 } 15264 } 15265 15266 /* 15267 * If this is the time zone changed action, queue up a message that will reset the timezone 15268 * of all currently running processes. This message will get queued up before the broadcast 15269 * happens. 15270 */ 15271 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15272 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15273 } 15274 15275 /* 15276 * If the user set the time, let all running processes know. 15277 */ 15278 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15279 final int is24Hour = intent.getBooleanExtra( 15280 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15281 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15282 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15283 synchronized (stats) { 15284 stats.noteCurrentTimeChangedLocked(); 15285 } 15286 } 15287 15288 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15289 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15290 } 15291 15292 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15293 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15294 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15295 } 15296 15297 // Add to the sticky list if requested. 15298 if (sticky) { 15299 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15300 callingPid, callingUid) 15301 != PackageManager.PERMISSION_GRANTED) { 15302 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15303 + callingPid + ", uid=" + callingUid 15304 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15305 Slog.w(TAG, msg); 15306 throw new SecurityException(msg); 15307 } 15308 if (requiredPermission != null) { 15309 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15310 + " and enforce permission " + requiredPermission); 15311 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15312 } 15313 if (intent.getComponent() != null) { 15314 throw new SecurityException( 15315 "Sticky broadcasts can't target a specific component"); 15316 } 15317 // We use userId directly here, since the "all" target is maintained 15318 // as a separate set of sticky broadcasts. 15319 if (userId != UserHandle.USER_ALL) { 15320 // But first, if this is not a broadcast to all users, then 15321 // make sure it doesn't conflict with an existing broadcast to 15322 // all users. 15323 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15324 UserHandle.USER_ALL); 15325 if (stickies != null) { 15326 ArrayList<Intent> list = stickies.get(intent.getAction()); 15327 if (list != null) { 15328 int N = list.size(); 15329 int i; 15330 for (i=0; i<N; i++) { 15331 if (intent.filterEquals(list.get(i))) { 15332 throw new IllegalArgumentException( 15333 "Sticky broadcast " + intent + " for user " 15334 + userId + " conflicts with existing global broadcast"); 15335 } 15336 } 15337 } 15338 } 15339 } 15340 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15341 if (stickies == null) { 15342 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15343 mStickyBroadcasts.put(userId, stickies); 15344 } 15345 ArrayList<Intent> list = stickies.get(intent.getAction()); 15346 if (list == null) { 15347 list = new ArrayList<Intent>(); 15348 stickies.put(intent.getAction(), list); 15349 } 15350 int N = list.size(); 15351 int i; 15352 for (i=0; i<N; i++) { 15353 if (intent.filterEquals(list.get(i))) { 15354 // This sticky already exists, replace it. 15355 list.set(i, new Intent(intent)); 15356 break; 15357 } 15358 } 15359 if (i >= N) { 15360 list.add(new Intent(intent)); 15361 } 15362 } 15363 15364 int[] users; 15365 if (userId == UserHandle.USER_ALL) { 15366 // Caller wants broadcast to go to all started users. 15367 users = mStartedUserArray; 15368 } else { 15369 // Caller wants broadcast to go to one specific user. 15370 users = new int[] {userId}; 15371 } 15372 15373 // Figure out who all will receive this broadcast. 15374 List receivers = null; 15375 List<BroadcastFilter> registeredReceivers = null; 15376 // Need to resolve the intent to interested receivers... 15377 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15378 == 0) { 15379 receivers = collectReceiverComponents(intent, resolvedType, users); 15380 } 15381 if (intent.getComponent() == null) { 15382 registeredReceivers = mReceiverResolver.queryIntent(intent, 15383 resolvedType, false, userId); 15384 } 15385 15386 final boolean replacePending = 15387 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15388 15389 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15390 + " replacePending=" + replacePending); 15391 15392 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15393 if (!ordered && NR > 0) { 15394 // If we are not serializing this broadcast, then send the 15395 // registered receivers separately so they don't wait for the 15396 // components to be launched. 15397 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15398 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15399 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15400 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15401 ordered, sticky, false, userId); 15402 if (DEBUG_BROADCAST) Slog.v( 15403 TAG, "Enqueueing parallel broadcast " + r); 15404 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15405 if (!replaced) { 15406 queue.enqueueParallelBroadcastLocked(r); 15407 queue.scheduleBroadcastsLocked(); 15408 } 15409 registeredReceivers = null; 15410 NR = 0; 15411 } 15412 15413 // Merge into one list. 15414 int ir = 0; 15415 if (receivers != null) { 15416 // A special case for PACKAGE_ADDED: do not allow the package 15417 // being added to see this broadcast. This prevents them from 15418 // using this as a back door to get run as soon as they are 15419 // installed. Maybe in the future we want to have a special install 15420 // broadcast or such for apps, but we'd like to deliberately make 15421 // this decision. 15422 String skipPackages[] = null; 15423 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15424 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15425 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15426 Uri data = intent.getData(); 15427 if (data != null) { 15428 String pkgName = data.getSchemeSpecificPart(); 15429 if (pkgName != null) { 15430 skipPackages = new String[] { pkgName }; 15431 } 15432 } 15433 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15434 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15435 } 15436 if (skipPackages != null && (skipPackages.length > 0)) { 15437 for (String skipPackage : skipPackages) { 15438 if (skipPackage != null) { 15439 int NT = receivers.size(); 15440 for (int it=0; it<NT; it++) { 15441 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15442 if (curt.activityInfo.packageName.equals(skipPackage)) { 15443 receivers.remove(it); 15444 it--; 15445 NT--; 15446 } 15447 } 15448 } 15449 } 15450 } 15451 15452 int NT = receivers != null ? receivers.size() : 0; 15453 int it = 0; 15454 ResolveInfo curt = null; 15455 BroadcastFilter curr = null; 15456 while (it < NT && ir < NR) { 15457 if (curt == null) { 15458 curt = (ResolveInfo)receivers.get(it); 15459 } 15460 if (curr == null) { 15461 curr = registeredReceivers.get(ir); 15462 } 15463 if (curr.getPriority() >= curt.priority) { 15464 // Insert this broadcast record into the final list. 15465 receivers.add(it, curr); 15466 ir++; 15467 curr = null; 15468 it++; 15469 NT++; 15470 } else { 15471 // Skip to the next ResolveInfo in the final list. 15472 it++; 15473 curt = null; 15474 } 15475 } 15476 } 15477 while (ir < NR) { 15478 if (receivers == null) { 15479 receivers = new ArrayList(); 15480 } 15481 receivers.add(registeredReceivers.get(ir)); 15482 ir++; 15483 } 15484 15485 if ((receivers != null && receivers.size() > 0) 15486 || resultTo != null) { 15487 BroadcastQueue queue = broadcastQueueForIntent(intent); 15488 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15489 callerPackage, callingPid, callingUid, resolvedType, 15490 requiredPermission, appOp, receivers, resultTo, resultCode, 15491 resultData, map, ordered, sticky, false, userId); 15492 if (DEBUG_BROADCAST) Slog.v( 15493 TAG, "Enqueueing ordered broadcast " + r 15494 + ": prev had " + queue.mOrderedBroadcasts.size()); 15495 if (DEBUG_BROADCAST) { 15496 int seq = r.intent.getIntExtra("seq", -1); 15497 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15498 } 15499 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15500 if (!replaced) { 15501 queue.enqueueOrderedBroadcastLocked(r); 15502 queue.scheduleBroadcastsLocked(); 15503 } 15504 } 15505 15506 return ActivityManager.BROADCAST_SUCCESS; 15507 } 15508 15509 final Intent verifyBroadcastLocked(Intent intent) { 15510 // Refuse possible leaked file descriptors 15511 if (intent != null && intent.hasFileDescriptors() == true) { 15512 throw new IllegalArgumentException("File descriptors passed in Intent"); 15513 } 15514 15515 int flags = intent.getFlags(); 15516 15517 if (!mProcessesReady) { 15518 // if the caller really truly claims to know what they're doing, go 15519 // ahead and allow the broadcast without launching any receivers 15520 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15521 intent = new Intent(intent); 15522 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15523 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15524 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15525 + " before boot completion"); 15526 throw new IllegalStateException("Cannot broadcast before boot completed"); 15527 } 15528 } 15529 15530 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15531 throw new IllegalArgumentException( 15532 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15533 } 15534 15535 return intent; 15536 } 15537 15538 public final int broadcastIntent(IApplicationThread caller, 15539 Intent intent, String resolvedType, IIntentReceiver resultTo, 15540 int resultCode, String resultData, Bundle map, 15541 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15542 enforceNotIsolatedCaller("broadcastIntent"); 15543 synchronized(this) { 15544 intent = verifyBroadcastLocked(intent); 15545 15546 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15547 final int callingPid = Binder.getCallingPid(); 15548 final int callingUid = Binder.getCallingUid(); 15549 final long origId = Binder.clearCallingIdentity(); 15550 int res = broadcastIntentLocked(callerApp, 15551 callerApp != null ? callerApp.info.packageName : null, 15552 intent, resolvedType, resultTo, 15553 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15554 callingPid, callingUid, userId); 15555 Binder.restoreCallingIdentity(origId); 15556 return res; 15557 } 15558 } 15559 15560 int broadcastIntentInPackage(String packageName, int uid, 15561 Intent intent, String resolvedType, IIntentReceiver resultTo, 15562 int resultCode, String resultData, Bundle map, 15563 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15564 synchronized(this) { 15565 intent = verifyBroadcastLocked(intent); 15566 15567 final long origId = Binder.clearCallingIdentity(); 15568 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15569 resultTo, resultCode, resultData, map, requiredPermission, 15570 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15571 Binder.restoreCallingIdentity(origId); 15572 return res; 15573 } 15574 } 15575 15576 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15577 // Refuse possible leaked file descriptors 15578 if (intent != null && intent.hasFileDescriptors() == true) { 15579 throw new IllegalArgumentException("File descriptors passed in Intent"); 15580 } 15581 15582 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15583 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15584 15585 synchronized(this) { 15586 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15587 != PackageManager.PERMISSION_GRANTED) { 15588 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15589 + Binder.getCallingPid() 15590 + ", uid=" + Binder.getCallingUid() 15591 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15592 Slog.w(TAG, msg); 15593 throw new SecurityException(msg); 15594 } 15595 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15596 if (stickies != null) { 15597 ArrayList<Intent> list = stickies.get(intent.getAction()); 15598 if (list != null) { 15599 int N = list.size(); 15600 int i; 15601 for (i=0; i<N; i++) { 15602 if (intent.filterEquals(list.get(i))) { 15603 list.remove(i); 15604 break; 15605 } 15606 } 15607 if (list.size() <= 0) { 15608 stickies.remove(intent.getAction()); 15609 } 15610 } 15611 if (stickies.size() <= 0) { 15612 mStickyBroadcasts.remove(userId); 15613 } 15614 } 15615 } 15616 } 15617 15618 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15619 String resultData, Bundle resultExtras, boolean resultAbort) { 15620 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15621 if (r == null) { 15622 Slog.w(TAG, "finishReceiver called but not found on queue"); 15623 return false; 15624 } 15625 15626 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15627 } 15628 15629 void backgroundServicesFinishedLocked(int userId) { 15630 for (BroadcastQueue queue : mBroadcastQueues) { 15631 queue.backgroundServicesFinishedLocked(userId); 15632 } 15633 } 15634 15635 public void finishReceiver(IBinder who, int resultCode, String resultData, 15636 Bundle resultExtras, boolean resultAbort) { 15637 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15638 15639 // Refuse possible leaked file descriptors 15640 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15641 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15642 } 15643 15644 final long origId = Binder.clearCallingIdentity(); 15645 try { 15646 boolean doNext = false; 15647 BroadcastRecord r; 15648 15649 synchronized(this) { 15650 r = broadcastRecordForReceiverLocked(who); 15651 if (r != null) { 15652 doNext = r.queue.finishReceiverLocked(r, resultCode, 15653 resultData, resultExtras, resultAbort, true); 15654 } 15655 } 15656 15657 if (doNext) { 15658 r.queue.processNextBroadcast(false); 15659 } 15660 trimApplications(); 15661 } finally { 15662 Binder.restoreCallingIdentity(origId); 15663 } 15664 } 15665 15666 // ========================================================= 15667 // INSTRUMENTATION 15668 // ========================================================= 15669 15670 public boolean startInstrumentation(ComponentName className, 15671 String profileFile, int flags, Bundle arguments, 15672 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15673 int userId, String abiOverride) { 15674 enforceNotIsolatedCaller("startInstrumentation"); 15675 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15676 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15677 // Refuse possible leaked file descriptors 15678 if (arguments != null && arguments.hasFileDescriptors()) { 15679 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15680 } 15681 15682 synchronized(this) { 15683 InstrumentationInfo ii = null; 15684 ApplicationInfo ai = null; 15685 try { 15686 ii = mContext.getPackageManager().getInstrumentationInfo( 15687 className, STOCK_PM_FLAGS); 15688 ai = AppGlobals.getPackageManager().getApplicationInfo( 15689 ii.targetPackage, STOCK_PM_FLAGS, userId); 15690 } catch (PackageManager.NameNotFoundException e) { 15691 } catch (RemoteException e) { 15692 } 15693 if (ii == null) { 15694 reportStartInstrumentationFailure(watcher, className, 15695 "Unable to find instrumentation info for: " + className); 15696 return false; 15697 } 15698 if (ai == null) { 15699 reportStartInstrumentationFailure(watcher, className, 15700 "Unable to find instrumentation target package: " + ii.targetPackage); 15701 return false; 15702 } 15703 15704 int match = mContext.getPackageManager().checkSignatures( 15705 ii.targetPackage, ii.packageName); 15706 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15707 String msg = "Permission Denial: starting instrumentation " 15708 + className + " from pid=" 15709 + Binder.getCallingPid() 15710 + ", uid=" + Binder.getCallingPid() 15711 + " not allowed because package " + ii.packageName 15712 + " does not have a signature matching the target " 15713 + ii.targetPackage; 15714 reportStartInstrumentationFailure(watcher, className, msg); 15715 throw new SecurityException(msg); 15716 } 15717 15718 final long origId = Binder.clearCallingIdentity(); 15719 // Instrumentation can kill and relaunch even persistent processes 15720 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15721 "start instr"); 15722 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15723 app.instrumentationClass = className; 15724 app.instrumentationInfo = ai; 15725 app.instrumentationProfileFile = profileFile; 15726 app.instrumentationArguments = arguments; 15727 app.instrumentationWatcher = watcher; 15728 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15729 app.instrumentationResultClass = className; 15730 Binder.restoreCallingIdentity(origId); 15731 } 15732 15733 return true; 15734 } 15735 15736 /** 15737 * Report errors that occur while attempting to start Instrumentation. Always writes the 15738 * error to the logs, but if somebody is watching, send the report there too. This enables 15739 * the "am" command to report errors with more information. 15740 * 15741 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15742 * @param cn The component name of the instrumentation. 15743 * @param report The error report. 15744 */ 15745 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15746 ComponentName cn, String report) { 15747 Slog.w(TAG, report); 15748 try { 15749 if (watcher != null) { 15750 Bundle results = new Bundle(); 15751 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15752 results.putString("Error", report); 15753 watcher.instrumentationStatus(cn, -1, results); 15754 } 15755 } catch (RemoteException e) { 15756 Slog.w(TAG, e); 15757 } 15758 } 15759 15760 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15761 if (app.instrumentationWatcher != null) { 15762 try { 15763 // NOTE: IInstrumentationWatcher *must* be oneway here 15764 app.instrumentationWatcher.instrumentationFinished( 15765 app.instrumentationClass, 15766 resultCode, 15767 results); 15768 } catch (RemoteException e) { 15769 } 15770 } 15771 if (app.instrumentationUiAutomationConnection != null) { 15772 try { 15773 app.instrumentationUiAutomationConnection.shutdown(); 15774 } catch (RemoteException re) { 15775 /* ignore */ 15776 } 15777 // Only a UiAutomation can set this flag and now that 15778 // it is finished we make sure it is reset to its default. 15779 mUserIsMonkey = false; 15780 } 15781 app.instrumentationWatcher = null; 15782 app.instrumentationUiAutomationConnection = null; 15783 app.instrumentationClass = null; 15784 app.instrumentationInfo = null; 15785 app.instrumentationProfileFile = null; 15786 app.instrumentationArguments = null; 15787 15788 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15789 "finished inst"); 15790 } 15791 15792 public void finishInstrumentation(IApplicationThread target, 15793 int resultCode, Bundle results) { 15794 int userId = UserHandle.getCallingUserId(); 15795 // Refuse possible leaked file descriptors 15796 if (results != null && results.hasFileDescriptors()) { 15797 throw new IllegalArgumentException("File descriptors passed in Intent"); 15798 } 15799 15800 synchronized(this) { 15801 ProcessRecord app = getRecordForAppLocked(target); 15802 if (app == null) { 15803 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15804 return; 15805 } 15806 final long origId = Binder.clearCallingIdentity(); 15807 finishInstrumentationLocked(app, resultCode, results); 15808 Binder.restoreCallingIdentity(origId); 15809 } 15810 } 15811 15812 // ========================================================= 15813 // CONFIGURATION 15814 // ========================================================= 15815 15816 public ConfigurationInfo getDeviceConfigurationInfo() { 15817 ConfigurationInfo config = new ConfigurationInfo(); 15818 synchronized (this) { 15819 config.reqTouchScreen = mConfiguration.touchscreen; 15820 config.reqKeyboardType = mConfiguration.keyboard; 15821 config.reqNavigation = mConfiguration.navigation; 15822 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15823 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15824 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15825 } 15826 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15827 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15828 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15829 } 15830 config.reqGlEsVersion = GL_ES_VERSION; 15831 } 15832 return config; 15833 } 15834 15835 ActivityStack getFocusedStack() { 15836 return mStackSupervisor.getFocusedStack(); 15837 } 15838 15839 public Configuration getConfiguration() { 15840 Configuration ci; 15841 synchronized(this) { 15842 ci = new Configuration(mConfiguration); 15843 } 15844 return ci; 15845 } 15846 15847 public void updatePersistentConfiguration(Configuration values) { 15848 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15849 "updateConfiguration()"); 15850 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15851 "updateConfiguration()"); 15852 if (values == null) { 15853 throw new NullPointerException("Configuration must not be null"); 15854 } 15855 15856 synchronized(this) { 15857 final long origId = Binder.clearCallingIdentity(); 15858 updateConfigurationLocked(values, null, true, false); 15859 Binder.restoreCallingIdentity(origId); 15860 } 15861 } 15862 15863 public void updateConfiguration(Configuration values) { 15864 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15865 "updateConfiguration()"); 15866 15867 synchronized(this) { 15868 if (values == null && mWindowManager != null) { 15869 // sentinel: fetch the current configuration from the window manager 15870 values = mWindowManager.computeNewConfiguration(); 15871 } 15872 15873 if (mWindowManager != null) { 15874 mProcessList.applyDisplaySize(mWindowManager); 15875 } 15876 15877 final long origId = Binder.clearCallingIdentity(); 15878 if (values != null) { 15879 Settings.System.clearConfiguration(values); 15880 } 15881 updateConfigurationLocked(values, null, false, false); 15882 Binder.restoreCallingIdentity(origId); 15883 } 15884 } 15885 15886 /** 15887 * Do either or both things: (1) change the current configuration, and (2) 15888 * make sure the given activity is running with the (now) current 15889 * configuration. Returns true if the activity has been left running, or 15890 * false if <var>starting</var> is being destroyed to match the new 15891 * configuration. 15892 * @param persistent TODO 15893 */ 15894 boolean updateConfigurationLocked(Configuration values, 15895 ActivityRecord starting, boolean persistent, boolean initLocale) { 15896 int changes = 0; 15897 15898 if (values != null) { 15899 Configuration newConfig = new Configuration(mConfiguration); 15900 changes = newConfig.updateFrom(values); 15901 if (changes != 0) { 15902 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15903 Slog.i(TAG, "Updating configuration to: " + values); 15904 } 15905 15906 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15907 15908 if (values.locale != null && !initLocale) { 15909 saveLocaleLocked(values.locale, 15910 !values.locale.equals(mConfiguration.locale), 15911 values.userSetLocale); 15912 } 15913 15914 mConfigurationSeq++; 15915 if (mConfigurationSeq <= 0) { 15916 mConfigurationSeq = 1; 15917 } 15918 newConfig.seq = mConfigurationSeq; 15919 mConfiguration = newConfig; 15920 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15921 //mUsageStatsService.noteStartConfig(newConfig); 15922 15923 final Configuration configCopy = new Configuration(mConfiguration); 15924 15925 // TODO: If our config changes, should we auto dismiss any currently 15926 // showing dialogs? 15927 mShowDialogs = shouldShowDialogs(newConfig); 15928 15929 AttributeCache ac = AttributeCache.instance(); 15930 if (ac != null) { 15931 ac.updateConfiguration(configCopy); 15932 } 15933 15934 // Make sure all resources in our process are updated 15935 // right now, so that anyone who is going to retrieve 15936 // resource values after we return will be sure to get 15937 // the new ones. This is especially important during 15938 // boot, where the first config change needs to guarantee 15939 // all resources have that config before following boot 15940 // code is executed. 15941 mSystemThread.applyConfigurationToResources(configCopy); 15942 15943 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15944 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15945 msg.obj = new Configuration(configCopy); 15946 mHandler.sendMessage(msg); 15947 } 15948 15949 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15950 ProcessRecord app = mLruProcesses.get(i); 15951 try { 15952 if (app.thread != null) { 15953 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15954 + app.processName + " new config " + mConfiguration); 15955 app.thread.scheduleConfigurationChanged(configCopy); 15956 } 15957 } catch (Exception e) { 15958 } 15959 } 15960 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15961 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15962 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15963 | Intent.FLAG_RECEIVER_FOREGROUND); 15964 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15965 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15966 Process.SYSTEM_UID, UserHandle.USER_ALL); 15967 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15968 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15969 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15970 broadcastIntentLocked(null, null, intent, 15971 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15972 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15973 } 15974 } 15975 } 15976 15977 boolean kept = true; 15978 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15979 // mainStack is null during startup. 15980 if (mainStack != null) { 15981 if (changes != 0 && starting == null) { 15982 // If the configuration changed, and the caller is not already 15983 // in the process of starting an activity, then find the top 15984 // activity to check if its configuration needs to change. 15985 starting = mainStack.topRunningActivityLocked(null); 15986 } 15987 15988 if (starting != null) { 15989 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15990 // And we need to make sure at this point that all other activities 15991 // are made visible with the correct configuration. 15992 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15993 } 15994 } 15995 15996 if (values != null && mWindowManager != null) { 15997 mWindowManager.setNewConfiguration(mConfiguration); 15998 } 15999 16000 return kept; 16001 } 16002 16003 /** 16004 * Decide based on the configuration whether we should shouw the ANR, 16005 * crash, etc dialogs. The idea is that if there is no affordnace to 16006 * press the on-screen buttons, we shouldn't show the dialog. 16007 * 16008 * A thought: SystemUI might also want to get told about this, the Power 16009 * dialog / global actions also might want different behaviors. 16010 */ 16011 private static final boolean shouldShowDialogs(Configuration config) { 16012 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16013 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16014 } 16015 16016 /** 16017 * Save the locale. You must be inside a synchronized (this) block. 16018 */ 16019 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16020 if(isDiff) { 16021 SystemProperties.set("user.language", l.getLanguage()); 16022 SystemProperties.set("user.region", l.getCountry()); 16023 } 16024 16025 if(isPersist) { 16026 SystemProperties.set("persist.sys.language", l.getLanguage()); 16027 SystemProperties.set("persist.sys.country", l.getCountry()); 16028 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16029 } 16030 } 16031 16032 @Override 16033 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16034 synchronized (this) { 16035 ActivityRecord srec = ActivityRecord.forToken(token); 16036 if (srec.task != null && srec.task.stack != null) { 16037 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16038 } 16039 } 16040 return false; 16041 } 16042 16043 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16044 Intent resultData) { 16045 16046 synchronized (this) { 16047 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16048 if (stack != null) { 16049 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16050 } 16051 return false; 16052 } 16053 } 16054 16055 public int getLaunchedFromUid(IBinder activityToken) { 16056 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16057 if (srec == null) { 16058 return -1; 16059 } 16060 return srec.launchedFromUid; 16061 } 16062 16063 public String getLaunchedFromPackage(IBinder activityToken) { 16064 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16065 if (srec == null) { 16066 return null; 16067 } 16068 return srec.launchedFromPackage; 16069 } 16070 16071 // ========================================================= 16072 // LIFETIME MANAGEMENT 16073 // ========================================================= 16074 16075 // Returns which broadcast queue the app is the current [or imminent] receiver 16076 // on, or 'null' if the app is not an active broadcast recipient. 16077 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16078 BroadcastRecord r = app.curReceiver; 16079 if (r != null) { 16080 return r.queue; 16081 } 16082 16083 // It's not the current receiver, but it might be starting up to become one 16084 synchronized (this) { 16085 for (BroadcastQueue queue : mBroadcastQueues) { 16086 r = queue.mPendingBroadcast; 16087 if (r != null && r.curApp == app) { 16088 // found it; report which queue it's in 16089 return queue; 16090 } 16091 } 16092 } 16093 16094 return null; 16095 } 16096 16097 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16098 boolean doingAll, long now) { 16099 if (mAdjSeq == app.adjSeq) { 16100 // This adjustment has already been computed. 16101 return app.curRawAdj; 16102 } 16103 16104 if (app.thread == null) { 16105 app.adjSeq = mAdjSeq; 16106 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16107 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16108 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16109 } 16110 16111 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16112 app.adjSource = null; 16113 app.adjTarget = null; 16114 app.empty = false; 16115 app.cached = false; 16116 16117 final int activitiesSize = app.activities.size(); 16118 16119 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16120 // The max adjustment doesn't allow this app to be anything 16121 // below foreground, so it is not worth doing work for it. 16122 app.adjType = "fixed"; 16123 app.adjSeq = mAdjSeq; 16124 app.curRawAdj = app.maxAdj; 16125 app.foregroundActivities = false; 16126 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16127 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16128 // System processes can do UI, and when they do we want to have 16129 // them trim their memory after the user leaves the UI. To 16130 // facilitate this, here we need to determine whether or not it 16131 // is currently showing UI. 16132 app.systemNoUi = true; 16133 if (app == TOP_APP) { 16134 app.systemNoUi = false; 16135 } else if (activitiesSize > 0) { 16136 for (int j = 0; j < activitiesSize; j++) { 16137 final ActivityRecord r = app.activities.get(j); 16138 if (r.visible) { 16139 app.systemNoUi = false; 16140 } 16141 } 16142 } 16143 if (!app.systemNoUi) { 16144 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16145 } 16146 return (app.curAdj=app.maxAdj); 16147 } 16148 16149 app.systemNoUi = false; 16150 16151 // Determine the importance of the process, starting with most 16152 // important to least, and assign an appropriate OOM adjustment. 16153 int adj; 16154 int schedGroup; 16155 int procState; 16156 boolean foregroundActivities = false; 16157 BroadcastQueue queue; 16158 if (app == TOP_APP) { 16159 // The last app on the list is the foreground app. 16160 adj = ProcessList.FOREGROUND_APP_ADJ; 16161 schedGroup = Process.THREAD_GROUP_DEFAULT; 16162 app.adjType = "top-activity"; 16163 foregroundActivities = true; 16164 procState = ActivityManager.PROCESS_STATE_TOP; 16165 } else if (app.instrumentationClass != null) { 16166 // Don't want to kill running instrumentation. 16167 adj = ProcessList.FOREGROUND_APP_ADJ; 16168 schedGroup = Process.THREAD_GROUP_DEFAULT; 16169 app.adjType = "instrumentation"; 16170 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16171 } else if ((queue = isReceivingBroadcast(app)) != null) { 16172 // An app that is currently receiving a broadcast also 16173 // counts as being in the foreground for OOM killer purposes. 16174 // It's placed in a sched group based on the nature of the 16175 // broadcast as reflected by which queue it's active in. 16176 adj = ProcessList.FOREGROUND_APP_ADJ; 16177 schedGroup = (queue == mFgBroadcastQueue) 16178 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16179 app.adjType = "broadcast"; 16180 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16181 } else if (app.executingServices.size() > 0) { 16182 // An app that is currently executing a service callback also 16183 // counts as being in the foreground. 16184 adj = ProcessList.FOREGROUND_APP_ADJ; 16185 schedGroup = app.execServicesFg ? 16186 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16187 app.adjType = "exec-service"; 16188 procState = ActivityManager.PROCESS_STATE_SERVICE; 16189 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16190 } else { 16191 // As far as we know the process is empty. We may change our mind later. 16192 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16193 // At this point we don't actually know the adjustment. Use the cached adj 16194 // value that the caller wants us to. 16195 adj = cachedAdj; 16196 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16197 app.cached = true; 16198 app.empty = true; 16199 app.adjType = "cch-empty"; 16200 } 16201 16202 // Examine all activities if not already foreground. 16203 if (!foregroundActivities && activitiesSize > 0) { 16204 for (int j = 0; j < activitiesSize; j++) { 16205 final ActivityRecord r = app.activities.get(j); 16206 if (r.app != app) { 16207 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16208 + app + "?!?"); 16209 continue; 16210 } 16211 if (r.visible) { 16212 // App has a visible activity; only upgrade adjustment. 16213 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16214 adj = ProcessList.VISIBLE_APP_ADJ; 16215 app.adjType = "visible"; 16216 } 16217 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16218 procState = ActivityManager.PROCESS_STATE_TOP; 16219 } 16220 schedGroup = Process.THREAD_GROUP_DEFAULT; 16221 app.cached = false; 16222 app.empty = false; 16223 foregroundActivities = true; 16224 break; 16225 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16226 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16227 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16228 app.adjType = "pausing"; 16229 } 16230 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16231 procState = ActivityManager.PROCESS_STATE_TOP; 16232 } 16233 schedGroup = Process.THREAD_GROUP_DEFAULT; 16234 app.cached = false; 16235 app.empty = false; 16236 foregroundActivities = true; 16237 } else if (r.state == ActivityState.STOPPING) { 16238 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16239 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16240 app.adjType = "stopping"; 16241 } 16242 // For the process state, we will at this point consider the 16243 // process to be cached. It will be cached either as an activity 16244 // or empty depending on whether the activity is finishing. We do 16245 // this so that we can treat the process as cached for purposes of 16246 // memory trimming (determing current memory level, trim command to 16247 // send to process) since there can be an arbitrary number of stopping 16248 // processes and they should soon all go into the cached state. 16249 if (!r.finishing) { 16250 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16251 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16252 } 16253 } 16254 app.cached = false; 16255 app.empty = false; 16256 foregroundActivities = true; 16257 } else { 16258 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16259 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16260 app.adjType = "cch-act"; 16261 } 16262 } 16263 } 16264 } 16265 16266 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16267 if (app.foregroundServices) { 16268 // The user is aware of this app, so make it visible. 16269 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16270 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16271 app.cached = false; 16272 app.adjType = "fg-service"; 16273 schedGroup = Process.THREAD_GROUP_DEFAULT; 16274 } else if (app.forcingToForeground != null) { 16275 // The user is aware of this app, so make it visible. 16276 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16277 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16278 app.cached = false; 16279 app.adjType = "force-fg"; 16280 app.adjSource = app.forcingToForeground; 16281 schedGroup = Process.THREAD_GROUP_DEFAULT; 16282 } 16283 } 16284 16285 if (app == mHeavyWeightProcess) { 16286 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16287 // We don't want to kill the current heavy-weight process. 16288 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16289 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16290 app.cached = false; 16291 app.adjType = "heavy"; 16292 } 16293 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16294 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16295 } 16296 } 16297 16298 if (app == mHomeProcess) { 16299 if (adj > ProcessList.HOME_APP_ADJ) { 16300 // This process is hosting what we currently consider to be the 16301 // home app, so we don't want to let it go into the background. 16302 adj = ProcessList.HOME_APP_ADJ; 16303 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16304 app.cached = false; 16305 app.adjType = "home"; 16306 } 16307 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16308 procState = ActivityManager.PROCESS_STATE_HOME; 16309 } 16310 } 16311 16312 if (app == mPreviousProcess && app.activities.size() > 0) { 16313 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16314 // This was the previous process that showed UI to the user. 16315 // We want to try to keep it around more aggressively, to give 16316 // a good experience around switching between two apps. 16317 adj = ProcessList.PREVIOUS_APP_ADJ; 16318 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16319 app.cached = false; 16320 app.adjType = "previous"; 16321 } 16322 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16323 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16324 } 16325 } 16326 16327 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16328 + " reason=" + app.adjType); 16329 16330 // By default, we use the computed adjustment. It may be changed if 16331 // there are applications dependent on our services or providers, but 16332 // this gives us a baseline and makes sure we don't get into an 16333 // infinite recursion. 16334 app.adjSeq = mAdjSeq; 16335 app.curRawAdj = adj; 16336 app.hasStartedServices = false; 16337 16338 if (mBackupTarget != null && app == mBackupTarget.app) { 16339 // If possible we want to avoid killing apps while they're being backed up 16340 if (adj > ProcessList.BACKUP_APP_ADJ) { 16341 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16342 adj = ProcessList.BACKUP_APP_ADJ; 16343 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16344 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16345 } 16346 app.adjType = "backup"; 16347 app.cached = false; 16348 } 16349 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16350 procState = ActivityManager.PROCESS_STATE_BACKUP; 16351 } 16352 } 16353 16354 boolean mayBeTop = false; 16355 16356 for (int is = app.services.size()-1; 16357 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16358 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16359 || procState > ActivityManager.PROCESS_STATE_TOP); 16360 is--) { 16361 ServiceRecord s = app.services.valueAt(is); 16362 if (s.startRequested) { 16363 app.hasStartedServices = true; 16364 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16365 procState = ActivityManager.PROCESS_STATE_SERVICE; 16366 } 16367 if (app.hasShownUi && app != mHomeProcess) { 16368 // If this process has shown some UI, let it immediately 16369 // go to the LRU list because it may be pretty heavy with 16370 // UI stuff. We'll tag it with a label just to help 16371 // debug and understand what is going on. 16372 if (adj > ProcessList.SERVICE_ADJ) { 16373 app.adjType = "cch-started-ui-services"; 16374 } 16375 } else { 16376 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16377 // This service has seen some activity within 16378 // recent memory, so we will keep its process ahead 16379 // of the background processes. 16380 if (adj > ProcessList.SERVICE_ADJ) { 16381 adj = ProcessList.SERVICE_ADJ; 16382 app.adjType = "started-services"; 16383 app.cached = false; 16384 } 16385 } 16386 // If we have let the service slide into the background 16387 // state, still have some text describing what it is doing 16388 // even though the service no longer has an impact. 16389 if (adj > ProcessList.SERVICE_ADJ) { 16390 app.adjType = "cch-started-services"; 16391 } 16392 } 16393 } 16394 for (int conni = s.connections.size()-1; 16395 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16396 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16397 || procState > ActivityManager.PROCESS_STATE_TOP); 16398 conni--) { 16399 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16400 for (int i = 0; 16401 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16402 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16403 || procState > ActivityManager.PROCESS_STATE_TOP); 16404 i++) { 16405 // XXX should compute this based on the max of 16406 // all connected clients. 16407 ConnectionRecord cr = clist.get(i); 16408 if (cr.binding.client == app) { 16409 // Binding to ourself is not interesting. 16410 continue; 16411 } 16412 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16413 ProcessRecord client = cr.binding.client; 16414 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16415 TOP_APP, doingAll, now); 16416 int clientProcState = client.curProcState; 16417 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16418 // If the other app is cached for any reason, for purposes here 16419 // we are going to consider it empty. The specific cached state 16420 // doesn't propagate except under certain conditions. 16421 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16422 } 16423 String adjType = null; 16424 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16425 // Not doing bind OOM management, so treat 16426 // this guy more like a started service. 16427 if (app.hasShownUi && app != mHomeProcess) { 16428 // If this process has shown some UI, let it immediately 16429 // go to the LRU list because it may be pretty heavy with 16430 // UI stuff. We'll tag it with a label just to help 16431 // debug and understand what is going on. 16432 if (adj > clientAdj) { 16433 adjType = "cch-bound-ui-services"; 16434 } 16435 app.cached = false; 16436 clientAdj = adj; 16437 clientProcState = procState; 16438 } else { 16439 if (now >= (s.lastActivity 16440 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16441 // This service has not seen activity within 16442 // recent memory, so allow it to drop to the 16443 // LRU list if there is no other reason to keep 16444 // it around. We'll also tag it with a label just 16445 // to help debug and undertand what is going on. 16446 if (adj > clientAdj) { 16447 adjType = "cch-bound-services"; 16448 } 16449 clientAdj = adj; 16450 } 16451 } 16452 } 16453 if (adj > clientAdj) { 16454 // If this process has recently shown UI, and 16455 // the process that is binding to it is less 16456 // important than being visible, then we don't 16457 // care about the binding as much as we care 16458 // about letting this process get into the LRU 16459 // list to be killed and restarted if needed for 16460 // memory. 16461 if (app.hasShownUi && app != mHomeProcess 16462 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16463 adjType = "cch-bound-ui-services"; 16464 } else { 16465 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16466 |Context.BIND_IMPORTANT)) != 0) { 16467 adj = clientAdj; 16468 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16469 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16470 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16471 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16472 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16473 adj = clientAdj; 16474 } else { 16475 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16476 adj = ProcessList.VISIBLE_APP_ADJ; 16477 } 16478 } 16479 if (!client.cached) { 16480 app.cached = false; 16481 } 16482 adjType = "service"; 16483 } 16484 } 16485 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16486 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16487 schedGroup = Process.THREAD_GROUP_DEFAULT; 16488 } 16489 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16490 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16491 // Special handling of clients who are in the top state. 16492 // We *may* want to consider this process to be in the 16493 // top state as well, but only if there is not another 16494 // reason for it to be running. Being on the top is a 16495 // special state, meaning you are specifically running 16496 // for the current top app. If the process is already 16497 // running in the background for some other reason, it 16498 // is more important to continue considering it to be 16499 // in the background state. 16500 mayBeTop = true; 16501 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16502 } else { 16503 // Special handling for above-top states (persistent 16504 // processes). These should not bring the current process 16505 // into the top state, since they are not on top. Instead 16506 // give them the best state after that. 16507 clientProcState = 16508 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16509 } 16510 } 16511 } else { 16512 if (clientProcState < 16513 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16514 clientProcState = 16515 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16516 } 16517 } 16518 if (procState > clientProcState) { 16519 procState = clientProcState; 16520 } 16521 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16522 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16523 app.pendingUiClean = true; 16524 } 16525 if (adjType != null) { 16526 app.adjType = adjType; 16527 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16528 .REASON_SERVICE_IN_USE; 16529 app.adjSource = cr.binding.client; 16530 app.adjSourceProcState = clientProcState; 16531 app.adjTarget = s.name; 16532 } 16533 } 16534 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16535 app.treatLikeActivity = true; 16536 } 16537 final ActivityRecord a = cr.activity; 16538 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16539 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16540 (a.visible || a.state == ActivityState.RESUMED 16541 || a.state == ActivityState.PAUSING)) { 16542 adj = ProcessList.FOREGROUND_APP_ADJ; 16543 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16544 schedGroup = Process.THREAD_GROUP_DEFAULT; 16545 } 16546 app.cached = false; 16547 app.adjType = "service"; 16548 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16549 .REASON_SERVICE_IN_USE; 16550 app.adjSource = a; 16551 app.adjSourceProcState = procState; 16552 app.adjTarget = s.name; 16553 } 16554 } 16555 } 16556 } 16557 } 16558 16559 for (int provi = app.pubProviders.size()-1; 16560 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16561 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16562 || procState > ActivityManager.PROCESS_STATE_TOP); 16563 provi--) { 16564 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16565 for (int i = cpr.connections.size()-1; 16566 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16567 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16568 || procState > ActivityManager.PROCESS_STATE_TOP); 16569 i--) { 16570 ContentProviderConnection conn = cpr.connections.get(i); 16571 ProcessRecord client = conn.client; 16572 if (client == app) { 16573 // Being our own client is not interesting. 16574 continue; 16575 } 16576 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16577 int clientProcState = client.curProcState; 16578 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16579 // If the other app is cached for any reason, for purposes here 16580 // we are going to consider it empty. 16581 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16582 } 16583 if (adj > clientAdj) { 16584 if (app.hasShownUi && app != mHomeProcess 16585 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16586 app.adjType = "cch-ui-provider"; 16587 } else { 16588 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16589 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16590 app.adjType = "provider"; 16591 } 16592 app.cached &= client.cached; 16593 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16594 .REASON_PROVIDER_IN_USE; 16595 app.adjSource = client; 16596 app.adjSourceProcState = clientProcState; 16597 app.adjTarget = cpr.name; 16598 } 16599 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16600 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16601 // Special handling of clients who are in the top state. 16602 // We *may* want to consider this process to be in the 16603 // top state as well, but only if there is not another 16604 // reason for it to be running. Being on the top is a 16605 // special state, meaning you are specifically running 16606 // for the current top app. If the process is already 16607 // running in the background for some other reason, it 16608 // is more important to continue considering it to be 16609 // in the background state. 16610 mayBeTop = true; 16611 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16612 } else { 16613 // Special handling for above-top states (persistent 16614 // processes). These should not bring the current process 16615 // into the top state, since they are not on top. Instead 16616 // give them the best state after that. 16617 clientProcState = 16618 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16619 } 16620 } 16621 if (procState > clientProcState) { 16622 procState = clientProcState; 16623 } 16624 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16625 schedGroup = Process.THREAD_GROUP_DEFAULT; 16626 } 16627 } 16628 // If the provider has external (non-framework) process 16629 // dependencies, ensure that its adjustment is at least 16630 // FOREGROUND_APP_ADJ. 16631 if (cpr.hasExternalProcessHandles()) { 16632 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16633 adj = ProcessList.FOREGROUND_APP_ADJ; 16634 schedGroup = Process.THREAD_GROUP_DEFAULT; 16635 app.cached = false; 16636 app.adjType = "provider"; 16637 app.adjTarget = cpr.name; 16638 } 16639 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16640 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16641 } 16642 } 16643 } 16644 16645 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16646 // A client of one of our services or providers is in the top state. We 16647 // *may* want to be in the top state, but not if we are already running in 16648 // the background for some other reason. For the decision here, we are going 16649 // to pick out a few specific states that we want to remain in when a client 16650 // is top (states that tend to be longer-term) and otherwise allow it to go 16651 // to the top state. 16652 switch (procState) { 16653 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16654 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16655 case ActivityManager.PROCESS_STATE_SERVICE: 16656 // These all are longer-term states, so pull them up to the top 16657 // of the background states, but not all the way to the top state. 16658 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16659 break; 16660 default: 16661 // Otherwise, top is a better choice, so take it. 16662 procState = ActivityManager.PROCESS_STATE_TOP; 16663 break; 16664 } 16665 } 16666 16667 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16668 if (app.hasClientActivities) { 16669 // This is a cached process, but with client activities. Mark it so. 16670 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16671 app.adjType = "cch-client-act"; 16672 } else if (app.treatLikeActivity) { 16673 // This is a cached process, but somebody wants us to treat it like it has 16674 // an activity, okay! 16675 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16676 app.adjType = "cch-as-act"; 16677 } 16678 } 16679 16680 if (adj == ProcessList.SERVICE_ADJ) { 16681 if (doingAll) { 16682 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16683 mNewNumServiceProcs++; 16684 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16685 if (!app.serviceb) { 16686 // This service isn't far enough down on the LRU list to 16687 // normally be a B service, but if we are low on RAM and it 16688 // is large we want to force it down since we would prefer to 16689 // keep launcher over it. 16690 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16691 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16692 app.serviceHighRam = true; 16693 app.serviceb = true; 16694 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16695 } else { 16696 mNewNumAServiceProcs++; 16697 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16698 } 16699 } else { 16700 app.serviceHighRam = false; 16701 } 16702 } 16703 if (app.serviceb) { 16704 adj = ProcessList.SERVICE_B_ADJ; 16705 } 16706 } 16707 16708 app.curRawAdj = adj; 16709 16710 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16711 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16712 if (adj > app.maxAdj) { 16713 adj = app.maxAdj; 16714 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16715 schedGroup = Process.THREAD_GROUP_DEFAULT; 16716 } 16717 } 16718 16719 // Do final modification to adj. Everything we do between here and applying 16720 // the final setAdj must be done in this function, because we will also use 16721 // it when computing the final cached adj later. Note that we don't need to 16722 // worry about this for max adj above, since max adj will always be used to 16723 // keep it out of the cached vaues. 16724 app.curAdj = app.modifyRawOomAdj(adj); 16725 app.curSchedGroup = schedGroup; 16726 app.curProcState = procState; 16727 app.foregroundActivities = foregroundActivities; 16728 16729 return app.curRawAdj; 16730 } 16731 16732 /** 16733 * Schedule PSS collection of a process. 16734 */ 16735 void requestPssLocked(ProcessRecord proc, int procState) { 16736 if (mPendingPssProcesses.contains(proc)) { 16737 return; 16738 } 16739 if (mPendingPssProcesses.size() == 0) { 16740 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16741 } 16742 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16743 proc.pssProcState = procState; 16744 mPendingPssProcesses.add(proc); 16745 } 16746 16747 /** 16748 * Schedule PSS collection of all processes. 16749 */ 16750 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16751 if (!always) { 16752 if (now < (mLastFullPssTime + 16753 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16754 return; 16755 } 16756 } 16757 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16758 mLastFullPssTime = now; 16759 mFullPssPending = true; 16760 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16761 mPendingPssProcesses.clear(); 16762 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16763 ProcessRecord app = mLruProcesses.get(i); 16764 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16765 app.pssProcState = app.setProcState; 16766 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16767 isSleeping(), now); 16768 mPendingPssProcesses.add(app); 16769 } 16770 } 16771 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16772 } 16773 16774 /** 16775 * Ask a given process to GC right now. 16776 */ 16777 final void performAppGcLocked(ProcessRecord app) { 16778 try { 16779 app.lastRequestedGc = SystemClock.uptimeMillis(); 16780 if (app.thread != null) { 16781 if (app.reportLowMemory) { 16782 app.reportLowMemory = false; 16783 app.thread.scheduleLowMemory(); 16784 } else { 16785 app.thread.processInBackground(); 16786 } 16787 } 16788 } catch (Exception e) { 16789 // whatever. 16790 } 16791 } 16792 16793 /** 16794 * Returns true if things are idle enough to perform GCs. 16795 */ 16796 private final boolean canGcNowLocked() { 16797 boolean processingBroadcasts = false; 16798 for (BroadcastQueue q : mBroadcastQueues) { 16799 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16800 processingBroadcasts = true; 16801 } 16802 } 16803 return !processingBroadcasts 16804 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16805 } 16806 16807 /** 16808 * Perform GCs on all processes that are waiting for it, but only 16809 * if things are idle. 16810 */ 16811 final void performAppGcsLocked() { 16812 final int N = mProcessesToGc.size(); 16813 if (N <= 0) { 16814 return; 16815 } 16816 if (canGcNowLocked()) { 16817 while (mProcessesToGc.size() > 0) { 16818 ProcessRecord proc = mProcessesToGc.remove(0); 16819 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16820 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16821 <= SystemClock.uptimeMillis()) { 16822 // To avoid spamming the system, we will GC processes one 16823 // at a time, waiting a few seconds between each. 16824 performAppGcLocked(proc); 16825 scheduleAppGcsLocked(); 16826 return; 16827 } else { 16828 // It hasn't been long enough since we last GCed this 16829 // process... put it in the list to wait for its time. 16830 addProcessToGcListLocked(proc); 16831 break; 16832 } 16833 } 16834 } 16835 16836 scheduleAppGcsLocked(); 16837 } 16838 } 16839 16840 /** 16841 * If all looks good, perform GCs on all processes waiting for them. 16842 */ 16843 final void performAppGcsIfAppropriateLocked() { 16844 if (canGcNowLocked()) { 16845 performAppGcsLocked(); 16846 return; 16847 } 16848 // Still not idle, wait some more. 16849 scheduleAppGcsLocked(); 16850 } 16851 16852 /** 16853 * Schedule the execution of all pending app GCs. 16854 */ 16855 final void scheduleAppGcsLocked() { 16856 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16857 16858 if (mProcessesToGc.size() > 0) { 16859 // Schedule a GC for the time to the next process. 16860 ProcessRecord proc = mProcessesToGc.get(0); 16861 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16862 16863 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16864 long now = SystemClock.uptimeMillis(); 16865 if (when < (now+GC_TIMEOUT)) { 16866 when = now + GC_TIMEOUT; 16867 } 16868 mHandler.sendMessageAtTime(msg, when); 16869 } 16870 } 16871 16872 /** 16873 * Add a process to the array of processes waiting to be GCed. Keeps the 16874 * list in sorted order by the last GC time. The process can't already be 16875 * on the list. 16876 */ 16877 final void addProcessToGcListLocked(ProcessRecord proc) { 16878 boolean added = false; 16879 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16880 if (mProcessesToGc.get(i).lastRequestedGc < 16881 proc.lastRequestedGc) { 16882 added = true; 16883 mProcessesToGc.add(i+1, proc); 16884 break; 16885 } 16886 } 16887 if (!added) { 16888 mProcessesToGc.add(0, proc); 16889 } 16890 } 16891 16892 /** 16893 * Set up to ask a process to GC itself. This will either do it 16894 * immediately, or put it on the list of processes to gc the next 16895 * time things are idle. 16896 */ 16897 final void scheduleAppGcLocked(ProcessRecord app) { 16898 long now = SystemClock.uptimeMillis(); 16899 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16900 return; 16901 } 16902 if (!mProcessesToGc.contains(app)) { 16903 addProcessToGcListLocked(app); 16904 scheduleAppGcsLocked(); 16905 } 16906 } 16907 16908 final void checkExcessivePowerUsageLocked(boolean doKills) { 16909 updateCpuStatsNow(); 16910 16911 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16912 boolean doWakeKills = doKills; 16913 boolean doCpuKills = doKills; 16914 if (mLastPowerCheckRealtime == 0) { 16915 doWakeKills = false; 16916 } 16917 if (mLastPowerCheckUptime == 0) { 16918 doCpuKills = false; 16919 } 16920 if (stats.isScreenOn()) { 16921 doWakeKills = false; 16922 } 16923 final long curRealtime = SystemClock.elapsedRealtime(); 16924 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16925 final long curUptime = SystemClock.uptimeMillis(); 16926 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16927 mLastPowerCheckRealtime = curRealtime; 16928 mLastPowerCheckUptime = curUptime; 16929 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16930 doWakeKills = false; 16931 } 16932 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16933 doCpuKills = false; 16934 } 16935 int i = mLruProcesses.size(); 16936 while (i > 0) { 16937 i--; 16938 ProcessRecord app = mLruProcesses.get(i); 16939 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16940 long wtime; 16941 synchronized (stats) { 16942 wtime = stats.getProcessWakeTime(app.info.uid, 16943 app.pid, curRealtime); 16944 } 16945 long wtimeUsed = wtime - app.lastWakeTime; 16946 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16947 if (DEBUG_POWER) { 16948 StringBuilder sb = new StringBuilder(128); 16949 sb.append("Wake for "); 16950 app.toShortString(sb); 16951 sb.append(": over "); 16952 TimeUtils.formatDuration(realtimeSince, sb); 16953 sb.append(" used "); 16954 TimeUtils.formatDuration(wtimeUsed, sb); 16955 sb.append(" ("); 16956 sb.append((wtimeUsed*100)/realtimeSince); 16957 sb.append("%)"); 16958 Slog.i(TAG, sb.toString()); 16959 sb.setLength(0); 16960 sb.append("CPU for "); 16961 app.toShortString(sb); 16962 sb.append(": over "); 16963 TimeUtils.formatDuration(uptimeSince, sb); 16964 sb.append(" used "); 16965 TimeUtils.formatDuration(cputimeUsed, sb); 16966 sb.append(" ("); 16967 sb.append((cputimeUsed*100)/uptimeSince); 16968 sb.append("%)"); 16969 Slog.i(TAG, sb.toString()); 16970 } 16971 // If a process has held a wake lock for more 16972 // than 50% of the time during this period, 16973 // that sounds bad. Kill! 16974 if (doWakeKills && realtimeSince > 0 16975 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16976 synchronized (stats) { 16977 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16978 realtimeSince, wtimeUsed); 16979 } 16980 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16981 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16982 } else if (doCpuKills && uptimeSince > 0 16983 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16984 synchronized (stats) { 16985 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16986 uptimeSince, cputimeUsed); 16987 } 16988 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 16989 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16990 } else { 16991 app.lastWakeTime = wtime; 16992 app.lastCpuTime = app.curCpuTime; 16993 } 16994 } 16995 } 16996 } 16997 16998 private final boolean applyOomAdjLocked(ProcessRecord app, 16999 ProcessRecord TOP_APP, boolean doingAll, long now) { 17000 boolean success = true; 17001 17002 if (app.curRawAdj != app.setRawAdj) { 17003 app.setRawAdj = app.curRawAdj; 17004 } 17005 17006 int changes = 0; 17007 17008 if (app.curAdj != app.setAdj) { 17009 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17010 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17011 TAG, "Set " + app.pid + " " + app.processName + 17012 " adj " + app.curAdj + ": " + app.adjType); 17013 app.setAdj = app.curAdj; 17014 } 17015 17016 if (app.setSchedGroup != app.curSchedGroup) { 17017 app.setSchedGroup = app.curSchedGroup; 17018 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17019 "Setting process group of " + app.processName 17020 + " to " + app.curSchedGroup); 17021 if (app.waitingToKill != null && 17022 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17023 app.kill(app.waitingToKill, true); 17024 success = false; 17025 } else { 17026 if (true) { 17027 long oldId = Binder.clearCallingIdentity(); 17028 try { 17029 Process.setProcessGroup(app.pid, app.curSchedGroup); 17030 } catch (Exception e) { 17031 Slog.w(TAG, "Failed setting process group of " + app.pid 17032 + " to " + app.curSchedGroup); 17033 e.printStackTrace(); 17034 } finally { 17035 Binder.restoreCallingIdentity(oldId); 17036 } 17037 } else { 17038 if (app.thread != null) { 17039 try { 17040 app.thread.setSchedulingGroup(app.curSchedGroup); 17041 } catch (RemoteException e) { 17042 } 17043 } 17044 } 17045 Process.setSwappiness(app.pid, 17046 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17047 } 17048 } 17049 if (app.repForegroundActivities != app.foregroundActivities) { 17050 app.repForegroundActivities = app.foregroundActivities; 17051 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17052 } 17053 if (app.repProcState != app.curProcState) { 17054 app.repProcState = app.curProcState; 17055 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17056 if (app.thread != null) { 17057 try { 17058 if (false) { 17059 //RuntimeException h = new RuntimeException("here"); 17060 Slog.i(TAG, "Sending new process state " + app.repProcState 17061 + " to " + app /*, h*/); 17062 } 17063 app.thread.setProcessState(app.repProcState); 17064 } catch (RemoteException e) { 17065 } 17066 } 17067 } 17068 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17069 app.setProcState)) { 17070 app.lastStateTime = now; 17071 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17072 isSleeping(), now); 17073 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17074 + ProcessList.makeProcStateString(app.setProcState) + " to " 17075 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17076 + (app.nextPssTime-now) + ": " + app); 17077 } else { 17078 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17079 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17080 requestPssLocked(app, app.setProcState); 17081 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17082 isSleeping(), now); 17083 } else if (false && DEBUG_PSS) { 17084 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17085 } 17086 } 17087 if (app.setProcState != app.curProcState) { 17088 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17089 "Proc state change of " + app.processName 17090 + " to " + app.curProcState); 17091 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17092 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17093 if (setImportant && !curImportant) { 17094 // This app is no longer something we consider important enough to allow to 17095 // use arbitrary amounts of battery power. Note 17096 // its current wake lock time to later know to kill it if 17097 // it is not behaving well. 17098 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17099 synchronized (stats) { 17100 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17101 app.pid, SystemClock.elapsedRealtime()); 17102 } 17103 app.lastCpuTime = app.curCpuTime; 17104 17105 } 17106 app.setProcState = app.curProcState; 17107 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17108 app.notCachedSinceIdle = false; 17109 } 17110 if (!doingAll) { 17111 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17112 } else { 17113 app.procStateChanged = true; 17114 } 17115 } 17116 17117 if (changes != 0) { 17118 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17119 int i = mPendingProcessChanges.size()-1; 17120 ProcessChangeItem item = null; 17121 while (i >= 0) { 17122 item = mPendingProcessChanges.get(i); 17123 if (item.pid == app.pid) { 17124 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17125 break; 17126 } 17127 i--; 17128 } 17129 if (i < 0) { 17130 // No existing item in pending changes; need a new one. 17131 final int NA = mAvailProcessChanges.size(); 17132 if (NA > 0) { 17133 item = mAvailProcessChanges.remove(NA-1); 17134 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17135 } else { 17136 item = new ProcessChangeItem(); 17137 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17138 } 17139 item.changes = 0; 17140 item.pid = app.pid; 17141 item.uid = app.info.uid; 17142 if (mPendingProcessChanges.size() == 0) { 17143 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17144 "*** Enqueueing dispatch processes changed!"); 17145 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17146 } 17147 mPendingProcessChanges.add(item); 17148 } 17149 item.changes |= changes; 17150 item.processState = app.repProcState; 17151 item.foregroundActivities = app.repForegroundActivities; 17152 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17153 + Integer.toHexString(System.identityHashCode(item)) 17154 + " " + app.toShortString() + ": changes=" + item.changes 17155 + " procState=" + item.processState 17156 + " foreground=" + item.foregroundActivities 17157 + " type=" + app.adjType + " source=" + app.adjSource 17158 + " target=" + app.adjTarget); 17159 } 17160 17161 return success; 17162 } 17163 17164 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17165 if (proc.thread != null) { 17166 if (proc.baseProcessTracker != null) { 17167 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17168 } 17169 if (proc.repProcState >= 0) { 17170 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17171 proc.repProcState); 17172 } 17173 } 17174 } 17175 17176 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17177 ProcessRecord TOP_APP, boolean doingAll, long now) { 17178 if (app.thread == null) { 17179 return false; 17180 } 17181 17182 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17183 17184 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17185 } 17186 17187 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17188 boolean oomAdj) { 17189 if (isForeground != proc.foregroundServices) { 17190 proc.foregroundServices = isForeground; 17191 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17192 proc.info.uid); 17193 if (isForeground) { 17194 if (curProcs == null) { 17195 curProcs = new ArrayList<ProcessRecord>(); 17196 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17197 } 17198 if (!curProcs.contains(proc)) { 17199 curProcs.add(proc); 17200 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17201 proc.info.packageName, proc.info.uid); 17202 } 17203 } else { 17204 if (curProcs != null) { 17205 if (curProcs.remove(proc)) { 17206 mBatteryStatsService.noteEvent( 17207 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17208 proc.info.packageName, proc.info.uid); 17209 if (curProcs.size() <= 0) { 17210 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17211 } 17212 } 17213 } 17214 } 17215 if (oomAdj) { 17216 updateOomAdjLocked(); 17217 } 17218 } 17219 } 17220 17221 private final ActivityRecord resumedAppLocked() { 17222 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17223 String pkg; 17224 int uid; 17225 if (act != null) { 17226 pkg = act.packageName; 17227 uid = act.info.applicationInfo.uid; 17228 } else { 17229 pkg = null; 17230 uid = -1; 17231 } 17232 // Has the UID or resumed package name changed? 17233 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17234 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17235 if (mCurResumedPackage != null) { 17236 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17237 mCurResumedPackage, mCurResumedUid); 17238 } 17239 mCurResumedPackage = pkg; 17240 mCurResumedUid = uid; 17241 if (mCurResumedPackage != null) { 17242 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17243 mCurResumedPackage, mCurResumedUid); 17244 } 17245 } 17246 return act; 17247 } 17248 17249 final boolean updateOomAdjLocked(ProcessRecord app) { 17250 final ActivityRecord TOP_ACT = resumedAppLocked(); 17251 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17252 final boolean wasCached = app.cached; 17253 17254 mAdjSeq++; 17255 17256 // This is the desired cached adjusment we want to tell it to use. 17257 // If our app is currently cached, we know it, and that is it. Otherwise, 17258 // we don't know it yet, and it needs to now be cached we will then 17259 // need to do a complete oom adj. 17260 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17261 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17262 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17263 SystemClock.uptimeMillis()); 17264 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17265 // Changed to/from cached state, so apps after it in the LRU 17266 // list may also be changed. 17267 updateOomAdjLocked(); 17268 } 17269 return success; 17270 } 17271 17272 final void updateOomAdjLocked() { 17273 final ActivityRecord TOP_ACT = resumedAppLocked(); 17274 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17275 final long now = SystemClock.uptimeMillis(); 17276 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17277 final int N = mLruProcesses.size(); 17278 17279 if (false) { 17280 RuntimeException e = new RuntimeException(); 17281 e.fillInStackTrace(); 17282 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17283 } 17284 17285 mAdjSeq++; 17286 mNewNumServiceProcs = 0; 17287 mNewNumAServiceProcs = 0; 17288 17289 final int emptyProcessLimit; 17290 final int cachedProcessLimit; 17291 if (mProcessLimit <= 0) { 17292 emptyProcessLimit = cachedProcessLimit = 0; 17293 } else if (mProcessLimit == 1) { 17294 emptyProcessLimit = 1; 17295 cachedProcessLimit = 0; 17296 } else { 17297 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17298 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17299 } 17300 17301 // Let's determine how many processes we have running vs. 17302 // how many slots we have for background processes; we may want 17303 // to put multiple processes in a slot of there are enough of 17304 // them. 17305 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17306 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17307 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17308 if (numEmptyProcs > cachedProcessLimit) { 17309 // If there are more empty processes than our limit on cached 17310 // processes, then use the cached process limit for the factor. 17311 // This ensures that the really old empty processes get pushed 17312 // down to the bottom, so if we are running low on memory we will 17313 // have a better chance at keeping around more cached processes 17314 // instead of a gazillion empty processes. 17315 numEmptyProcs = cachedProcessLimit; 17316 } 17317 int emptyFactor = numEmptyProcs/numSlots; 17318 if (emptyFactor < 1) emptyFactor = 1; 17319 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17320 if (cachedFactor < 1) cachedFactor = 1; 17321 int stepCached = 0; 17322 int stepEmpty = 0; 17323 int numCached = 0; 17324 int numEmpty = 0; 17325 int numTrimming = 0; 17326 17327 mNumNonCachedProcs = 0; 17328 mNumCachedHiddenProcs = 0; 17329 17330 // First update the OOM adjustment for each of the 17331 // application processes based on their current state. 17332 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17333 int nextCachedAdj = curCachedAdj+1; 17334 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17335 int nextEmptyAdj = curEmptyAdj+2; 17336 for (int i=N-1; i>=0; i--) { 17337 ProcessRecord app = mLruProcesses.get(i); 17338 if (!app.killedByAm && app.thread != null) { 17339 app.procStateChanged = false; 17340 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17341 17342 // If we haven't yet assigned the final cached adj 17343 // to the process, do that now. 17344 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17345 switch (app.curProcState) { 17346 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17347 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17348 // This process is a cached process holding activities... 17349 // assign it the next cached value for that type, and then 17350 // step that cached level. 17351 app.curRawAdj = curCachedAdj; 17352 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17353 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17354 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17355 + ")"); 17356 if (curCachedAdj != nextCachedAdj) { 17357 stepCached++; 17358 if (stepCached >= cachedFactor) { 17359 stepCached = 0; 17360 curCachedAdj = nextCachedAdj; 17361 nextCachedAdj += 2; 17362 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17363 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17364 } 17365 } 17366 } 17367 break; 17368 default: 17369 // For everything else, assign next empty cached process 17370 // level and bump that up. Note that this means that 17371 // long-running services that have dropped down to the 17372 // cached level will be treated as empty (since their process 17373 // state is still as a service), which is what we want. 17374 app.curRawAdj = curEmptyAdj; 17375 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17376 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17377 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17378 + ")"); 17379 if (curEmptyAdj != nextEmptyAdj) { 17380 stepEmpty++; 17381 if (stepEmpty >= emptyFactor) { 17382 stepEmpty = 0; 17383 curEmptyAdj = nextEmptyAdj; 17384 nextEmptyAdj += 2; 17385 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17386 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17387 } 17388 } 17389 } 17390 break; 17391 } 17392 } 17393 17394 applyOomAdjLocked(app, TOP_APP, true, now); 17395 17396 // Count the number of process types. 17397 switch (app.curProcState) { 17398 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17399 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17400 mNumCachedHiddenProcs++; 17401 numCached++; 17402 if (numCached > cachedProcessLimit) { 17403 app.kill("cached #" + numCached, true); 17404 } 17405 break; 17406 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17407 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17408 && app.lastActivityTime < oldTime) { 17409 app.kill("empty for " 17410 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17411 / 1000) + "s", true); 17412 } else { 17413 numEmpty++; 17414 if (numEmpty > emptyProcessLimit) { 17415 app.kill("empty #" + numEmpty, true); 17416 } 17417 } 17418 break; 17419 default: 17420 mNumNonCachedProcs++; 17421 break; 17422 } 17423 17424 if (app.isolated && app.services.size() <= 0) { 17425 // If this is an isolated process, and there are no 17426 // services running in it, then the process is no longer 17427 // needed. We agressively kill these because we can by 17428 // definition not re-use the same process again, and it is 17429 // good to avoid having whatever code was running in them 17430 // left sitting around after no longer needed. 17431 app.kill("isolated not needed", true); 17432 } 17433 17434 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17435 && !app.killedByAm) { 17436 numTrimming++; 17437 } 17438 } 17439 } 17440 17441 mNumServiceProcs = mNewNumServiceProcs; 17442 17443 // Now determine the memory trimming level of background processes. 17444 // Unfortunately we need to start at the back of the list to do this 17445 // properly. We only do this if the number of background apps we 17446 // are managing to keep around is less than half the maximum we desire; 17447 // if we are keeping a good number around, we'll let them use whatever 17448 // memory they want. 17449 final int numCachedAndEmpty = numCached + numEmpty; 17450 int memFactor; 17451 if (numCached <= ProcessList.TRIM_CACHED_APPS 17452 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17453 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17454 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17455 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17456 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17457 } else { 17458 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17459 } 17460 } else { 17461 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17462 } 17463 // We always allow the memory level to go up (better). We only allow it to go 17464 // down if we are in a state where that is allowed, *and* the total number of processes 17465 // has gone down since last time. 17466 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17467 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17468 + " last=" + mLastNumProcesses); 17469 if (memFactor > mLastMemoryLevel) { 17470 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17471 memFactor = mLastMemoryLevel; 17472 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17473 } 17474 } 17475 mLastMemoryLevel = memFactor; 17476 mLastNumProcesses = mLruProcesses.size(); 17477 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17478 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17479 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17480 if (mLowRamStartTime == 0) { 17481 mLowRamStartTime = now; 17482 } 17483 int step = 0; 17484 int fgTrimLevel; 17485 switch (memFactor) { 17486 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17487 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17488 break; 17489 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17490 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17491 break; 17492 default: 17493 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17494 break; 17495 } 17496 int factor = numTrimming/3; 17497 int minFactor = 2; 17498 if (mHomeProcess != null) minFactor++; 17499 if (mPreviousProcess != null) minFactor++; 17500 if (factor < minFactor) factor = minFactor; 17501 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17502 for (int i=N-1; i>=0; i--) { 17503 ProcessRecord app = mLruProcesses.get(i); 17504 if (allChanged || app.procStateChanged) { 17505 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17506 app.procStateChanged = false; 17507 } 17508 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17509 && !app.killedByAm) { 17510 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17511 try { 17512 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17513 "Trimming memory of " + app.processName 17514 + " to " + curLevel); 17515 app.thread.scheduleTrimMemory(curLevel); 17516 } catch (RemoteException e) { 17517 } 17518 if (false) { 17519 // For now we won't do this; our memory trimming seems 17520 // to be good enough at this point that destroying 17521 // activities causes more harm than good. 17522 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17523 && app != mHomeProcess && app != mPreviousProcess) { 17524 // Need to do this on its own message because the stack may not 17525 // be in a consistent state at this point. 17526 // For these apps we will also finish their activities 17527 // to help them free memory. 17528 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17529 } 17530 } 17531 } 17532 app.trimMemoryLevel = curLevel; 17533 step++; 17534 if (step >= factor) { 17535 step = 0; 17536 switch (curLevel) { 17537 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17538 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17539 break; 17540 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17541 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17542 break; 17543 } 17544 } 17545 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17546 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17547 && app.thread != null) { 17548 try { 17549 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17550 "Trimming memory of heavy-weight " + app.processName 17551 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17552 app.thread.scheduleTrimMemory( 17553 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17554 } catch (RemoteException e) { 17555 } 17556 } 17557 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17558 } else { 17559 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17560 || app.systemNoUi) && app.pendingUiClean) { 17561 // If this application is now in the background and it 17562 // had done UI, then give it the special trim level to 17563 // have it free UI resources. 17564 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17565 if (app.trimMemoryLevel < level && app.thread != null) { 17566 try { 17567 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17568 "Trimming memory of bg-ui " + app.processName 17569 + " to " + level); 17570 app.thread.scheduleTrimMemory(level); 17571 } catch (RemoteException e) { 17572 } 17573 } 17574 app.pendingUiClean = false; 17575 } 17576 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17577 try { 17578 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17579 "Trimming memory of fg " + app.processName 17580 + " to " + fgTrimLevel); 17581 app.thread.scheduleTrimMemory(fgTrimLevel); 17582 } catch (RemoteException e) { 17583 } 17584 } 17585 app.trimMemoryLevel = fgTrimLevel; 17586 } 17587 } 17588 } else { 17589 if (mLowRamStartTime != 0) { 17590 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17591 mLowRamStartTime = 0; 17592 } 17593 for (int i=N-1; i>=0; i--) { 17594 ProcessRecord app = mLruProcesses.get(i); 17595 if (allChanged || app.procStateChanged) { 17596 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17597 app.procStateChanged = false; 17598 } 17599 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17600 || app.systemNoUi) && app.pendingUiClean) { 17601 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17602 && app.thread != null) { 17603 try { 17604 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17605 "Trimming memory of ui hidden " + app.processName 17606 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17607 app.thread.scheduleTrimMemory( 17608 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17609 } catch (RemoteException e) { 17610 } 17611 } 17612 app.pendingUiClean = false; 17613 } 17614 app.trimMemoryLevel = 0; 17615 } 17616 } 17617 17618 if (mAlwaysFinishActivities) { 17619 // Need to do this on its own message because the stack may not 17620 // be in a consistent state at this point. 17621 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17622 } 17623 17624 if (allChanged) { 17625 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17626 } 17627 17628 if (mProcessStats.shouldWriteNowLocked(now)) { 17629 mHandler.post(new Runnable() { 17630 @Override public void run() { 17631 synchronized (ActivityManagerService.this) { 17632 mProcessStats.writeStateAsyncLocked(); 17633 } 17634 } 17635 }); 17636 } 17637 17638 if (DEBUG_OOM_ADJ) { 17639 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17640 } 17641 } 17642 17643 final void trimApplications() { 17644 synchronized (this) { 17645 int i; 17646 17647 // First remove any unused application processes whose package 17648 // has been removed. 17649 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17650 final ProcessRecord app = mRemovedProcesses.get(i); 17651 if (app.activities.size() == 0 17652 && app.curReceiver == null && app.services.size() == 0) { 17653 Slog.i( 17654 TAG, "Exiting empty application process " 17655 + app.processName + " (" 17656 + (app.thread != null ? app.thread.asBinder() : null) 17657 + ")\n"); 17658 if (app.pid > 0 && app.pid != MY_PID) { 17659 app.kill("empty", false); 17660 } else { 17661 try { 17662 app.thread.scheduleExit(); 17663 } catch (Exception e) { 17664 // Ignore exceptions. 17665 } 17666 } 17667 cleanUpApplicationRecordLocked(app, false, true, -1); 17668 mRemovedProcesses.remove(i); 17669 17670 if (app.persistent) { 17671 addAppLocked(app.info, false, null /* ABI override */); 17672 } 17673 } 17674 } 17675 17676 // Now update the oom adj for all processes. 17677 updateOomAdjLocked(); 17678 } 17679 } 17680 17681 /** This method sends the specified signal to each of the persistent apps */ 17682 public void signalPersistentProcesses(int sig) throws RemoteException { 17683 if (sig != Process.SIGNAL_USR1) { 17684 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17685 } 17686 17687 synchronized (this) { 17688 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17689 != PackageManager.PERMISSION_GRANTED) { 17690 throw new SecurityException("Requires permission " 17691 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17692 } 17693 17694 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17695 ProcessRecord r = mLruProcesses.get(i); 17696 if (r.thread != null && r.persistent) { 17697 Process.sendSignal(r.pid, sig); 17698 } 17699 } 17700 } 17701 } 17702 17703 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17704 if (proc == null || proc == mProfileProc) { 17705 proc = mProfileProc; 17706 profileType = mProfileType; 17707 clearProfilerLocked(); 17708 } 17709 if (proc == null) { 17710 return; 17711 } 17712 try { 17713 proc.thread.profilerControl(false, null, profileType); 17714 } catch (RemoteException e) { 17715 throw new IllegalStateException("Process disappeared"); 17716 } 17717 } 17718 17719 private void clearProfilerLocked() { 17720 if (mProfileFd != null) { 17721 try { 17722 mProfileFd.close(); 17723 } catch (IOException e) { 17724 } 17725 } 17726 mProfileApp = null; 17727 mProfileProc = null; 17728 mProfileFile = null; 17729 mProfileType = 0; 17730 mAutoStopProfiler = false; 17731 mSamplingInterval = 0; 17732 } 17733 17734 public boolean profileControl(String process, int userId, boolean start, 17735 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17736 17737 try { 17738 synchronized (this) { 17739 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17740 // its own permission. 17741 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17742 != PackageManager.PERMISSION_GRANTED) { 17743 throw new SecurityException("Requires permission " 17744 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17745 } 17746 17747 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17748 throw new IllegalArgumentException("null profile info or fd"); 17749 } 17750 17751 ProcessRecord proc = null; 17752 if (process != null) { 17753 proc = findProcessLocked(process, userId, "profileControl"); 17754 } 17755 17756 if (start && (proc == null || proc.thread == null)) { 17757 throw new IllegalArgumentException("Unknown process: " + process); 17758 } 17759 17760 if (start) { 17761 stopProfilerLocked(null, 0); 17762 setProfileApp(proc.info, proc.processName, profilerInfo); 17763 mProfileProc = proc; 17764 mProfileType = profileType; 17765 ParcelFileDescriptor fd = profilerInfo.profileFd; 17766 try { 17767 fd = fd.dup(); 17768 } catch (IOException e) { 17769 fd = null; 17770 } 17771 profilerInfo.profileFd = fd; 17772 proc.thread.profilerControl(start, profilerInfo, profileType); 17773 fd = null; 17774 mProfileFd = null; 17775 } else { 17776 stopProfilerLocked(proc, profileType); 17777 if (profilerInfo != null && profilerInfo.profileFd != null) { 17778 try { 17779 profilerInfo.profileFd.close(); 17780 } catch (IOException e) { 17781 } 17782 } 17783 } 17784 17785 return true; 17786 } 17787 } catch (RemoteException e) { 17788 throw new IllegalStateException("Process disappeared"); 17789 } finally { 17790 if (profilerInfo != null && profilerInfo.profileFd != null) { 17791 try { 17792 profilerInfo.profileFd.close(); 17793 } catch (IOException e) { 17794 } 17795 } 17796 } 17797 } 17798 17799 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17800 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17801 userId, true, ALLOW_FULL_ONLY, callName, null); 17802 ProcessRecord proc = null; 17803 try { 17804 int pid = Integer.parseInt(process); 17805 synchronized (mPidsSelfLocked) { 17806 proc = mPidsSelfLocked.get(pid); 17807 } 17808 } catch (NumberFormatException e) { 17809 } 17810 17811 if (proc == null) { 17812 ArrayMap<String, SparseArray<ProcessRecord>> all 17813 = mProcessNames.getMap(); 17814 SparseArray<ProcessRecord> procs = all.get(process); 17815 if (procs != null && procs.size() > 0) { 17816 proc = procs.valueAt(0); 17817 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17818 for (int i=1; i<procs.size(); i++) { 17819 ProcessRecord thisProc = procs.valueAt(i); 17820 if (thisProc.userId == userId) { 17821 proc = thisProc; 17822 break; 17823 } 17824 } 17825 } 17826 } 17827 } 17828 17829 return proc; 17830 } 17831 17832 public boolean dumpHeap(String process, int userId, boolean managed, 17833 String path, ParcelFileDescriptor fd) throws RemoteException { 17834 17835 try { 17836 synchronized (this) { 17837 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17838 // its own permission (same as profileControl). 17839 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17840 != PackageManager.PERMISSION_GRANTED) { 17841 throw new SecurityException("Requires permission " 17842 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17843 } 17844 17845 if (fd == null) { 17846 throw new IllegalArgumentException("null fd"); 17847 } 17848 17849 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17850 if (proc == null || proc.thread == null) { 17851 throw new IllegalArgumentException("Unknown process: " + process); 17852 } 17853 17854 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17855 if (!isDebuggable) { 17856 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17857 throw new SecurityException("Process not debuggable: " + proc); 17858 } 17859 } 17860 17861 proc.thread.dumpHeap(managed, path, fd); 17862 fd = null; 17863 return true; 17864 } 17865 } catch (RemoteException e) { 17866 throw new IllegalStateException("Process disappeared"); 17867 } finally { 17868 if (fd != null) { 17869 try { 17870 fd.close(); 17871 } catch (IOException e) { 17872 } 17873 } 17874 } 17875 } 17876 17877 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17878 public void monitor() { 17879 synchronized (this) { } 17880 } 17881 17882 void onCoreSettingsChange(Bundle settings) { 17883 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17884 ProcessRecord processRecord = mLruProcesses.get(i); 17885 try { 17886 if (processRecord.thread != null) { 17887 processRecord.thread.setCoreSettings(settings); 17888 } 17889 } catch (RemoteException re) { 17890 /* ignore */ 17891 } 17892 } 17893 } 17894 17895 // Multi-user methods 17896 17897 /** 17898 * Start user, if its not already running, but don't bring it to foreground. 17899 */ 17900 @Override 17901 public boolean startUserInBackground(final int userId) { 17902 return startUser(userId, /* foreground */ false); 17903 } 17904 17905 /** 17906 * Start user, if its not already running, and bring it to foreground. 17907 */ 17908 boolean startUserInForeground(final int userId, Dialog dlg) { 17909 boolean result = startUser(userId, /* foreground */ true); 17910 dlg.dismiss(); 17911 return result; 17912 } 17913 17914 /** 17915 * Refreshes the list of users related to the current user when either a 17916 * user switch happens or when a new related user is started in the 17917 * background. 17918 */ 17919 private void updateCurrentProfileIdsLocked() { 17920 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17921 mCurrentUserId, false /* enabledOnly */); 17922 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17923 for (int i = 0; i < currentProfileIds.length; i++) { 17924 currentProfileIds[i] = profiles.get(i).id; 17925 } 17926 mCurrentProfileIds = currentProfileIds; 17927 17928 synchronized (mUserProfileGroupIdsSelfLocked) { 17929 mUserProfileGroupIdsSelfLocked.clear(); 17930 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17931 for (int i = 0; i < users.size(); i++) { 17932 UserInfo user = users.get(i); 17933 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17934 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17935 } 17936 } 17937 } 17938 } 17939 17940 private Set getProfileIdsLocked(int userId) { 17941 Set userIds = new HashSet<Integer>(); 17942 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17943 userId, false /* enabledOnly */); 17944 for (UserInfo user : profiles) { 17945 userIds.add(Integer.valueOf(user.id)); 17946 } 17947 return userIds; 17948 } 17949 17950 @Override 17951 public boolean switchUser(final int userId) { 17952 String userName; 17953 synchronized (this) { 17954 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17955 if (userInfo == null) { 17956 Slog.w(TAG, "No user info for user #" + userId); 17957 return false; 17958 } 17959 if (userInfo.isManagedProfile()) { 17960 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17961 return false; 17962 } 17963 userName = userInfo.name; 17964 } 17965 mHandler.removeMessages(START_USER_SWITCH_MSG); 17966 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17967 return true; 17968 } 17969 17970 private void showUserSwitchDialog(int userId, String userName) { 17971 // The dialog will show and then initiate the user switch by calling startUserInForeground 17972 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17973 true /* above system */); 17974 d.show(); 17975 } 17976 17977 private boolean startUser(final int userId, final boolean foreground) { 17978 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17979 != PackageManager.PERMISSION_GRANTED) { 17980 String msg = "Permission Denial: switchUser() from pid=" 17981 + Binder.getCallingPid() 17982 + ", uid=" + Binder.getCallingUid() 17983 + " requires " + INTERACT_ACROSS_USERS_FULL; 17984 Slog.w(TAG, msg); 17985 throw new SecurityException(msg); 17986 } 17987 17988 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17989 17990 final long ident = Binder.clearCallingIdentity(); 17991 try { 17992 synchronized (this) { 17993 final int oldUserId = mCurrentUserId; 17994 if (oldUserId == userId) { 17995 return true; 17996 } 17997 17998 mStackSupervisor.setLockTaskModeLocked(null, false); 17999 18000 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18001 if (userInfo == null) { 18002 Slog.w(TAG, "No user info for user #" + userId); 18003 return false; 18004 } 18005 if (foreground && userInfo.isManagedProfile()) { 18006 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18007 return false; 18008 } 18009 18010 if (foreground) { 18011 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18012 R.anim.screen_user_enter); 18013 } 18014 18015 boolean needStart = false; 18016 18017 // If the user we are switching to is not currently started, then 18018 // we need to start it now. 18019 if (mStartedUsers.get(userId) == null) { 18020 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18021 updateStartedUserArrayLocked(); 18022 needStart = true; 18023 } 18024 18025 final Integer userIdInt = Integer.valueOf(userId); 18026 mUserLru.remove(userIdInt); 18027 mUserLru.add(userIdInt); 18028 18029 if (foreground) { 18030 mCurrentUserId = userId; 18031 updateCurrentProfileIdsLocked(); 18032 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18033 // Once the internal notion of the active user has switched, we lock the device 18034 // with the option to show the user switcher on the keyguard. 18035 mWindowManager.lockNow(null); 18036 } else { 18037 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18038 updateCurrentProfileIdsLocked(); 18039 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18040 mUserLru.remove(currentUserIdInt); 18041 mUserLru.add(currentUserIdInt); 18042 } 18043 18044 final UserStartedState uss = mStartedUsers.get(userId); 18045 18046 // Make sure user is in the started state. If it is currently 18047 // stopping, we need to knock that off. 18048 if (uss.mState == UserStartedState.STATE_STOPPING) { 18049 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18050 // so we can just fairly silently bring the user back from 18051 // the almost-dead. 18052 uss.mState = UserStartedState.STATE_RUNNING; 18053 updateStartedUserArrayLocked(); 18054 needStart = true; 18055 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18056 // This means ACTION_SHUTDOWN has been sent, so we will 18057 // need to treat this as a new boot of the user. 18058 uss.mState = UserStartedState.STATE_BOOTING; 18059 updateStartedUserArrayLocked(); 18060 needStart = true; 18061 } 18062 18063 if (uss.mState == UserStartedState.STATE_BOOTING) { 18064 // Booting up a new user, need to tell system services about it. 18065 // Note that this is on the same handler as scheduling of broadcasts, 18066 // which is important because it needs to go first. 18067 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18068 } 18069 18070 if (foreground) { 18071 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18072 oldUserId)); 18073 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18074 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18075 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18076 oldUserId, userId, uss)); 18077 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18078 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18079 } 18080 18081 if (needStart) { 18082 // Send USER_STARTED broadcast 18083 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18084 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18085 | Intent.FLAG_RECEIVER_FOREGROUND); 18086 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18087 broadcastIntentLocked(null, null, intent, 18088 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18089 false, false, MY_PID, Process.SYSTEM_UID, userId); 18090 } 18091 18092 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18093 if (userId != UserHandle.USER_OWNER) { 18094 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18095 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18096 broadcastIntentLocked(null, null, intent, null, 18097 new IIntentReceiver.Stub() { 18098 public void performReceive(Intent intent, int resultCode, 18099 String data, Bundle extras, boolean ordered, 18100 boolean sticky, int sendingUser) { 18101 onUserInitialized(uss, foreground, oldUserId, userId); 18102 } 18103 }, 0, null, null, null, AppOpsManager.OP_NONE, 18104 true, false, MY_PID, Process.SYSTEM_UID, 18105 userId); 18106 uss.initializing = true; 18107 } else { 18108 getUserManagerLocked().makeInitialized(userInfo.id); 18109 } 18110 } 18111 18112 if (foreground) { 18113 if (!uss.initializing) { 18114 moveUserToForeground(uss, oldUserId, userId); 18115 } 18116 } else { 18117 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18118 } 18119 18120 if (needStart) { 18121 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18122 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18123 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18124 broadcastIntentLocked(null, null, intent, 18125 null, new IIntentReceiver.Stub() { 18126 @Override 18127 public void performReceive(Intent intent, int resultCode, String data, 18128 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18129 throws RemoteException { 18130 } 18131 }, 0, null, null, 18132 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18133 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18134 } 18135 } 18136 } finally { 18137 Binder.restoreCallingIdentity(ident); 18138 } 18139 18140 return true; 18141 } 18142 18143 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18144 long ident = Binder.clearCallingIdentity(); 18145 try { 18146 Intent intent; 18147 if (oldUserId >= 0) { 18148 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18149 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18150 int count = profiles.size(); 18151 for (int i = 0; i < count; i++) { 18152 int profileUserId = profiles.get(i).id; 18153 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18154 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18155 | Intent.FLAG_RECEIVER_FOREGROUND); 18156 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18157 broadcastIntentLocked(null, null, intent, 18158 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18159 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18160 } 18161 } 18162 if (newUserId >= 0) { 18163 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18164 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18165 int count = profiles.size(); 18166 for (int i = 0; i < count; i++) { 18167 int profileUserId = profiles.get(i).id; 18168 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18169 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18170 | Intent.FLAG_RECEIVER_FOREGROUND); 18171 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18172 broadcastIntentLocked(null, null, intent, 18173 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18174 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18175 } 18176 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18177 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18178 | Intent.FLAG_RECEIVER_FOREGROUND); 18179 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18180 broadcastIntentLocked(null, null, intent, 18181 null, null, 0, null, null, 18182 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18183 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18184 } 18185 } finally { 18186 Binder.restoreCallingIdentity(ident); 18187 } 18188 } 18189 18190 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18191 final int newUserId) { 18192 final int N = mUserSwitchObservers.beginBroadcast(); 18193 if (N > 0) { 18194 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18195 int mCount = 0; 18196 @Override 18197 public void sendResult(Bundle data) throws RemoteException { 18198 synchronized (ActivityManagerService.this) { 18199 if (mCurUserSwitchCallback == this) { 18200 mCount++; 18201 if (mCount == N) { 18202 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18203 } 18204 } 18205 } 18206 } 18207 }; 18208 synchronized (this) { 18209 uss.switching = true; 18210 mCurUserSwitchCallback = callback; 18211 } 18212 for (int i=0; i<N; i++) { 18213 try { 18214 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18215 newUserId, callback); 18216 } catch (RemoteException e) { 18217 } 18218 } 18219 } else { 18220 synchronized (this) { 18221 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18222 } 18223 } 18224 mUserSwitchObservers.finishBroadcast(); 18225 } 18226 18227 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18228 synchronized (this) { 18229 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18230 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18231 } 18232 } 18233 18234 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18235 mCurUserSwitchCallback = null; 18236 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18237 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18238 oldUserId, newUserId, uss)); 18239 } 18240 18241 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18242 synchronized (this) { 18243 if (foreground) { 18244 moveUserToForeground(uss, oldUserId, newUserId); 18245 } 18246 } 18247 18248 completeSwitchAndInitalize(uss, newUserId, true, false); 18249 } 18250 18251 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18252 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18253 if (homeInFront) { 18254 startHomeActivityLocked(newUserId); 18255 } else { 18256 mStackSupervisor.resumeTopActivitiesLocked(); 18257 } 18258 EventLogTags.writeAmSwitchUser(newUserId); 18259 getUserManagerLocked().userForeground(newUserId); 18260 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18261 } 18262 18263 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18264 completeSwitchAndInitalize(uss, newUserId, false, true); 18265 } 18266 18267 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18268 boolean clearInitializing, boolean clearSwitching) { 18269 boolean unfrozen = false; 18270 synchronized (this) { 18271 if (clearInitializing) { 18272 uss.initializing = false; 18273 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18274 } 18275 if (clearSwitching) { 18276 uss.switching = false; 18277 } 18278 if (!uss.switching && !uss.initializing) { 18279 mWindowManager.stopFreezingScreen(); 18280 unfrozen = true; 18281 } 18282 } 18283 if (unfrozen) { 18284 final int N = mUserSwitchObservers.beginBroadcast(); 18285 for (int i=0; i<N; i++) { 18286 try { 18287 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18288 } catch (RemoteException e) { 18289 } 18290 } 18291 mUserSwitchObservers.finishBroadcast(); 18292 } 18293 } 18294 18295 void scheduleStartProfilesLocked() { 18296 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18297 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18298 DateUtils.SECOND_IN_MILLIS); 18299 } 18300 } 18301 18302 void startProfilesLocked() { 18303 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18304 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18305 mCurrentUserId, false /* enabledOnly */); 18306 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18307 for (UserInfo user : profiles) { 18308 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18309 && user.id != mCurrentUserId) { 18310 toStart.add(user); 18311 } 18312 } 18313 final int n = toStart.size(); 18314 int i = 0; 18315 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18316 startUserInBackground(toStart.get(i).id); 18317 } 18318 if (i < n) { 18319 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18320 } 18321 } 18322 18323 void finishUserBoot(UserStartedState uss) { 18324 synchronized (this) { 18325 if (uss.mState == UserStartedState.STATE_BOOTING 18326 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18327 uss.mState = UserStartedState.STATE_RUNNING; 18328 final int userId = uss.mHandle.getIdentifier(); 18329 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18330 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18331 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18332 broadcastIntentLocked(null, null, intent, 18333 null, null, 0, null, null, 18334 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18335 true, false, MY_PID, Process.SYSTEM_UID, userId); 18336 } 18337 } 18338 } 18339 18340 void finishUserSwitch(UserStartedState uss) { 18341 synchronized (this) { 18342 finishUserBoot(uss); 18343 18344 startProfilesLocked(); 18345 18346 int num = mUserLru.size(); 18347 int i = 0; 18348 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18349 Integer oldUserId = mUserLru.get(i); 18350 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18351 if (oldUss == null) { 18352 // Shouldn't happen, but be sane if it does. 18353 mUserLru.remove(i); 18354 num--; 18355 continue; 18356 } 18357 if (oldUss.mState == UserStartedState.STATE_STOPPING 18358 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18359 // This user is already stopping, doesn't count. 18360 num--; 18361 i++; 18362 continue; 18363 } 18364 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18365 // Owner and current can't be stopped, but count as running. 18366 i++; 18367 continue; 18368 } 18369 // This is a user to be stopped. 18370 stopUserLocked(oldUserId, null); 18371 num--; 18372 i++; 18373 } 18374 } 18375 } 18376 18377 @Override 18378 public int stopUser(final int userId, final IStopUserCallback callback) { 18379 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18380 != PackageManager.PERMISSION_GRANTED) { 18381 String msg = "Permission Denial: switchUser() from pid=" 18382 + Binder.getCallingPid() 18383 + ", uid=" + Binder.getCallingUid() 18384 + " requires " + INTERACT_ACROSS_USERS_FULL; 18385 Slog.w(TAG, msg); 18386 throw new SecurityException(msg); 18387 } 18388 if (userId <= 0) { 18389 throw new IllegalArgumentException("Can't stop primary user " + userId); 18390 } 18391 synchronized (this) { 18392 return stopUserLocked(userId, callback); 18393 } 18394 } 18395 18396 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18397 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18398 if (mCurrentUserId == userId) { 18399 return ActivityManager.USER_OP_IS_CURRENT; 18400 } 18401 18402 final UserStartedState uss = mStartedUsers.get(userId); 18403 if (uss == null) { 18404 // User is not started, nothing to do... but we do need to 18405 // callback if requested. 18406 if (callback != null) { 18407 mHandler.post(new Runnable() { 18408 @Override 18409 public void run() { 18410 try { 18411 callback.userStopped(userId); 18412 } catch (RemoteException e) { 18413 } 18414 } 18415 }); 18416 } 18417 return ActivityManager.USER_OP_SUCCESS; 18418 } 18419 18420 if (callback != null) { 18421 uss.mStopCallbacks.add(callback); 18422 } 18423 18424 if (uss.mState != UserStartedState.STATE_STOPPING 18425 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18426 uss.mState = UserStartedState.STATE_STOPPING; 18427 updateStartedUserArrayLocked(); 18428 18429 long ident = Binder.clearCallingIdentity(); 18430 try { 18431 // We are going to broadcast ACTION_USER_STOPPING and then 18432 // once that is done send a final ACTION_SHUTDOWN and then 18433 // stop the user. 18434 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18435 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18436 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18437 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18438 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18439 // This is the result receiver for the final shutdown broadcast. 18440 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18441 @Override 18442 public void performReceive(Intent intent, int resultCode, String data, 18443 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18444 finishUserStop(uss); 18445 } 18446 }; 18447 // This is the result receiver for the initial stopping broadcast. 18448 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18449 @Override 18450 public void performReceive(Intent intent, int resultCode, String data, 18451 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18452 // On to the next. 18453 synchronized (ActivityManagerService.this) { 18454 if (uss.mState != UserStartedState.STATE_STOPPING) { 18455 // Whoops, we are being started back up. Abort, abort! 18456 return; 18457 } 18458 uss.mState = UserStartedState.STATE_SHUTDOWN; 18459 } 18460 mBatteryStatsService.noteEvent( 18461 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18462 Integer.toString(userId), userId); 18463 mSystemServiceManager.stopUser(userId); 18464 broadcastIntentLocked(null, null, shutdownIntent, 18465 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18466 true, false, MY_PID, Process.SYSTEM_UID, userId); 18467 } 18468 }; 18469 // Kick things off. 18470 broadcastIntentLocked(null, null, stoppingIntent, 18471 null, stoppingReceiver, 0, null, null, 18472 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18473 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18474 } finally { 18475 Binder.restoreCallingIdentity(ident); 18476 } 18477 } 18478 18479 return ActivityManager.USER_OP_SUCCESS; 18480 } 18481 18482 void finishUserStop(UserStartedState uss) { 18483 final int userId = uss.mHandle.getIdentifier(); 18484 boolean stopped; 18485 ArrayList<IStopUserCallback> callbacks; 18486 synchronized (this) { 18487 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18488 if (mStartedUsers.get(userId) != uss) { 18489 stopped = false; 18490 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18491 stopped = false; 18492 } else { 18493 stopped = true; 18494 // User can no longer run. 18495 mStartedUsers.remove(userId); 18496 mUserLru.remove(Integer.valueOf(userId)); 18497 updateStartedUserArrayLocked(); 18498 18499 // Clean up all state and processes associated with the user. 18500 // Kill all the processes for the user. 18501 forceStopUserLocked(userId, "finish user"); 18502 } 18503 18504 // Explicitly remove the old information in mRecentTasks. 18505 removeRecentTasksForUserLocked(userId); 18506 } 18507 18508 for (int i=0; i<callbacks.size(); i++) { 18509 try { 18510 if (stopped) callbacks.get(i).userStopped(userId); 18511 else callbacks.get(i).userStopAborted(userId); 18512 } catch (RemoteException e) { 18513 } 18514 } 18515 18516 if (stopped) { 18517 mSystemServiceManager.cleanupUser(userId); 18518 synchronized (this) { 18519 mStackSupervisor.removeUserLocked(userId); 18520 } 18521 } 18522 } 18523 18524 @Override 18525 public UserInfo getCurrentUser() { 18526 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18527 != PackageManager.PERMISSION_GRANTED) && ( 18528 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18529 != PackageManager.PERMISSION_GRANTED)) { 18530 String msg = "Permission Denial: getCurrentUser() from pid=" 18531 + Binder.getCallingPid() 18532 + ", uid=" + Binder.getCallingUid() 18533 + " requires " + INTERACT_ACROSS_USERS; 18534 Slog.w(TAG, msg); 18535 throw new SecurityException(msg); 18536 } 18537 synchronized (this) { 18538 return getUserManagerLocked().getUserInfo(mCurrentUserId); 18539 } 18540 } 18541 18542 int getCurrentUserIdLocked() { 18543 return mCurrentUserId; 18544 } 18545 18546 @Override 18547 public boolean isUserRunning(int userId, boolean orStopped) { 18548 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18549 != PackageManager.PERMISSION_GRANTED) { 18550 String msg = "Permission Denial: isUserRunning() from pid=" 18551 + Binder.getCallingPid() 18552 + ", uid=" + Binder.getCallingUid() 18553 + " requires " + INTERACT_ACROSS_USERS; 18554 Slog.w(TAG, msg); 18555 throw new SecurityException(msg); 18556 } 18557 synchronized (this) { 18558 return isUserRunningLocked(userId, orStopped); 18559 } 18560 } 18561 18562 boolean isUserRunningLocked(int userId, boolean orStopped) { 18563 UserStartedState state = mStartedUsers.get(userId); 18564 if (state == null) { 18565 return false; 18566 } 18567 if (orStopped) { 18568 return true; 18569 } 18570 return state.mState != UserStartedState.STATE_STOPPING 18571 && state.mState != UserStartedState.STATE_SHUTDOWN; 18572 } 18573 18574 @Override 18575 public int[] getRunningUserIds() { 18576 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18577 != PackageManager.PERMISSION_GRANTED) { 18578 String msg = "Permission Denial: isUserRunning() from pid=" 18579 + Binder.getCallingPid() 18580 + ", uid=" + Binder.getCallingUid() 18581 + " requires " + INTERACT_ACROSS_USERS; 18582 Slog.w(TAG, msg); 18583 throw new SecurityException(msg); 18584 } 18585 synchronized (this) { 18586 return mStartedUserArray; 18587 } 18588 } 18589 18590 private void updateStartedUserArrayLocked() { 18591 int num = 0; 18592 for (int i=0; i<mStartedUsers.size(); i++) { 18593 UserStartedState uss = mStartedUsers.valueAt(i); 18594 // This list does not include stopping users. 18595 if (uss.mState != UserStartedState.STATE_STOPPING 18596 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18597 num++; 18598 } 18599 } 18600 mStartedUserArray = new int[num]; 18601 num = 0; 18602 for (int i=0; i<mStartedUsers.size(); i++) { 18603 UserStartedState uss = mStartedUsers.valueAt(i); 18604 if (uss.mState != UserStartedState.STATE_STOPPING 18605 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18606 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18607 num++; 18608 } 18609 } 18610 } 18611 18612 @Override 18613 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18614 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18615 != PackageManager.PERMISSION_GRANTED) { 18616 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18617 + Binder.getCallingPid() 18618 + ", uid=" + Binder.getCallingUid() 18619 + " requires " + INTERACT_ACROSS_USERS_FULL; 18620 Slog.w(TAG, msg); 18621 throw new SecurityException(msg); 18622 } 18623 18624 mUserSwitchObservers.register(observer); 18625 } 18626 18627 @Override 18628 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18629 mUserSwitchObservers.unregister(observer); 18630 } 18631 18632 private boolean userExists(int userId) { 18633 if (userId == 0) { 18634 return true; 18635 } 18636 UserManagerService ums = getUserManagerLocked(); 18637 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18638 } 18639 18640 int[] getUsersLocked() { 18641 UserManagerService ums = getUserManagerLocked(); 18642 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18643 } 18644 18645 UserManagerService getUserManagerLocked() { 18646 if (mUserManager == null) { 18647 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18648 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18649 } 18650 return mUserManager; 18651 } 18652 18653 private int applyUserId(int uid, int userId) { 18654 return UserHandle.getUid(userId, uid); 18655 } 18656 18657 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18658 if (info == null) return null; 18659 ApplicationInfo newInfo = new ApplicationInfo(info); 18660 newInfo.uid = applyUserId(info.uid, userId); 18661 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18662 + info.packageName; 18663 return newInfo; 18664 } 18665 18666 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18667 if (aInfo == null 18668 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18669 return aInfo; 18670 } 18671 18672 ActivityInfo info = new ActivityInfo(aInfo); 18673 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18674 return info; 18675 } 18676 18677 private final class LocalService extends ActivityManagerInternal { 18678 @Override 18679 public void goingToSleep() { 18680 ActivityManagerService.this.goingToSleep(); 18681 } 18682 18683 @Override 18684 public void wakingUp() { 18685 ActivityManagerService.this.wakingUp(); 18686 } 18687 18688 @Override 18689 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18690 String processName, String abiOverride, int uid, Runnable crashHandler) { 18691 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18692 processName, abiOverride, uid, crashHandler); 18693 } 18694 } 18695 18696 /** 18697 * An implementation of IAppTask, that allows an app to manage its own tasks via 18698 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18699 * only the process that calls getAppTasks() can call the AppTask methods. 18700 */ 18701 class AppTaskImpl extends IAppTask.Stub { 18702 private int mTaskId; 18703 private int mCallingUid; 18704 18705 public AppTaskImpl(int taskId, int callingUid) { 18706 mTaskId = taskId; 18707 mCallingUid = callingUid; 18708 } 18709 18710 private void checkCaller() { 18711 if (mCallingUid != Binder.getCallingUid()) { 18712 throw new SecurityException("Caller " + mCallingUid 18713 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18714 } 18715 } 18716 18717 @Override 18718 public void finishAndRemoveTask() { 18719 checkCaller(); 18720 18721 synchronized (ActivityManagerService.this) { 18722 long origId = Binder.clearCallingIdentity(); 18723 try { 18724 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18725 if (tr == null) { 18726 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18727 } 18728 // Only kill the process if we are not a new document 18729 int flags = tr.getBaseIntent().getFlags(); 18730 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18731 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18732 removeTaskByIdLocked(mTaskId, 18733 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18734 } finally { 18735 Binder.restoreCallingIdentity(origId); 18736 } 18737 } 18738 } 18739 18740 @Override 18741 public ActivityManager.RecentTaskInfo getTaskInfo() { 18742 checkCaller(); 18743 18744 synchronized (ActivityManagerService.this) { 18745 long origId = Binder.clearCallingIdentity(); 18746 try { 18747 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18748 if (tr == null) { 18749 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18750 } 18751 return createRecentTaskInfoFromTaskRecord(tr); 18752 } finally { 18753 Binder.restoreCallingIdentity(origId); 18754 } 18755 } 18756 } 18757 18758 @Override 18759 public void moveToFront() { 18760 checkCaller(); 18761 18762 final TaskRecord tr; 18763 synchronized (ActivityManagerService.this) { 18764 tr = recentTaskForIdLocked(mTaskId); 18765 if (tr == null) { 18766 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18767 } 18768 if (tr.getRootActivity() != null) { 18769 long origId = Binder.clearCallingIdentity(); 18770 try { 18771 moveTaskToFrontLocked(tr.taskId, 0, null); 18772 return; 18773 } finally { 18774 Binder.restoreCallingIdentity(origId); 18775 } 18776 } 18777 } 18778 18779 startActivityFromRecentsInner(tr.taskId, null); 18780 } 18781 18782 @Override 18783 public int startActivity(IBinder whoThread, String callingPackage, 18784 Intent intent, String resolvedType, Bundle options) { 18785 checkCaller(); 18786 18787 int callingUser = UserHandle.getCallingUserId(); 18788 TaskRecord tr; 18789 IApplicationThread appThread; 18790 synchronized (ActivityManagerService.this) { 18791 tr = recentTaskForIdLocked(mTaskId); 18792 if (tr == null) { 18793 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18794 } 18795 appThread = ApplicationThreadNative.asInterface(whoThread); 18796 if (appThread == null) { 18797 throw new IllegalArgumentException("Bad app thread " + appThread); 18798 } 18799 } 18800 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18801 resolvedType, null, null, null, null, 0, 0, null, null, 18802 null, options, callingUser, null, tr); 18803 } 18804 18805 @Override 18806 public void setExcludeFromRecents(boolean exclude) { 18807 checkCaller(); 18808 18809 synchronized (ActivityManagerService.this) { 18810 long origId = Binder.clearCallingIdentity(); 18811 try { 18812 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18813 if (tr == null) { 18814 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18815 } 18816 Intent intent = tr.getBaseIntent(); 18817 if (exclude) { 18818 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18819 } else { 18820 intent.setFlags(intent.getFlags() 18821 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18822 } 18823 } finally { 18824 Binder.restoreCallingIdentity(origId); 18825 } 18826 } 18827 } 18828 } 18829} 18830