ActivityManagerService.java revision a7a61594df2f0b6ee9e3577f3d928e5f01ab4a75
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199 200import java.io.BufferedInputStream; 201import java.io.BufferedOutputStream; 202import java.io.DataInputStream; 203import java.io.DataOutputStream; 204import java.io.File; 205import java.io.FileDescriptor; 206import java.io.FileInputStream; 207import java.io.FileNotFoundException; 208import java.io.FileOutputStream; 209import java.io.IOException; 210import java.io.InputStreamReader; 211import java.io.PrintWriter; 212import java.io.StringWriter; 213import java.lang.ref.WeakReference; 214import java.util.ArrayList; 215import java.util.Arrays; 216import java.util.Collections; 217import java.util.Comparator; 218import java.util.HashMap; 219import java.util.HashSet; 220import java.util.Iterator; 221import java.util.List; 222import java.util.Locale; 223import java.util.Map; 224import java.util.Set; 225import java.util.concurrent.atomic.AtomicBoolean; 226import java.util.concurrent.atomic.AtomicLong; 227 228public final class ActivityManagerService extends ActivityManagerNative 229 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 230 231 private static final String USER_DATA_DIR = "/data/user/"; 232 // File that stores last updated system version and called preboot receivers 233 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 234 235 static final String TAG = "ActivityManager"; 236 static final String TAG_MU = "ActivityManagerServiceMU"; 237 static final boolean DEBUG = false; 238 static final boolean localLOGV = DEBUG; 239 static final boolean DEBUG_BACKUP = localLOGV || false; 240 static final boolean DEBUG_BROADCAST = localLOGV || false; 241 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 242 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_CLEANUP = localLOGV || false; 244 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 245 static final boolean DEBUG_FOCUS = false; 246 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 247 static final boolean DEBUG_MU = localLOGV || false; 248 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 249 static final boolean DEBUG_LRU = localLOGV || false; 250 static final boolean DEBUG_PAUSE = localLOGV || false; 251 static final boolean DEBUG_POWER = localLOGV || false; 252 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 253 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 254 static final boolean DEBUG_PROCESSES = localLOGV || false; 255 static final boolean DEBUG_PROVIDER = localLOGV || false; 256 static final boolean DEBUG_RESULTS = localLOGV || false; 257 static final boolean DEBUG_SERVICE = localLOGV || false; 258 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 259 static final boolean DEBUG_STACK = localLOGV || false; 260 static final boolean DEBUG_SWITCH = localLOGV || false; 261 static final boolean DEBUG_TASKS = localLOGV || false; 262 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 263 static final boolean DEBUG_TRANSITION = localLOGV || false; 264 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 265 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 266 static final boolean DEBUG_VISBILITY = localLOGV || false; 267 static final boolean DEBUG_PSS = localLOGV || false; 268 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 269 static final boolean DEBUG_RECENTS = localLOGV || false; 270 static final boolean VALIDATE_TOKENS = false; 271 static final boolean SHOW_ACTIVITY_START_TIME = true; 272 273 // Control over CPU and battery monitoring. 274 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 275 static final boolean MONITOR_CPU_USAGE = true; 276 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 277 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 278 static final boolean MONITOR_THREAD_CPU_USAGE = false; 279 280 // The flags that are set for all calls we make to the package manager. 281 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 282 283 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 284 285 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 286 287 // Maximum number recent bitmaps to keep in memory. 288 static final int MAX_RECENT_BITMAPS = 5; 289 290 // Amount of time after a call to stopAppSwitches() during which we will 291 // prevent further untrusted switches from happening. 292 static final long APP_SWITCH_DELAY_TIME = 5*1000; 293 294 // How long we wait for a launched process to attach to the activity manager 295 // before we decide it's never going to come up for real. 296 static final int PROC_START_TIMEOUT = 10*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real, when the process was 300 // started with a wrapper for instrumentation (such as Valgrind) because it 301 // could take much longer than usual. 302 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 303 304 // How long to wait after going idle before forcing apps to GC. 305 static final int GC_TIMEOUT = 5*1000; 306 307 // The minimum amount of time between successive GC requests for a process. 308 static final int GC_MIN_INTERVAL = 60*1000; 309 310 // The minimum amount of time between successive PSS requests for a process. 311 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 312 313 // The minimum amount of time between successive PSS requests for a process 314 // when the request is due to the memory state being lowered. 315 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 316 317 // The rate at which we check for apps using excessive power -- 15 mins. 318 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 319 320 // The minimum sample duration we will allow before deciding we have 321 // enough data on wake locks to start killing things. 322 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on CPU usage to start killing things. 326 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // How long we allow a receiver to run before giving up on it. 329 static final int BROADCAST_FG_TIMEOUT = 10*1000; 330 static final int BROADCAST_BG_TIMEOUT = 60*1000; 331 332 // How long we wait until we timeout on key dispatching. 333 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 334 335 // How long we wait until we timeout on key dispatching during instrumentation. 336 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 337 338 // Amount of time we wait for observers to handle a user switch before 339 // giving up on them and unfreezing the screen. 340 static final int USER_SWITCH_TIMEOUT = 2*1000; 341 342 // Maximum number of users we allow to be running at a time. 343 static final int MAX_RUNNING_USERS = 3; 344 345 // How long to wait in getAssistContextExtras for the activity and foreground services 346 // to respond with the result. 347 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 348 349 // Maximum number of persisted Uri grants a package is allowed 350 static final int MAX_PERSISTED_URI_GRANTS = 128; 351 352 static final int MY_PID = Process.myPid(); 353 354 static final String[] EMPTY_STRING_ARRAY = new String[0]; 355 356 // How many bytes to write into the dropbox log before truncating 357 static final int DROPBOX_MAX_SIZE = 256 * 1024; 358 359 // Access modes for handleIncomingUser. 360 static final int ALLOW_NON_FULL = 0; 361 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 362 static final int ALLOW_FULL_ONLY = 2; 363 364 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 365 366 /** All system services */ 367 SystemServiceManager mSystemServiceManager; 368 369 /** Run all ActivityStacks through this */ 370 ActivityStackSupervisor mStackSupervisor; 371 372 public IntentFirewall mIntentFirewall; 373 374 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 375 // default actuion automatically. Important for devices without direct input 376 // devices. 377 private boolean mShowDialogs = true; 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 415 416 /** 417 * For addAppTask: cached of the last activity component that was added. 418 */ 419 ComponentName mLastAddedTaskComponent; 420 421 /** 422 * For addAppTask: cached of the last activity uid that was added. 423 */ 424 int mLastAddedTaskUid; 425 426 /** 427 * For addAppTask: cached of the last ActivityInfo that was added. 428 */ 429 ActivityInfo mLastAddedTaskActivity; 430 431 public class PendingAssistExtras extends Binder implements Runnable { 432 public final ActivityRecord activity; 433 public boolean haveResult = false; 434 public Bundle result = null; 435 public PendingAssistExtras(ActivityRecord _activity) { 436 activity = _activity; 437 } 438 @Override 439 public void run() { 440 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 441 synchronized (this) { 442 haveResult = true; 443 notifyAll(); 444 } 445 } 446 } 447 448 final ArrayList<PendingAssistExtras> mPendingAssistExtras 449 = new ArrayList<PendingAssistExtras>(); 450 451 /** 452 * Process management. 453 */ 454 final ProcessList mProcessList = new ProcessList(); 455 456 /** 457 * All of the applications we currently have running organized by name. 458 * The keys are strings of the application package name (as 459 * returned by the package manager), and the keys are ApplicationRecord 460 * objects. 461 */ 462 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 463 464 /** 465 * Tracking long-term execution of processes to look for abuse and other 466 * bad app behavior. 467 */ 468 final ProcessStatsService mProcessStats; 469 470 /** 471 * The currently running isolated processes. 472 */ 473 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 474 475 /** 476 * Counter for assigning isolated process uids, to avoid frequently reusing the 477 * same ones. 478 */ 479 int mNextIsolatedProcessUid = 0; 480 481 /** 482 * The currently running heavy-weight process, if any. 483 */ 484 ProcessRecord mHeavyWeightProcess = null; 485 486 /** 487 * The last time that various processes have crashed. 488 */ 489 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 490 491 /** 492 * Information about a process that is currently marked as bad. 493 */ 494 static final class BadProcessInfo { 495 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 496 this.time = time; 497 this.shortMsg = shortMsg; 498 this.longMsg = longMsg; 499 this.stack = stack; 500 } 501 502 final long time; 503 final String shortMsg; 504 final String longMsg; 505 final String stack; 506 } 507 508 /** 509 * Set of applications that we consider to be bad, and will reject 510 * incoming broadcasts from (which the user has no control over). 511 * Processes are added to this set when they have crashed twice within 512 * a minimum amount of time; they are removed from it when they are 513 * later restarted (hopefully due to some user action). The value is the 514 * time it was added to the list. 515 */ 516 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 517 518 /** 519 * All of the processes we currently have running organized by pid. 520 * The keys are the pid running the application. 521 * 522 * <p>NOTE: This object is protected by its own lock, NOT the global 523 * activity manager lock! 524 */ 525 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 526 527 /** 528 * All of the processes that have been forced to be foreground. The key 529 * is the pid of the caller who requested it (we hold a death 530 * link on it). 531 */ 532 abstract class ForegroundToken implements IBinder.DeathRecipient { 533 int pid; 534 IBinder token; 535 } 536 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 537 538 /** 539 * List of records for processes that someone had tried to start before the 540 * system was ready. We don't start them at that point, but ensure they 541 * are started by the time booting is complete. 542 */ 543 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 544 545 /** 546 * List of persistent applications that are in the process 547 * of being started. 548 */ 549 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes that are being forcibly torn down. 553 */ 554 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * List of running applications, sorted by recent usage. 558 * The first entry in the list is the least recently used. 559 */ 560 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Where in mLruProcesses that the processes hosting activities start. 564 */ 565 int mLruProcessActivityStart = 0; 566 567 /** 568 * Where in mLruProcesses that the processes hosting services start. 569 * This is after (lower index) than mLruProcessesActivityStart. 570 */ 571 int mLruProcessServiceStart = 0; 572 573 /** 574 * List of processes that should gc as soon as things are idle. 575 */ 576 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes we want to collect PSS data from. 580 */ 581 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * Last time we requested PSS data of all processes. 585 */ 586 long mLastFullPssTime = SystemClock.uptimeMillis(); 587 588 /** 589 * If set, the next time we collect PSS data we should do a full collection 590 * with data from native processes and the kernel. 591 */ 592 boolean mFullPssPending = false; 593 594 /** 595 * This is the process holding what we currently consider to be 596 * the "home" activity. 597 */ 598 ProcessRecord mHomeProcess; 599 600 /** 601 * This is the process holding the activity the user last visited that 602 * is in a different process from the one they are currently in. 603 */ 604 ProcessRecord mPreviousProcess; 605 606 /** 607 * The time at which the previous process was last visible. 608 */ 609 long mPreviousProcessVisibleTime; 610 611 /** 612 * Which uses have been started, so are allowed to run code. 613 */ 614 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 615 616 /** 617 * LRU list of history of current users. Most recently current is at the end. 618 */ 619 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 620 621 /** 622 * Constant array of the users that are currently started. 623 */ 624 int[] mStartedUserArray = new int[] { 0 }; 625 626 /** 627 * Registered observers of the user switching mechanics. 628 */ 629 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 630 = new RemoteCallbackList<IUserSwitchObserver>(); 631 632 /** 633 * Currently active user switch. 634 */ 635 Object mCurUserSwitchCallback; 636 637 /** 638 * Packages that the user has asked to have run in screen size 639 * compatibility mode instead of filling the screen. 640 */ 641 final CompatModePackages mCompatModePackages; 642 643 /** 644 * Set of IntentSenderRecord objects that are currently active. 645 */ 646 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 647 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 648 649 /** 650 * Fingerprints (hashCode()) of stack traces that we've 651 * already logged DropBox entries for. Guarded by itself. If 652 * something (rogue user app) forces this over 653 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 654 */ 655 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 656 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 657 658 /** 659 * Strict Mode background batched logging state. 660 * 661 * The string buffer is guarded by itself, and its lock is also 662 * used to determine if another batched write is already 663 * in-flight. 664 */ 665 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 666 667 /** 668 * Keeps track of all IIntentReceivers that have been registered for 669 * broadcasts. Hash keys are the receiver IBinder, hash value is 670 * a ReceiverList. 671 */ 672 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 673 new HashMap<IBinder, ReceiverList>(); 674 675 /** 676 * Resolver for broadcast intents to registered receivers. 677 * Holds BroadcastFilter (subclass of IntentFilter). 678 */ 679 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 680 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 681 @Override 682 protected boolean allowFilterResult( 683 BroadcastFilter filter, List<BroadcastFilter> dest) { 684 IBinder target = filter.receiverList.receiver.asBinder(); 685 for (int i=dest.size()-1; i>=0; i--) { 686 if (dest.get(i).receiverList.receiver.asBinder() == target) { 687 return false; 688 } 689 } 690 return true; 691 } 692 693 @Override 694 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 695 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 696 || userId == filter.owningUserId) { 697 return super.newResult(filter, match, userId); 698 } 699 return null; 700 } 701 702 @Override 703 protected BroadcastFilter[] newArray(int size) { 704 return new BroadcastFilter[size]; 705 } 706 707 @Override 708 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 709 return packageName.equals(filter.packageName); 710 } 711 }; 712 713 /** 714 * State of all active sticky broadcasts per user. Keys are the action of the 715 * sticky Intent, values are an ArrayList of all broadcasted intents with 716 * that action (which should usually be one). The SparseArray is keyed 717 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 718 * for stickies that are sent to all users. 719 */ 720 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 721 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 722 723 final ActiveServices mServices; 724 725 /** 726 * Backup/restore process management 727 */ 728 String mBackupAppName = null; 729 BackupRecord mBackupTarget = null; 730 731 final ProviderMap mProviderMap; 732 733 /** 734 * List of content providers who have clients waiting for them. The 735 * application is currently being launched and the provider will be 736 * removed from this list once it is published. 737 */ 738 final ArrayList<ContentProviderRecord> mLaunchingProviders 739 = new ArrayList<ContentProviderRecord>(); 740 741 /** 742 * File storing persisted {@link #mGrantedUriPermissions}. 743 */ 744 private final AtomicFile mGrantFile; 745 746 /** XML constants used in {@link #mGrantFile} */ 747 private static final String TAG_URI_GRANTS = "uri-grants"; 748 private static final String TAG_URI_GRANT = "uri-grant"; 749 private static final String ATTR_USER_HANDLE = "userHandle"; 750 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 751 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 752 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 753 private static final String ATTR_TARGET_PKG = "targetPkg"; 754 private static final String ATTR_URI = "uri"; 755 private static final String ATTR_MODE_FLAGS = "modeFlags"; 756 private static final String ATTR_CREATED_TIME = "createdTime"; 757 private static final String ATTR_PREFIX = "prefix"; 758 759 /** 760 * Global set of specific {@link Uri} permissions that have been granted. 761 * This optimized lookup structure maps from {@link UriPermission#targetUid} 762 * to {@link UriPermission#uri} to {@link UriPermission}. 763 */ 764 @GuardedBy("this") 765 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 766 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 767 768 public static class GrantUri { 769 public final int sourceUserId; 770 public final Uri uri; 771 public boolean prefix; 772 773 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 774 this.sourceUserId = sourceUserId; 775 this.uri = uri; 776 this.prefix = prefix; 777 } 778 779 @Override 780 public int hashCode() { 781 return toString().hashCode(); 782 } 783 784 @Override 785 public boolean equals(Object o) { 786 if (o instanceof GrantUri) { 787 GrantUri other = (GrantUri) o; 788 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 789 && prefix == other.prefix; 790 } 791 return false; 792 } 793 794 @Override 795 public String toString() { 796 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 797 if (prefix) result += " [prefix]"; 798 return result; 799 } 800 801 public String toSafeString() { 802 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 803 if (prefix) result += " [prefix]"; 804 return result; 805 } 806 807 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 808 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 809 ContentProvider.getUriWithoutUserId(uri), false); 810 } 811 } 812 813 CoreSettingsObserver mCoreSettingsObserver; 814 815 /** 816 * Thread-local storage used to carry caller permissions over through 817 * indirect content-provider access. 818 */ 819 private class Identity { 820 public int pid; 821 public int uid; 822 823 Identity(int _pid, int _uid) { 824 pid = _pid; 825 uid = _uid; 826 } 827 } 828 829 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 830 831 /** 832 * All information we have collected about the runtime performance of 833 * any user id that can impact battery performance. 834 */ 835 final BatteryStatsService mBatteryStatsService; 836 837 /** 838 * Information about component usage 839 */ 840 UsageStatsManagerInternal mUsageStatsService; 841 842 /** 843 * Information about and control over application operations 844 */ 845 final AppOpsService mAppOpsService; 846 847 /** 848 * Save recent tasks information across reboots. 849 */ 850 final TaskPersister mTaskPersister; 851 852 /** 853 * Current configuration information. HistoryRecord objects are given 854 * a reference to this object to indicate which configuration they are 855 * currently running in, so this object must be kept immutable. 856 */ 857 Configuration mConfiguration = new Configuration(); 858 859 /** 860 * Current sequencing integer of the configuration, for skipping old 861 * configurations. 862 */ 863 int mConfigurationSeq = 0; 864 865 /** 866 * Hardware-reported OpenGLES version. 867 */ 868 final int GL_ES_VERSION; 869 870 /** 871 * List of initialization arguments to pass to all processes when binding applications to them. 872 * For example, references to the commonly used services. 873 */ 874 HashMap<String, IBinder> mAppBindArgs; 875 876 /** 877 * Temporary to avoid allocations. Protected by main lock. 878 */ 879 final StringBuilder mStringBuilder = new StringBuilder(256); 880 881 /** 882 * Used to control how we initialize the service. 883 */ 884 ComponentName mTopComponent; 885 String mTopAction = Intent.ACTION_MAIN; 886 String mTopData; 887 boolean mProcessesReady = false; 888 boolean mSystemReady = false; 889 boolean mBooting = false; 890 boolean mWaitingUpdate = false; 891 boolean mDidUpdate = false; 892 boolean mOnBattery = false; 893 boolean mLaunchWarningShown = false; 894 895 Context mContext; 896 897 int mFactoryTest; 898 899 boolean mCheckedForSetup; 900 901 /** 902 * The time at which we will allow normal application switches again, 903 * after a call to {@link #stopAppSwitches()}. 904 */ 905 long mAppSwitchesAllowedTime; 906 907 /** 908 * This is set to true after the first switch after mAppSwitchesAllowedTime 909 * is set; any switches after that will clear the time. 910 */ 911 boolean mDidAppSwitch; 912 913 /** 914 * Last time (in realtime) at which we checked for power usage. 915 */ 916 long mLastPowerCheckRealtime; 917 918 /** 919 * Last time (in uptime) at which we checked for power usage. 920 */ 921 long mLastPowerCheckUptime; 922 923 /** 924 * Set while we are wanting to sleep, to prevent any 925 * activities from being started/resumed. 926 */ 927 private boolean mSleeping = false; 928 929 /** 930 * Set while we are running a voice interaction. This overrides 931 * sleeping while it is active. 932 */ 933 private boolean mRunningVoice = false; 934 935 /** 936 * State of external calls telling us if the device is asleep. 937 */ 938 private boolean mWentToSleep = false; 939 940 /** 941 * State of external call telling us if the lock screen is shown. 942 */ 943 private boolean mLockScreenShown = false; 944 945 /** 946 * Set if we are shutting down the system, similar to sleeping. 947 */ 948 boolean mShuttingDown = false; 949 950 /** 951 * Current sequence id for oom_adj computation traversal. 952 */ 953 int mAdjSeq = 0; 954 955 /** 956 * Current sequence id for process LRU updating. 957 */ 958 int mLruSeq = 0; 959 960 /** 961 * Keep track of the non-cached/empty process we last found, to help 962 * determine how to distribute cached/empty processes next time. 963 */ 964 int mNumNonCachedProcs = 0; 965 966 /** 967 * Keep track of the number of cached hidden procs, to balance oom adj 968 * distribution between those and empty procs. 969 */ 970 int mNumCachedHiddenProcs = 0; 971 972 /** 973 * Keep track of the number of service processes we last found, to 974 * determine on the next iteration which should be B services. 975 */ 976 int mNumServiceProcs = 0; 977 int mNewNumAServiceProcs = 0; 978 int mNewNumServiceProcs = 0; 979 980 /** 981 * Allow the current computed overall memory level of the system to go down? 982 * This is set to false when we are killing processes for reasons other than 983 * memory management, so that the now smaller process list will not be taken as 984 * an indication that memory is tighter. 985 */ 986 boolean mAllowLowerMemLevel = false; 987 988 /** 989 * The last computed memory level, for holding when we are in a state that 990 * processes are going away for other reasons. 991 */ 992 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 993 994 /** 995 * The last total number of process we have, to determine if changes actually look 996 * like a shrinking number of process due to lower RAM. 997 */ 998 int mLastNumProcesses; 999 1000 /** 1001 * The uptime of the last time we performed idle maintenance. 1002 */ 1003 long mLastIdleTime = SystemClock.uptimeMillis(); 1004 1005 /** 1006 * Total time spent with RAM that has been added in the past since the last idle time. 1007 */ 1008 long mLowRamTimeSinceLastIdle = 0; 1009 1010 /** 1011 * If RAM is currently low, when that horrible situation started. 1012 */ 1013 long mLowRamStartTime = 0; 1014 1015 /** 1016 * For reporting to battery stats the current top application. 1017 */ 1018 private String mCurResumedPackage = null; 1019 private int mCurResumedUid = -1; 1020 1021 /** 1022 * For reporting to battery stats the apps currently running foreground 1023 * service. The ProcessMap is package/uid tuples; each of these contain 1024 * an array of the currently foreground processes. 1025 */ 1026 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1027 = new ProcessMap<ArrayList<ProcessRecord>>(); 1028 1029 /** 1030 * This is set if we had to do a delayed dexopt of an app before launching 1031 * it, to increase the ANR timeouts in that case. 1032 */ 1033 boolean mDidDexOpt; 1034 1035 /** 1036 * Set if the systemServer made a call to enterSafeMode. 1037 */ 1038 boolean mSafeMode; 1039 1040 String mDebugApp = null; 1041 boolean mWaitForDebugger = false; 1042 boolean mDebugTransient = false; 1043 String mOrigDebugApp = null; 1044 boolean mOrigWaitForDebugger = false; 1045 boolean mAlwaysFinishActivities = false; 1046 IActivityController mController = null; 1047 String mProfileApp = null; 1048 ProcessRecord mProfileProc = null; 1049 String mProfileFile; 1050 ParcelFileDescriptor mProfileFd; 1051 int mSamplingInterval = 0; 1052 boolean mAutoStopProfiler = false; 1053 int mProfileType = 0; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 // Holds the current foreground user's id 1111 int mCurrentUserId = 0; 1112 // Holds the target user's id during a user switch 1113 int mTargetUserId = UserHandle.USER_NULL; 1114 // If there are multiple profiles for the current user, their ids are here 1115 // Currently only the primary user can have managed profiles 1116 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1117 1118 /** 1119 * Mapping from each known user ID to the profile group ID it is associated with. 1120 */ 1121 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1122 1123 private UserManagerService mUserManager; 1124 1125 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1126 final ProcessRecord mApp; 1127 final int mPid; 1128 final IApplicationThread mAppThread; 1129 1130 AppDeathRecipient(ProcessRecord app, int pid, 1131 IApplicationThread thread) { 1132 if (localLOGV) Slog.v( 1133 TAG, "New death recipient " + this 1134 + " for thread " + thread.asBinder()); 1135 mApp = app; 1136 mPid = pid; 1137 mAppThread = thread; 1138 } 1139 1140 @Override 1141 public void binderDied() { 1142 if (localLOGV) Slog.v( 1143 TAG, "Death received in " + this 1144 + " for thread " + mAppThread.asBinder()); 1145 synchronized(ActivityManagerService.this) { 1146 appDiedLocked(mApp, mPid, mAppThread); 1147 } 1148 } 1149 } 1150 1151 static final int SHOW_ERROR_MSG = 1; 1152 static final int SHOW_NOT_RESPONDING_MSG = 2; 1153 static final int SHOW_FACTORY_ERROR_MSG = 3; 1154 static final int UPDATE_CONFIGURATION_MSG = 4; 1155 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1156 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1157 static final int SERVICE_TIMEOUT_MSG = 12; 1158 static final int UPDATE_TIME_ZONE = 13; 1159 static final int SHOW_UID_ERROR_MSG = 14; 1160 static final int IM_FEELING_LUCKY_MSG = 15; 1161 static final int PROC_START_TIMEOUT_MSG = 20; 1162 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1163 static final int KILL_APPLICATION_MSG = 22; 1164 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1165 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1166 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1167 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1168 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1169 static final int CLEAR_DNS_CACHE_MSG = 28; 1170 static final int UPDATE_HTTP_PROXY_MSG = 29; 1171 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1172 static final int DISPATCH_PROCESSES_CHANGED = 31; 1173 static final int DISPATCH_PROCESS_DIED = 32; 1174 static final int REPORT_MEM_USAGE_MSG = 33; 1175 static final int REPORT_USER_SWITCH_MSG = 34; 1176 static final int CONTINUE_USER_SWITCH_MSG = 35; 1177 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1178 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1179 static final int PERSIST_URI_GRANTS_MSG = 38; 1180 static final int REQUEST_ALL_PSS_MSG = 39; 1181 static final int START_PROFILES_MSG = 40; 1182 static final int UPDATE_TIME = 41; 1183 static final int SYSTEM_USER_START_MSG = 42; 1184 static final int SYSTEM_USER_CURRENT_MSG = 43; 1185 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1186 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1187 static final int START_USER_SWITCH_MSG = 46; 1188 1189 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1190 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1191 static final int FIRST_COMPAT_MODE_MSG = 300; 1192 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1193 1194 AlertDialog mUidAlert; 1195 CompatModeDialog mCompatModeDialog; 1196 long mLastMemUsageReportTime = 0; 1197 1198 private LockToAppRequestDialog mLockToAppRequest; 1199 1200 /** 1201 * Flag whether the current user is a "monkey", i.e. whether 1202 * the UI is driven by a UI automation tool. 1203 */ 1204 private boolean mUserIsMonkey; 1205 1206 /** Flag whether the device has a Recents UI */ 1207 boolean mHasRecents; 1208 1209 /** The dimensions of the thumbnails in the Recents UI. */ 1210 int mThumbnailWidth; 1211 int mThumbnailHeight; 1212 1213 final ServiceThread mHandlerThread; 1214 final MainHandler mHandler; 1215 1216 final class MainHandler extends Handler { 1217 public MainHandler(Looper looper) { 1218 super(looper, null, true); 1219 } 1220 1221 @Override 1222 public void handleMessage(Message msg) { 1223 switch (msg.what) { 1224 case SHOW_ERROR_MSG: { 1225 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1226 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1227 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1228 synchronized (ActivityManagerService.this) { 1229 ProcessRecord proc = (ProcessRecord)data.get("app"); 1230 AppErrorResult res = (AppErrorResult) data.get("result"); 1231 if (proc != null && proc.crashDialog != null) { 1232 Slog.e(TAG, "App already has crash dialog: " + proc); 1233 if (res != null) { 1234 res.set(0); 1235 } 1236 return; 1237 } 1238 boolean isBackground = (UserHandle.getAppId(proc.uid) 1239 >= Process.FIRST_APPLICATION_UID 1240 && proc.pid != MY_PID); 1241 for (int userId : mCurrentProfileIds) { 1242 isBackground &= (proc.userId != userId); 1243 } 1244 if (isBackground && !showBackground) { 1245 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1246 if (res != null) { 1247 res.set(0); 1248 } 1249 return; 1250 } 1251 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1252 Dialog d = new AppErrorDialog(mContext, 1253 ActivityManagerService.this, res, proc); 1254 d.show(); 1255 proc.crashDialog = d; 1256 } else { 1257 // The device is asleep, so just pretend that the user 1258 // saw a crash dialog and hit "force quit". 1259 if (res != null) { 1260 res.set(0); 1261 } 1262 } 1263 } 1264 1265 ensureBootCompleted(); 1266 } break; 1267 case SHOW_NOT_RESPONDING_MSG: { 1268 synchronized (ActivityManagerService.this) { 1269 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1270 ProcessRecord proc = (ProcessRecord)data.get("app"); 1271 if (proc != null && proc.anrDialog != null) { 1272 Slog.e(TAG, "App already has anr dialog: " + proc); 1273 return; 1274 } 1275 1276 Intent intent = new Intent("android.intent.action.ANR"); 1277 if (!mProcessesReady) { 1278 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1279 | Intent.FLAG_RECEIVER_FOREGROUND); 1280 } 1281 broadcastIntentLocked(null, null, intent, 1282 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1283 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1284 1285 if (mShowDialogs) { 1286 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1287 mContext, proc, (ActivityRecord)data.get("activity"), 1288 msg.arg1 != 0); 1289 d.show(); 1290 proc.anrDialog = d; 1291 } else { 1292 // Just kill the app if there is no dialog to be shown. 1293 killAppAtUsersRequest(proc, null); 1294 } 1295 } 1296 1297 ensureBootCompleted(); 1298 } break; 1299 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1300 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1301 synchronized (ActivityManagerService.this) { 1302 ProcessRecord proc = (ProcessRecord) data.get("app"); 1303 if (proc == null) { 1304 Slog.e(TAG, "App not found when showing strict mode dialog."); 1305 break; 1306 } 1307 if (proc.crashDialog != null) { 1308 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1309 return; 1310 } 1311 AppErrorResult res = (AppErrorResult) data.get("result"); 1312 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1313 Dialog d = new StrictModeViolationDialog(mContext, 1314 ActivityManagerService.this, res, proc); 1315 d.show(); 1316 proc.crashDialog = d; 1317 } else { 1318 // The device is asleep, so just pretend that the user 1319 // saw a crash dialog and hit "force quit". 1320 res.set(0); 1321 } 1322 } 1323 ensureBootCompleted(); 1324 } break; 1325 case SHOW_FACTORY_ERROR_MSG: { 1326 Dialog d = new FactoryErrorDialog( 1327 mContext, msg.getData().getCharSequence("msg")); 1328 d.show(); 1329 ensureBootCompleted(); 1330 } break; 1331 case UPDATE_CONFIGURATION_MSG: { 1332 final ContentResolver resolver = mContext.getContentResolver(); 1333 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1334 } break; 1335 case GC_BACKGROUND_PROCESSES_MSG: { 1336 synchronized (ActivityManagerService.this) { 1337 performAppGcsIfAppropriateLocked(); 1338 } 1339 } break; 1340 case WAIT_FOR_DEBUGGER_MSG: { 1341 synchronized (ActivityManagerService.this) { 1342 ProcessRecord app = (ProcessRecord)msg.obj; 1343 if (msg.arg1 != 0) { 1344 if (!app.waitedForDebugger) { 1345 Dialog d = new AppWaitingForDebuggerDialog( 1346 ActivityManagerService.this, 1347 mContext, app); 1348 app.waitDialog = d; 1349 app.waitedForDebugger = true; 1350 d.show(); 1351 } 1352 } else { 1353 if (app.waitDialog != null) { 1354 app.waitDialog.dismiss(); 1355 app.waitDialog = null; 1356 } 1357 } 1358 } 1359 } break; 1360 case SERVICE_TIMEOUT_MSG: { 1361 if (mDidDexOpt) { 1362 mDidDexOpt = false; 1363 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1364 nmsg.obj = msg.obj; 1365 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1366 return; 1367 } 1368 mServices.serviceTimeout((ProcessRecord)msg.obj); 1369 } break; 1370 case UPDATE_TIME_ZONE: { 1371 synchronized (ActivityManagerService.this) { 1372 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1373 ProcessRecord r = mLruProcesses.get(i); 1374 if (r.thread != null) { 1375 try { 1376 r.thread.updateTimeZone(); 1377 } catch (RemoteException ex) { 1378 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1379 } 1380 } 1381 } 1382 } 1383 } break; 1384 case CLEAR_DNS_CACHE_MSG: { 1385 synchronized (ActivityManagerService.this) { 1386 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1387 ProcessRecord r = mLruProcesses.get(i); 1388 if (r.thread != null) { 1389 try { 1390 r.thread.clearDnsCache(); 1391 } catch (RemoteException ex) { 1392 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1393 } 1394 } 1395 } 1396 } 1397 } break; 1398 case UPDATE_HTTP_PROXY_MSG: { 1399 ProxyInfo proxy = (ProxyInfo)msg.obj; 1400 String host = ""; 1401 String port = ""; 1402 String exclList = ""; 1403 Uri pacFileUrl = Uri.EMPTY; 1404 if (proxy != null) { 1405 host = proxy.getHost(); 1406 port = Integer.toString(proxy.getPort()); 1407 exclList = proxy.getExclusionListAsString(); 1408 pacFileUrl = proxy.getPacFileUrl(); 1409 } 1410 synchronized (ActivityManagerService.this) { 1411 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1412 ProcessRecord r = mLruProcesses.get(i); 1413 if (r.thread != null) { 1414 try { 1415 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1416 } catch (RemoteException ex) { 1417 Slog.w(TAG, "Failed to update http proxy for: " + 1418 r.info.processName); 1419 } 1420 } 1421 } 1422 } 1423 } break; 1424 case SHOW_UID_ERROR_MSG: { 1425 String title = "System UIDs Inconsistent"; 1426 String text = "UIDs on the system are inconsistent, you need to wipe your" 1427 + " data partition or your device will be unstable."; 1428 Log.e(TAG, title + ": " + text); 1429 if (mShowDialogs) { 1430 // XXX This is a temporary dialog, no need to localize. 1431 AlertDialog d = new BaseErrorDialog(mContext); 1432 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1433 d.setCancelable(false); 1434 d.setTitle(title); 1435 d.setMessage(text); 1436 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1437 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1438 mUidAlert = d; 1439 d.show(); 1440 } 1441 } break; 1442 case IM_FEELING_LUCKY_MSG: { 1443 if (mUidAlert != null) { 1444 mUidAlert.dismiss(); 1445 mUidAlert = null; 1446 } 1447 } break; 1448 case PROC_START_TIMEOUT_MSG: { 1449 if (mDidDexOpt) { 1450 mDidDexOpt = false; 1451 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1452 nmsg.obj = msg.obj; 1453 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1454 return; 1455 } 1456 ProcessRecord app = (ProcessRecord)msg.obj; 1457 synchronized (ActivityManagerService.this) { 1458 processStartTimedOutLocked(app); 1459 } 1460 } break; 1461 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1462 synchronized (ActivityManagerService.this) { 1463 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1464 } 1465 } break; 1466 case KILL_APPLICATION_MSG: { 1467 synchronized (ActivityManagerService.this) { 1468 int appid = msg.arg1; 1469 boolean restart = (msg.arg2 == 1); 1470 Bundle bundle = (Bundle)msg.obj; 1471 String pkg = bundle.getString("pkg"); 1472 String reason = bundle.getString("reason"); 1473 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1474 false, UserHandle.USER_ALL, reason); 1475 } 1476 } break; 1477 case FINALIZE_PENDING_INTENT_MSG: { 1478 ((PendingIntentRecord)msg.obj).completeFinalize(); 1479 } break; 1480 case POST_HEAVY_NOTIFICATION_MSG: { 1481 INotificationManager inm = NotificationManager.getService(); 1482 if (inm == null) { 1483 return; 1484 } 1485 1486 ActivityRecord root = (ActivityRecord)msg.obj; 1487 ProcessRecord process = root.app; 1488 if (process == null) { 1489 return; 1490 } 1491 1492 try { 1493 Context context = mContext.createPackageContext(process.info.packageName, 0); 1494 String text = mContext.getString(R.string.heavy_weight_notification, 1495 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1496 Notification notification = new Notification(); 1497 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1498 notification.when = 0; 1499 notification.flags = Notification.FLAG_ONGOING_EVENT; 1500 notification.tickerText = text; 1501 notification.defaults = 0; // please be quiet 1502 notification.sound = null; 1503 notification.vibrate = null; 1504 notification.color = mContext.getResources().getColor( 1505 com.android.internal.R.color.system_notification_accent_color); 1506 notification.setLatestEventInfo(context, text, 1507 mContext.getText(R.string.heavy_weight_notification_detail), 1508 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1509 PendingIntent.FLAG_CANCEL_CURRENT, null, 1510 new UserHandle(root.userId))); 1511 1512 try { 1513 int[] outId = new int[1]; 1514 inm.enqueueNotificationWithTag("android", "android", null, 1515 R.string.heavy_weight_notification, 1516 notification, outId, root.userId); 1517 } catch (RuntimeException e) { 1518 Slog.w(ActivityManagerService.TAG, 1519 "Error showing notification for heavy-weight app", e); 1520 } catch (RemoteException e) { 1521 } 1522 } catch (NameNotFoundException e) { 1523 Slog.w(TAG, "Unable to create context for heavy notification", e); 1524 } 1525 } break; 1526 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1527 INotificationManager inm = NotificationManager.getService(); 1528 if (inm == null) { 1529 return; 1530 } 1531 try { 1532 inm.cancelNotificationWithTag("android", null, 1533 R.string.heavy_weight_notification, msg.arg1); 1534 } catch (RuntimeException e) { 1535 Slog.w(ActivityManagerService.TAG, 1536 "Error canceling notification for service", e); 1537 } catch (RemoteException e) { 1538 } 1539 } break; 1540 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1541 synchronized (ActivityManagerService.this) { 1542 checkExcessivePowerUsageLocked(true); 1543 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1544 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1545 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1546 } 1547 } break; 1548 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1549 synchronized (ActivityManagerService.this) { 1550 ActivityRecord ar = (ActivityRecord)msg.obj; 1551 if (mCompatModeDialog != null) { 1552 if (mCompatModeDialog.mAppInfo.packageName.equals( 1553 ar.info.applicationInfo.packageName)) { 1554 return; 1555 } 1556 mCompatModeDialog.dismiss(); 1557 mCompatModeDialog = null; 1558 } 1559 if (ar != null && false) { 1560 if (mCompatModePackages.getPackageAskCompatModeLocked( 1561 ar.packageName)) { 1562 int mode = mCompatModePackages.computeCompatModeLocked( 1563 ar.info.applicationInfo); 1564 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1565 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1566 mCompatModeDialog = new CompatModeDialog( 1567 ActivityManagerService.this, mContext, 1568 ar.info.applicationInfo); 1569 mCompatModeDialog.show(); 1570 } 1571 } 1572 } 1573 } 1574 break; 1575 } 1576 case DISPATCH_PROCESSES_CHANGED: { 1577 dispatchProcessesChanged(); 1578 break; 1579 } 1580 case DISPATCH_PROCESS_DIED: { 1581 final int pid = msg.arg1; 1582 final int uid = msg.arg2; 1583 dispatchProcessDied(pid, uid); 1584 break; 1585 } 1586 case REPORT_MEM_USAGE_MSG: { 1587 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1588 Thread thread = new Thread() { 1589 @Override public void run() { 1590 final SparseArray<ProcessMemInfo> infoMap 1591 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1592 for (int i=0, N=memInfos.size(); i<N; i++) { 1593 ProcessMemInfo mi = memInfos.get(i); 1594 infoMap.put(mi.pid, mi); 1595 } 1596 updateCpuStatsNow(); 1597 synchronized (mProcessCpuThread) { 1598 final int N = mProcessCpuTracker.countStats(); 1599 for (int i=0; i<N; i++) { 1600 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1601 if (st.vsize > 0) { 1602 long pss = Debug.getPss(st.pid, null); 1603 if (pss > 0) { 1604 if (infoMap.indexOfKey(st.pid) < 0) { 1605 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1606 ProcessList.NATIVE_ADJ, -1, "native", null); 1607 mi.pss = pss; 1608 memInfos.add(mi); 1609 } 1610 } 1611 } 1612 } 1613 } 1614 1615 long totalPss = 0; 1616 for (int i=0, N=memInfos.size(); i<N; i++) { 1617 ProcessMemInfo mi = memInfos.get(i); 1618 if (mi.pss == 0) { 1619 mi.pss = Debug.getPss(mi.pid, null); 1620 } 1621 totalPss += mi.pss; 1622 } 1623 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1624 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1625 if (lhs.oomAdj != rhs.oomAdj) { 1626 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1627 } 1628 if (lhs.pss != rhs.pss) { 1629 return lhs.pss < rhs.pss ? 1 : -1; 1630 } 1631 return 0; 1632 } 1633 }); 1634 1635 StringBuilder tag = new StringBuilder(128); 1636 StringBuilder stack = new StringBuilder(128); 1637 tag.append("Low on memory -- "); 1638 appendMemBucket(tag, totalPss, "total", false); 1639 appendMemBucket(stack, totalPss, "total", true); 1640 1641 StringBuilder logBuilder = new StringBuilder(1024); 1642 logBuilder.append("Low on memory:\n"); 1643 1644 boolean firstLine = true; 1645 int lastOomAdj = Integer.MIN_VALUE; 1646 for (int i=0, N=memInfos.size(); i<N; i++) { 1647 ProcessMemInfo mi = memInfos.get(i); 1648 1649 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1650 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1651 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1652 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1653 if (lastOomAdj != mi.oomAdj) { 1654 lastOomAdj = mi.oomAdj; 1655 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1656 tag.append(" / "); 1657 } 1658 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1659 if (firstLine) { 1660 stack.append(":"); 1661 firstLine = false; 1662 } 1663 stack.append("\n\t at "); 1664 } else { 1665 stack.append("$"); 1666 } 1667 } else { 1668 tag.append(" "); 1669 stack.append("$"); 1670 } 1671 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1672 appendMemBucket(tag, mi.pss, mi.name, false); 1673 } 1674 appendMemBucket(stack, mi.pss, mi.name, true); 1675 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1676 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1677 stack.append("("); 1678 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1679 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1680 stack.append(DUMP_MEM_OOM_LABEL[k]); 1681 stack.append(":"); 1682 stack.append(DUMP_MEM_OOM_ADJ[k]); 1683 } 1684 } 1685 stack.append(")"); 1686 } 1687 } 1688 1689 logBuilder.append(" "); 1690 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1691 logBuilder.append(' '); 1692 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1693 logBuilder.append(' '); 1694 ProcessList.appendRamKb(logBuilder, mi.pss); 1695 logBuilder.append(" kB: "); 1696 logBuilder.append(mi.name); 1697 logBuilder.append(" ("); 1698 logBuilder.append(mi.pid); 1699 logBuilder.append(") "); 1700 logBuilder.append(mi.adjType); 1701 logBuilder.append('\n'); 1702 if (mi.adjReason != null) { 1703 logBuilder.append(" "); 1704 logBuilder.append(mi.adjReason); 1705 logBuilder.append('\n'); 1706 } 1707 } 1708 1709 logBuilder.append(" "); 1710 ProcessList.appendRamKb(logBuilder, totalPss); 1711 logBuilder.append(" kB: TOTAL\n"); 1712 1713 long[] infos = new long[Debug.MEMINFO_COUNT]; 1714 Debug.getMemInfo(infos); 1715 logBuilder.append(" MemInfo: "); 1716 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1717 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1718 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1719 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1720 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1721 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1722 logBuilder.append(" ZRAM: "); 1723 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1724 logBuilder.append(" kB RAM, "); 1725 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1726 logBuilder.append(" kB swap total, "); 1727 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1728 logBuilder.append(" kB swap free\n"); 1729 } 1730 Slog.i(TAG, logBuilder.toString()); 1731 1732 StringBuilder dropBuilder = new StringBuilder(1024); 1733 /* 1734 StringWriter oomSw = new StringWriter(); 1735 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1736 StringWriter catSw = new StringWriter(); 1737 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1738 String[] emptyArgs = new String[] { }; 1739 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1740 oomPw.flush(); 1741 String oomString = oomSw.toString(); 1742 */ 1743 dropBuilder.append(stack); 1744 dropBuilder.append('\n'); 1745 dropBuilder.append('\n'); 1746 dropBuilder.append(logBuilder); 1747 dropBuilder.append('\n'); 1748 /* 1749 dropBuilder.append(oomString); 1750 dropBuilder.append('\n'); 1751 */ 1752 StringWriter catSw = new StringWriter(); 1753 synchronized (ActivityManagerService.this) { 1754 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1755 String[] emptyArgs = new String[] { }; 1756 catPw.println(); 1757 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1758 catPw.println(); 1759 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1760 false, false, null); 1761 catPw.println(); 1762 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1763 catPw.flush(); 1764 } 1765 dropBuilder.append(catSw.toString()); 1766 addErrorToDropBox("lowmem", null, "system_server", null, 1767 null, tag.toString(), dropBuilder.toString(), null, null); 1768 //Slog.i(TAG, "Sent to dropbox:"); 1769 //Slog.i(TAG, dropBuilder.toString()); 1770 synchronized (ActivityManagerService.this) { 1771 long now = SystemClock.uptimeMillis(); 1772 if (mLastMemUsageReportTime < now) { 1773 mLastMemUsageReportTime = now; 1774 } 1775 } 1776 } 1777 }; 1778 thread.start(); 1779 break; 1780 } 1781 case START_USER_SWITCH_MSG: { 1782 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1783 break; 1784 } 1785 case REPORT_USER_SWITCH_MSG: { 1786 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1787 break; 1788 } 1789 case CONTINUE_USER_SWITCH_MSG: { 1790 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1791 break; 1792 } 1793 case USER_SWITCH_TIMEOUT_MSG: { 1794 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1795 break; 1796 } 1797 case IMMERSIVE_MODE_LOCK_MSG: { 1798 final boolean nextState = (msg.arg1 != 0); 1799 if (mUpdateLock.isHeld() != nextState) { 1800 if (DEBUG_IMMERSIVE) { 1801 final ActivityRecord r = (ActivityRecord) msg.obj; 1802 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1803 } 1804 if (nextState) { 1805 mUpdateLock.acquire(); 1806 } else { 1807 mUpdateLock.release(); 1808 } 1809 } 1810 break; 1811 } 1812 case PERSIST_URI_GRANTS_MSG: { 1813 writeGrantedUriPermissions(); 1814 break; 1815 } 1816 case REQUEST_ALL_PSS_MSG: { 1817 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1818 break; 1819 } 1820 case START_PROFILES_MSG: { 1821 synchronized (ActivityManagerService.this) { 1822 startProfilesLocked(); 1823 } 1824 break; 1825 } 1826 case UPDATE_TIME: { 1827 synchronized (ActivityManagerService.this) { 1828 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1829 ProcessRecord r = mLruProcesses.get(i); 1830 if (r.thread != null) { 1831 try { 1832 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1833 } catch (RemoteException ex) { 1834 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1835 } 1836 } 1837 } 1838 } 1839 break; 1840 } 1841 case SYSTEM_USER_START_MSG: { 1842 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1843 Integer.toString(msg.arg1), msg.arg1); 1844 mSystemServiceManager.startUser(msg.arg1); 1845 break; 1846 } 1847 case SYSTEM_USER_CURRENT_MSG: { 1848 mBatteryStatsService.noteEvent( 1849 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1850 Integer.toString(msg.arg2), msg.arg2); 1851 mBatteryStatsService.noteEvent( 1852 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1853 Integer.toString(msg.arg1), msg.arg1); 1854 mSystemServiceManager.switchUser(msg.arg1); 1855 mLockToAppRequest.clearPrompt(); 1856 break; 1857 } 1858 case ENTER_ANIMATION_COMPLETE_MSG: { 1859 synchronized (ActivityManagerService.this) { 1860 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1861 if (r != null && r.app != null && r.app.thread != null) { 1862 try { 1863 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1864 } catch (RemoteException e) { 1865 } 1866 } 1867 } 1868 break; 1869 } 1870 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1871 enableScreenAfterBoot(); 1872 break; 1873 } 1874 } 1875 } 1876 }; 1877 1878 static final int COLLECT_PSS_BG_MSG = 1; 1879 1880 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1881 @Override 1882 public void handleMessage(Message msg) { 1883 switch (msg.what) { 1884 case COLLECT_PSS_BG_MSG: { 1885 long start = SystemClock.uptimeMillis(); 1886 MemInfoReader memInfo = null; 1887 synchronized (ActivityManagerService.this) { 1888 if (mFullPssPending) { 1889 mFullPssPending = false; 1890 memInfo = new MemInfoReader(); 1891 } 1892 } 1893 if (memInfo != null) { 1894 updateCpuStatsNow(); 1895 long nativeTotalPss = 0; 1896 synchronized (mProcessCpuThread) { 1897 final int N = mProcessCpuTracker.countStats(); 1898 for (int j=0; j<N; j++) { 1899 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1900 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1901 // This is definitely an application process; skip it. 1902 continue; 1903 } 1904 synchronized (mPidsSelfLocked) { 1905 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1906 // This is one of our own processes; skip it. 1907 continue; 1908 } 1909 } 1910 nativeTotalPss += Debug.getPss(st.pid, null); 1911 } 1912 } 1913 memInfo.readMemInfo(); 1914 synchronized (this) { 1915 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1916 + (SystemClock.uptimeMillis()-start) + "ms"); 1917 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1918 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1919 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1920 +memInfo.getSlabSizeKb(), 1921 nativeTotalPss); 1922 } 1923 } 1924 1925 int i=0, num=0; 1926 long[] tmp = new long[1]; 1927 do { 1928 ProcessRecord proc; 1929 int procState; 1930 int pid; 1931 synchronized (ActivityManagerService.this) { 1932 if (i >= mPendingPssProcesses.size()) { 1933 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1934 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1935 mPendingPssProcesses.clear(); 1936 return; 1937 } 1938 proc = mPendingPssProcesses.get(i); 1939 procState = proc.pssProcState; 1940 if (proc.thread != null && procState == proc.setProcState) { 1941 pid = proc.pid; 1942 } else { 1943 proc = null; 1944 pid = 0; 1945 } 1946 i++; 1947 } 1948 if (proc != null) { 1949 long pss = Debug.getPss(pid, tmp); 1950 synchronized (ActivityManagerService.this) { 1951 if (proc.thread != null && proc.setProcState == procState 1952 && proc.pid == pid) { 1953 num++; 1954 proc.lastPssTime = SystemClock.uptimeMillis(); 1955 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1956 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1957 + ": " + pss + " lastPss=" + proc.lastPss 1958 + " state=" + ProcessList.makeProcStateString(procState)); 1959 if (proc.initialIdlePss == 0) { 1960 proc.initialIdlePss = pss; 1961 } 1962 proc.lastPss = pss; 1963 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1964 proc.lastCachedPss = pss; 1965 } 1966 } 1967 } 1968 } 1969 } while (true); 1970 } 1971 } 1972 } 1973 }; 1974 1975 /** 1976 * Monitor for package changes and update our internal state. 1977 */ 1978 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1979 @Override 1980 public void onPackageRemoved(String packageName, int uid) { 1981 // Remove all tasks with activities in the specified package from the list of recent tasks 1982 synchronized (ActivityManagerService.this) { 1983 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1984 TaskRecord tr = mRecentTasks.get(i); 1985 ComponentName cn = tr.intent.getComponent(); 1986 if (cn != null && cn.getPackageName().equals(packageName)) { 1987 // If the package name matches, remove the task and kill the process 1988 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1989 } 1990 } 1991 } 1992 } 1993 1994 @Override 1995 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1996 onPackageModified(packageName); 1997 return true; 1998 } 1999 2000 @Override 2001 public void onPackageModified(String packageName) { 2002 final PackageManager pm = mContext.getPackageManager(); 2003 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 2004 new ArrayList<Pair<Intent, Integer>>(); 2005 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2006 // Copy the list of recent tasks so that we don't hold onto the lock on 2007 // ActivityManagerService for long periods while checking if components exist. 2008 synchronized (ActivityManagerService.this) { 2009 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2010 TaskRecord tr = mRecentTasks.get(i); 2011 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2012 } 2013 } 2014 // Check the recent tasks and filter out all tasks with components that no longer exist. 2015 Intent tmpI = new Intent(); 2016 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2017 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2018 ComponentName cn = p.first.getComponent(); 2019 if (cn != null && cn.getPackageName().equals(packageName)) { 2020 try { 2021 // Add the task to the list to remove if the component no longer exists 2022 tmpI.setComponent(cn); 2023 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2024 tasksToRemove.add(p.second); 2025 } 2026 } catch (Exception e) {} 2027 } 2028 } 2029 // Prune all the tasks with removed components from the list of recent tasks 2030 synchronized (ActivityManagerService.this) { 2031 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2032 // Remove the task but don't kill the process (since other components in that 2033 // package may still be running and in the background) 2034 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2035 } 2036 } 2037 } 2038 2039 @Override 2040 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2041 // Force stop the specified packages 2042 if (packages != null) { 2043 for (String pkg : packages) { 2044 synchronized (ActivityManagerService.this) { 2045 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2046 "finished booting")) { 2047 return true; 2048 } 2049 } 2050 } 2051 } 2052 return false; 2053 } 2054 }; 2055 2056 public void setSystemProcess() { 2057 try { 2058 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2059 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2060 ServiceManager.addService("meminfo", new MemBinder(this)); 2061 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2062 ServiceManager.addService("dbinfo", new DbBinder(this)); 2063 if (MONITOR_CPU_USAGE) { 2064 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2065 } 2066 ServiceManager.addService("permission", new PermissionController(this)); 2067 2068 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2069 "android", STOCK_PM_FLAGS); 2070 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2071 2072 synchronized (this) { 2073 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2074 app.persistent = true; 2075 app.pid = MY_PID; 2076 app.maxAdj = ProcessList.SYSTEM_ADJ; 2077 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2078 mProcessNames.put(app.processName, app.uid, app); 2079 synchronized (mPidsSelfLocked) { 2080 mPidsSelfLocked.put(app.pid, app); 2081 } 2082 updateLruProcessLocked(app, false, null); 2083 updateOomAdjLocked(); 2084 } 2085 } catch (PackageManager.NameNotFoundException e) { 2086 throw new RuntimeException( 2087 "Unable to find android system package", e); 2088 } 2089 } 2090 2091 public void setWindowManager(WindowManagerService wm) { 2092 mWindowManager = wm; 2093 mStackSupervisor.setWindowManager(wm); 2094 } 2095 2096 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2097 mUsageStatsService = usageStatsManager; 2098 } 2099 2100 public void startObservingNativeCrashes() { 2101 final NativeCrashListener ncl = new NativeCrashListener(this); 2102 ncl.start(); 2103 } 2104 2105 public IAppOpsService getAppOpsService() { 2106 return mAppOpsService; 2107 } 2108 2109 static class MemBinder extends Binder { 2110 ActivityManagerService mActivityManagerService; 2111 MemBinder(ActivityManagerService activityManagerService) { 2112 mActivityManagerService = activityManagerService; 2113 } 2114 2115 @Override 2116 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2117 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2118 != PackageManager.PERMISSION_GRANTED) { 2119 pw.println("Permission Denial: can't dump meminfo from from pid=" 2120 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2121 + " without permission " + android.Manifest.permission.DUMP); 2122 return; 2123 } 2124 2125 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2126 } 2127 } 2128 2129 static class GraphicsBinder extends Binder { 2130 ActivityManagerService mActivityManagerService; 2131 GraphicsBinder(ActivityManagerService activityManagerService) { 2132 mActivityManagerService = activityManagerService; 2133 } 2134 2135 @Override 2136 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2137 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2138 != PackageManager.PERMISSION_GRANTED) { 2139 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2140 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2141 + " without permission " + android.Manifest.permission.DUMP); 2142 return; 2143 } 2144 2145 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2146 } 2147 } 2148 2149 static class DbBinder extends Binder { 2150 ActivityManagerService mActivityManagerService; 2151 DbBinder(ActivityManagerService activityManagerService) { 2152 mActivityManagerService = activityManagerService; 2153 } 2154 2155 @Override 2156 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2157 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2158 != PackageManager.PERMISSION_GRANTED) { 2159 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2160 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2161 + " without permission " + android.Manifest.permission.DUMP); 2162 return; 2163 } 2164 2165 mActivityManagerService.dumpDbInfo(fd, pw, args); 2166 } 2167 } 2168 2169 static class CpuBinder extends Binder { 2170 ActivityManagerService mActivityManagerService; 2171 CpuBinder(ActivityManagerService activityManagerService) { 2172 mActivityManagerService = activityManagerService; 2173 } 2174 2175 @Override 2176 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2177 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2178 != PackageManager.PERMISSION_GRANTED) { 2179 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2180 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2181 + " without permission " + android.Manifest.permission.DUMP); 2182 return; 2183 } 2184 2185 synchronized (mActivityManagerService.mProcessCpuThread) { 2186 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2187 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2188 SystemClock.uptimeMillis())); 2189 } 2190 } 2191 } 2192 2193 public static final class Lifecycle extends SystemService { 2194 private final ActivityManagerService mService; 2195 2196 public Lifecycle(Context context) { 2197 super(context); 2198 mService = new ActivityManagerService(context); 2199 } 2200 2201 @Override 2202 public void onStart() { 2203 mService.start(); 2204 } 2205 2206 public ActivityManagerService getService() { 2207 return mService; 2208 } 2209 } 2210 2211 // Note: This method is invoked on the main thread but may need to attach various 2212 // handlers to other threads. So take care to be explicit about the looper. 2213 public ActivityManagerService(Context systemContext) { 2214 mContext = systemContext; 2215 mFactoryTest = FactoryTest.getMode(); 2216 mSystemThread = ActivityThread.currentActivityThread(); 2217 2218 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2219 2220 mHandlerThread = new ServiceThread(TAG, 2221 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2222 mHandlerThread.start(); 2223 mHandler = new MainHandler(mHandlerThread.getLooper()); 2224 2225 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2226 "foreground", BROADCAST_FG_TIMEOUT, false); 2227 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2228 "background", BROADCAST_BG_TIMEOUT, true); 2229 mBroadcastQueues[0] = mFgBroadcastQueue; 2230 mBroadcastQueues[1] = mBgBroadcastQueue; 2231 2232 mServices = new ActiveServices(this); 2233 mProviderMap = new ProviderMap(this); 2234 2235 // TODO: Move creation of battery stats service outside of activity manager service. 2236 File dataDir = Environment.getDataDirectory(); 2237 File systemDir = new File(dataDir, "system"); 2238 systemDir.mkdirs(); 2239 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2240 mBatteryStatsService.getActiveStatistics().readLocked(); 2241 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2242 mOnBattery = DEBUG_POWER ? true 2243 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2244 mBatteryStatsService.getActiveStatistics().setCallback(this); 2245 2246 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2247 2248 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2249 2250 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2251 2252 // User 0 is the first and only user that runs at boot. 2253 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2254 mUserLru.add(Integer.valueOf(0)); 2255 updateStartedUserArrayLocked(); 2256 2257 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2258 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2259 2260 mConfiguration.setToDefaults(); 2261 mConfiguration.setLocale(Locale.getDefault()); 2262 2263 mConfigurationSeq = mConfiguration.seq = 1; 2264 mProcessCpuTracker.init(); 2265 2266 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2267 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2268 mStackSupervisor = new ActivityStackSupervisor(this); 2269 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2270 2271 mProcessCpuThread = new Thread("CpuTracker") { 2272 @Override 2273 public void run() { 2274 while (true) { 2275 try { 2276 try { 2277 synchronized(this) { 2278 final long now = SystemClock.uptimeMillis(); 2279 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2280 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2281 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2282 // + ", write delay=" + nextWriteDelay); 2283 if (nextWriteDelay < nextCpuDelay) { 2284 nextCpuDelay = nextWriteDelay; 2285 } 2286 if (nextCpuDelay > 0) { 2287 mProcessCpuMutexFree.set(true); 2288 this.wait(nextCpuDelay); 2289 } 2290 } 2291 } catch (InterruptedException e) { 2292 } 2293 updateCpuStatsNow(); 2294 } catch (Exception e) { 2295 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2296 } 2297 } 2298 } 2299 }; 2300 2301 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2302 2303 Watchdog.getInstance().addMonitor(this); 2304 Watchdog.getInstance().addThread(mHandler); 2305 } 2306 2307 public void setSystemServiceManager(SystemServiceManager mgr) { 2308 mSystemServiceManager = mgr; 2309 } 2310 2311 private void start() { 2312 Process.removeAllProcessGroups(); 2313 mProcessCpuThread.start(); 2314 2315 mBatteryStatsService.publish(mContext); 2316 mAppOpsService.publish(mContext); 2317 Slog.d("AppOps", "AppOpsService published"); 2318 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2319 } 2320 2321 public void initPowerManagement() { 2322 mStackSupervisor.initPowerManagement(); 2323 mBatteryStatsService.initPowerManagement(); 2324 } 2325 2326 @Override 2327 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2328 throws RemoteException { 2329 if (code == SYSPROPS_TRANSACTION) { 2330 // We need to tell all apps about the system property change. 2331 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2332 synchronized(this) { 2333 final int NP = mProcessNames.getMap().size(); 2334 for (int ip=0; ip<NP; ip++) { 2335 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2336 final int NA = apps.size(); 2337 for (int ia=0; ia<NA; ia++) { 2338 ProcessRecord app = apps.valueAt(ia); 2339 if (app.thread != null) { 2340 procs.add(app.thread.asBinder()); 2341 } 2342 } 2343 } 2344 } 2345 2346 int N = procs.size(); 2347 for (int i=0; i<N; i++) { 2348 Parcel data2 = Parcel.obtain(); 2349 try { 2350 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2351 } catch (RemoteException e) { 2352 } 2353 data2.recycle(); 2354 } 2355 } 2356 try { 2357 return super.onTransact(code, data, reply, flags); 2358 } catch (RuntimeException e) { 2359 // The activity manager only throws security exceptions, so let's 2360 // log all others. 2361 if (!(e instanceof SecurityException)) { 2362 Slog.wtf(TAG, "Activity Manager Crash", e); 2363 } 2364 throw e; 2365 } 2366 } 2367 2368 void updateCpuStats() { 2369 final long now = SystemClock.uptimeMillis(); 2370 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2371 return; 2372 } 2373 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2374 synchronized (mProcessCpuThread) { 2375 mProcessCpuThread.notify(); 2376 } 2377 } 2378 } 2379 2380 void updateCpuStatsNow() { 2381 synchronized (mProcessCpuThread) { 2382 mProcessCpuMutexFree.set(false); 2383 final long now = SystemClock.uptimeMillis(); 2384 boolean haveNewCpuStats = false; 2385 2386 if (MONITOR_CPU_USAGE && 2387 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2388 mLastCpuTime.set(now); 2389 haveNewCpuStats = true; 2390 mProcessCpuTracker.update(); 2391 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2392 //Slog.i(TAG, "Total CPU usage: " 2393 // + mProcessCpu.getTotalCpuPercent() + "%"); 2394 2395 // Slog the cpu usage if the property is set. 2396 if ("true".equals(SystemProperties.get("events.cpu"))) { 2397 int user = mProcessCpuTracker.getLastUserTime(); 2398 int system = mProcessCpuTracker.getLastSystemTime(); 2399 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2400 int irq = mProcessCpuTracker.getLastIrqTime(); 2401 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2402 int idle = mProcessCpuTracker.getLastIdleTime(); 2403 2404 int total = user + system + iowait + irq + softIrq + idle; 2405 if (total == 0) total = 1; 2406 2407 EventLog.writeEvent(EventLogTags.CPU, 2408 ((user+system+iowait+irq+softIrq) * 100) / total, 2409 (user * 100) / total, 2410 (system * 100) / total, 2411 (iowait * 100) / total, 2412 (irq * 100) / total, 2413 (softIrq * 100) / total); 2414 } 2415 } 2416 2417 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2418 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2419 synchronized(bstats) { 2420 synchronized(mPidsSelfLocked) { 2421 if (haveNewCpuStats) { 2422 if (mOnBattery) { 2423 int perc = bstats.startAddingCpuLocked(); 2424 int totalUTime = 0; 2425 int totalSTime = 0; 2426 final int N = mProcessCpuTracker.countStats(); 2427 for (int i=0; i<N; i++) { 2428 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2429 if (!st.working) { 2430 continue; 2431 } 2432 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2433 int otherUTime = (st.rel_utime*perc)/100; 2434 int otherSTime = (st.rel_stime*perc)/100; 2435 totalUTime += otherUTime; 2436 totalSTime += otherSTime; 2437 if (pr != null) { 2438 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2439 if (ps == null || !ps.isActive()) { 2440 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2441 pr.info.uid, pr.processName); 2442 } 2443 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2444 st.rel_stime-otherSTime); 2445 ps.addSpeedStepTimes(cpuSpeedTimes); 2446 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2447 } else { 2448 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2449 if (ps == null || !ps.isActive()) { 2450 st.batteryStats = ps = bstats.getProcessStatsLocked( 2451 bstats.mapUid(st.uid), st.name); 2452 } 2453 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2454 st.rel_stime-otherSTime); 2455 ps.addSpeedStepTimes(cpuSpeedTimes); 2456 } 2457 } 2458 bstats.finishAddingCpuLocked(perc, totalUTime, 2459 totalSTime, cpuSpeedTimes); 2460 } 2461 } 2462 } 2463 2464 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2465 mLastWriteTime = now; 2466 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2467 } 2468 } 2469 } 2470 } 2471 2472 @Override 2473 public void batteryNeedsCpuUpdate() { 2474 updateCpuStatsNow(); 2475 } 2476 2477 @Override 2478 public void batteryPowerChanged(boolean onBattery) { 2479 // When plugging in, update the CPU stats first before changing 2480 // the plug state. 2481 updateCpuStatsNow(); 2482 synchronized (this) { 2483 synchronized(mPidsSelfLocked) { 2484 mOnBattery = DEBUG_POWER ? true : onBattery; 2485 } 2486 } 2487 } 2488 2489 /** 2490 * Initialize the application bind args. These are passed to each 2491 * process when the bindApplication() IPC is sent to the process. They're 2492 * lazily setup to make sure the services are running when they're asked for. 2493 */ 2494 private HashMap<String, IBinder> getCommonServicesLocked() { 2495 if (mAppBindArgs == null) { 2496 mAppBindArgs = new HashMap<String, IBinder>(); 2497 2498 // Setup the application init args 2499 mAppBindArgs.put("package", ServiceManager.getService("package")); 2500 mAppBindArgs.put("window", ServiceManager.getService("window")); 2501 mAppBindArgs.put(Context.ALARM_SERVICE, 2502 ServiceManager.getService(Context.ALARM_SERVICE)); 2503 } 2504 return mAppBindArgs; 2505 } 2506 2507 final void setFocusedActivityLocked(ActivityRecord r) { 2508 if (mFocusedActivity != r) { 2509 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2510 mFocusedActivity = r; 2511 if (r.task != null && r.task.voiceInteractor != null) { 2512 startRunningVoiceLocked(); 2513 } else { 2514 finishRunningVoiceLocked(); 2515 } 2516 mStackSupervisor.setFocusedStack(r); 2517 if (r != null) { 2518 mWindowManager.setFocusedApp(r.appToken, true); 2519 } 2520 applyUpdateLockStateLocked(r); 2521 } 2522 } 2523 2524 final void clearFocusedActivity(ActivityRecord r) { 2525 if (mFocusedActivity == r) { 2526 mFocusedActivity = null; 2527 } 2528 } 2529 2530 @Override 2531 public void setFocusedStack(int stackId) { 2532 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2533 synchronized (ActivityManagerService.this) { 2534 ActivityStack stack = mStackSupervisor.getStack(stackId); 2535 if (stack != null) { 2536 ActivityRecord r = stack.topRunningActivityLocked(null); 2537 if (r != null) { 2538 setFocusedActivityLocked(r); 2539 } 2540 } 2541 } 2542 } 2543 2544 @Override 2545 public void notifyActivityDrawn(IBinder token) { 2546 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2547 synchronized (this) { 2548 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2549 if (r != null) { 2550 r.task.stack.notifyActivityDrawnLocked(r); 2551 } 2552 } 2553 } 2554 2555 final void applyUpdateLockStateLocked(ActivityRecord r) { 2556 // Modifications to the UpdateLock state are done on our handler, outside 2557 // the activity manager's locks. The new state is determined based on the 2558 // state *now* of the relevant activity record. The object is passed to 2559 // the handler solely for logging detail, not to be consulted/modified. 2560 final boolean nextState = r != null && r.immersive; 2561 mHandler.sendMessage( 2562 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2563 } 2564 2565 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2566 Message msg = Message.obtain(); 2567 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2568 msg.obj = r.task.askedCompatMode ? null : r; 2569 mHandler.sendMessage(msg); 2570 } 2571 2572 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2573 String what, Object obj, ProcessRecord srcApp) { 2574 app.lastActivityTime = now; 2575 2576 if (app.activities.size() > 0) { 2577 // Don't want to touch dependent processes that are hosting activities. 2578 return index; 2579 } 2580 2581 int lrui = mLruProcesses.lastIndexOf(app); 2582 if (lrui < 0) { 2583 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2584 + what + " " + obj + " from " + srcApp); 2585 return index; 2586 } 2587 2588 if (lrui >= index) { 2589 // Don't want to cause this to move dependent processes *back* in the 2590 // list as if they were less frequently used. 2591 return index; 2592 } 2593 2594 if (lrui >= mLruProcessActivityStart) { 2595 // Don't want to touch dependent processes that are hosting activities. 2596 return index; 2597 } 2598 2599 mLruProcesses.remove(lrui); 2600 if (index > 0) { 2601 index--; 2602 } 2603 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2604 + " in LRU list: " + app); 2605 mLruProcesses.add(index, app); 2606 return index; 2607 } 2608 2609 final void removeLruProcessLocked(ProcessRecord app) { 2610 int lrui = mLruProcesses.lastIndexOf(app); 2611 if (lrui >= 0) { 2612 if (lrui <= mLruProcessActivityStart) { 2613 mLruProcessActivityStart--; 2614 } 2615 if (lrui <= mLruProcessServiceStart) { 2616 mLruProcessServiceStart--; 2617 } 2618 mLruProcesses.remove(lrui); 2619 } 2620 } 2621 2622 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2623 ProcessRecord client) { 2624 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2625 || app.treatLikeActivity; 2626 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2627 if (!activityChange && hasActivity) { 2628 // The process has activities, so we are only allowing activity-based adjustments 2629 // to move it. It should be kept in the front of the list with other 2630 // processes that have activities, and we don't want those to change their 2631 // order except due to activity operations. 2632 return; 2633 } 2634 2635 mLruSeq++; 2636 final long now = SystemClock.uptimeMillis(); 2637 app.lastActivityTime = now; 2638 2639 // First a quick reject: if the app is already at the position we will 2640 // put it, then there is nothing to do. 2641 if (hasActivity) { 2642 final int N = mLruProcesses.size(); 2643 if (N > 0 && mLruProcesses.get(N-1) == app) { 2644 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2645 return; 2646 } 2647 } else { 2648 if (mLruProcessServiceStart > 0 2649 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2650 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2651 return; 2652 } 2653 } 2654 2655 int lrui = mLruProcesses.lastIndexOf(app); 2656 2657 if (app.persistent && lrui >= 0) { 2658 // We don't care about the position of persistent processes, as long as 2659 // they are in the list. 2660 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2661 return; 2662 } 2663 2664 /* In progress: compute new position first, so we can avoid doing work 2665 if the process is not actually going to move. Not yet working. 2666 int addIndex; 2667 int nextIndex; 2668 boolean inActivity = false, inService = false; 2669 if (hasActivity) { 2670 // Process has activities, put it at the very tipsy-top. 2671 addIndex = mLruProcesses.size(); 2672 nextIndex = mLruProcessServiceStart; 2673 inActivity = true; 2674 } else if (hasService) { 2675 // Process has services, put it at the top of the service list. 2676 addIndex = mLruProcessActivityStart; 2677 nextIndex = mLruProcessServiceStart; 2678 inActivity = true; 2679 inService = true; 2680 } else { 2681 // Process not otherwise of interest, it goes to the top of the non-service area. 2682 addIndex = mLruProcessServiceStart; 2683 if (client != null) { 2684 int clientIndex = mLruProcesses.lastIndexOf(client); 2685 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2686 + app); 2687 if (clientIndex >= 0 && addIndex > clientIndex) { 2688 addIndex = clientIndex; 2689 } 2690 } 2691 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2692 } 2693 2694 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2695 + mLruProcessActivityStart + "): " + app); 2696 */ 2697 2698 if (lrui >= 0) { 2699 if (lrui < mLruProcessActivityStart) { 2700 mLruProcessActivityStart--; 2701 } 2702 if (lrui < mLruProcessServiceStart) { 2703 mLruProcessServiceStart--; 2704 } 2705 /* 2706 if (addIndex > lrui) { 2707 addIndex--; 2708 } 2709 if (nextIndex > lrui) { 2710 nextIndex--; 2711 } 2712 */ 2713 mLruProcesses.remove(lrui); 2714 } 2715 2716 /* 2717 mLruProcesses.add(addIndex, app); 2718 if (inActivity) { 2719 mLruProcessActivityStart++; 2720 } 2721 if (inService) { 2722 mLruProcessActivityStart++; 2723 } 2724 */ 2725 2726 int nextIndex; 2727 if (hasActivity) { 2728 final int N = mLruProcesses.size(); 2729 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2730 // Process doesn't have activities, but has clients with 2731 // activities... move it up, but one below the top (the top 2732 // should always have a real activity). 2733 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2734 mLruProcesses.add(N-1, app); 2735 // To keep it from spamming the LRU list (by making a bunch of clients), 2736 // we will push down any other entries owned by the app. 2737 final int uid = app.info.uid; 2738 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2739 ProcessRecord subProc = mLruProcesses.get(i); 2740 if (subProc.info.uid == uid) { 2741 // We want to push this one down the list. If the process after 2742 // it is for the same uid, however, don't do so, because we don't 2743 // want them internally to be re-ordered. 2744 if (mLruProcesses.get(i-1).info.uid != uid) { 2745 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2746 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2747 ProcessRecord tmp = mLruProcesses.get(i); 2748 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2749 mLruProcesses.set(i-1, tmp); 2750 i--; 2751 } 2752 } else { 2753 // A gap, we can stop here. 2754 break; 2755 } 2756 } 2757 } else { 2758 // Process has activities, put it at the very tipsy-top. 2759 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2760 mLruProcesses.add(app); 2761 } 2762 nextIndex = mLruProcessServiceStart; 2763 } else if (hasService) { 2764 // Process has services, put it at the top of the service list. 2765 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2766 mLruProcesses.add(mLruProcessActivityStart, app); 2767 nextIndex = mLruProcessServiceStart; 2768 mLruProcessActivityStart++; 2769 } else { 2770 // Process not otherwise of interest, it goes to the top of the non-service area. 2771 int index = mLruProcessServiceStart; 2772 if (client != null) { 2773 // If there is a client, don't allow the process to be moved up higher 2774 // in the list than that client. 2775 int clientIndex = mLruProcesses.lastIndexOf(client); 2776 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2777 + " when updating " + app); 2778 if (clientIndex <= lrui) { 2779 // Don't allow the client index restriction to push it down farther in the 2780 // list than it already is. 2781 clientIndex = lrui; 2782 } 2783 if (clientIndex >= 0 && index > clientIndex) { 2784 index = clientIndex; 2785 } 2786 } 2787 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2788 mLruProcesses.add(index, app); 2789 nextIndex = index-1; 2790 mLruProcessActivityStart++; 2791 mLruProcessServiceStart++; 2792 } 2793 2794 // If the app is currently using a content provider or service, 2795 // bump those processes as well. 2796 for (int j=app.connections.size()-1; j>=0; j--) { 2797 ConnectionRecord cr = app.connections.valueAt(j); 2798 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2799 && cr.binding.service.app != null 2800 && cr.binding.service.app.lruSeq != mLruSeq 2801 && !cr.binding.service.app.persistent) { 2802 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2803 "service connection", cr, app); 2804 } 2805 } 2806 for (int j=app.conProviders.size()-1; j>=0; j--) { 2807 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2808 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2809 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2810 "provider reference", cpr, app); 2811 } 2812 } 2813 } 2814 2815 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2816 if (uid == Process.SYSTEM_UID) { 2817 // The system gets to run in any process. If there are multiple 2818 // processes with the same uid, just pick the first (this 2819 // should never happen). 2820 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2821 if (procs == null) return null; 2822 final int N = procs.size(); 2823 for (int i = 0; i < N; i++) { 2824 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2825 } 2826 } 2827 ProcessRecord proc = mProcessNames.get(processName, uid); 2828 if (false && proc != null && !keepIfLarge 2829 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2830 && proc.lastCachedPss >= 4000) { 2831 // Turn this condition on to cause killing to happen regularly, for testing. 2832 if (proc.baseProcessTracker != null) { 2833 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2834 } 2835 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2836 } else if (proc != null && !keepIfLarge 2837 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2838 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2839 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2840 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2841 if (proc.baseProcessTracker != null) { 2842 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2843 } 2844 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2845 } 2846 } 2847 return proc; 2848 } 2849 2850 void ensurePackageDexOpt(String packageName) { 2851 IPackageManager pm = AppGlobals.getPackageManager(); 2852 try { 2853 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2854 mDidDexOpt = true; 2855 } 2856 } catch (RemoteException e) { 2857 } 2858 } 2859 2860 boolean isNextTransitionForward() { 2861 int transit = mWindowManager.getPendingAppTransition(); 2862 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2863 || transit == AppTransition.TRANSIT_TASK_OPEN 2864 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2865 } 2866 2867 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2868 String processName, String abiOverride, int uid, Runnable crashHandler) { 2869 synchronized(this) { 2870 ApplicationInfo info = new ApplicationInfo(); 2871 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2872 // For isolated processes, the former contains the parent's uid and the latter the 2873 // actual uid of the isolated process. 2874 // In the special case introduced by this method (which is, starting an isolated 2875 // process directly from the SystemServer without an actual parent app process) the 2876 // closest thing to a parent's uid is SYSTEM_UID. 2877 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2878 // the |isolated| logic in the ProcessRecord constructor. 2879 info.uid = Process.SYSTEM_UID; 2880 info.processName = processName; 2881 info.className = entryPoint; 2882 info.packageName = "android"; 2883 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2884 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2885 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2886 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2887 crashHandler); 2888 return proc != null ? proc.pid : 0; 2889 } 2890 } 2891 2892 final ProcessRecord startProcessLocked(String processName, 2893 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2894 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2895 boolean isolated, boolean keepIfLarge) { 2896 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2897 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2898 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2899 null /* crashHandler */); 2900 } 2901 2902 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2903 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2904 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2905 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2906 long startTime = SystemClock.elapsedRealtime(); 2907 ProcessRecord app; 2908 if (!isolated) { 2909 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2910 checkTime(startTime, "startProcess: after getProcessRecord"); 2911 } else { 2912 // If this is an isolated process, it can't re-use an existing process. 2913 app = null; 2914 } 2915 // We don't have to do anything more if: 2916 // (1) There is an existing application record; and 2917 // (2) The caller doesn't think it is dead, OR there is no thread 2918 // object attached to it so we know it couldn't have crashed; and 2919 // (3) There is a pid assigned to it, so it is either starting or 2920 // already running. 2921 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2922 + " app=" + app + " knownToBeDead=" + knownToBeDead 2923 + " thread=" + (app != null ? app.thread : null) 2924 + " pid=" + (app != null ? app.pid : -1)); 2925 if (app != null && app.pid > 0) { 2926 if (!knownToBeDead || app.thread == null) { 2927 // We already have the app running, or are waiting for it to 2928 // come up (we have a pid but not yet its thread), so keep it. 2929 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2930 // If this is a new package in the process, add the package to the list 2931 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2932 checkTime(startTime, "startProcess: done, added package to proc"); 2933 return app; 2934 } 2935 2936 // An application record is attached to a previous process, 2937 // clean it up now. 2938 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2939 checkTime(startTime, "startProcess: bad proc running, killing"); 2940 Process.killProcessGroup(app.info.uid, app.pid); 2941 handleAppDiedLocked(app, true, true); 2942 checkTime(startTime, "startProcess: done killing old proc"); 2943 } 2944 2945 String hostingNameStr = hostingName != null 2946 ? hostingName.flattenToShortString() : null; 2947 2948 if (!isolated) { 2949 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2950 // If we are in the background, then check to see if this process 2951 // is bad. If so, we will just silently fail. 2952 if (mBadProcesses.get(info.processName, info.uid) != null) { 2953 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2954 + "/" + info.processName); 2955 return null; 2956 } 2957 } else { 2958 // When the user is explicitly starting a process, then clear its 2959 // crash count so that we won't make it bad until they see at 2960 // least one crash dialog again, and make the process good again 2961 // if it had been bad. 2962 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2963 + "/" + info.processName); 2964 mProcessCrashTimes.remove(info.processName, info.uid); 2965 if (mBadProcesses.get(info.processName, info.uid) != null) { 2966 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2967 UserHandle.getUserId(info.uid), info.uid, 2968 info.processName); 2969 mBadProcesses.remove(info.processName, info.uid); 2970 if (app != null) { 2971 app.bad = false; 2972 } 2973 } 2974 } 2975 } 2976 2977 if (app == null) { 2978 checkTime(startTime, "startProcess: creating new process record"); 2979 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2980 app.crashHandler = crashHandler; 2981 if (app == null) { 2982 Slog.w(TAG, "Failed making new process record for " 2983 + processName + "/" + info.uid + " isolated=" + isolated); 2984 return null; 2985 } 2986 mProcessNames.put(processName, app.uid, app); 2987 if (isolated) { 2988 mIsolatedProcesses.put(app.uid, app); 2989 } 2990 checkTime(startTime, "startProcess: done creating new process record"); 2991 } else { 2992 // If this is a new package in the process, add the package to the list 2993 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2994 checkTime(startTime, "startProcess: added package to existing proc"); 2995 } 2996 2997 // If the system is not ready yet, then hold off on starting this 2998 // process until it is. 2999 if (!mProcessesReady 3000 && !isAllowedWhileBooting(info) 3001 && !allowWhileBooting) { 3002 if (!mProcessesOnHold.contains(app)) { 3003 mProcessesOnHold.add(app); 3004 } 3005 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 3006 checkTime(startTime, "startProcess: returning with proc on hold"); 3007 return app; 3008 } 3009 3010 checkTime(startTime, "startProcess: stepping in to startProcess"); 3011 startProcessLocked( 3012 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3013 checkTime(startTime, "startProcess: done starting proc!"); 3014 return (app.pid != 0) ? app : null; 3015 } 3016 3017 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3018 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3019 } 3020 3021 private final void startProcessLocked(ProcessRecord app, 3022 String hostingType, String hostingNameStr) { 3023 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3024 null /* entryPoint */, null /* entryPointArgs */); 3025 } 3026 3027 private final void startProcessLocked(ProcessRecord app, String hostingType, 3028 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3029 long startTime = SystemClock.elapsedRealtime(); 3030 if (app.pid > 0 && app.pid != MY_PID) { 3031 checkTime(startTime, "startProcess: removing from pids map"); 3032 synchronized (mPidsSelfLocked) { 3033 mPidsSelfLocked.remove(app.pid); 3034 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3035 } 3036 checkTime(startTime, "startProcess: done removing from pids map"); 3037 app.setPid(0); 3038 } 3039 3040 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3041 "startProcessLocked removing on hold: " + app); 3042 mProcessesOnHold.remove(app); 3043 3044 checkTime(startTime, "startProcess: starting to update cpu stats"); 3045 updateCpuStats(); 3046 checkTime(startTime, "startProcess: done updating cpu stats"); 3047 3048 try { 3049 int uid = app.uid; 3050 3051 int[] gids = null; 3052 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3053 if (!app.isolated) { 3054 int[] permGids = null; 3055 try { 3056 checkTime(startTime, "startProcess: getting gids from package manager"); 3057 final PackageManager pm = mContext.getPackageManager(); 3058 permGids = pm.getPackageGids(app.info.packageName); 3059 3060 if (Environment.isExternalStorageEmulated()) { 3061 checkTime(startTime, "startProcess: checking external storage perm"); 3062 if (pm.checkPermission( 3063 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3064 app.info.packageName) == PERMISSION_GRANTED) { 3065 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3066 } else { 3067 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3068 } 3069 } 3070 } catch (PackageManager.NameNotFoundException e) { 3071 Slog.w(TAG, "Unable to retrieve gids", e); 3072 } 3073 3074 /* 3075 * Add shared application and profile GIDs so applications can share some 3076 * resources like shared libraries and access user-wide resources 3077 */ 3078 if (permGids == null) { 3079 gids = new int[2]; 3080 } else { 3081 gids = new int[permGids.length + 2]; 3082 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3083 } 3084 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3085 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3086 } 3087 checkTime(startTime, "startProcess: building args"); 3088 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3089 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3090 && mTopComponent != null 3091 && app.processName.equals(mTopComponent.getPackageName())) { 3092 uid = 0; 3093 } 3094 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3095 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3096 uid = 0; 3097 } 3098 } 3099 int debugFlags = 0; 3100 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3101 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3102 // Also turn on CheckJNI for debuggable apps. It's quite 3103 // awkward to turn on otherwise. 3104 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3105 } 3106 // Run the app in safe mode if its manifest requests so or the 3107 // system is booted in safe mode. 3108 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3109 mSafeMode == true) { 3110 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3111 } 3112 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3113 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3114 } 3115 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3116 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3117 } 3118 if ("1".equals(SystemProperties.get("debug.assert"))) { 3119 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3120 } 3121 3122 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3123 if (requiredAbi == null) { 3124 requiredAbi = Build.SUPPORTED_ABIS[0]; 3125 } 3126 3127 // Start the process. It will either succeed and return a result containing 3128 // the PID of the new process, or else throw a RuntimeException. 3129 boolean isActivityProcess = (entryPoint == null); 3130 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3131 checkTime(startTime, "startProcess: asking zygote to start proc"); 3132 Process.ProcessStartResult startResult = Process.start(entryPoint, 3133 app.processName, uid, uid, gids, debugFlags, mountExternal, 3134 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3135 checkTime(startTime, "startProcess: returned from zygote!"); 3136 3137 if (app.isolated) { 3138 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3139 } 3140 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3141 checkTime(startTime, "startProcess: done updating battery stats"); 3142 3143 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3144 UserHandle.getUserId(uid), startResult.pid, uid, 3145 app.processName, hostingType, 3146 hostingNameStr != null ? hostingNameStr : ""); 3147 3148 if (app.persistent) { 3149 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3150 } 3151 3152 checkTime(startTime, "startProcess: building log message"); 3153 StringBuilder buf = mStringBuilder; 3154 buf.setLength(0); 3155 buf.append("Start proc "); 3156 buf.append(app.processName); 3157 if (!isActivityProcess) { 3158 buf.append(" ["); 3159 buf.append(entryPoint); 3160 buf.append("]"); 3161 } 3162 buf.append(" for "); 3163 buf.append(hostingType); 3164 if (hostingNameStr != null) { 3165 buf.append(" "); 3166 buf.append(hostingNameStr); 3167 } 3168 buf.append(": pid="); 3169 buf.append(startResult.pid); 3170 buf.append(" uid="); 3171 buf.append(uid); 3172 buf.append(" gids={"); 3173 if (gids != null) { 3174 for (int gi=0; gi<gids.length; gi++) { 3175 if (gi != 0) buf.append(", "); 3176 buf.append(gids[gi]); 3177 3178 } 3179 } 3180 buf.append("}"); 3181 if (requiredAbi != null) { 3182 buf.append(" abi="); 3183 buf.append(requiredAbi); 3184 } 3185 Slog.i(TAG, buf.toString()); 3186 app.setPid(startResult.pid); 3187 app.usingWrapper = startResult.usingWrapper; 3188 app.removed = false; 3189 app.killedByAm = false; 3190 checkTime(startTime, "startProcess: starting to update pids map"); 3191 synchronized (mPidsSelfLocked) { 3192 this.mPidsSelfLocked.put(startResult.pid, app); 3193 if (isActivityProcess) { 3194 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3195 msg.obj = app; 3196 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3197 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3198 } 3199 } 3200 checkTime(startTime, "startProcess: done updating pids map"); 3201 } catch (RuntimeException e) { 3202 // XXX do better error recovery. 3203 app.setPid(0); 3204 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3205 if (app.isolated) { 3206 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3207 } 3208 Slog.e(TAG, "Failure starting process " + app.processName, e); 3209 } 3210 } 3211 3212 void updateUsageStats(ActivityRecord component, boolean resumed) { 3213 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3214 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3215 if (resumed) { 3216 if (mUsageStatsService != null) { 3217 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3218 System.currentTimeMillis(), 3219 UsageEvents.Event.MOVE_TO_FOREGROUND); 3220 } 3221 synchronized (stats) { 3222 stats.noteActivityResumedLocked(component.app.uid); 3223 } 3224 } else { 3225 if (mUsageStatsService != null) { 3226 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3227 System.currentTimeMillis(), 3228 UsageEvents.Event.MOVE_TO_BACKGROUND); 3229 } 3230 synchronized (stats) { 3231 stats.noteActivityPausedLocked(component.app.uid); 3232 } 3233 } 3234 } 3235 3236 Intent getHomeIntent() { 3237 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3238 intent.setComponent(mTopComponent); 3239 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3240 intent.addCategory(Intent.CATEGORY_HOME); 3241 } 3242 return intent; 3243 } 3244 3245 boolean startHomeActivityLocked(int userId) { 3246 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3247 && mTopAction == null) { 3248 // We are running in factory test mode, but unable to find 3249 // the factory test app, so just sit around displaying the 3250 // error message and don't try to start anything. 3251 return false; 3252 } 3253 Intent intent = getHomeIntent(); 3254 ActivityInfo aInfo = 3255 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3256 if (aInfo != null) { 3257 intent.setComponent(new ComponentName( 3258 aInfo.applicationInfo.packageName, aInfo.name)); 3259 // Don't do this if the home app is currently being 3260 // instrumented. 3261 aInfo = new ActivityInfo(aInfo); 3262 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3263 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3264 aInfo.applicationInfo.uid, true); 3265 if (app == null || app.instrumentationClass == null) { 3266 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3267 mStackSupervisor.startHomeActivity(intent, aInfo); 3268 } 3269 } 3270 3271 return true; 3272 } 3273 3274 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3275 ActivityInfo ai = null; 3276 ComponentName comp = intent.getComponent(); 3277 try { 3278 if (comp != null) { 3279 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3280 } else { 3281 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3282 intent, 3283 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3284 flags, userId); 3285 3286 if (info != null) { 3287 ai = info.activityInfo; 3288 } 3289 } 3290 } catch (RemoteException e) { 3291 // ignore 3292 } 3293 3294 return ai; 3295 } 3296 3297 /** 3298 * Starts the "new version setup screen" if appropriate. 3299 */ 3300 void startSetupActivityLocked() { 3301 // Only do this once per boot. 3302 if (mCheckedForSetup) { 3303 return; 3304 } 3305 3306 // We will show this screen if the current one is a different 3307 // version than the last one shown, and we are not running in 3308 // low-level factory test mode. 3309 final ContentResolver resolver = mContext.getContentResolver(); 3310 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3311 Settings.Global.getInt(resolver, 3312 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3313 mCheckedForSetup = true; 3314 3315 // See if we should be showing the platform update setup UI. 3316 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3317 List<ResolveInfo> ris = mContext.getPackageManager() 3318 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3319 3320 // We don't allow third party apps to replace this. 3321 ResolveInfo ri = null; 3322 for (int i=0; ris != null && i<ris.size(); i++) { 3323 if ((ris.get(i).activityInfo.applicationInfo.flags 3324 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3325 ri = ris.get(i); 3326 break; 3327 } 3328 } 3329 3330 if (ri != null) { 3331 String vers = ri.activityInfo.metaData != null 3332 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3333 : null; 3334 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3335 vers = ri.activityInfo.applicationInfo.metaData.getString( 3336 Intent.METADATA_SETUP_VERSION); 3337 } 3338 String lastVers = Settings.Secure.getString( 3339 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3340 if (vers != null && !vers.equals(lastVers)) { 3341 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3342 intent.setComponent(new ComponentName( 3343 ri.activityInfo.packageName, ri.activityInfo.name)); 3344 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3345 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3346 null); 3347 } 3348 } 3349 } 3350 } 3351 3352 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3353 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3354 } 3355 3356 void enforceNotIsolatedCaller(String caller) { 3357 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3358 throw new SecurityException("Isolated process not allowed to call " + caller); 3359 } 3360 } 3361 3362 @Override 3363 public int getFrontActivityScreenCompatMode() { 3364 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3365 synchronized (this) { 3366 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3367 } 3368 } 3369 3370 @Override 3371 public void setFrontActivityScreenCompatMode(int mode) { 3372 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3373 "setFrontActivityScreenCompatMode"); 3374 synchronized (this) { 3375 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3376 } 3377 } 3378 3379 @Override 3380 public int getPackageScreenCompatMode(String packageName) { 3381 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3382 synchronized (this) { 3383 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3384 } 3385 } 3386 3387 @Override 3388 public void setPackageScreenCompatMode(String packageName, int mode) { 3389 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3390 "setPackageScreenCompatMode"); 3391 synchronized (this) { 3392 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3393 } 3394 } 3395 3396 @Override 3397 public boolean getPackageAskScreenCompat(String packageName) { 3398 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3399 synchronized (this) { 3400 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3401 } 3402 } 3403 3404 @Override 3405 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3406 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3407 "setPackageAskScreenCompat"); 3408 synchronized (this) { 3409 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3410 } 3411 } 3412 3413 private void dispatchProcessesChanged() { 3414 int N; 3415 synchronized (this) { 3416 N = mPendingProcessChanges.size(); 3417 if (mActiveProcessChanges.length < N) { 3418 mActiveProcessChanges = new ProcessChangeItem[N]; 3419 } 3420 mPendingProcessChanges.toArray(mActiveProcessChanges); 3421 mAvailProcessChanges.addAll(mPendingProcessChanges); 3422 mPendingProcessChanges.clear(); 3423 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3424 } 3425 3426 int i = mProcessObservers.beginBroadcast(); 3427 while (i > 0) { 3428 i--; 3429 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3430 if (observer != null) { 3431 try { 3432 for (int j=0; j<N; j++) { 3433 ProcessChangeItem item = mActiveProcessChanges[j]; 3434 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3435 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3436 + item.pid + " uid=" + item.uid + ": " 3437 + item.foregroundActivities); 3438 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3439 item.foregroundActivities); 3440 } 3441 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3442 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3443 + item.pid + " uid=" + item.uid + ": " + item.processState); 3444 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3445 } 3446 } 3447 } catch (RemoteException e) { 3448 } 3449 } 3450 } 3451 mProcessObservers.finishBroadcast(); 3452 } 3453 3454 private void dispatchProcessDied(int pid, int uid) { 3455 int i = mProcessObservers.beginBroadcast(); 3456 while (i > 0) { 3457 i--; 3458 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3459 if (observer != null) { 3460 try { 3461 observer.onProcessDied(pid, uid); 3462 } catch (RemoteException e) { 3463 } 3464 } 3465 } 3466 mProcessObservers.finishBroadcast(); 3467 } 3468 3469 @Override 3470 public final int startActivity(IApplicationThread caller, String callingPackage, 3471 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3472 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3473 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3474 resultWho, requestCode, startFlags, profilerInfo, options, 3475 UserHandle.getCallingUserId()); 3476 } 3477 3478 @Override 3479 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3480 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3481 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3482 enforceNotIsolatedCaller("startActivity"); 3483 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3484 false, ALLOW_FULL_ONLY, "startActivity", null); 3485 // TODO: Switch to user app stacks here. 3486 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3487 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3488 profilerInfo, null, null, options, userId, null, null); 3489 } 3490 3491 @Override 3492 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3493 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3494 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3495 3496 // This is very dangerous -- it allows you to perform a start activity (including 3497 // permission grants) as any app that may launch one of your own activities. So 3498 // we will only allow this to be done from activities that are part of the core framework, 3499 // and then only when they are running as the system. 3500 final ActivityRecord sourceRecord; 3501 final int targetUid; 3502 final String targetPackage; 3503 synchronized (this) { 3504 if (resultTo == null) { 3505 throw new SecurityException("Must be called from an activity"); 3506 } 3507 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3508 if (sourceRecord == null) { 3509 throw new SecurityException("Called with bad activity token: " + resultTo); 3510 } 3511 if (!sourceRecord.info.packageName.equals("android")) { 3512 throw new SecurityException( 3513 "Must be called from an activity that is declared in the android package"); 3514 } 3515 if (sourceRecord.app == null) { 3516 throw new SecurityException("Called without a process attached to activity"); 3517 } 3518 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3519 // This is still okay, as long as this activity is running under the 3520 // uid of the original calling activity. 3521 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3522 throw new SecurityException( 3523 "Calling activity in uid " + sourceRecord.app.uid 3524 + " must be system uid or original calling uid " 3525 + sourceRecord.launchedFromUid); 3526 } 3527 } 3528 targetUid = sourceRecord.launchedFromUid; 3529 targetPackage = sourceRecord.launchedFromPackage; 3530 } 3531 3532 // TODO: Switch to user app stacks here. 3533 try { 3534 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3535 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3536 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3537 return ret; 3538 } catch (SecurityException e) { 3539 // XXX need to figure out how to propagate to original app. 3540 // A SecurityException here is generally actually a fault of the original 3541 // calling activity (such as a fairly granting permissions), so propagate it 3542 // back to them. 3543 /* 3544 StringBuilder msg = new StringBuilder(); 3545 msg.append("While launching"); 3546 msg.append(intent.toString()); 3547 msg.append(": "); 3548 msg.append(e.getMessage()); 3549 */ 3550 throw e; 3551 } 3552 } 3553 3554 @Override 3555 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3556 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3557 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3558 enforceNotIsolatedCaller("startActivityAndWait"); 3559 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3560 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3561 WaitResult res = new WaitResult(); 3562 // TODO: Switch to user app stacks here. 3563 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3564 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3565 options, userId, null, null); 3566 return res; 3567 } 3568 3569 @Override 3570 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3571 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3572 int startFlags, Configuration config, Bundle options, int userId) { 3573 enforceNotIsolatedCaller("startActivityWithConfig"); 3574 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3575 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3576 // TODO: Switch to user app stacks here. 3577 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3578 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3579 null, null, config, options, userId, null, null); 3580 return ret; 3581 } 3582 3583 @Override 3584 public int startActivityIntentSender(IApplicationThread caller, 3585 IntentSender intent, Intent fillInIntent, String resolvedType, 3586 IBinder resultTo, String resultWho, int requestCode, 3587 int flagsMask, int flagsValues, Bundle options) { 3588 enforceNotIsolatedCaller("startActivityIntentSender"); 3589 // Refuse possible leaked file descriptors 3590 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3591 throw new IllegalArgumentException("File descriptors passed in Intent"); 3592 } 3593 3594 IIntentSender sender = intent.getTarget(); 3595 if (!(sender instanceof PendingIntentRecord)) { 3596 throw new IllegalArgumentException("Bad PendingIntent object"); 3597 } 3598 3599 PendingIntentRecord pir = (PendingIntentRecord)sender; 3600 3601 synchronized (this) { 3602 // If this is coming from the currently resumed activity, it is 3603 // effectively saying that app switches are allowed at this point. 3604 final ActivityStack stack = getFocusedStack(); 3605 if (stack.mResumedActivity != null && 3606 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3607 mAppSwitchesAllowedTime = 0; 3608 } 3609 } 3610 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3611 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3612 return ret; 3613 } 3614 3615 @Override 3616 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3617 Intent intent, String resolvedType, IVoiceInteractionSession session, 3618 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3619 Bundle options, int userId) { 3620 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3621 != PackageManager.PERMISSION_GRANTED) { 3622 String msg = "Permission Denial: startVoiceActivity() from pid=" 3623 + Binder.getCallingPid() 3624 + ", uid=" + Binder.getCallingUid() 3625 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3626 Slog.w(TAG, msg); 3627 throw new SecurityException(msg); 3628 } 3629 if (session == null || interactor == null) { 3630 throw new NullPointerException("null session or interactor"); 3631 } 3632 userId = handleIncomingUser(callingPid, callingUid, userId, 3633 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3634 // TODO: Switch to user app stacks here. 3635 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3636 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3637 null, options, userId, null, null); 3638 } 3639 3640 @Override 3641 public boolean startNextMatchingActivity(IBinder callingActivity, 3642 Intent intent, Bundle options) { 3643 // Refuse possible leaked file descriptors 3644 if (intent != null && intent.hasFileDescriptors() == true) { 3645 throw new IllegalArgumentException("File descriptors passed in Intent"); 3646 } 3647 3648 synchronized (this) { 3649 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3650 if (r == null) { 3651 ActivityOptions.abort(options); 3652 return false; 3653 } 3654 if (r.app == null || r.app.thread == null) { 3655 // The caller is not running... d'oh! 3656 ActivityOptions.abort(options); 3657 return false; 3658 } 3659 intent = new Intent(intent); 3660 // The caller is not allowed to change the data. 3661 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3662 // And we are resetting to find the next component... 3663 intent.setComponent(null); 3664 3665 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3666 3667 ActivityInfo aInfo = null; 3668 try { 3669 List<ResolveInfo> resolves = 3670 AppGlobals.getPackageManager().queryIntentActivities( 3671 intent, r.resolvedType, 3672 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3673 UserHandle.getCallingUserId()); 3674 3675 // Look for the original activity in the list... 3676 final int N = resolves != null ? resolves.size() : 0; 3677 for (int i=0; i<N; i++) { 3678 ResolveInfo rInfo = resolves.get(i); 3679 if (rInfo.activityInfo.packageName.equals(r.packageName) 3680 && rInfo.activityInfo.name.equals(r.info.name)) { 3681 // We found the current one... the next matching is 3682 // after it. 3683 i++; 3684 if (i<N) { 3685 aInfo = resolves.get(i).activityInfo; 3686 } 3687 if (debug) { 3688 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3689 + "/" + r.info.name); 3690 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3691 + "/" + aInfo.name); 3692 } 3693 break; 3694 } 3695 } 3696 } catch (RemoteException e) { 3697 } 3698 3699 if (aInfo == null) { 3700 // Nobody who is next! 3701 ActivityOptions.abort(options); 3702 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3703 return false; 3704 } 3705 3706 intent.setComponent(new ComponentName( 3707 aInfo.applicationInfo.packageName, aInfo.name)); 3708 intent.setFlags(intent.getFlags()&~( 3709 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3710 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3711 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3712 Intent.FLAG_ACTIVITY_NEW_TASK)); 3713 3714 // Okay now we need to start the new activity, replacing the 3715 // currently running activity. This is a little tricky because 3716 // we want to start the new one as if the current one is finished, 3717 // but not finish the current one first so that there is no flicker. 3718 // And thus... 3719 final boolean wasFinishing = r.finishing; 3720 r.finishing = true; 3721 3722 // Propagate reply information over to the new activity. 3723 final ActivityRecord resultTo = r.resultTo; 3724 final String resultWho = r.resultWho; 3725 final int requestCode = r.requestCode; 3726 r.resultTo = null; 3727 if (resultTo != null) { 3728 resultTo.removeResultsLocked(r, resultWho, requestCode); 3729 } 3730 3731 final long origId = Binder.clearCallingIdentity(); 3732 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3733 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3734 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3735 options, false, null, null, null); 3736 Binder.restoreCallingIdentity(origId); 3737 3738 r.finishing = wasFinishing; 3739 if (res != ActivityManager.START_SUCCESS) { 3740 return false; 3741 } 3742 return true; 3743 } 3744 } 3745 3746 @Override 3747 public final int startActivityFromRecents(int taskId, Bundle options) { 3748 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3749 String msg = "Permission Denial: startActivityFromRecents called without " + 3750 START_TASKS_FROM_RECENTS; 3751 Slog.w(TAG, msg); 3752 throw new SecurityException(msg); 3753 } 3754 return startActivityFromRecentsInner(taskId, options); 3755 } 3756 3757 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3758 final TaskRecord task; 3759 final int callingUid; 3760 final String callingPackage; 3761 final Intent intent; 3762 final int userId; 3763 synchronized (this) { 3764 task = recentTaskForIdLocked(taskId); 3765 if (task == null) { 3766 throw new IllegalArgumentException("Task " + taskId + " not found."); 3767 } 3768 callingUid = task.mCallingUid; 3769 callingPackage = task.mCallingPackage; 3770 intent = task.intent; 3771 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3772 userId = task.userId; 3773 } 3774 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3775 options, userId, null, task); 3776 } 3777 3778 final int startActivityInPackage(int uid, String callingPackage, 3779 Intent intent, String resolvedType, IBinder resultTo, 3780 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3781 IActivityContainer container, TaskRecord inTask) { 3782 3783 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3784 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3785 3786 // TODO: Switch to user app stacks here. 3787 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3788 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3789 null, null, null, options, userId, container, inTask); 3790 return ret; 3791 } 3792 3793 @Override 3794 public final int startActivities(IApplicationThread caller, String callingPackage, 3795 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3796 int userId) { 3797 enforceNotIsolatedCaller("startActivities"); 3798 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3799 false, ALLOW_FULL_ONLY, "startActivity", null); 3800 // TODO: Switch to user app stacks here. 3801 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3802 resolvedTypes, resultTo, options, userId); 3803 return ret; 3804 } 3805 3806 final int startActivitiesInPackage(int uid, String callingPackage, 3807 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3808 Bundle options, int userId) { 3809 3810 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3811 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3812 // TODO: Switch to user app stacks here. 3813 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3814 resultTo, options, userId); 3815 return ret; 3816 } 3817 3818 //explicitly remove thd old information in mRecentTasks when removing existing user. 3819 private void removeRecentTasksForUserLocked(int userId) { 3820 if(userId <= 0) { 3821 Slog.i(TAG, "Can't remove recent task on user " + userId); 3822 return; 3823 } 3824 3825 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3826 TaskRecord tr = mRecentTasks.get(i); 3827 if (tr.userId == userId) { 3828 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3829 + " when finishing user" + userId); 3830 mRecentTasks.remove(i); 3831 tr.removedFromRecents(mTaskPersister); 3832 } 3833 } 3834 3835 // Remove tasks from persistent storage. 3836 mTaskPersister.wakeup(null, true); 3837 } 3838 3839 /** 3840 * Update the recent tasks lists: make sure tasks should still be here (their 3841 * applications / activities still exist), update their availability, fixup ordering 3842 * of affiliations. 3843 */ 3844 void cleanupRecentTasksLocked(int userId) { 3845 if (mRecentTasks == null) { 3846 // Happens when called from the packagemanager broadcast before boot. 3847 return; 3848 } 3849 3850 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3851 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3852 final IPackageManager pm = AppGlobals.getPackageManager(); 3853 final ActivityInfo dummyAct = new ActivityInfo(); 3854 final ApplicationInfo dummyApp = new ApplicationInfo(); 3855 3856 int N = mRecentTasks.size(); 3857 3858 int[] users = userId == UserHandle.USER_ALL 3859 ? getUsersLocked() : new int[] { userId }; 3860 for (int user : users) { 3861 for (int i = 0; i < N; i++) { 3862 TaskRecord task = mRecentTasks.get(i); 3863 if (task.userId != user) { 3864 // Only look at tasks for the user ID of interest. 3865 continue; 3866 } 3867 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3868 // This situation is broken, and we should just get rid of it now. 3869 mRecentTasks.remove(i); 3870 task.removedFromRecents(mTaskPersister); 3871 i--; 3872 N--; 3873 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3874 continue; 3875 } 3876 // Check whether this activity is currently available. 3877 if (task.realActivity != null) { 3878 ActivityInfo ai = availActCache.get(task.realActivity); 3879 if (ai == null) { 3880 try { 3881 ai = pm.getActivityInfo(task.realActivity, 3882 PackageManager.GET_UNINSTALLED_PACKAGES 3883 | PackageManager.GET_DISABLED_COMPONENTS, user); 3884 } catch (RemoteException e) { 3885 // Will never happen. 3886 continue; 3887 } 3888 if (ai == null) { 3889 ai = dummyAct; 3890 } 3891 availActCache.put(task.realActivity, ai); 3892 } 3893 if (ai == dummyAct) { 3894 // This could be either because the activity no longer exists, or the 3895 // app is temporarily gone. For the former we want to remove the recents 3896 // entry; for the latter we want to mark it as unavailable. 3897 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3898 if (app == null) { 3899 try { 3900 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3901 PackageManager.GET_UNINSTALLED_PACKAGES 3902 | PackageManager.GET_DISABLED_COMPONENTS, user); 3903 } catch (RemoteException e) { 3904 // Will never happen. 3905 continue; 3906 } 3907 if (app == null) { 3908 app = dummyApp; 3909 } 3910 availAppCache.put(task.realActivity.getPackageName(), app); 3911 } 3912 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3913 // Doesn't exist any more! Good-bye. 3914 mRecentTasks.remove(i); 3915 task.removedFromRecents(mTaskPersister); 3916 i--; 3917 N--; 3918 Slog.w(TAG, "Removing no longer valid recent: " + task); 3919 continue; 3920 } else { 3921 // Otherwise just not available for now. 3922 if (task.isAvailable) { 3923 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3924 + task); 3925 } 3926 task.isAvailable = false; 3927 } 3928 } else { 3929 if (!ai.enabled || !ai.applicationInfo.enabled 3930 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3931 if (task.isAvailable) { 3932 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3933 + task + " (enabled=" + ai.enabled + "/" 3934 + ai.applicationInfo.enabled + " flags=" 3935 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3936 } 3937 task.isAvailable = false; 3938 } else { 3939 if (!task.isAvailable) { 3940 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3941 + task); 3942 } 3943 task.isAvailable = true; 3944 } 3945 } 3946 } 3947 } 3948 } 3949 3950 // Verify the affiliate chain for each task. 3951 for (int i = 0; i < N; ) { 3952 TaskRecord task = mRecentTasks.remove(i); 3953 if (mTmpRecents.contains(task)) { 3954 continue; 3955 } 3956 int affiliatedTaskId = task.mAffiliatedTaskId; 3957 while (true) { 3958 TaskRecord next = task.mNextAffiliate; 3959 if (next == null) { 3960 break; 3961 } 3962 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3963 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3964 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3965 task.setNextAffiliate(null); 3966 if (next.mPrevAffiliate == task) { 3967 next.setPrevAffiliate(null); 3968 } 3969 break; 3970 } 3971 if (next.mPrevAffiliate != task) { 3972 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3973 next.mPrevAffiliate + " task=" + task); 3974 next.setPrevAffiliate(null); 3975 task.setNextAffiliate(null); 3976 break; 3977 } 3978 if (!mRecentTasks.contains(next)) { 3979 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3980 task.setNextAffiliate(null); 3981 // We know that next.mPrevAffiliate is always task, from above, so clear 3982 // its previous affiliate. 3983 next.setPrevAffiliate(null); 3984 break; 3985 } 3986 task = next; 3987 } 3988 // task is now the end of the list 3989 do { 3990 mRecentTasks.remove(task); 3991 mRecentTasks.add(i++, task); 3992 mTmpRecents.add(task); 3993 task.inRecents = true; 3994 } while ((task = task.mPrevAffiliate) != null); 3995 } 3996 mTmpRecents.clear(); 3997 // mRecentTasks is now in sorted, affiliated order. 3998 } 3999 4000 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 4001 int N = mRecentTasks.size(); 4002 TaskRecord top = task; 4003 int topIndex = taskIndex; 4004 while (top.mNextAffiliate != null && topIndex > 0) { 4005 top = top.mNextAffiliate; 4006 topIndex--; 4007 } 4008 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 4009 + topIndex + " from intial " + taskIndex); 4010 // Find the end of the chain, doing a sanity check along the way. 4011 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 4012 int endIndex = topIndex; 4013 TaskRecord prev = top; 4014 while (endIndex < N) { 4015 TaskRecord cur = mRecentTasks.get(endIndex); 4016 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 4017 + endIndex + " " + cur); 4018 if (cur == top) { 4019 // Verify start of the chain. 4020 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 4021 Slog.wtf(TAG, "Bad chain @" + endIndex 4022 + ": first task has next affiliate: " + prev); 4023 sane = false; 4024 break; 4025 } 4026 } else { 4027 // Verify middle of the chain's next points back to the one before. 4028 if (cur.mNextAffiliate != prev 4029 || cur.mNextAffiliateTaskId != prev.taskId) { 4030 Slog.wtf(TAG, "Bad chain @" + endIndex 4031 + ": middle task " + cur + " @" + endIndex 4032 + " has bad next affiliate " 4033 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4034 + ", expected " + prev); 4035 sane = false; 4036 break; 4037 } 4038 } 4039 if (cur.mPrevAffiliateTaskId == -1) { 4040 // Chain ends here. 4041 if (cur.mPrevAffiliate != null) { 4042 Slog.wtf(TAG, "Bad chain @" + endIndex 4043 + ": last task " + cur + " has previous affiliate " 4044 + cur.mPrevAffiliate); 4045 sane = false; 4046 } 4047 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4048 break; 4049 } else { 4050 // Verify middle of the chain's prev points to a valid item. 4051 if (cur.mPrevAffiliate == null) { 4052 Slog.wtf(TAG, "Bad chain @" + endIndex 4053 + ": task " + cur + " has previous affiliate " 4054 + cur.mPrevAffiliate + " but should be id " 4055 + cur.mPrevAffiliate); 4056 sane = false; 4057 break; 4058 } 4059 } 4060 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4061 Slog.wtf(TAG, "Bad chain @" + endIndex 4062 + ": task " + cur + " has affiliated id " 4063 + cur.mAffiliatedTaskId + " but should be " 4064 + task.mAffiliatedTaskId); 4065 sane = false; 4066 break; 4067 } 4068 prev = cur; 4069 endIndex++; 4070 if (endIndex >= N) { 4071 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4072 + ": last task " + prev); 4073 sane = false; 4074 break; 4075 } 4076 } 4077 if (sane) { 4078 if (endIndex < taskIndex) { 4079 Slog.wtf(TAG, "Bad chain @" + endIndex 4080 + ": did not extend to task " + task + " @" + taskIndex); 4081 sane = false; 4082 } 4083 } 4084 if (sane) { 4085 // All looks good, we can just move all of the affiliated tasks 4086 // to the top. 4087 for (int i=topIndex; i<=endIndex; i++) { 4088 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4089 + " from " + i + " to " + (i-topIndex)); 4090 TaskRecord cur = mRecentTasks.remove(i); 4091 mRecentTasks.add(i-topIndex, cur); 4092 } 4093 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4094 + " to " + endIndex); 4095 return true; 4096 } 4097 4098 // Whoops, couldn't do it. 4099 return false; 4100 } 4101 4102 final void addRecentTaskLocked(TaskRecord task) { 4103 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4104 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4105 4106 int N = mRecentTasks.size(); 4107 // Quick case: check if the top-most recent task is the same. 4108 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4109 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4110 return; 4111 } 4112 // Another quick case: check if this is part of a set of affiliated 4113 // tasks that are at the top. 4114 if (isAffiliated && N > 0 && task.inRecents 4115 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4116 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4117 + " at top when adding " + task); 4118 return; 4119 } 4120 // Another quick case: never add voice sessions. 4121 if (task.voiceSession != null) { 4122 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4123 return; 4124 } 4125 4126 boolean needAffiliationFix = false; 4127 4128 // Slightly less quick case: the task is already in recents, so all we need 4129 // to do is move it. 4130 if (task.inRecents) { 4131 int taskIndex = mRecentTasks.indexOf(task); 4132 if (taskIndex >= 0) { 4133 if (!isAffiliated) { 4134 // Simple case: this is not an affiliated task, so we just move it to the front. 4135 mRecentTasks.remove(taskIndex); 4136 mRecentTasks.add(0, task); 4137 notifyTaskPersisterLocked(task, false); 4138 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4139 + " from " + taskIndex); 4140 return; 4141 } else { 4142 // More complicated: need to keep all affiliated tasks together. 4143 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4144 // All went well. 4145 return; 4146 } 4147 4148 // Uh oh... something bad in the affiliation chain, try to rebuild 4149 // everything and then go through our general path of adding a new task. 4150 needAffiliationFix = true; 4151 } 4152 } else { 4153 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4154 needAffiliationFix = true; 4155 } 4156 } 4157 4158 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4159 trimRecentsForTask(task, true); 4160 4161 N = mRecentTasks.size(); 4162 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4163 final TaskRecord tr = mRecentTasks.remove(N - 1); 4164 tr.removedFromRecents(mTaskPersister); 4165 N--; 4166 } 4167 task.inRecents = true; 4168 if (!isAffiliated || needAffiliationFix) { 4169 // If this is a simple non-affiliated task, or we had some failure trying to 4170 // handle it as part of an affilated task, then just place it at the top. 4171 mRecentTasks.add(0, task); 4172 } else if (isAffiliated) { 4173 // If this is a new affiliated task, then move all of the affiliated tasks 4174 // to the front and insert this new one. 4175 TaskRecord other = task.mNextAffiliate; 4176 if (other == null) { 4177 other = task.mPrevAffiliate; 4178 } 4179 if (other != null) { 4180 int otherIndex = mRecentTasks.indexOf(other); 4181 if (otherIndex >= 0) { 4182 // Insert new task at appropriate location. 4183 int taskIndex; 4184 if (other == task.mNextAffiliate) { 4185 // We found the index of our next affiliation, which is who is 4186 // before us in the list, so add after that point. 4187 taskIndex = otherIndex+1; 4188 } else { 4189 // We found the index of our previous affiliation, which is who is 4190 // after us in the list, so add at their position. 4191 taskIndex = otherIndex; 4192 } 4193 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4194 + taskIndex + ": " + task); 4195 mRecentTasks.add(taskIndex, task); 4196 4197 // Now move everything to the front. 4198 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4199 // All went well. 4200 return; 4201 } 4202 4203 // Uh oh... something bad in the affiliation chain, try to rebuild 4204 // everything and then go through our general path of adding a new task. 4205 needAffiliationFix = true; 4206 } else { 4207 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4208 + other); 4209 needAffiliationFix = true; 4210 } 4211 } else { 4212 if (DEBUG_RECENTS) Slog.d(TAG, 4213 "addRecent: adding affiliated task without next/prev:" + task); 4214 needAffiliationFix = true; 4215 } 4216 } 4217 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4218 4219 if (needAffiliationFix) { 4220 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4221 cleanupRecentTasksLocked(task.userId); 4222 } 4223 } 4224 4225 /** 4226 * If needed, remove oldest existing entries in recents that are for the same kind 4227 * of task as the given one. 4228 */ 4229 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4230 int N = mRecentTasks.size(); 4231 final Intent intent = task.intent; 4232 final boolean document = intent != null && intent.isDocument(); 4233 4234 int maxRecents = task.maxRecents - 1; 4235 for (int i=0; i<N; i++) { 4236 final TaskRecord tr = mRecentTasks.get(i); 4237 if (task != tr) { 4238 if (task.userId != tr.userId) { 4239 continue; 4240 } 4241 if (i > MAX_RECENT_BITMAPS) { 4242 tr.freeLastThumbnail(); 4243 } 4244 final Intent trIntent = tr.intent; 4245 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4246 (intent == null || !intent.filterEquals(trIntent))) { 4247 continue; 4248 } 4249 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4250 if (document && trIsDocument) { 4251 // These are the same document activity (not necessarily the same doc). 4252 if (maxRecents > 0) { 4253 --maxRecents; 4254 continue; 4255 } 4256 // Hit the maximum number of documents for this task. Fall through 4257 // and remove this document from recents. 4258 } else if (document || trIsDocument) { 4259 // Only one of these is a document. Not the droid we're looking for. 4260 continue; 4261 } 4262 } 4263 4264 if (!doTrim) { 4265 // If the caller is not actually asking for a trim, just tell them we reached 4266 // a point where the trim would happen. 4267 return i; 4268 } 4269 4270 // Either task and tr are the same or, their affinities match or their intents match 4271 // and neither of them is a document, or they are documents using the same activity 4272 // and their maxRecents has been reached. 4273 tr.disposeThumbnail(); 4274 mRecentTasks.remove(i); 4275 if (task != tr) { 4276 tr.removedFromRecents(mTaskPersister); 4277 } 4278 i--; 4279 N--; 4280 if (task.intent == null) { 4281 // If the new recent task we are adding is not fully 4282 // specified, then replace it with the existing recent task. 4283 task = tr; 4284 } 4285 notifyTaskPersisterLocked(tr, false); 4286 } 4287 4288 return -1; 4289 } 4290 4291 @Override 4292 public void reportActivityFullyDrawn(IBinder token) { 4293 synchronized (this) { 4294 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4295 if (r == null) { 4296 return; 4297 } 4298 r.reportFullyDrawnLocked(); 4299 } 4300 } 4301 4302 @Override 4303 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4304 synchronized (this) { 4305 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4306 if (r == null) { 4307 return; 4308 } 4309 final long origId = Binder.clearCallingIdentity(); 4310 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4311 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4312 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4313 if (config != null) { 4314 r.frozenBeforeDestroy = true; 4315 if (!updateConfigurationLocked(config, r, false, false)) { 4316 mStackSupervisor.resumeTopActivitiesLocked(); 4317 } 4318 } 4319 Binder.restoreCallingIdentity(origId); 4320 } 4321 } 4322 4323 @Override 4324 public int getRequestedOrientation(IBinder token) { 4325 synchronized (this) { 4326 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4327 if (r == null) { 4328 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4329 } 4330 return mWindowManager.getAppOrientation(r.appToken); 4331 } 4332 } 4333 4334 /** 4335 * This is the internal entry point for handling Activity.finish(). 4336 * 4337 * @param token The Binder token referencing the Activity we want to finish. 4338 * @param resultCode Result code, if any, from this Activity. 4339 * @param resultData Result data (Intent), if any, from this Activity. 4340 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4341 * the root Activity in the task. 4342 * 4343 * @return Returns true if the activity successfully finished, or false if it is still running. 4344 */ 4345 @Override 4346 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4347 boolean finishTask) { 4348 // Refuse possible leaked file descriptors 4349 if (resultData != null && resultData.hasFileDescriptors() == true) { 4350 throw new IllegalArgumentException("File descriptors passed in Intent"); 4351 } 4352 4353 synchronized(this) { 4354 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4355 if (r == null) { 4356 return true; 4357 } 4358 // Keep track of the root activity of the task before we finish it 4359 TaskRecord tr = r.task; 4360 ActivityRecord rootR = tr.getRootActivity(); 4361 // Do not allow task to finish in Lock Task mode. 4362 if (tr == mStackSupervisor.mLockTaskModeTask) { 4363 if (rootR == r) { 4364 mStackSupervisor.showLockTaskToast(); 4365 return false; 4366 } 4367 } 4368 if (mController != null) { 4369 // Find the first activity that is not finishing. 4370 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4371 if (next != null) { 4372 // ask watcher if this is allowed 4373 boolean resumeOK = true; 4374 try { 4375 resumeOK = mController.activityResuming(next.packageName); 4376 } catch (RemoteException e) { 4377 mController = null; 4378 Watchdog.getInstance().setActivityController(null); 4379 } 4380 4381 if (!resumeOK) { 4382 return false; 4383 } 4384 } 4385 } 4386 final long origId = Binder.clearCallingIdentity(); 4387 try { 4388 boolean res; 4389 if (finishTask && r == rootR) { 4390 // If requested, remove the task that is associated to this activity only if it 4391 // was the root activity in the task. The result code and data is ignored because 4392 // we don't support returning them across task boundaries. 4393 res = removeTaskByIdLocked(tr.taskId, 0); 4394 } else { 4395 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4396 resultData, "app-request", true); 4397 } 4398 return res; 4399 } finally { 4400 Binder.restoreCallingIdentity(origId); 4401 } 4402 } 4403 } 4404 4405 @Override 4406 public final void finishHeavyWeightApp() { 4407 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4408 != PackageManager.PERMISSION_GRANTED) { 4409 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4410 + Binder.getCallingPid() 4411 + ", uid=" + Binder.getCallingUid() 4412 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4413 Slog.w(TAG, msg); 4414 throw new SecurityException(msg); 4415 } 4416 4417 synchronized(this) { 4418 if (mHeavyWeightProcess == null) { 4419 return; 4420 } 4421 4422 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4423 mHeavyWeightProcess.activities); 4424 for (int i=0; i<activities.size(); i++) { 4425 ActivityRecord r = activities.get(i); 4426 if (!r.finishing) { 4427 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4428 null, "finish-heavy", true); 4429 } 4430 } 4431 4432 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4433 mHeavyWeightProcess.userId, 0)); 4434 mHeavyWeightProcess = null; 4435 } 4436 } 4437 4438 @Override 4439 public void crashApplication(int uid, int initialPid, String packageName, 4440 String message) { 4441 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4442 != PackageManager.PERMISSION_GRANTED) { 4443 String msg = "Permission Denial: crashApplication() from pid=" 4444 + Binder.getCallingPid() 4445 + ", uid=" + Binder.getCallingUid() 4446 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4447 Slog.w(TAG, msg); 4448 throw new SecurityException(msg); 4449 } 4450 4451 synchronized(this) { 4452 ProcessRecord proc = null; 4453 4454 // Figure out which process to kill. We don't trust that initialPid 4455 // still has any relation to current pids, so must scan through the 4456 // list. 4457 synchronized (mPidsSelfLocked) { 4458 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4459 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4460 if (p.uid != uid) { 4461 continue; 4462 } 4463 if (p.pid == initialPid) { 4464 proc = p; 4465 break; 4466 } 4467 if (p.pkgList.containsKey(packageName)) { 4468 proc = p; 4469 } 4470 } 4471 } 4472 4473 if (proc == null) { 4474 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4475 + " initialPid=" + initialPid 4476 + " packageName=" + packageName); 4477 return; 4478 } 4479 4480 if (proc.thread != null) { 4481 if (proc.pid == Process.myPid()) { 4482 Log.w(TAG, "crashApplication: trying to crash self!"); 4483 return; 4484 } 4485 long ident = Binder.clearCallingIdentity(); 4486 try { 4487 proc.thread.scheduleCrash(message); 4488 } catch (RemoteException e) { 4489 } 4490 Binder.restoreCallingIdentity(ident); 4491 } 4492 } 4493 } 4494 4495 @Override 4496 public final void finishSubActivity(IBinder token, String resultWho, 4497 int requestCode) { 4498 synchronized(this) { 4499 final long origId = Binder.clearCallingIdentity(); 4500 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4501 if (r != null) { 4502 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4503 } 4504 Binder.restoreCallingIdentity(origId); 4505 } 4506 } 4507 4508 @Override 4509 public boolean finishActivityAffinity(IBinder token) { 4510 synchronized(this) { 4511 final long origId = Binder.clearCallingIdentity(); 4512 try { 4513 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4514 4515 ActivityRecord rootR = r.task.getRootActivity(); 4516 // Do not allow task to finish in Lock Task mode. 4517 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4518 if (rootR == r) { 4519 mStackSupervisor.showLockTaskToast(); 4520 return false; 4521 } 4522 } 4523 boolean res = false; 4524 if (r != null) { 4525 res = r.task.stack.finishActivityAffinityLocked(r); 4526 } 4527 return res; 4528 } finally { 4529 Binder.restoreCallingIdentity(origId); 4530 } 4531 } 4532 } 4533 4534 @Override 4535 public void finishVoiceTask(IVoiceInteractionSession session) { 4536 synchronized(this) { 4537 final long origId = Binder.clearCallingIdentity(); 4538 try { 4539 mStackSupervisor.finishVoiceTask(session); 4540 } finally { 4541 Binder.restoreCallingIdentity(origId); 4542 } 4543 } 4544 4545 } 4546 4547 @Override 4548 public boolean releaseActivityInstance(IBinder token) { 4549 synchronized(this) { 4550 final long origId = Binder.clearCallingIdentity(); 4551 try { 4552 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4553 if (r.task == null || r.task.stack == null) { 4554 return false; 4555 } 4556 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4557 } finally { 4558 Binder.restoreCallingIdentity(origId); 4559 } 4560 } 4561 } 4562 4563 @Override 4564 public void releaseSomeActivities(IApplicationThread appInt) { 4565 synchronized(this) { 4566 final long origId = Binder.clearCallingIdentity(); 4567 try { 4568 ProcessRecord app = getRecordForAppLocked(appInt); 4569 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4570 } finally { 4571 Binder.restoreCallingIdentity(origId); 4572 } 4573 } 4574 } 4575 4576 @Override 4577 public boolean willActivityBeVisible(IBinder token) { 4578 synchronized(this) { 4579 ActivityStack stack = ActivityRecord.getStackLocked(token); 4580 if (stack != null) { 4581 return stack.willActivityBeVisibleLocked(token); 4582 } 4583 return false; 4584 } 4585 } 4586 4587 @Override 4588 public void overridePendingTransition(IBinder token, String packageName, 4589 int enterAnim, int exitAnim) { 4590 synchronized(this) { 4591 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4592 if (self == null) { 4593 return; 4594 } 4595 4596 final long origId = Binder.clearCallingIdentity(); 4597 4598 if (self.state == ActivityState.RESUMED 4599 || self.state == ActivityState.PAUSING) { 4600 mWindowManager.overridePendingAppTransition(packageName, 4601 enterAnim, exitAnim, null); 4602 } 4603 4604 Binder.restoreCallingIdentity(origId); 4605 } 4606 } 4607 4608 /** 4609 * Main function for removing an existing process from the activity manager 4610 * as a result of that process going away. Clears out all connections 4611 * to the process. 4612 */ 4613 private final void handleAppDiedLocked(ProcessRecord app, 4614 boolean restarting, boolean allowRestart) { 4615 int pid = app.pid; 4616 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4617 if (!restarting) { 4618 removeLruProcessLocked(app); 4619 if (pid > 0) { 4620 ProcessList.remove(pid); 4621 } 4622 } 4623 4624 if (mProfileProc == app) { 4625 clearProfilerLocked(); 4626 } 4627 4628 // Remove this application's activities from active lists. 4629 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4630 4631 app.activities.clear(); 4632 4633 if (app.instrumentationClass != null) { 4634 Slog.w(TAG, "Crash of app " + app.processName 4635 + " running instrumentation " + app.instrumentationClass); 4636 Bundle info = new Bundle(); 4637 info.putString("shortMsg", "Process crashed."); 4638 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4639 } 4640 4641 if (!restarting) { 4642 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4643 // If there was nothing to resume, and we are not already 4644 // restarting this process, but there is a visible activity that 4645 // is hosted by the process... then make sure all visible 4646 // activities are running, taking care of restarting this 4647 // process. 4648 if (hasVisibleActivities) { 4649 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4650 } 4651 } 4652 } 4653 } 4654 4655 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4656 IBinder threadBinder = thread.asBinder(); 4657 // Find the application record. 4658 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4659 ProcessRecord rec = mLruProcesses.get(i); 4660 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4661 return i; 4662 } 4663 } 4664 return -1; 4665 } 4666 4667 final ProcessRecord getRecordForAppLocked( 4668 IApplicationThread thread) { 4669 if (thread == null) { 4670 return null; 4671 } 4672 4673 int appIndex = getLRURecordIndexForAppLocked(thread); 4674 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4675 } 4676 4677 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4678 // If there are no longer any background processes running, 4679 // and the app that died was not running instrumentation, 4680 // then tell everyone we are now low on memory. 4681 boolean haveBg = false; 4682 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4683 ProcessRecord rec = mLruProcesses.get(i); 4684 if (rec.thread != null 4685 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4686 haveBg = true; 4687 break; 4688 } 4689 } 4690 4691 if (!haveBg) { 4692 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4693 if (doReport) { 4694 long now = SystemClock.uptimeMillis(); 4695 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4696 doReport = false; 4697 } else { 4698 mLastMemUsageReportTime = now; 4699 } 4700 } 4701 final ArrayList<ProcessMemInfo> memInfos 4702 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4703 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4704 long now = SystemClock.uptimeMillis(); 4705 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4706 ProcessRecord rec = mLruProcesses.get(i); 4707 if (rec == dyingProc || rec.thread == null) { 4708 continue; 4709 } 4710 if (doReport) { 4711 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4712 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4713 } 4714 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4715 // The low memory report is overriding any current 4716 // state for a GC request. Make sure to do 4717 // heavy/important/visible/foreground processes first. 4718 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4719 rec.lastRequestedGc = 0; 4720 } else { 4721 rec.lastRequestedGc = rec.lastLowMemory; 4722 } 4723 rec.reportLowMemory = true; 4724 rec.lastLowMemory = now; 4725 mProcessesToGc.remove(rec); 4726 addProcessToGcListLocked(rec); 4727 } 4728 } 4729 if (doReport) { 4730 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4731 mHandler.sendMessage(msg); 4732 } 4733 scheduleAppGcsLocked(); 4734 } 4735 } 4736 4737 final void appDiedLocked(ProcessRecord app) { 4738 appDiedLocked(app, app.pid, app.thread); 4739 } 4740 4741 final void appDiedLocked(ProcessRecord app, int pid, 4742 IApplicationThread thread) { 4743 4744 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4745 synchronized (stats) { 4746 stats.noteProcessDiedLocked(app.info.uid, pid); 4747 } 4748 4749 Process.killProcessGroup(app.info.uid, pid); 4750 4751 // Clean up already done if the process has been re-started. 4752 if (app.pid == pid && app.thread != null && 4753 app.thread.asBinder() == thread.asBinder()) { 4754 boolean doLowMem = app.instrumentationClass == null; 4755 boolean doOomAdj = doLowMem; 4756 if (!app.killedByAm) { 4757 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4758 + ") has died."); 4759 mAllowLowerMemLevel = true; 4760 } else { 4761 // Note that we always want to do oom adj to update our state with the 4762 // new number of procs. 4763 mAllowLowerMemLevel = false; 4764 doLowMem = false; 4765 } 4766 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4767 if (DEBUG_CLEANUP) Slog.v( 4768 TAG, "Dying app: " + app + ", pid: " + pid 4769 + ", thread: " + thread.asBinder()); 4770 handleAppDiedLocked(app, false, true); 4771 4772 if (doOomAdj) { 4773 updateOomAdjLocked(); 4774 } 4775 if (doLowMem) { 4776 doLowMemReportIfNeededLocked(app); 4777 } 4778 } else if (app.pid != pid) { 4779 // A new process has already been started. 4780 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4781 + ") has died and restarted (pid " + app.pid + ")."); 4782 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4783 } else if (DEBUG_PROCESSES) { 4784 Slog.d(TAG, "Received spurious death notification for thread " 4785 + thread.asBinder()); 4786 } 4787 } 4788 4789 /** 4790 * If a stack trace dump file is configured, dump process stack traces. 4791 * @param clearTraces causes the dump file to be erased prior to the new 4792 * traces being written, if true; when false, the new traces will be 4793 * appended to any existing file content. 4794 * @param firstPids of dalvik VM processes to dump stack traces for first 4795 * @param lastPids of dalvik VM processes to dump stack traces for last 4796 * @param nativeProcs optional list of native process names to dump stack crawls 4797 * @return file containing stack traces, or null if no dump file is configured 4798 */ 4799 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4800 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4801 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4802 if (tracesPath == null || tracesPath.length() == 0) { 4803 return null; 4804 } 4805 4806 File tracesFile = new File(tracesPath); 4807 try { 4808 File tracesDir = tracesFile.getParentFile(); 4809 if (!tracesDir.exists()) { 4810 tracesFile.mkdirs(); 4811 if (!SELinux.restorecon(tracesDir)) { 4812 return null; 4813 } 4814 } 4815 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4816 4817 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4818 tracesFile.createNewFile(); 4819 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4820 } catch (IOException e) { 4821 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4822 return null; 4823 } 4824 4825 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4826 return tracesFile; 4827 } 4828 4829 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4830 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4831 // Use a FileObserver to detect when traces finish writing. 4832 // The order of traces is considered important to maintain for legibility. 4833 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4834 @Override 4835 public synchronized void onEvent(int event, String path) { notify(); } 4836 }; 4837 4838 try { 4839 observer.startWatching(); 4840 4841 // First collect all of the stacks of the most important pids. 4842 if (firstPids != null) { 4843 try { 4844 int num = firstPids.size(); 4845 for (int i = 0; i < num; i++) { 4846 synchronized (observer) { 4847 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4848 observer.wait(200); // Wait for write-close, give up after 200msec 4849 } 4850 } 4851 } catch (InterruptedException e) { 4852 Log.wtf(TAG, e); 4853 } 4854 } 4855 4856 // Next collect the stacks of the native pids 4857 if (nativeProcs != null) { 4858 int[] pids = Process.getPidsForCommands(nativeProcs); 4859 if (pids != null) { 4860 for (int pid : pids) { 4861 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4862 } 4863 } 4864 } 4865 4866 // Lastly, measure CPU usage. 4867 if (processCpuTracker != null) { 4868 processCpuTracker.init(); 4869 System.gc(); 4870 processCpuTracker.update(); 4871 try { 4872 synchronized (processCpuTracker) { 4873 processCpuTracker.wait(500); // measure over 1/2 second. 4874 } 4875 } catch (InterruptedException e) { 4876 } 4877 processCpuTracker.update(); 4878 4879 // We'll take the stack crawls of just the top apps using CPU. 4880 final int N = processCpuTracker.countWorkingStats(); 4881 int numProcs = 0; 4882 for (int i=0; i<N && numProcs<5; i++) { 4883 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4884 if (lastPids.indexOfKey(stats.pid) >= 0) { 4885 numProcs++; 4886 try { 4887 synchronized (observer) { 4888 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4889 observer.wait(200); // Wait for write-close, give up after 200msec 4890 } 4891 } catch (InterruptedException e) { 4892 Log.wtf(TAG, e); 4893 } 4894 4895 } 4896 } 4897 } 4898 } finally { 4899 observer.stopWatching(); 4900 } 4901 } 4902 4903 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4904 if (true || IS_USER_BUILD) { 4905 return; 4906 } 4907 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4908 if (tracesPath == null || tracesPath.length() == 0) { 4909 return; 4910 } 4911 4912 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4913 StrictMode.allowThreadDiskWrites(); 4914 try { 4915 final File tracesFile = new File(tracesPath); 4916 final File tracesDir = tracesFile.getParentFile(); 4917 final File tracesTmp = new File(tracesDir, "__tmp__"); 4918 try { 4919 if (!tracesDir.exists()) { 4920 tracesFile.mkdirs(); 4921 if (!SELinux.restorecon(tracesDir.getPath())) { 4922 return; 4923 } 4924 } 4925 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4926 4927 if (tracesFile.exists()) { 4928 tracesTmp.delete(); 4929 tracesFile.renameTo(tracesTmp); 4930 } 4931 StringBuilder sb = new StringBuilder(); 4932 Time tobj = new Time(); 4933 tobj.set(System.currentTimeMillis()); 4934 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4935 sb.append(": "); 4936 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4937 sb.append(" since "); 4938 sb.append(msg); 4939 FileOutputStream fos = new FileOutputStream(tracesFile); 4940 fos.write(sb.toString().getBytes()); 4941 if (app == null) { 4942 fos.write("\n*** No application process!".getBytes()); 4943 } 4944 fos.close(); 4945 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4946 } catch (IOException e) { 4947 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4948 return; 4949 } 4950 4951 if (app != null) { 4952 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4953 firstPids.add(app.pid); 4954 dumpStackTraces(tracesPath, firstPids, null, null, null); 4955 } 4956 4957 File lastTracesFile = null; 4958 File curTracesFile = null; 4959 for (int i=9; i>=0; i--) { 4960 String name = String.format(Locale.US, "slow%02d.txt", i); 4961 curTracesFile = new File(tracesDir, name); 4962 if (curTracesFile.exists()) { 4963 if (lastTracesFile != null) { 4964 curTracesFile.renameTo(lastTracesFile); 4965 } else { 4966 curTracesFile.delete(); 4967 } 4968 } 4969 lastTracesFile = curTracesFile; 4970 } 4971 tracesFile.renameTo(curTracesFile); 4972 if (tracesTmp.exists()) { 4973 tracesTmp.renameTo(tracesFile); 4974 } 4975 } finally { 4976 StrictMode.setThreadPolicy(oldPolicy); 4977 } 4978 } 4979 4980 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4981 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4982 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4983 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4984 4985 if (mController != null) { 4986 try { 4987 // 0 == continue, -1 = kill process immediately 4988 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4989 if (res < 0 && app.pid != MY_PID) { 4990 app.kill("anr", true); 4991 } 4992 } catch (RemoteException e) { 4993 mController = null; 4994 Watchdog.getInstance().setActivityController(null); 4995 } 4996 } 4997 4998 long anrTime = SystemClock.uptimeMillis(); 4999 if (MONITOR_CPU_USAGE) { 5000 updateCpuStatsNow(); 5001 } 5002 5003 synchronized (this) { 5004 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 5005 if (mShuttingDown) { 5006 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 5007 return; 5008 } else if (app.notResponding) { 5009 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 5010 return; 5011 } else if (app.crashing) { 5012 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 5013 return; 5014 } 5015 5016 // In case we come through here for the same app before completing 5017 // this one, mark as anring now so we will bail out. 5018 app.notResponding = true; 5019 5020 // Log the ANR to the event log. 5021 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 5022 app.processName, app.info.flags, annotation); 5023 5024 // Dump thread traces as quickly as we can, starting with "interesting" processes. 5025 firstPids.add(app.pid); 5026 5027 int parentPid = app.pid; 5028 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5029 if (parentPid != app.pid) firstPids.add(parentPid); 5030 5031 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5032 5033 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5034 ProcessRecord r = mLruProcesses.get(i); 5035 if (r != null && r.thread != null) { 5036 int pid = r.pid; 5037 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5038 if (r.persistent) { 5039 firstPids.add(pid); 5040 } else { 5041 lastPids.put(pid, Boolean.TRUE); 5042 } 5043 } 5044 } 5045 } 5046 } 5047 5048 // Log the ANR to the main log. 5049 StringBuilder info = new StringBuilder(); 5050 info.setLength(0); 5051 info.append("ANR in ").append(app.processName); 5052 if (activity != null && activity.shortComponentName != null) { 5053 info.append(" (").append(activity.shortComponentName).append(")"); 5054 } 5055 info.append("\n"); 5056 info.append("PID: ").append(app.pid).append("\n"); 5057 if (annotation != null) { 5058 info.append("Reason: ").append(annotation).append("\n"); 5059 } 5060 if (parent != null && parent != activity) { 5061 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5062 } 5063 5064 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5065 5066 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5067 NATIVE_STACKS_OF_INTEREST); 5068 5069 String cpuInfo = null; 5070 if (MONITOR_CPU_USAGE) { 5071 updateCpuStatsNow(); 5072 synchronized (mProcessCpuThread) { 5073 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5074 } 5075 info.append(processCpuTracker.printCurrentLoad()); 5076 info.append(cpuInfo); 5077 } 5078 5079 info.append(processCpuTracker.printCurrentState(anrTime)); 5080 5081 Slog.e(TAG, info.toString()); 5082 if (tracesFile == null) { 5083 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5084 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5085 } 5086 5087 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5088 cpuInfo, tracesFile, null); 5089 5090 if (mController != null) { 5091 try { 5092 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5093 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5094 if (res != 0) { 5095 if (res < 0 && app.pid != MY_PID) { 5096 app.kill("anr", true); 5097 } else { 5098 synchronized (this) { 5099 mServices.scheduleServiceTimeoutLocked(app); 5100 } 5101 } 5102 return; 5103 } 5104 } catch (RemoteException e) { 5105 mController = null; 5106 Watchdog.getInstance().setActivityController(null); 5107 } 5108 } 5109 5110 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5111 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5112 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5113 5114 synchronized (this) { 5115 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5116 app.kill("bg anr", true); 5117 return; 5118 } 5119 5120 // Set the app's notResponding state, and look up the errorReportReceiver 5121 makeAppNotRespondingLocked(app, 5122 activity != null ? activity.shortComponentName : null, 5123 annotation != null ? "ANR " + annotation : "ANR", 5124 info.toString()); 5125 5126 // Bring up the infamous App Not Responding dialog 5127 Message msg = Message.obtain(); 5128 HashMap<String, Object> map = new HashMap<String, Object>(); 5129 msg.what = SHOW_NOT_RESPONDING_MSG; 5130 msg.obj = map; 5131 msg.arg1 = aboveSystem ? 1 : 0; 5132 map.put("app", app); 5133 if (activity != null) { 5134 map.put("activity", activity); 5135 } 5136 5137 mHandler.sendMessage(msg); 5138 } 5139 } 5140 5141 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5142 if (!mLaunchWarningShown) { 5143 mLaunchWarningShown = true; 5144 mHandler.post(new Runnable() { 5145 @Override 5146 public void run() { 5147 synchronized (ActivityManagerService.this) { 5148 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5149 d.show(); 5150 mHandler.postDelayed(new Runnable() { 5151 @Override 5152 public void run() { 5153 synchronized (ActivityManagerService.this) { 5154 d.dismiss(); 5155 mLaunchWarningShown = false; 5156 } 5157 } 5158 }, 4000); 5159 } 5160 } 5161 }); 5162 } 5163 } 5164 5165 @Override 5166 public boolean clearApplicationUserData(final String packageName, 5167 final IPackageDataObserver observer, int userId) { 5168 enforceNotIsolatedCaller("clearApplicationUserData"); 5169 int uid = Binder.getCallingUid(); 5170 int pid = Binder.getCallingPid(); 5171 userId = handleIncomingUser(pid, uid, 5172 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5173 long callingId = Binder.clearCallingIdentity(); 5174 try { 5175 IPackageManager pm = AppGlobals.getPackageManager(); 5176 int pkgUid = -1; 5177 synchronized(this) { 5178 try { 5179 pkgUid = pm.getPackageUid(packageName, userId); 5180 } catch (RemoteException e) { 5181 } 5182 if (pkgUid == -1) { 5183 Slog.w(TAG, "Invalid packageName: " + packageName); 5184 if (observer != null) { 5185 try { 5186 observer.onRemoveCompleted(packageName, false); 5187 } catch (RemoteException e) { 5188 Slog.i(TAG, "Observer no longer exists."); 5189 } 5190 } 5191 return false; 5192 } 5193 if (uid == pkgUid || checkComponentPermission( 5194 android.Manifest.permission.CLEAR_APP_USER_DATA, 5195 pid, uid, -1, true) 5196 == PackageManager.PERMISSION_GRANTED) { 5197 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5198 } else { 5199 throw new SecurityException("PID " + pid + " does not have permission " 5200 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5201 + " of package " + packageName); 5202 } 5203 5204 // Remove all tasks match the cleared application package and user 5205 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5206 final TaskRecord tr = mRecentTasks.get(i); 5207 final String taskPackageName = 5208 tr.getBaseIntent().getComponent().getPackageName(); 5209 if (tr.userId != userId) continue; 5210 if (!taskPackageName.equals(packageName)) continue; 5211 removeTaskByIdLocked(tr.taskId, 0); 5212 } 5213 } 5214 5215 try { 5216 // Clear application user data 5217 pm.clearApplicationUserData(packageName, observer, userId); 5218 5219 synchronized(this) { 5220 // Remove all permissions granted from/to this package 5221 removeUriPermissionsForPackageLocked(packageName, userId, true); 5222 } 5223 5224 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5225 Uri.fromParts("package", packageName, null)); 5226 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5227 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5228 null, null, 0, null, null, null, false, false, userId); 5229 } catch (RemoteException e) { 5230 } 5231 } finally { 5232 Binder.restoreCallingIdentity(callingId); 5233 } 5234 return true; 5235 } 5236 5237 @Override 5238 public void killBackgroundProcesses(final String packageName, int userId) { 5239 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5240 != PackageManager.PERMISSION_GRANTED && 5241 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5242 != PackageManager.PERMISSION_GRANTED) { 5243 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5244 + Binder.getCallingPid() 5245 + ", uid=" + Binder.getCallingUid() 5246 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5247 Slog.w(TAG, msg); 5248 throw new SecurityException(msg); 5249 } 5250 5251 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5252 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5253 long callingId = Binder.clearCallingIdentity(); 5254 try { 5255 IPackageManager pm = AppGlobals.getPackageManager(); 5256 synchronized(this) { 5257 int appId = -1; 5258 try { 5259 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5260 } catch (RemoteException e) { 5261 } 5262 if (appId == -1) { 5263 Slog.w(TAG, "Invalid packageName: " + packageName); 5264 return; 5265 } 5266 killPackageProcessesLocked(packageName, appId, userId, 5267 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5268 } 5269 } finally { 5270 Binder.restoreCallingIdentity(callingId); 5271 } 5272 } 5273 5274 @Override 5275 public void killAllBackgroundProcesses() { 5276 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5277 != PackageManager.PERMISSION_GRANTED) { 5278 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5279 + Binder.getCallingPid() 5280 + ", uid=" + Binder.getCallingUid() 5281 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5282 Slog.w(TAG, msg); 5283 throw new SecurityException(msg); 5284 } 5285 5286 long callingId = Binder.clearCallingIdentity(); 5287 try { 5288 synchronized(this) { 5289 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5290 final int NP = mProcessNames.getMap().size(); 5291 for (int ip=0; ip<NP; ip++) { 5292 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5293 final int NA = apps.size(); 5294 for (int ia=0; ia<NA; ia++) { 5295 ProcessRecord app = apps.valueAt(ia); 5296 if (app.persistent) { 5297 // we don't kill persistent processes 5298 continue; 5299 } 5300 if (app.removed) { 5301 procs.add(app); 5302 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5303 app.removed = true; 5304 procs.add(app); 5305 } 5306 } 5307 } 5308 5309 int N = procs.size(); 5310 for (int i=0; i<N; i++) { 5311 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5312 } 5313 mAllowLowerMemLevel = true; 5314 updateOomAdjLocked(); 5315 doLowMemReportIfNeededLocked(null); 5316 } 5317 } finally { 5318 Binder.restoreCallingIdentity(callingId); 5319 } 5320 } 5321 5322 @Override 5323 public void forceStopPackage(final String packageName, int userId) { 5324 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5325 != PackageManager.PERMISSION_GRANTED) { 5326 String msg = "Permission Denial: forceStopPackage() from pid=" 5327 + Binder.getCallingPid() 5328 + ", uid=" + Binder.getCallingUid() 5329 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5330 Slog.w(TAG, msg); 5331 throw new SecurityException(msg); 5332 } 5333 final int callingPid = Binder.getCallingPid(); 5334 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5335 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5336 long callingId = Binder.clearCallingIdentity(); 5337 try { 5338 IPackageManager pm = AppGlobals.getPackageManager(); 5339 synchronized(this) { 5340 int[] users = userId == UserHandle.USER_ALL 5341 ? getUsersLocked() : new int[] { userId }; 5342 for (int user : users) { 5343 int pkgUid = -1; 5344 try { 5345 pkgUid = pm.getPackageUid(packageName, user); 5346 } catch (RemoteException e) { 5347 } 5348 if (pkgUid == -1) { 5349 Slog.w(TAG, "Invalid packageName: " + packageName); 5350 continue; 5351 } 5352 try { 5353 pm.setPackageStoppedState(packageName, true, user); 5354 } catch (RemoteException e) { 5355 } catch (IllegalArgumentException e) { 5356 Slog.w(TAG, "Failed trying to unstop package " 5357 + packageName + ": " + e); 5358 } 5359 if (isUserRunningLocked(user, false)) { 5360 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5361 } 5362 } 5363 } 5364 } finally { 5365 Binder.restoreCallingIdentity(callingId); 5366 } 5367 } 5368 5369 @Override 5370 public void addPackageDependency(String packageName) { 5371 synchronized (this) { 5372 int callingPid = Binder.getCallingPid(); 5373 if (callingPid == Process.myPid()) { 5374 // Yeah, um, no. 5375 Slog.w(TAG, "Can't addPackageDependency on system process"); 5376 return; 5377 } 5378 ProcessRecord proc; 5379 synchronized (mPidsSelfLocked) { 5380 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5381 } 5382 if (proc != null) { 5383 if (proc.pkgDeps == null) { 5384 proc.pkgDeps = new ArraySet<String>(1); 5385 } 5386 proc.pkgDeps.add(packageName); 5387 } 5388 } 5389 } 5390 5391 /* 5392 * The pkg name and app id have to be specified. 5393 */ 5394 @Override 5395 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5396 if (pkg == null) { 5397 return; 5398 } 5399 // Make sure the uid is valid. 5400 if (appid < 0) { 5401 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5402 return; 5403 } 5404 int callerUid = Binder.getCallingUid(); 5405 // Only the system server can kill an application 5406 if (callerUid == Process.SYSTEM_UID) { 5407 // Post an aysnc message to kill the application 5408 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5409 msg.arg1 = appid; 5410 msg.arg2 = 0; 5411 Bundle bundle = new Bundle(); 5412 bundle.putString("pkg", pkg); 5413 bundle.putString("reason", reason); 5414 msg.obj = bundle; 5415 mHandler.sendMessage(msg); 5416 } else { 5417 throw new SecurityException(callerUid + " cannot kill pkg: " + 5418 pkg); 5419 } 5420 } 5421 5422 @Override 5423 public void closeSystemDialogs(String reason) { 5424 enforceNotIsolatedCaller("closeSystemDialogs"); 5425 5426 final int pid = Binder.getCallingPid(); 5427 final int uid = Binder.getCallingUid(); 5428 final long origId = Binder.clearCallingIdentity(); 5429 try { 5430 synchronized (this) { 5431 // Only allow this from foreground processes, so that background 5432 // applications can't abuse it to prevent system UI from being shown. 5433 if (uid >= Process.FIRST_APPLICATION_UID) { 5434 ProcessRecord proc; 5435 synchronized (mPidsSelfLocked) { 5436 proc = mPidsSelfLocked.get(pid); 5437 } 5438 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5439 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5440 + " from background process " + proc); 5441 return; 5442 } 5443 } 5444 closeSystemDialogsLocked(reason); 5445 } 5446 } finally { 5447 Binder.restoreCallingIdentity(origId); 5448 } 5449 } 5450 5451 void closeSystemDialogsLocked(String reason) { 5452 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5453 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5454 | Intent.FLAG_RECEIVER_FOREGROUND); 5455 if (reason != null) { 5456 intent.putExtra("reason", reason); 5457 } 5458 mWindowManager.closeSystemDialogs(reason); 5459 5460 mStackSupervisor.closeSystemDialogsLocked(); 5461 5462 broadcastIntentLocked(null, null, intent, null, 5463 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5464 Process.SYSTEM_UID, UserHandle.USER_ALL); 5465 } 5466 5467 @Override 5468 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5469 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5470 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5471 for (int i=pids.length-1; i>=0; i--) { 5472 ProcessRecord proc; 5473 int oomAdj; 5474 synchronized (this) { 5475 synchronized (mPidsSelfLocked) { 5476 proc = mPidsSelfLocked.get(pids[i]); 5477 oomAdj = proc != null ? proc.setAdj : 0; 5478 } 5479 } 5480 infos[i] = new Debug.MemoryInfo(); 5481 Debug.getMemoryInfo(pids[i], infos[i]); 5482 if (proc != null) { 5483 synchronized (this) { 5484 if (proc.thread != null && proc.setAdj == oomAdj) { 5485 // Record this for posterity if the process has been stable. 5486 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5487 infos[i].getTotalUss(), false, proc.pkgList); 5488 } 5489 } 5490 } 5491 } 5492 return infos; 5493 } 5494 5495 @Override 5496 public long[] getProcessPss(int[] pids) { 5497 enforceNotIsolatedCaller("getProcessPss"); 5498 long[] pss = new long[pids.length]; 5499 for (int i=pids.length-1; i>=0; i--) { 5500 ProcessRecord proc; 5501 int oomAdj; 5502 synchronized (this) { 5503 synchronized (mPidsSelfLocked) { 5504 proc = mPidsSelfLocked.get(pids[i]); 5505 oomAdj = proc != null ? proc.setAdj : 0; 5506 } 5507 } 5508 long[] tmpUss = new long[1]; 5509 pss[i] = Debug.getPss(pids[i], tmpUss); 5510 if (proc != null) { 5511 synchronized (this) { 5512 if (proc.thread != null && proc.setAdj == oomAdj) { 5513 // Record this for posterity if the process has been stable. 5514 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5515 } 5516 } 5517 } 5518 } 5519 return pss; 5520 } 5521 5522 @Override 5523 public void killApplicationProcess(String processName, int uid) { 5524 if (processName == null) { 5525 return; 5526 } 5527 5528 int callerUid = Binder.getCallingUid(); 5529 // Only the system server can kill an application 5530 if (callerUid == Process.SYSTEM_UID) { 5531 synchronized (this) { 5532 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5533 if (app != null && app.thread != null) { 5534 try { 5535 app.thread.scheduleSuicide(); 5536 } catch (RemoteException e) { 5537 // If the other end already died, then our work here is done. 5538 } 5539 } else { 5540 Slog.w(TAG, "Process/uid not found attempting kill of " 5541 + processName + " / " + uid); 5542 } 5543 } 5544 } else { 5545 throw new SecurityException(callerUid + " cannot kill app process: " + 5546 processName); 5547 } 5548 } 5549 5550 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5551 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5552 false, true, false, false, UserHandle.getUserId(uid), reason); 5553 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5554 Uri.fromParts("package", packageName, null)); 5555 if (!mProcessesReady) { 5556 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5557 | Intent.FLAG_RECEIVER_FOREGROUND); 5558 } 5559 intent.putExtra(Intent.EXTRA_UID, uid); 5560 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5561 broadcastIntentLocked(null, null, intent, 5562 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5563 false, false, 5564 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5565 } 5566 5567 private void forceStopUserLocked(int userId, String reason) { 5568 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5569 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5570 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5571 | Intent.FLAG_RECEIVER_FOREGROUND); 5572 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5573 broadcastIntentLocked(null, null, intent, 5574 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5575 false, false, 5576 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5577 } 5578 5579 private final boolean killPackageProcessesLocked(String packageName, int appId, 5580 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5581 boolean doit, boolean evenPersistent, String reason) { 5582 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5583 5584 // Remove all processes this package may have touched: all with the 5585 // same UID (except for the system or root user), and all whose name 5586 // matches the package name. 5587 final int NP = mProcessNames.getMap().size(); 5588 for (int ip=0; ip<NP; ip++) { 5589 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5590 final int NA = apps.size(); 5591 for (int ia=0; ia<NA; ia++) { 5592 ProcessRecord app = apps.valueAt(ia); 5593 if (app.persistent && !evenPersistent) { 5594 // we don't kill persistent processes 5595 continue; 5596 } 5597 if (app.removed) { 5598 if (doit) { 5599 procs.add(app); 5600 } 5601 continue; 5602 } 5603 5604 // Skip process if it doesn't meet our oom adj requirement. 5605 if (app.setAdj < minOomAdj) { 5606 continue; 5607 } 5608 5609 // If no package is specified, we call all processes under the 5610 // give user id. 5611 if (packageName == null) { 5612 if (app.userId != userId) { 5613 continue; 5614 } 5615 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5616 continue; 5617 } 5618 // Package has been specified, we want to hit all processes 5619 // that match it. We need to qualify this by the processes 5620 // that are running under the specified app and user ID. 5621 } else { 5622 final boolean isDep = app.pkgDeps != null 5623 && app.pkgDeps.contains(packageName); 5624 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5625 continue; 5626 } 5627 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5628 continue; 5629 } 5630 if (!app.pkgList.containsKey(packageName) && !isDep) { 5631 continue; 5632 } 5633 } 5634 5635 // Process has passed all conditions, kill it! 5636 if (!doit) { 5637 return true; 5638 } 5639 app.removed = true; 5640 procs.add(app); 5641 } 5642 } 5643 5644 int N = procs.size(); 5645 for (int i=0; i<N; i++) { 5646 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5647 } 5648 updateOomAdjLocked(); 5649 return N > 0; 5650 } 5651 5652 private final boolean forceStopPackageLocked(String name, int appId, 5653 boolean callerWillRestart, boolean purgeCache, boolean doit, 5654 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5655 int i; 5656 int N; 5657 5658 if (userId == UserHandle.USER_ALL && name == null) { 5659 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5660 } 5661 5662 if (appId < 0 && name != null) { 5663 try { 5664 appId = UserHandle.getAppId( 5665 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5666 } catch (RemoteException e) { 5667 } 5668 } 5669 5670 if (doit) { 5671 if (name != null) { 5672 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5673 + " user=" + userId + ": " + reason); 5674 } else { 5675 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5676 } 5677 5678 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5679 for (int ip=pmap.size()-1; ip>=0; ip--) { 5680 SparseArray<Long> ba = pmap.valueAt(ip); 5681 for (i=ba.size()-1; i>=0; i--) { 5682 boolean remove = false; 5683 final int entUid = ba.keyAt(i); 5684 if (name != null) { 5685 if (userId == UserHandle.USER_ALL) { 5686 if (UserHandle.getAppId(entUid) == appId) { 5687 remove = true; 5688 } 5689 } else { 5690 if (entUid == UserHandle.getUid(userId, appId)) { 5691 remove = true; 5692 } 5693 } 5694 } else if (UserHandle.getUserId(entUid) == userId) { 5695 remove = true; 5696 } 5697 if (remove) { 5698 ba.removeAt(i); 5699 } 5700 } 5701 if (ba.size() == 0) { 5702 pmap.removeAt(ip); 5703 } 5704 } 5705 } 5706 5707 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5708 -100, callerWillRestart, true, doit, evenPersistent, 5709 name == null ? ("stop user " + userId) : ("stop " + name)); 5710 5711 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5712 if (!doit) { 5713 return true; 5714 } 5715 didSomething = true; 5716 } 5717 5718 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5719 if (!doit) { 5720 return true; 5721 } 5722 didSomething = true; 5723 } 5724 5725 if (name == null) { 5726 // Remove all sticky broadcasts from this user. 5727 mStickyBroadcasts.remove(userId); 5728 } 5729 5730 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5731 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5732 userId, providers)) { 5733 if (!doit) { 5734 return true; 5735 } 5736 didSomething = true; 5737 } 5738 N = providers.size(); 5739 for (i=0; i<N; i++) { 5740 removeDyingProviderLocked(null, providers.get(i), true); 5741 } 5742 5743 // Remove transient permissions granted from/to this package/user 5744 removeUriPermissionsForPackageLocked(name, userId, false); 5745 5746 if (name == null || uninstalling) { 5747 // Remove pending intents. For now we only do this when force 5748 // stopping users, because we have some problems when doing this 5749 // for packages -- app widgets are not currently cleaned up for 5750 // such packages, so they can be left with bad pending intents. 5751 if (mIntentSenderRecords.size() > 0) { 5752 Iterator<WeakReference<PendingIntentRecord>> it 5753 = mIntentSenderRecords.values().iterator(); 5754 while (it.hasNext()) { 5755 WeakReference<PendingIntentRecord> wpir = it.next(); 5756 if (wpir == null) { 5757 it.remove(); 5758 continue; 5759 } 5760 PendingIntentRecord pir = wpir.get(); 5761 if (pir == null) { 5762 it.remove(); 5763 continue; 5764 } 5765 if (name == null) { 5766 // Stopping user, remove all objects for the user. 5767 if (pir.key.userId != userId) { 5768 // Not the same user, skip it. 5769 continue; 5770 } 5771 } else { 5772 if (UserHandle.getAppId(pir.uid) != appId) { 5773 // Different app id, skip it. 5774 continue; 5775 } 5776 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5777 // Different user, skip it. 5778 continue; 5779 } 5780 if (!pir.key.packageName.equals(name)) { 5781 // Different package, skip it. 5782 continue; 5783 } 5784 } 5785 if (!doit) { 5786 return true; 5787 } 5788 didSomething = true; 5789 it.remove(); 5790 pir.canceled = true; 5791 if (pir.key.activity != null) { 5792 pir.key.activity.pendingResults.remove(pir.ref); 5793 } 5794 } 5795 } 5796 } 5797 5798 if (doit) { 5799 if (purgeCache && name != null) { 5800 AttributeCache ac = AttributeCache.instance(); 5801 if (ac != null) { 5802 ac.removePackage(name); 5803 } 5804 } 5805 if (mBooted) { 5806 mStackSupervisor.resumeTopActivitiesLocked(); 5807 mStackSupervisor.scheduleIdleLocked(); 5808 } 5809 } 5810 5811 return didSomething; 5812 } 5813 5814 private final boolean removeProcessLocked(ProcessRecord app, 5815 boolean callerWillRestart, boolean allowRestart, String reason) { 5816 final String name = app.processName; 5817 final int uid = app.uid; 5818 if (DEBUG_PROCESSES) Slog.d( 5819 TAG, "Force removing proc " + app.toShortString() + " (" + name 5820 + "/" + uid + ")"); 5821 5822 mProcessNames.remove(name, uid); 5823 mIsolatedProcesses.remove(app.uid); 5824 if (mHeavyWeightProcess == app) { 5825 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5826 mHeavyWeightProcess.userId, 0)); 5827 mHeavyWeightProcess = null; 5828 } 5829 boolean needRestart = false; 5830 if (app.pid > 0 && app.pid != MY_PID) { 5831 int pid = app.pid; 5832 synchronized (mPidsSelfLocked) { 5833 mPidsSelfLocked.remove(pid); 5834 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5835 } 5836 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5837 if (app.isolated) { 5838 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5839 } 5840 app.kill(reason, true); 5841 handleAppDiedLocked(app, true, allowRestart); 5842 removeLruProcessLocked(app); 5843 5844 if (app.persistent && !app.isolated) { 5845 if (!callerWillRestart) { 5846 addAppLocked(app.info, false, null /* ABI override */); 5847 } else { 5848 needRestart = true; 5849 } 5850 } 5851 } else { 5852 mRemovedProcesses.add(app); 5853 } 5854 5855 return needRestart; 5856 } 5857 5858 private final void processStartTimedOutLocked(ProcessRecord app) { 5859 final int pid = app.pid; 5860 boolean gone = false; 5861 synchronized (mPidsSelfLocked) { 5862 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5863 if (knownApp != null && knownApp.thread == null) { 5864 mPidsSelfLocked.remove(pid); 5865 gone = true; 5866 } 5867 } 5868 5869 if (gone) { 5870 Slog.w(TAG, "Process " + app + " failed to attach"); 5871 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5872 pid, app.uid, app.processName); 5873 mProcessNames.remove(app.processName, app.uid); 5874 mIsolatedProcesses.remove(app.uid); 5875 if (mHeavyWeightProcess == app) { 5876 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5877 mHeavyWeightProcess.userId, 0)); 5878 mHeavyWeightProcess = null; 5879 } 5880 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5881 if (app.isolated) { 5882 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5883 } 5884 // Take care of any launching providers waiting for this process. 5885 checkAppInLaunchingProvidersLocked(app, true); 5886 // Take care of any services that are waiting for the process. 5887 mServices.processStartTimedOutLocked(app); 5888 app.kill("start timeout", true); 5889 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5890 Slog.w(TAG, "Unattached app died before backup, skipping"); 5891 try { 5892 IBackupManager bm = IBackupManager.Stub.asInterface( 5893 ServiceManager.getService(Context.BACKUP_SERVICE)); 5894 bm.agentDisconnected(app.info.packageName); 5895 } catch (RemoteException e) { 5896 // Can't happen; the backup manager is local 5897 } 5898 } 5899 if (isPendingBroadcastProcessLocked(pid)) { 5900 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5901 skipPendingBroadcastLocked(pid); 5902 } 5903 } else { 5904 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5905 } 5906 } 5907 5908 private final boolean attachApplicationLocked(IApplicationThread thread, 5909 int pid) { 5910 5911 // Find the application record that is being attached... either via 5912 // the pid if we are running in multiple processes, or just pull the 5913 // next app record if we are emulating process with anonymous threads. 5914 ProcessRecord app; 5915 if (pid != MY_PID && pid >= 0) { 5916 synchronized (mPidsSelfLocked) { 5917 app = mPidsSelfLocked.get(pid); 5918 } 5919 } else { 5920 app = null; 5921 } 5922 5923 if (app == null) { 5924 Slog.w(TAG, "No pending application record for pid " + pid 5925 + " (IApplicationThread " + thread + "); dropping process"); 5926 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5927 if (pid > 0 && pid != MY_PID) { 5928 Process.killProcessQuiet(pid); 5929 //TODO: Process.killProcessGroup(app.info.uid, pid); 5930 } else { 5931 try { 5932 thread.scheduleExit(); 5933 } catch (Exception e) { 5934 // Ignore exceptions. 5935 } 5936 } 5937 return false; 5938 } 5939 5940 // If this application record is still attached to a previous 5941 // process, clean it up now. 5942 if (app.thread != null) { 5943 handleAppDiedLocked(app, true, true); 5944 } 5945 5946 // Tell the process all about itself. 5947 5948 if (localLOGV) Slog.v( 5949 TAG, "Binding process pid " + pid + " to record " + app); 5950 5951 final String processName = app.processName; 5952 try { 5953 AppDeathRecipient adr = new AppDeathRecipient( 5954 app, pid, thread); 5955 thread.asBinder().linkToDeath(adr, 0); 5956 app.deathRecipient = adr; 5957 } catch (RemoteException e) { 5958 app.resetPackageList(mProcessStats); 5959 startProcessLocked(app, "link fail", processName); 5960 return false; 5961 } 5962 5963 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5964 5965 app.makeActive(thread, mProcessStats); 5966 app.curAdj = app.setAdj = -100; 5967 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5968 app.forcingToForeground = null; 5969 updateProcessForegroundLocked(app, false, false); 5970 app.hasShownUi = false; 5971 app.debugging = false; 5972 app.cached = false; 5973 5974 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5975 5976 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5977 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5978 5979 if (!normalMode) { 5980 Slog.i(TAG, "Launching preboot mode app: " + app); 5981 } 5982 5983 if (localLOGV) Slog.v( 5984 TAG, "New app record " + app 5985 + " thread=" + thread.asBinder() + " pid=" + pid); 5986 try { 5987 int testMode = IApplicationThread.DEBUG_OFF; 5988 if (mDebugApp != null && mDebugApp.equals(processName)) { 5989 testMode = mWaitForDebugger 5990 ? IApplicationThread.DEBUG_WAIT 5991 : IApplicationThread.DEBUG_ON; 5992 app.debugging = true; 5993 if (mDebugTransient) { 5994 mDebugApp = mOrigDebugApp; 5995 mWaitForDebugger = mOrigWaitForDebugger; 5996 } 5997 } 5998 String profileFile = app.instrumentationProfileFile; 5999 ParcelFileDescriptor profileFd = null; 6000 int samplingInterval = 0; 6001 boolean profileAutoStop = false; 6002 if (mProfileApp != null && mProfileApp.equals(processName)) { 6003 mProfileProc = app; 6004 profileFile = mProfileFile; 6005 profileFd = mProfileFd; 6006 samplingInterval = mSamplingInterval; 6007 profileAutoStop = mAutoStopProfiler; 6008 } 6009 boolean enableOpenGlTrace = false; 6010 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 6011 enableOpenGlTrace = true; 6012 mOpenGlTraceApp = null; 6013 } 6014 6015 // If the app is being launched for restore or full backup, set it up specially 6016 boolean isRestrictedBackupMode = false; 6017 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 6018 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 6019 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 6020 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 6021 } 6022 6023 ensurePackageDexOpt(app.instrumentationInfo != null 6024 ? app.instrumentationInfo.packageName 6025 : app.info.packageName); 6026 if (app.instrumentationClass != null) { 6027 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6028 } 6029 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6030 + processName + " with config " + mConfiguration); 6031 ApplicationInfo appInfo = app.instrumentationInfo != null 6032 ? app.instrumentationInfo : app.info; 6033 app.compat = compatibilityInfoForPackageLocked(appInfo); 6034 if (profileFd != null) { 6035 profileFd = profileFd.dup(); 6036 } 6037 ProfilerInfo profilerInfo = profileFile == null ? null 6038 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6039 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6040 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6041 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6042 isRestrictedBackupMode || !normalMode, app.persistent, 6043 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6044 mCoreSettingsObserver.getCoreSettingsLocked()); 6045 updateLruProcessLocked(app, false, null); 6046 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6047 } catch (Exception e) { 6048 // todo: Yikes! What should we do? For now we will try to 6049 // start another process, but that could easily get us in 6050 // an infinite loop of restarting processes... 6051 Slog.w(TAG, "Exception thrown during bind!", e); 6052 6053 app.resetPackageList(mProcessStats); 6054 app.unlinkDeathRecipient(); 6055 startProcessLocked(app, "bind fail", processName); 6056 return false; 6057 } 6058 6059 // Remove this record from the list of starting applications. 6060 mPersistentStartingProcesses.remove(app); 6061 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6062 "Attach application locked removing on hold: " + app); 6063 mProcessesOnHold.remove(app); 6064 6065 boolean badApp = false; 6066 boolean didSomething = false; 6067 6068 // See if the top visible activity is waiting to run in this process... 6069 if (normalMode) { 6070 try { 6071 if (mStackSupervisor.attachApplicationLocked(app)) { 6072 didSomething = true; 6073 } 6074 } catch (Exception e) { 6075 badApp = true; 6076 } 6077 } 6078 6079 // Find any services that should be running in this process... 6080 if (!badApp) { 6081 try { 6082 didSomething |= mServices.attachApplicationLocked(app, processName); 6083 } catch (Exception e) { 6084 badApp = true; 6085 } 6086 } 6087 6088 // Check if a next-broadcast receiver is in this process... 6089 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6090 try { 6091 didSomething |= sendPendingBroadcastsLocked(app); 6092 } catch (Exception e) { 6093 // If the app died trying to launch the receiver we declare it 'bad' 6094 badApp = true; 6095 } 6096 } 6097 6098 // Check whether the next backup agent is in this process... 6099 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6100 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6101 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6102 try { 6103 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6104 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6105 mBackupTarget.backupMode); 6106 } catch (Exception e) { 6107 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6108 e.printStackTrace(); 6109 } 6110 } 6111 6112 if (badApp) { 6113 // todo: Also need to kill application to deal with all 6114 // kinds of exceptions. 6115 handleAppDiedLocked(app, false, true); 6116 return false; 6117 } 6118 6119 if (!didSomething) { 6120 updateOomAdjLocked(); 6121 } 6122 6123 return true; 6124 } 6125 6126 @Override 6127 public final void attachApplication(IApplicationThread thread) { 6128 synchronized (this) { 6129 int callingPid = Binder.getCallingPid(); 6130 final long origId = Binder.clearCallingIdentity(); 6131 attachApplicationLocked(thread, callingPid); 6132 Binder.restoreCallingIdentity(origId); 6133 } 6134 } 6135 6136 @Override 6137 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6138 final long origId = Binder.clearCallingIdentity(); 6139 synchronized (this) { 6140 ActivityStack stack = ActivityRecord.getStackLocked(token); 6141 if (stack != null) { 6142 ActivityRecord r = 6143 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6144 if (stopProfiling) { 6145 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6146 try { 6147 mProfileFd.close(); 6148 } catch (IOException e) { 6149 } 6150 clearProfilerLocked(); 6151 } 6152 } 6153 } 6154 } 6155 Binder.restoreCallingIdentity(origId); 6156 } 6157 6158 void postEnableScreenAfterBootLocked() { 6159 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6160 } 6161 6162 void enableScreenAfterBoot() { 6163 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6164 SystemClock.uptimeMillis()); 6165 mWindowManager.enableScreenAfterBoot(); 6166 6167 synchronized (this) { 6168 updateEventDispatchingLocked(); 6169 } 6170 } 6171 6172 @Override 6173 public void showBootMessage(final CharSequence msg, final boolean always) { 6174 enforceNotIsolatedCaller("showBootMessage"); 6175 mWindowManager.showBootMessage(msg, always); 6176 } 6177 6178 @Override 6179 public void keyguardWaitingForActivityDrawn() { 6180 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6181 final long token = Binder.clearCallingIdentity(); 6182 try { 6183 synchronized (this) { 6184 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6185 mWindowManager.keyguardWaitingForActivityDrawn(); 6186 } 6187 } finally { 6188 Binder.restoreCallingIdentity(token); 6189 } 6190 } 6191 6192 final void finishBooting() { 6193 // Register receivers to handle package update events 6194 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6195 6196 // Let system services know. 6197 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6198 6199 synchronized (this) { 6200 // Ensure that any processes we had put on hold are now started 6201 // up. 6202 final int NP = mProcessesOnHold.size(); 6203 if (NP > 0) { 6204 ArrayList<ProcessRecord> procs = 6205 new ArrayList<ProcessRecord>(mProcessesOnHold); 6206 for (int ip=0; ip<NP; ip++) { 6207 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6208 + procs.get(ip)); 6209 startProcessLocked(procs.get(ip), "on-hold", null); 6210 } 6211 } 6212 6213 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6214 // Start looking for apps that are abusing wake locks. 6215 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6216 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6217 // Tell anyone interested that we are done booting! 6218 SystemProperties.set("sys.boot_completed", "1"); 6219 SystemProperties.set("dev.bootcomplete", "1"); 6220 for (int i=0; i<mStartedUsers.size(); i++) { 6221 UserStartedState uss = mStartedUsers.valueAt(i); 6222 if (uss.mState == UserStartedState.STATE_BOOTING) { 6223 uss.mState = UserStartedState.STATE_RUNNING; 6224 final int userId = mStartedUsers.keyAt(i); 6225 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6226 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6227 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6228 broadcastIntentLocked(null, null, intent, null, 6229 new IIntentReceiver.Stub() { 6230 @Override 6231 public void performReceive(Intent intent, int resultCode, 6232 String data, Bundle extras, boolean ordered, 6233 boolean sticky, int sendingUser) { 6234 synchronized (ActivityManagerService.this) { 6235 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6236 true, false); 6237 } 6238 } 6239 }, 6240 0, null, null, 6241 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6242 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6243 userId); 6244 } 6245 } 6246 scheduleStartProfilesLocked(); 6247 } 6248 } 6249 } 6250 6251 final void ensureBootCompleted() { 6252 boolean booting; 6253 boolean enableScreen; 6254 synchronized (this) { 6255 booting = mBooting; 6256 mBooting = false; 6257 enableScreen = !mBooted; 6258 mBooted = true; 6259 } 6260 6261 if (booting) { 6262 finishBooting(); 6263 } 6264 6265 if (enableScreen) { 6266 enableScreenAfterBoot(); 6267 } 6268 } 6269 6270 @Override 6271 public final void activityResumed(IBinder token) { 6272 final long origId = Binder.clearCallingIdentity(); 6273 synchronized(this) { 6274 ActivityStack stack = ActivityRecord.getStackLocked(token); 6275 if (stack != null) { 6276 ActivityRecord.activityResumedLocked(token); 6277 } 6278 } 6279 Binder.restoreCallingIdentity(origId); 6280 } 6281 6282 @Override 6283 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6284 final long origId = Binder.clearCallingIdentity(); 6285 synchronized(this) { 6286 ActivityStack stack = ActivityRecord.getStackLocked(token); 6287 if (stack != null) { 6288 stack.activityPausedLocked(token, false, persistentState); 6289 } 6290 } 6291 Binder.restoreCallingIdentity(origId); 6292 } 6293 6294 @Override 6295 public final void activityStopped(IBinder token, Bundle icicle, 6296 PersistableBundle persistentState, CharSequence description) { 6297 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6298 6299 // Refuse possible leaked file descriptors 6300 if (icicle != null && icicle.hasFileDescriptors()) { 6301 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6302 } 6303 6304 final long origId = Binder.clearCallingIdentity(); 6305 6306 synchronized (this) { 6307 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6308 if (r != null) { 6309 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6310 } 6311 } 6312 6313 trimApplications(); 6314 6315 Binder.restoreCallingIdentity(origId); 6316 } 6317 6318 @Override 6319 public final void activityDestroyed(IBinder token) { 6320 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6321 synchronized (this) { 6322 ActivityStack stack = ActivityRecord.getStackLocked(token); 6323 if (stack != null) { 6324 stack.activityDestroyedLocked(token); 6325 } 6326 } 6327 } 6328 6329 @Override 6330 public final void backgroundResourcesReleased(IBinder token) { 6331 final long origId = Binder.clearCallingIdentity(); 6332 try { 6333 synchronized (this) { 6334 ActivityStack stack = ActivityRecord.getStackLocked(token); 6335 if (stack != null) { 6336 stack.backgroundResourcesReleased(token); 6337 } 6338 } 6339 } finally { 6340 Binder.restoreCallingIdentity(origId); 6341 } 6342 } 6343 6344 @Override 6345 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6346 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6347 } 6348 6349 @Override 6350 public final void notifyEnterAnimationComplete(IBinder token) { 6351 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6352 } 6353 6354 @Override 6355 public String getCallingPackage(IBinder token) { 6356 synchronized (this) { 6357 ActivityRecord r = getCallingRecordLocked(token); 6358 return r != null ? r.info.packageName : null; 6359 } 6360 } 6361 6362 @Override 6363 public ComponentName getCallingActivity(IBinder token) { 6364 synchronized (this) { 6365 ActivityRecord r = getCallingRecordLocked(token); 6366 return r != null ? r.intent.getComponent() : null; 6367 } 6368 } 6369 6370 private ActivityRecord getCallingRecordLocked(IBinder token) { 6371 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6372 if (r == null) { 6373 return null; 6374 } 6375 return r.resultTo; 6376 } 6377 6378 @Override 6379 public ComponentName getActivityClassForToken(IBinder token) { 6380 synchronized(this) { 6381 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6382 if (r == null) { 6383 return null; 6384 } 6385 return r.intent.getComponent(); 6386 } 6387 } 6388 6389 @Override 6390 public String getPackageForToken(IBinder token) { 6391 synchronized(this) { 6392 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6393 if (r == null) { 6394 return null; 6395 } 6396 return r.packageName; 6397 } 6398 } 6399 6400 @Override 6401 public IIntentSender getIntentSender(int type, 6402 String packageName, IBinder token, String resultWho, 6403 int requestCode, Intent[] intents, String[] resolvedTypes, 6404 int flags, Bundle options, int userId) { 6405 enforceNotIsolatedCaller("getIntentSender"); 6406 // Refuse possible leaked file descriptors 6407 if (intents != null) { 6408 if (intents.length < 1) { 6409 throw new IllegalArgumentException("Intents array length must be >= 1"); 6410 } 6411 for (int i=0; i<intents.length; i++) { 6412 Intent intent = intents[i]; 6413 if (intent != null) { 6414 if (intent.hasFileDescriptors()) { 6415 throw new IllegalArgumentException("File descriptors passed in Intent"); 6416 } 6417 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6418 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6419 throw new IllegalArgumentException( 6420 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6421 } 6422 intents[i] = new Intent(intent); 6423 } 6424 } 6425 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6426 throw new IllegalArgumentException( 6427 "Intent array length does not match resolvedTypes length"); 6428 } 6429 } 6430 if (options != null) { 6431 if (options.hasFileDescriptors()) { 6432 throw new IllegalArgumentException("File descriptors passed in options"); 6433 } 6434 } 6435 6436 synchronized(this) { 6437 int callingUid = Binder.getCallingUid(); 6438 int origUserId = userId; 6439 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6440 type == ActivityManager.INTENT_SENDER_BROADCAST, 6441 ALLOW_NON_FULL, "getIntentSender", null); 6442 if (origUserId == UserHandle.USER_CURRENT) { 6443 // We don't want to evaluate this until the pending intent is 6444 // actually executed. However, we do want to always do the 6445 // security checking for it above. 6446 userId = UserHandle.USER_CURRENT; 6447 } 6448 try { 6449 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6450 int uid = AppGlobals.getPackageManager() 6451 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6452 if (!UserHandle.isSameApp(callingUid, uid)) { 6453 String msg = "Permission Denial: getIntentSender() from pid=" 6454 + Binder.getCallingPid() 6455 + ", uid=" + Binder.getCallingUid() 6456 + ", (need uid=" + uid + ")" 6457 + " is not allowed to send as package " + packageName; 6458 Slog.w(TAG, msg); 6459 throw new SecurityException(msg); 6460 } 6461 } 6462 6463 return getIntentSenderLocked(type, packageName, callingUid, userId, 6464 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6465 6466 } catch (RemoteException e) { 6467 throw new SecurityException(e); 6468 } 6469 } 6470 } 6471 6472 IIntentSender getIntentSenderLocked(int type, String packageName, 6473 int callingUid, int userId, IBinder token, String resultWho, 6474 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6475 Bundle options) { 6476 if (DEBUG_MU) 6477 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6478 ActivityRecord activity = null; 6479 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6480 activity = ActivityRecord.isInStackLocked(token); 6481 if (activity == null) { 6482 return null; 6483 } 6484 if (activity.finishing) { 6485 return null; 6486 } 6487 } 6488 6489 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6490 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6491 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6492 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6493 |PendingIntent.FLAG_UPDATE_CURRENT); 6494 6495 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6496 type, packageName, activity, resultWho, 6497 requestCode, intents, resolvedTypes, flags, options, userId); 6498 WeakReference<PendingIntentRecord> ref; 6499 ref = mIntentSenderRecords.get(key); 6500 PendingIntentRecord rec = ref != null ? ref.get() : null; 6501 if (rec != null) { 6502 if (!cancelCurrent) { 6503 if (updateCurrent) { 6504 if (rec.key.requestIntent != null) { 6505 rec.key.requestIntent.replaceExtras(intents != null ? 6506 intents[intents.length - 1] : null); 6507 } 6508 if (intents != null) { 6509 intents[intents.length-1] = rec.key.requestIntent; 6510 rec.key.allIntents = intents; 6511 rec.key.allResolvedTypes = resolvedTypes; 6512 } else { 6513 rec.key.allIntents = null; 6514 rec.key.allResolvedTypes = null; 6515 } 6516 } 6517 return rec; 6518 } 6519 rec.canceled = true; 6520 mIntentSenderRecords.remove(key); 6521 } 6522 if (noCreate) { 6523 return rec; 6524 } 6525 rec = new PendingIntentRecord(this, key, callingUid); 6526 mIntentSenderRecords.put(key, rec.ref); 6527 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6528 if (activity.pendingResults == null) { 6529 activity.pendingResults 6530 = new HashSet<WeakReference<PendingIntentRecord>>(); 6531 } 6532 activity.pendingResults.add(rec.ref); 6533 } 6534 return rec; 6535 } 6536 6537 @Override 6538 public void cancelIntentSender(IIntentSender sender) { 6539 if (!(sender instanceof PendingIntentRecord)) { 6540 return; 6541 } 6542 synchronized(this) { 6543 PendingIntentRecord rec = (PendingIntentRecord)sender; 6544 try { 6545 int uid = AppGlobals.getPackageManager() 6546 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6547 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6548 String msg = "Permission Denial: cancelIntentSender() from pid=" 6549 + Binder.getCallingPid() 6550 + ", uid=" + Binder.getCallingUid() 6551 + " is not allowed to cancel packges " 6552 + rec.key.packageName; 6553 Slog.w(TAG, msg); 6554 throw new SecurityException(msg); 6555 } 6556 } catch (RemoteException e) { 6557 throw new SecurityException(e); 6558 } 6559 cancelIntentSenderLocked(rec, true); 6560 } 6561 } 6562 6563 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6564 rec.canceled = true; 6565 mIntentSenderRecords.remove(rec.key); 6566 if (cleanActivity && rec.key.activity != null) { 6567 rec.key.activity.pendingResults.remove(rec.ref); 6568 } 6569 } 6570 6571 @Override 6572 public String getPackageForIntentSender(IIntentSender pendingResult) { 6573 if (!(pendingResult instanceof PendingIntentRecord)) { 6574 return null; 6575 } 6576 try { 6577 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6578 return res.key.packageName; 6579 } catch (ClassCastException e) { 6580 } 6581 return null; 6582 } 6583 6584 @Override 6585 public int getUidForIntentSender(IIntentSender sender) { 6586 if (sender instanceof PendingIntentRecord) { 6587 try { 6588 PendingIntentRecord res = (PendingIntentRecord)sender; 6589 return res.uid; 6590 } catch (ClassCastException e) { 6591 } 6592 } 6593 return -1; 6594 } 6595 6596 @Override 6597 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6598 if (!(pendingResult instanceof PendingIntentRecord)) { 6599 return false; 6600 } 6601 try { 6602 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6603 if (res.key.allIntents == null) { 6604 return false; 6605 } 6606 for (int i=0; i<res.key.allIntents.length; i++) { 6607 Intent intent = res.key.allIntents[i]; 6608 if (intent.getPackage() != null && intent.getComponent() != null) { 6609 return false; 6610 } 6611 } 6612 return true; 6613 } catch (ClassCastException e) { 6614 } 6615 return false; 6616 } 6617 6618 @Override 6619 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6620 if (!(pendingResult instanceof PendingIntentRecord)) { 6621 return false; 6622 } 6623 try { 6624 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6625 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6626 return true; 6627 } 6628 return false; 6629 } catch (ClassCastException e) { 6630 } 6631 return false; 6632 } 6633 6634 @Override 6635 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6636 if (!(pendingResult instanceof PendingIntentRecord)) { 6637 return null; 6638 } 6639 try { 6640 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6641 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6642 } catch (ClassCastException e) { 6643 } 6644 return null; 6645 } 6646 6647 @Override 6648 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6649 if (!(pendingResult instanceof PendingIntentRecord)) { 6650 return null; 6651 } 6652 try { 6653 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6654 Intent intent = res.key.requestIntent; 6655 if (intent != null) { 6656 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6657 || res.lastTagPrefix.equals(prefix))) { 6658 return res.lastTag; 6659 } 6660 res.lastTagPrefix = prefix; 6661 StringBuilder sb = new StringBuilder(128); 6662 if (prefix != null) { 6663 sb.append(prefix); 6664 } 6665 if (intent.getAction() != null) { 6666 sb.append(intent.getAction()); 6667 } else if (intent.getComponent() != null) { 6668 intent.getComponent().appendShortString(sb); 6669 } else { 6670 sb.append("?"); 6671 } 6672 return res.lastTag = sb.toString(); 6673 } 6674 } catch (ClassCastException e) { 6675 } 6676 return null; 6677 } 6678 6679 @Override 6680 public void setProcessLimit(int max) { 6681 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6682 "setProcessLimit()"); 6683 synchronized (this) { 6684 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6685 mProcessLimitOverride = max; 6686 } 6687 trimApplications(); 6688 } 6689 6690 @Override 6691 public int getProcessLimit() { 6692 synchronized (this) { 6693 return mProcessLimitOverride; 6694 } 6695 } 6696 6697 void foregroundTokenDied(ForegroundToken token) { 6698 synchronized (ActivityManagerService.this) { 6699 synchronized (mPidsSelfLocked) { 6700 ForegroundToken cur 6701 = mForegroundProcesses.get(token.pid); 6702 if (cur != token) { 6703 return; 6704 } 6705 mForegroundProcesses.remove(token.pid); 6706 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6707 if (pr == null) { 6708 return; 6709 } 6710 pr.forcingToForeground = null; 6711 updateProcessForegroundLocked(pr, false, false); 6712 } 6713 updateOomAdjLocked(); 6714 } 6715 } 6716 6717 @Override 6718 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6719 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6720 "setProcessForeground()"); 6721 synchronized(this) { 6722 boolean changed = false; 6723 6724 synchronized (mPidsSelfLocked) { 6725 ProcessRecord pr = mPidsSelfLocked.get(pid); 6726 if (pr == null && isForeground) { 6727 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6728 return; 6729 } 6730 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6731 if (oldToken != null) { 6732 oldToken.token.unlinkToDeath(oldToken, 0); 6733 mForegroundProcesses.remove(pid); 6734 if (pr != null) { 6735 pr.forcingToForeground = null; 6736 } 6737 changed = true; 6738 } 6739 if (isForeground && token != null) { 6740 ForegroundToken newToken = new ForegroundToken() { 6741 @Override 6742 public void binderDied() { 6743 foregroundTokenDied(this); 6744 } 6745 }; 6746 newToken.pid = pid; 6747 newToken.token = token; 6748 try { 6749 token.linkToDeath(newToken, 0); 6750 mForegroundProcesses.put(pid, newToken); 6751 pr.forcingToForeground = token; 6752 changed = true; 6753 } catch (RemoteException e) { 6754 // If the process died while doing this, we will later 6755 // do the cleanup with the process death link. 6756 } 6757 } 6758 } 6759 6760 if (changed) { 6761 updateOomAdjLocked(); 6762 } 6763 } 6764 } 6765 6766 // ========================================================= 6767 // PERMISSIONS 6768 // ========================================================= 6769 6770 static class PermissionController extends IPermissionController.Stub { 6771 ActivityManagerService mActivityManagerService; 6772 PermissionController(ActivityManagerService activityManagerService) { 6773 mActivityManagerService = activityManagerService; 6774 } 6775 6776 @Override 6777 public boolean checkPermission(String permission, int pid, int uid) { 6778 return mActivityManagerService.checkPermission(permission, pid, 6779 uid) == PackageManager.PERMISSION_GRANTED; 6780 } 6781 } 6782 6783 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6784 @Override 6785 public int checkComponentPermission(String permission, int pid, int uid, 6786 int owningUid, boolean exported) { 6787 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6788 owningUid, exported); 6789 } 6790 6791 @Override 6792 public Object getAMSLock() { 6793 return ActivityManagerService.this; 6794 } 6795 } 6796 6797 /** 6798 * This can be called with or without the global lock held. 6799 */ 6800 int checkComponentPermission(String permission, int pid, int uid, 6801 int owningUid, boolean exported) { 6802 // We might be performing an operation on behalf of an indirect binder 6803 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6804 // client identity accordingly before proceeding. 6805 Identity tlsIdentity = sCallerIdentity.get(); 6806 if (tlsIdentity != null) { 6807 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6808 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6809 uid = tlsIdentity.uid; 6810 pid = tlsIdentity.pid; 6811 } 6812 6813 if (pid == MY_PID) { 6814 return PackageManager.PERMISSION_GRANTED; 6815 } 6816 6817 return ActivityManager.checkComponentPermission(permission, uid, 6818 owningUid, exported); 6819 } 6820 6821 /** 6822 * As the only public entry point for permissions checking, this method 6823 * can enforce the semantic that requesting a check on a null global 6824 * permission is automatically denied. (Internally a null permission 6825 * string is used when calling {@link #checkComponentPermission} in cases 6826 * when only uid-based security is needed.) 6827 * 6828 * This can be called with or without the global lock held. 6829 */ 6830 @Override 6831 public int checkPermission(String permission, int pid, int uid) { 6832 if (permission == null) { 6833 return PackageManager.PERMISSION_DENIED; 6834 } 6835 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6836 } 6837 6838 /** 6839 * Binder IPC calls go through the public entry point. 6840 * This can be called with or without the global lock held. 6841 */ 6842 int checkCallingPermission(String permission) { 6843 return checkPermission(permission, 6844 Binder.getCallingPid(), 6845 UserHandle.getAppId(Binder.getCallingUid())); 6846 } 6847 6848 /** 6849 * This can be called with or without the global lock held. 6850 */ 6851 void enforceCallingPermission(String permission, String func) { 6852 if (checkCallingPermission(permission) 6853 == PackageManager.PERMISSION_GRANTED) { 6854 return; 6855 } 6856 6857 String msg = "Permission Denial: " + func + " from pid=" 6858 + Binder.getCallingPid() 6859 + ", uid=" + Binder.getCallingUid() 6860 + " requires " + permission; 6861 Slog.w(TAG, msg); 6862 throw new SecurityException(msg); 6863 } 6864 6865 /** 6866 * Determine if UID is holding permissions required to access {@link Uri} in 6867 * the given {@link ProviderInfo}. Final permission checking is always done 6868 * in {@link ContentProvider}. 6869 */ 6870 private final boolean checkHoldingPermissionsLocked( 6871 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6872 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6873 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6874 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6875 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6876 != PERMISSION_GRANTED) { 6877 return false; 6878 } 6879 } 6880 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6881 } 6882 6883 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6884 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6885 if (pi.applicationInfo.uid == uid) { 6886 return true; 6887 } else if (!pi.exported) { 6888 return false; 6889 } 6890 6891 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6892 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6893 try { 6894 // check if target holds top-level <provider> permissions 6895 if (!readMet && pi.readPermission != null && considerUidPermissions 6896 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6897 readMet = true; 6898 } 6899 if (!writeMet && pi.writePermission != null && considerUidPermissions 6900 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6901 writeMet = true; 6902 } 6903 6904 // track if unprotected read/write is allowed; any denied 6905 // <path-permission> below removes this ability 6906 boolean allowDefaultRead = pi.readPermission == null; 6907 boolean allowDefaultWrite = pi.writePermission == null; 6908 6909 // check if target holds any <path-permission> that match uri 6910 final PathPermission[] pps = pi.pathPermissions; 6911 if (pps != null) { 6912 final String path = grantUri.uri.getPath(); 6913 int i = pps.length; 6914 while (i > 0 && (!readMet || !writeMet)) { 6915 i--; 6916 PathPermission pp = pps[i]; 6917 if (pp.match(path)) { 6918 if (!readMet) { 6919 final String pprperm = pp.getReadPermission(); 6920 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6921 + pprperm + " for " + pp.getPath() 6922 + ": match=" + pp.match(path) 6923 + " check=" + pm.checkUidPermission(pprperm, uid)); 6924 if (pprperm != null) { 6925 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6926 == PERMISSION_GRANTED) { 6927 readMet = true; 6928 } else { 6929 allowDefaultRead = false; 6930 } 6931 } 6932 } 6933 if (!writeMet) { 6934 final String ppwperm = pp.getWritePermission(); 6935 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6936 + ppwperm + " for " + pp.getPath() 6937 + ": match=" + pp.match(path) 6938 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6939 if (ppwperm != null) { 6940 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6941 == PERMISSION_GRANTED) { 6942 writeMet = true; 6943 } else { 6944 allowDefaultWrite = false; 6945 } 6946 } 6947 } 6948 } 6949 } 6950 } 6951 6952 // grant unprotected <provider> read/write, if not blocked by 6953 // <path-permission> above 6954 if (allowDefaultRead) readMet = true; 6955 if (allowDefaultWrite) writeMet = true; 6956 6957 } catch (RemoteException e) { 6958 return false; 6959 } 6960 6961 return readMet && writeMet; 6962 } 6963 6964 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6965 ProviderInfo pi = null; 6966 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6967 if (cpr != null) { 6968 pi = cpr.info; 6969 } else { 6970 try { 6971 pi = AppGlobals.getPackageManager().resolveContentProvider( 6972 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6973 } catch (RemoteException ex) { 6974 } 6975 } 6976 return pi; 6977 } 6978 6979 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6980 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6981 if (targetUris != null) { 6982 return targetUris.get(grantUri); 6983 } 6984 return null; 6985 } 6986 6987 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6988 String targetPkg, int targetUid, GrantUri grantUri) { 6989 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6990 if (targetUris == null) { 6991 targetUris = Maps.newArrayMap(); 6992 mGrantedUriPermissions.put(targetUid, targetUris); 6993 } 6994 6995 UriPermission perm = targetUris.get(grantUri); 6996 if (perm == null) { 6997 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6998 targetUris.put(grantUri, perm); 6999 } 7000 7001 return perm; 7002 } 7003 7004 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 7005 final int modeFlags) { 7006 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 7007 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 7008 : UriPermission.STRENGTH_OWNED; 7009 7010 // Root gets to do everything. 7011 if (uid == 0) { 7012 return true; 7013 } 7014 7015 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7016 if (perms == null) return false; 7017 7018 // First look for exact match 7019 final UriPermission exactPerm = perms.get(grantUri); 7020 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 7021 return true; 7022 } 7023 7024 // No exact match, look for prefixes 7025 final int N = perms.size(); 7026 for (int i = 0; i < N; i++) { 7027 final UriPermission perm = perms.valueAt(i); 7028 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7029 && perm.getStrength(modeFlags) >= minStrength) { 7030 return true; 7031 } 7032 } 7033 7034 return false; 7035 } 7036 7037 /** 7038 * @param uri This uri must NOT contain an embedded userId. 7039 * @param userId The userId in which the uri is to be resolved. 7040 */ 7041 @Override 7042 public int checkUriPermission(Uri uri, int pid, int uid, 7043 final int modeFlags, int userId) { 7044 enforceNotIsolatedCaller("checkUriPermission"); 7045 7046 // Another redirected-binder-call permissions check as in 7047 // {@link checkComponentPermission}. 7048 Identity tlsIdentity = sCallerIdentity.get(); 7049 if (tlsIdentity != null) { 7050 uid = tlsIdentity.uid; 7051 pid = tlsIdentity.pid; 7052 } 7053 7054 // Our own process gets to do everything. 7055 if (pid == MY_PID) { 7056 return PackageManager.PERMISSION_GRANTED; 7057 } 7058 synchronized (this) { 7059 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7060 ? PackageManager.PERMISSION_GRANTED 7061 : PackageManager.PERMISSION_DENIED; 7062 } 7063 } 7064 7065 /** 7066 * Check if the targetPkg can be granted permission to access uri by 7067 * the callingUid using the given modeFlags. Throws a security exception 7068 * if callingUid is not allowed to do this. Returns the uid of the target 7069 * if the URI permission grant should be performed; returns -1 if it is not 7070 * needed (for example targetPkg already has permission to access the URI). 7071 * If you already know the uid of the target, you can supply it in 7072 * lastTargetUid else set that to -1. 7073 */ 7074 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7075 final int modeFlags, int lastTargetUid) { 7076 if (!Intent.isAccessUriMode(modeFlags)) { 7077 return -1; 7078 } 7079 7080 if (targetPkg != null) { 7081 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7082 "Checking grant " + targetPkg + " permission to " + grantUri); 7083 } 7084 7085 final IPackageManager pm = AppGlobals.getPackageManager(); 7086 7087 // If this is not a content: uri, we can't do anything with it. 7088 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7089 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7090 "Can't grant URI permission for non-content URI: " + grantUri); 7091 return -1; 7092 } 7093 7094 final String authority = grantUri.uri.getAuthority(); 7095 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7096 if (pi == null) { 7097 Slog.w(TAG, "No content provider found for permission check: " + 7098 grantUri.uri.toSafeString()); 7099 return -1; 7100 } 7101 7102 int targetUid = lastTargetUid; 7103 if (targetUid < 0 && targetPkg != null) { 7104 try { 7105 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7106 if (targetUid < 0) { 7107 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7108 "Can't grant URI permission no uid for: " + targetPkg); 7109 return -1; 7110 } 7111 } catch (RemoteException ex) { 7112 return -1; 7113 } 7114 } 7115 7116 if (targetUid >= 0) { 7117 // First... does the target actually need this permission? 7118 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7119 // No need to grant the target this permission. 7120 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7121 "Target " + targetPkg + " already has full permission to " + grantUri); 7122 return -1; 7123 } 7124 } else { 7125 // First... there is no target package, so can anyone access it? 7126 boolean allowed = pi.exported; 7127 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7128 if (pi.readPermission != null) { 7129 allowed = false; 7130 } 7131 } 7132 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7133 if (pi.writePermission != null) { 7134 allowed = false; 7135 } 7136 } 7137 if (allowed) { 7138 return -1; 7139 } 7140 } 7141 7142 /* There is a special cross user grant if: 7143 * - The target is on another user. 7144 * - Apps on the current user can access the uri without any uid permissions. 7145 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7146 * grant uri permissions. 7147 */ 7148 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7149 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7150 modeFlags, false /*without considering the uid permissions*/); 7151 7152 // Second... is the provider allowing granting of URI permissions? 7153 if (!specialCrossUserGrant) { 7154 if (!pi.grantUriPermissions) { 7155 throw new SecurityException("Provider " + pi.packageName 7156 + "/" + pi.name 7157 + " does not allow granting of Uri permissions (uri " 7158 + grantUri + ")"); 7159 } 7160 if (pi.uriPermissionPatterns != null) { 7161 final int N = pi.uriPermissionPatterns.length; 7162 boolean allowed = false; 7163 for (int i=0; i<N; i++) { 7164 if (pi.uriPermissionPatterns[i] != null 7165 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7166 allowed = true; 7167 break; 7168 } 7169 } 7170 if (!allowed) { 7171 throw new SecurityException("Provider " + pi.packageName 7172 + "/" + pi.name 7173 + " does not allow granting of permission to path of Uri " 7174 + grantUri); 7175 } 7176 } 7177 } 7178 7179 // Third... does the caller itself have permission to access 7180 // this uri? 7181 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7182 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7183 // Require they hold a strong enough Uri permission 7184 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7185 throw new SecurityException("Uid " + callingUid 7186 + " does not have permission to uri " + grantUri); 7187 } 7188 } 7189 } 7190 return targetUid; 7191 } 7192 7193 /** 7194 * @param uri This uri must NOT contain an embedded userId. 7195 * @param userId The userId in which the uri is to be resolved. 7196 */ 7197 @Override 7198 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7199 final int modeFlags, int userId) { 7200 enforceNotIsolatedCaller("checkGrantUriPermission"); 7201 synchronized(this) { 7202 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7203 new GrantUri(userId, uri, false), modeFlags, -1); 7204 } 7205 } 7206 7207 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7208 final int modeFlags, UriPermissionOwner owner) { 7209 if (!Intent.isAccessUriMode(modeFlags)) { 7210 return; 7211 } 7212 7213 // So here we are: the caller has the assumed permission 7214 // to the uri, and the target doesn't. Let's now give this to 7215 // the target. 7216 7217 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7218 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7219 7220 final String authority = grantUri.uri.getAuthority(); 7221 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7222 if (pi == null) { 7223 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7224 return; 7225 } 7226 7227 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7228 grantUri.prefix = true; 7229 } 7230 final UriPermission perm = findOrCreateUriPermissionLocked( 7231 pi.packageName, targetPkg, targetUid, grantUri); 7232 perm.grantModes(modeFlags, owner); 7233 } 7234 7235 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7236 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7237 if (targetPkg == null) { 7238 throw new NullPointerException("targetPkg"); 7239 } 7240 int targetUid; 7241 final IPackageManager pm = AppGlobals.getPackageManager(); 7242 try { 7243 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7244 } catch (RemoteException ex) { 7245 return; 7246 } 7247 7248 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7249 targetUid); 7250 if (targetUid < 0) { 7251 return; 7252 } 7253 7254 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7255 owner); 7256 } 7257 7258 static class NeededUriGrants extends ArrayList<GrantUri> { 7259 final String targetPkg; 7260 final int targetUid; 7261 final int flags; 7262 7263 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7264 this.targetPkg = targetPkg; 7265 this.targetUid = targetUid; 7266 this.flags = flags; 7267 } 7268 } 7269 7270 /** 7271 * Like checkGrantUriPermissionLocked, but takes an Intent. 7272 */ 7273 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7274 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7275 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7276 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7277 + " clip=" + (intent != null ? intent.getClipData() : null) 7278 + " from " + intent + "; flags=0x" 7279 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7280 7281 if (targetPkg == null) { 7282 throw new NullPointerException("targetPkg"); 7283 } 7284 7285 if (intent == null) { 7286 return null; 7287 } 7288 Uri data = intent.getData(); 7289 ClipData clip = intent.getClipData(); 7290 if (data == null && clip == null) { 7291 return null; 7292 } 7293 // Default userId for uris in the intent (if they don't specify it themselves) 7294 int contentUserHint = intent.getContentUserHint(); 7295 if (contentUserHint == UserHandle.USER_CURRENT) { 7296 contentUserHint = UserHandle.getUserId(callingUid); 7297 } 7298 final IPackageManager pm = AppGlobals.getPackageManager(); 7299 int targetUid; 7300 if (needed != null) { 7301 targetUid = needed.targetUid; 7302 } else { 7303 try { 7304 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7305 } catch (RemoteException ex) { 7306 return null; 7307 } 7308 if (targetUid < 0) { 7309 if (DEBUG_URI_PERMISSION) { 7310 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7311 + " on user " + targetUserId); 7312 } 7313 return null; 7314 } 7315 } 7316 if (data != null) { 7317 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7318 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7319 targetUid); 7320 if (targetUid > 0) { 7321 if (needed == null) { 7322 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7323 } 7324 needed.add(grantUri); 7325 } 7326 } 7327 if (clip != null) { 7328 for (int i=0; i<clip.getItemCount(); i++) { 7329 Uri uri = clip.getItemAt(i).getUri(); 7330 if (uri != null) { 7331 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7332 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7333 targetUid); 7334 if (targetUid > 0) { 7335 if (needed == null) { 7336 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7337 } 7338 needed.add(grantUri); 7339 } 7340 } else { 7341 Intent clipIntent = clip.getItemAt(i).getIntent(); 7342 if (clipIntent != null) { 7343 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7344 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7345 if (newNeeded != null) { 7346 needed = newNeeded; 7347 } 7348 } 7349 } 7350 } 7351 } 7352 7353 return needed; 7354 } 7355 7356 /** 7357 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7358 */ 7359 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7360 UriPermissionOwner owner) { 7361 if (needed != null) { 7362 for (int i=0; i<needed.size(); i++) { 7363 GrantUri grantUri = needed.get(i); 7364 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7365 grantUri, needed.flags, owner); 7366 } 7367 } 7368 } 7369 7370 void grantUriPermissionFromIntentLocked(int callingUid, 7371 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7372 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7373 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7374 if (needed == null) { 7375 return; 7376 } 7377 7378 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7379 } 7380 7381 /** 7382 * @param uri This uri must NOT contain an embedded userId. 7383 * @param userId The userId in which the uri is to be resolved. 7384 */ 7385 @Override 7386 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7387 final int modeFlags, int userId) { 7388 enforceNotIsolatedCaller("grantUriPermission"); 7389 GrantUri grantUri = new GrantUri(userId, uri, false); 7390 synchronized(this) { 7391 final ProcessRecord r = getRecordForAppLocked(caller); 7392 if (r == null) { 7393 throw new SecurityException("Unable to find app for caller " 7394 + caller 7395 + " when granting permission to uri " + grantUri); 7396 } 7397 if (targetPkg == null) { 7398 throw new IllegalArgumentException("null target"); 7399 } 7400 if (grantUri == null) { 7401 throw new IllegalArgumentException("null uri"); 7402 } 7403 7404 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7405 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7406 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7407 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7408 7409 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7410 UserHandle.getUserId(r.uid)); 7411 } 7412 } 7413 7414 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7415 if (perm.modeFlags == 0) { 7416 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7417 perm.targetUid); 7418 if (perms != null) { 7419 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7420 "Removing " + perm.targetUid + " permission to " + perm.uri); 7421 7422 perms.remove(perm.uri); 7423 if (perms.isEmpty()) { 7424 mGrantedUriPermissions.remove(perm.targetUid); 7425 } 7426 } 7427 } 7428 } 7429 7430 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7431 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7432 7433 final IPackageManager pm = AppGlobals.getPackageManager(); 7434 final String authority = grantUri.uri.getAuthority(); 7435 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7436 if (pi == null) { 7437 Slog.w(TAG, "No content provider found for permission revoke: " 7438 + grantUri.toSafeString()); 7439 return; 7440 } 7441 7442 // Does the caller have this permission on the URI? 7443 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7444 // Right now, if you are not the original owner of the permission, 7445 // you are not allowed to revoke it. 7446 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7447 throw new SecurityException("Uid " + callingUid 7448 + " does not have permission to uri " + grantUri); 7449 //} 7450 } 7451 7452 boolean persistChanged = false; 7453 7454 // Go through all of the permissions and remove any that match. 7455 int N = mGrantedUriPermissions.size(); 7456 for (int i = 0; i < N; i++) { 7457 final int targetUid = mGrantedUriPermissions.keyAt(i); 7458 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7459 7460 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7461 final UriPermission perm = it.next(); 7462 if (perm.uri.sourceUserId == grantUri.sourceUserId 7463 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7464 if (DEBUG_URI_PERMISSION) 7465 Slog.v(TAG, 7466 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7467 persistChanged |= perm.revokeModes( 7468 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7469 if (perm.modeFlags == 0) { 7470 it.remove(); 7471 } 7472 } 7473 } 7474 7475 if (perms.isEmpty()) { 7476 mGrantedUriPermissions.remove(targetUid); 7477 N--; 7478 i--; 7479 } 7480 } 7481 7482 if (persistChanged) { 7483 schedulePersistUriGrants(); 7484 } 7485 } 7486 7487 /** 7488 * @param uri This uri must NOT contain an embedded userId. 7489 * @param userId The userId in which the uri is to be resolved. 7490 */ 7491 @Override 7492 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7493 int userId) { 7494 enforceNotIsolatedCaller("revokeUriPermission"); 7495 synchronized(this) { 7496 final ProcessRecord r = getRecordForAppLocked(caller); 7497 if (r == null) { 7498 throw new SecurityException("Unable to find app for caller " 7499 + caller 7500 + " when revoking permission to uri " + uri); 7501 } 7502 if (uri == null) { 7503 Slog.w(TAG, "revokeUriPermission: null uri"); 7504 return; 7505 } 7506 7507 if (!Intent.isAccessUriMode(modeFlags)) { 7508 return; 7509 } 7510 7511 final IPackageManager pm = AppGlobals.getPackageManager(); 7512 final String authority = uri.getAuthority(); 7513 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7514 if (pi == null) { 7515 Slog.w(TAG, "No content provider found for permission revoke: " 7516 + uri.toSafeString()); 7517 return; 7518 } 7519 7520 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7521 } 7522 } 7523 7524 /** 7525 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7526 * given package. 7527 * 7528 * @param packageName Package name to match, or {@code null} to apply to all 7529 * packages. 7530 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7531 * to all users. 7532 * @param persistable If persistable grants should be removed. 7533 */ 7534 private void removeUriPermissionsForPackageLocked( 7535 String packageName, int userHandle, boolean persistable) { 7536 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7537 throw new IllegalArgumentException("Must narrow by either package or user"); 7538 } 7539 7540 boolean persistChanged = false; 7541 7542 int N = mGrantedUriPermissions.size(); 7543 for (int i = 0; i < N; i++) { 7544 final int targetUid = mGrantedUriPermissions.keyAt(i); 7545 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7546 7547 // Only inspect grants matching user 7548 if (userHandle == UserHandle.USER_ALL 7549 || userHandle == UserHandle.getUserId(targetUid)) { 7550 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7551 final UriPermission perm = it.next(); 7552 7553 // Only inspect grants matching package 7554 if (packageName == null || perm.sourcePkg.equals(packageName) 7555 || perm.targetPkg.equals(packageName)) { 7556 persistChanged |= perm.revokeModes( 7557 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7558 7559 // Only remove when no modes remain; any persisted grants 7560 // will keep this alive. 7561 if (perm.modeFlags == 0) { 7562 it.remove(); 7563 } 7564 } 7565 } 7566 7567 if (perms.isEmpty()) { 7568 mGrantedUriPermissions.remove(targetUid); 7569 N--; 7570 i--; 7571 } 7572 } 7573 } 7574 7575 if (persistChanged) { 7576 schedulePersistUriGrants(); 7577 } 7578 } 7579 7580 @Override 7581 public IBinder newUriPermissionOwner(String name) { 7582 enforceNotIsolatedCaller("newUriPermissionOwner"); 7583 synchronized(this) { 7584 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7585 return owner.getExternalTokenLocked(); 7586 } 7587 } 7588 7589 /** 7590 * @param uri This uri must NOT contain an embedded userId. 7591 * @param sourceUserId The userId in which the uri is to be resolved. 7592 * @param targetUserId The userId of the app that receives the grant. 7593 */ 7594 @Override 7595 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7596 final int modeFlags, int sourceUserId, int targetUserId) { 7597 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7598 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7599 synchronized(this) { 7600 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7601 if (owner == null) { 7602 throw new IllegalArgumentException("Unknown owner: " + token); 7603 } 7604 if (fromUid != Binder.getCallingUid()) { 7605 if (Binder.getCallingUid() != Process.myUid()) { 7606 // Only system code can grant URI permissions on behalf 7607 // of other users. 7608 throw new SecurityException("nice try"); 7609 } 7610 } 7611 if (targetPkg == null) { 7612 throw new IllegalArgumentException("null target"); 7613 } 7614 if (uri == null) { 7615 throw new IllegalArgumentException("null uri"); 7616 } 7617 7618 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7619 modeFlags, owner, targetUserId); 7620 } 7621 } 7622 7623 /** 7624 * @param uri This uri must NOT contain an embedded userId. 7625 * @param userId The userId in which the uri is to be resolved. 7626 */ 7627 @Override 7628 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7629 synchronized(this) { 7630 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7631 if (owner == null) { 7632 throw new IllegalArgumentException("Unknown owner: " + token); 7633 } 7634 7635 if (uri == null) { 7636 owner.removeUriPermissionsLocked(mode); 7637 } else { 7638 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7639 } 7640 } 7641 } 7642 7643 private void schedulePersistUriGrants() { 7644 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7645 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7646 10 * DateUtils.SECOND_IN_MILLIS); 7647 } 7648 } 7649 7650 private void writeGrantedUriPermissions() { 7651 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7652 7653 // Snapshot permissions so we can persist without lock 7654 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7655 synchronized (this) { 7656 final int size = mGrantedUriPermissions.size(); 7657 for (int i = 0; i < size; i++) { 7658 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7659 for (UriPermission perm : perms.values()) { 7660 if (perm.persistedModeFlags != 0) { 7661 persist.add(perm.snapshot()); 7662 } 7663 } 7664 } 7665 } 7666 7667 FileOutputStream fos = null; 7668 try { 7669 fos = mGrantFile.startWrite(); 7670 7671 XmlSerializer out = new FastXmlSerializer(); 7672 out.setOutput(fos, "utf-8"); 7673 out.startDocument(null, true); 7674 out.startTag(null, TAG_URI_GRANTS); 7675 for (UriPermission.Snapshot perm : persist) { 7676 out.startTag(null, TAG_URI_GRANT); 7677 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7678 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7679 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7680 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7681 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7682 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7683 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7684 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7685 out.endTag(null, TAG_URI_GRANT); 7686 } 7687 out.endTag(null, TAG_URI_GRANTS); 7688 out.endDocument(); 7689 7690 mGrantFile.finishWrite(fos); 7691 } catch (IOException e) { 7692 if (fos != null) { 7693 mGrantFile.failWrite(fos); 7694 } 7695 } 7696 } 7697 7698 private void readGrantedUriPermissionsLocked() { 7699 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7700 7701 final long now = System.currentTimeMillis(); 7702 7703 FileInputStream fis = null; 7704 try { 7705 fis = mGrantFile.openRead(); 7706 final XmlPullParser in = Xml.newPullParser(); 7707 in.setInput(fis, null); 7708 7709 int type; 7710 while ((type = in.next()) != END_DOCUMENT) { 7711 final String tag = in.getName(); 7712 if (type == START_TAG) { 7713 if (TAG_URI_GRANT.equals(tag)) { 7714 final int sourceUserId; 7715 final int targetUserId; 7716 final int userHandle = readIntAttribute(in, 7717 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7718 if (userHandle != UserHandle.USER_NULL) { 7719 // For backwards compatibility. 7720 sourceUserId = userHandle; 7721 targetUserId = userHandle; 7722 } else { 7723 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7724 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7725 } 7726 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7727 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7728 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7729 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7730 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7731 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7732 7733 // Sanity check that provider still belongs to source package 7734 final ProviderInfo pi = getProviderInfoLocked( 7735 uri.getAuthority(), sourceUserId); 7736 if (pi != null && sourcePkg.equals(pi.packageName)) { 7737 int targetUid = -1; 7738 try { 7739 targetUid = AppGlobals.getPackageManager() 7740 .getPackageUid(targetPkg, targetUserId); 7741 } catch (RemoteException e) { 7742 } 7743 if (targetUid != -1) { 7744 final UriPermission perm = findOrCreateUriPermissionLocked( 7745 sourcePkg, targetPkg, targetUid, 7746 new GrantUri(sourceUserId, uri, prefix)); 7747 perm.initPersistedModes(modeFlags, createdTime); 7748 } 7749 } else { 7750 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7751 + " but instead found " + pi); 7752 } 7753 } 7754 } 7755 } 7756 } catch (FileNotFoundException e) { 7757 // Missing grants is okay 7758 } catch (IOException e) { 7759 Log.wtf(TAG, "Failed reading Uri grants", e); 7760 } catch (XmlPullParserException e) { 7761 Log.wtf(TAG, "Failed reading Uri grants", e); 7762 } finally { 7763 IoUtils.closeQuietly(fis); 7764 } 7765 } 7766 7767 /** 7768 * @param uri This uri must NOT contain an embedded userId. 7769 * @param userId The userId in which the uri is to be resolved. 7770 */ 7771 @Override 7772 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7773 enforceNotIsolatedCaller("takePersistableUriPermission"); 7774 7775 Preconditions.checkFlagsArgument(modeFlags, 7776 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7777 7778 synchronized (this) { 7779 final int callingUid = Binder.getCallingUid(); 7780 boolean persistChanged = false; 7781 GrantUri grantUri = new GrantUri(userId, uri, false); 7782 7783 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7784 new GrantUri(userId, uri, false)); 7785 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7786 new GrantUri(userId, uri, true)); 7787 7788 final boolean exactValid = (exactPerm != null) 7789 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7790 final boolean prefixValid = (prefixPerm != null) 7791 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7792 7793 if (!(exactValid || prefixValid)) { 7794 throw new SecurityException("No persistable permission grants found for UID " 7795 + callingUid + " and Uri " + grantUri.toSafeString()); 7796 } 7797 7798 if (exactValid) { 7799 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7800 } 7801 if (prefixValid) { 7802 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7803 } 7804 7805 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7806 7807 if (persistChanged) { 7808 schedulePersistUriGrants(); 7809 } 7810 } 7811 } 7812 7813 /** 7814 * @param uri This uri must NOT contain an embedded userId. 7815 * @param userId The userId in which the uri is to be resolved. 7816 */ 7817 @Override 7818 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7819 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7820 7821 Preconditions.checkFlagsArgument(modeFlags, 7822 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7823 7824 synchronized (this) { 7825 final int callingUid = Binder.getCallingUid(); 7826 boolean persistChanged = false; 7827 7828 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7829 new GrantUri(userId, uri, false)); 7830 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7831 new GrantUri(userId, uri, true)); 7832 if (exactPerm == null && prefixPerm == null) { 7833 throw new SecurityException("No permission grants found for UID " + callingUid 7834 + " and Uri " + uri.toSafeString()); 7835 } 7836 7837 if (exactPerm != null) { 7838 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7839 removeUriPermissionIfNeededLocked(exactPerm); 7840 } 7841 if (prefixPerm != null) { 7842 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7843 removeUriPermissionIfNeededLocked(prefixPerm); 7844 } 7845 7846 if (persistChanged) { 7847 schedulePersistUriGrants(); 7848 } 7849 } 7850 } 7851 7852 /** 7853 * Prune any older {@link UriPermission} for the given UID until outstanding 7854 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7855 * 7856 * @return if any mutations occured that require persisting. 7857 */ 7858 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7859 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7860 if (perms == null) return false; 7861 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7862 7863 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7864 for (UriPermission perm : perms.values()) { 7865 if (perm.persistedModeFlags != 0) { 7866 persisted.add(perm); 7867 } 7868 } 7869 7870 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7871 if (trimCount <= 0) return false; 7872 7873 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7874 for (int i = 0; i < trimCount; i++) { 7875 final UriPermission perm = persisted.get(i); 7876 7877 if (DEBUG_URI_PERMISSION) { 7878 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7879 } 7880 7881 perm.releasePersistableModes(~0); 7882 removeUriPermissionIfNeededLocked(perm); 7883 } 7884 7885 return true; 7886 } 7887 7888 @Override 7889 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7890 String packageName, boolean incoming) { 7891 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7892 Preconditions.checkNotNull(packageName, "packageName"); 7893 7894 final int callingUid = Binder.getCallingUid(); 7895 final IPackageManager pm = AppGlobals.getPackageManager(); 7896 try { 7897 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7898 if (packageUid != callingUid) { 7899 throw new SecurityException( 7900 "Package " + packageName + " does not belong to calling UID " + callingUid); 7901 } 7902 } catch (RemoteException e) { 7903 throw new SecurityException("Failed to verify package name ownership"); 7904 } 7905 7906 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7907 synchronized (this) { 7908 if (incoming) { 7909 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7910 callingUid); 7911 if (perms == null) { 7912 Slog.w(TAG, "No permission grants found for " + packageName); 7913 } else { 7914 for (UriPermission perm : perms.values()) { 7915 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7916 result.add(perm.buildPersistedPublicApiObject()); 7917 } 7918 } 7919 } 7920 } else { 7921 final int size = mGrantedUriPermissions.size(); 7922 for (int i = 0; i < size; i++) { 7923 final ArrayMap<GrantUri, UriPermission> perms = 7924 mGrantedUriPermissions.valueAt(i); 7925 for (UriPermission perm : perms.values()) { 7926 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7927 result.add(perm.buildPersistedPublicApiObject()); 7928 } 7929 } 7930 } 7931 } 7932 } 7933 return new ParceledListSlice<android.content.UriPermission>(result); 7934 } 7935 7936 @Override 7937 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7938 synchronized (this) { 7939 ProcessRecord app = 7940 who != null ? getRecordForAppLocked(who) : null; 7941 if (app == null) return; 7942 7943 Message msg = Message.obtain(); 7944 msg.what = WAIT_FOR_DEBUGGER_MSG; 7945 msg.obj = app; 7946 msg.arg1 = waiting ? 1 : 0; 7947 mHandler.sendMessage(msg); 7948 } 7949 } 7950 7951 @Override 7952 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7953 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7954 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7955 outInfo.availMem = Process.getFreeMemory(); 7956 outInfo.totalMem = Process.getTotalMemory(); 7957 outInfo.threshold = homeAppMem; 7958 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7959 outInfo.hiddenAppThreshold = cachedAppMem; 7960 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7961 ProcessList.SERVICE_ADJ); 7962 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7963 ProcessList.VISIBLE_APP_ADJ); 7964 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7965 ProcessList.FOREGROUND_APP_ADJ); 7966 } 7967 7968 // ========================================================= 7969 // TASK MANAGEMENT 7970 // ========================================================= 7971 7972 @Override 7973 public List<IAppTask> getAppTasks(String callingPackage) { 7974 int callingUid = Binder.getCallingUid(); 7975 long ident = Binder.clearCallingIdentity(); 7976 7977 synchronized(this) { 7978 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7979 try { 7980 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7981 7982 final int N = mRecentTasks.size(); 7983 for (int i = 0; i < N; i++) { 7984 TaskRecord tr = mRecentTasks.get(i); 7985 // Skip tasks that do not match the caller. We don't need to verify 7986 // callingPackage, because we are also limiting to callingUid and know 7987 // that will limit to the correct security sandbox. 7988 if (tr.effectiveUid != callingUid) { 7989 continue; 7990 } 7991 Intent intent = tr.getBaseIntent(); 7992 if (intent == null || 7993 !callingPackage.equals(intent.getComponent().getPackageName())) { 7994 continue; 7995 } 7996 ActivityManager.RecentTaskInfo taskInfo = 7997 createRecentTaskInfoFromTaskRecord(tr); 7998 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7999 list.add(taskImpl); 8000 } 8001 } finally { 8002 Binder.restoreCallingIdentity(ident); 8003 } 8004 return list; 8005 } 8006 } 8007 8008 @Override 8009 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 8010 final int callingUid = Binder.getCallingUid(); 8011 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 8012 8013 synchronized(this) { 8014 if (localLOGV) Slog.v( 8015 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 8016 8017 final boolean allowed = checkCallingPermission( 8018 android.Manifest.permission.GET_TASKS) 8019 == PackageManager.PERMISSION_GRANTED; 8020 if (!allowed) { 8021 Slog.w(TAG, "getTasks: caller " + callingUid 8022 + " does not hold GET_TASKS; limiting output"); 8023 } 8024 8025 // TODO: Improve with MRU list from all ActivityStacks. 8026 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8027 } 8028 8029 return list; 8030 } 8031 8032 TaskRecord getMostRecentTask() { 8033 return mRecentTasks.get(0); 8034 } 8035 8036 /** 8037 * Creates a new RecentTaskInfo from a TaskRecord. 8038 */ 8039 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8040 // Update the task description to reflect any changes in the task stack 8041 tr.updateTaskDescription(); 8042 8043 // Compose the recent task info 8044 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8045 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8046 rti.persistentId = tr.taskId; 8047 rti.baseIntent = new Intent(tr.getBaseIntent()); 8048 rti.origActivity = tr.origActivity; 8049 rti.description = tr.lastDescription; 8050 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8051 rti.userId = tr.userId; 8052 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8053 rti.firstActiveTime = tr.firstActiveTime; 8054 rti.lastActiveTime = tr.lastActiveTime; 8055 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8056 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8057 return rti; 8058 } 8059 8060 @Override 8061 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8062 final int callingUid = Binder.getCallingUid(); 8063 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8064 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8065 8066 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8067 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8068 synchronized (this) { 8069 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8070 == PackageManager.PERMISSION_GRANTED; 8071 if (!allowed) { 8072 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8073 + " does not hold GET_TASKS; limiting output"); 8074 } 8075 final boolean detailed = checkCallingPermission( 8076 android.Manifest.permission.GET_DETAILED_TASKS) 8077 == PackageManager.PERMISSION_GRANTED; 8078 8079 final int N = mRecentTasks.size(); 8080 ArrayList<ActivityManager.RecentTaskInfo> res 8081 = new ArrayList<ActivityManager.RecentTaskInfo>( 8082 maxNum < N ? maxNum : N); 8083 8084 final Set<Integer> includedUsers; 8085 if (includeProfiles) { 8086 includedUsers = getProfileIdsLocked(userId); 8087 } else { 8088 includedUsers = new HashSet<Integer>(); 8089 } 8090 includedUsers.add(Integer.valueOf(userId)); 8091 8092 for (int i=0; i<N && maxNum > 0; i++) { 8093 TaskRecord tr = mRecentTasks.get(i); 8094 // Only add calling user or related users recent tasks 8095 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8096 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8097 continue; 8098 } 8099 8100 // Return the entry if desired by the caller. We always return 8101 // the first entry, because callers always expect this to be the 8102 // foreground app. We may filter others if the caller has 8103 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8104 // we should exclude the entry. 8105 8106 if (i == 0 8107 || withExcluded 8108 || (tr.intent == null) 8109 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8110 == 0)) { 8111 if (!allowed) { 8112 // If the caller doesn't have the GET_TASKS permission, then only 8113 // allow them to see a small subset of tasks -- their own and home. 8114 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8115 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8116 continue; 8117 } 8118 } 8119 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8120 if (tr.stack != null && tr.stack.isHomeStack()) { 8121 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8122 continue; 8123 } 8124 } 8125 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8126 // Don't include auto remove tasks that are finished or finishing. 8127 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8128 + tr); 8129 continue; 8130 } 8131 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8132 && !tr.isAvailable) { 8133 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8134 continue; 8135 } 8136 8137 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8138 if (!detailed) { 8139 rti.baseIntent.replaceExtras((Bundle)null); 8140 } 8141 8142 res.add(rti); 8143 maxNum--; 8144 } 8145 } 8146 return res; 8147 } 8148 } 8149 8150 private TaskRecord recentTaskForIdLocked(int id) { 8151 final int N = mRecentTasks.size(); 8152 for (int i=0; i<N; i++) { 8153 TaskRecord tr = mRecentTasks.get(i); 8154 if (tr.taskId == id) { 8155 return tr; 8156 } 8157 } 8158 return null; 8159 } 8160 8161 @Override 8162 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8163 synchronized (this) { 8164 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8165 "getTaskThumbnail()"); 8166 TaskRecord tr = recentTaskForIdLocked(id); 8167 if (tr != null) { 8168 return tr.getTaskThumbnailLocked(); 8169 } 8170 } 8171 return null; 8172 } 8173 8174 @Override 8175 public int addAppTask(IBinder activityToken, Intent intent, 8176 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8177 final int callingUid = Binder.getCallingUid(); 8178 final long callingIdent = Binder.clearCallingIdentity(); 8179 8180 try { 8181 synchronized (this) { 8182 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8183 if (r == null) { 8184 throw new IllegalArgumentException("Activity does not exist; token=" 8185 + activityToken); 8186 } 8187 ComponentName comp = intent.getComponent(); 8188 if (comp == null) { 8189 throw new IllegalArgumentException("Intent " + intent 8190 + " must specify explicit component"); 8191 } 8192 if (thumbnail.getWidth() != mThumbnailWidth 8193 || thumbnail.getHeight() != mThumbnailHeight) { 8194 throw new IllegalArgumentException("Bad thumbnail size: got " 8195 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8196 + mThumbnailWidth + "x" + mThumbnailHeight); 8197 } 8198 if (intent.getSelector() != null) { 8199 intent.setSelector(null); 8200 } 8201 if (intent.getSourceBounds() != null) { 8202 intent.setSourceBounds(null); 8203 } 8204 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8205 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8206 // The caller has added this as an auto-remove task... that makes no 8207 // sense, so turn off auto-remove. 8208 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8209 } 8210 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8211 // Must be a new task. 8212 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8213 } 8214 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8215 mLastAddedTaskActivity = null; 8216 } 8217 ActivityInfo ainfo = mLastAddedTaskActivity; 8218 if (ainfo == null) { 8219 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8220 comp, 0, UserHandle.getUserId(callingUid)); 8221 if (ainfo.applicationInfo.uid != callingUid) { 8222 throw new SecurityException( 8223 "Can't add task for another application: target uid=" 8224 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8225 } 8226 } 8227 8228 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8229 intent, description); 8230 8231 int trimIdx = trimRecentsForTask(task, false); 8232 if (trimIdx >= 0) { 8233 // If this would have caused a trim, then we'll abort because that 8234 // means it would be added at the end of the list but then just removed. 8235 return -1; 8236 } 8237 8238 final int N = mRecentTasks.size(); 8239 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8240 final TaskRecord tr = mRecentTasks.remove(N - 1); 8241 tr.removedFromRecents(mTaskPersister); 8242 } 8243 8244 task.inRecents = true; 8245 mRecentTasks.add(task); 8246 r.task.stack.addTask(task, false, false); 8247 8248 task.setLastThumbnail(thumbnail); 8249 task.freeLastThumbnail(); 8250 8251 return task.taskId; 8252 } 8253 } finally { 8254 Binder.restoreCallingIdentity(callingIdent); 8255 } 8256 } 8257 8258 @Override 8259 public Point getAppTaskThumbnailSize() { 8260 synchronized (this) { 8261 return new Point(mThumbnailWidth, mThumbnailHeight); 8262 } 8263 } 8264 8265 @Override 8266 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8267 synchronized (this) { 8268 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8269 if (r != null) { 8270 r.taskDescription = td; 8271 r.task.updateTaskDescription(); 8272 } 8273 } 8274 } 8275 8276 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8277 mRecentTasks.remove(tr); 8278 tr.removedFromRecents(mTaskPersister); 8279 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8280 Intent baseIntent = new Intent( 8281 tr.intent != null ? tr.intent : tr.affinityIntent); 8282 ComponentName component = baseIntent.getComponent(); 8283 if (component == null) { 8284 Slog.w(TAG, "Now component for base intent of task: " + tr); 8285 return; 8286 } 8287 8288 // Find any running services associated with this app. 8289 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8290 8291 if (killProcesses) { 8292 // Find any running processes associated with this app. 8293 final String pkg = component.getPackageName(); 8294 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8295 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8296 for (int i=0; i<pmap.size(); i++) { 8297 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8298 for (int j=0; j<uids.size(); j++) { 8299 ProcessRecord proc = uids.valueAt(j); 8300 if (proc.userId != tr.userId) { 8301 continue; 8302 } 8303 if (!proc.pkgList.containsKey(pkg)) { 8304 continue; 8305 } 8306 procs.add(proc); 8307 } 8308 } 8309 8310 // Kill the running processes. 8311 for (int i=0; i<procs.size(); i++) { 8312 ProcessRecord pr = procs.get(i); 8313 if (pr == mHomeProcess) { 8314 // Don't kill the home process along with tasks from the same package. 8315 continue; 8316 } 8317 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8318 pr.kill("remove task", true); 8319 } else { 8320 pr.waitingToKill = "remove task"; 8321 } 8322 } 8323 } 8324 } 8325 8326 /** 8327 * Removes the task with the specified task id. 8328 * 8329 * @param taskId Identifier of the task to be removed. 8330 * @param flags Additional operational flags. May be 0 or 8331 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8332 * @return Returns true if the given task was found and removed. 8333 */ 8334 private boolean removeTaskByIdLocked(int taskId, int flags) { 8335 TaskRecord tr = recentTaskForIdLocked(taskId); 8336 if (tr != null) { 8337 tr.removeTaskActivitiesLocked(); 8338 cleanUpRemovedTaskLocked(tr, flags); 8339 if (tr.isPersistable) { 8340 notifyTaskPersisterLocked(null, true); 8341 } 8342 return true; 8343 } 8344 return false; 8345 } 8346 8347 @Override 8348 public boolean removeTask(int taskId, int flags) { 8349 synchronized (this) { 8350 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8351 "removeTask()"); 8352 long ident = Binder.clearCallingIdentity(); 8353 try { 8354 return removeTaskByIdLocked(taskId, flags); 8355 } finally { 8356 Binder.restoreCallingIdentity(ident); 8357 } 8358 } 8359 } 8360 8361 /** 8362 * TODO: Add mController hook 8363 */ 8364 @Override 8365 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8366 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8367 "moveTaskToFront()"); 8368 8369 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8370 synchronized(this) { 8371 moveTaskToFrontLocked(taskId, flags, options); 8372 } 8373 } 8374 8375 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8376 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8377 Binder.getCallingUid(), "Task to front")) { 8378 ActivityOptions.abort(options); 8379 return; 8380 } 8381 final long origId = Binder.clearCallingIdentity(); 8382 try { 8383 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8384 if (task == null) { 8385 return; 8386 } 8387 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8388 mStackSupervisor.showLockTaskToast(); 8389 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8390 return; 8391 } 8392 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8393 if (prev != null && prev.isRecentsActivity()) { 8394 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8395 } 8396 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8397 } finally { 8398 Binder.restoreCallingIdentity(origId); 8399 } 8400 ActivityOptions.abort(options); 8401 } 8402 8403 @Override 8404 public void moveTaskToBack(int taskId) { 8405 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8406 "moveTaskToBack()"); 8407 8408 synchronized(this) { 8409 TaskRecord tr = recentTaskForIdLocked(taskId); 8410 if (tr != null) { 8411 if (tr == mStackSupervisor.mLockTaskModeTask) { 8412 mStackSupervisor.showLockTaskToast(); 8413 return; 8414 } 8415 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8416 ActivityStack stack = tr.stack; 8417 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8418 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8419 Binder.getCallingUid(), "Task to back")) { 8420 return; 8421 } 8422 } 8423 final long origId = Binder.clearCallingIdentity(); 8424 try { 8425 stack.moveTaskToBackLocked(taskId, null); 8426 } finally { 8427 Binder.restoreCallingIdentity(origId); 8428 } 8429 } 8430 } 8431 } 8432 8433 /** 8434 * Moves an activity, and all of the other activities within the same task, to the bottom 8435 * of the history stack. The activity's order within the task is unchanged. 8436 * 8437 * @param token A reference to the activity we wish to move 8438 * @param nonRoot If false then this only works if the activity is the root 8439 * of a task; if true it will work for any activity in a task. 8440 * @return Returns true if the move completed, false if not. 8441 */ 8442 @Override 8443 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8444 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8445 synchronized(this) { 8446 final long origId = Binder.clearCallingIdentity(); 8447 try { 8448 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8449 if (taskId >= 0) { 8450 if ((mStackSupervisor.mLockTaskModeTask != null) 8451 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) { 8452 mStackSupervisor.showLockTaskToast(); 8453 return false; 8454 } 8455 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8456 } 8457 } finally { 8458 Binder.restoreCallingIdentity(origId); 8459 } 8460 } 8461 return false; 8462 } 8463 8464 @Override 8465 public void moveTaskBackwards(int task) { 8466 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8467 "moveTaskBackwards()"); 8468 8469 synchronized(this) { 8470 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8471 Binder.getCallingUid(), "Task backwards")) { 8472 return; 8473 } 8474 final long origId = Binder.clearCallingIdentity(); 8475 moveTaskBackwardsLocked(task); 8476 Binder.restoreCallingIdentity(origId); 8477 } 8478 } 8479 8480 private final void moveTaskBackwardsLocked(int task) { 8481 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8482 } 8483 8484 @Override 8485 public IBinder getHomeActivityToken() throws RemoteException { 8486 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8487 "getHomeActivityToken()"); 8488 synchronized (this) { 8489 return mStackSupervisor.getHomeActivityToken(); 8490 } 8491 } 8492 8493 @Override 8494 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8495 IActivityContainerCallback callback) throws RemoteException { 8496 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8497 "createActivityContainer()"); 8498 synchronized (this) { 8499 if (parentActivityToken == null) { 8500 throw new IllegalArgumentException("parent token must not be null"); 8501 } 8502 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8503 if (r == null) { 8504 return null; 8505 } 8506 if (callback == null) { 8507 throw new IllegalArgumentException("callback must not be null"); 8508 } 8509 return mStackSupervisor.createActivityContainer(r, callback); 8510 } 8511 } 8512 8513 @Override 8514 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8515 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8516 "deleteActivityContainer()"); 8517 synchronized (this) { 8518 mStackSupervisor.deleteActivityContainer(container); 8519 } 8520 } 8521 8522 @Override 8523 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8524 throws RemoteException { 8525 synchronized (this) { 8526 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8527 if (stack != null) { 8528 return stack.mActivityContainer; 8529 } 8530 return null; 8531 } 8532 } 8533 8534 @Override 8535 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8536 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8537 "moveTaskToStack()"); 8538 if (stackId == HOME_STACK_ID) { 8539 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8540 new RuntimeException("here").fillInStackTrace()); 8541 } 8542 synchronized (this) { 8543 long ident = Binder.clearCallingIdentity(); 8544 try { 8545 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8546 + stackId + " toTop=" + toTop); 8547 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8548 } finally { 8549 Binder.restoreCallingIdentity(ident); 8550 } 8551 } 8552 } 8553 8554 @Override 8555 public void resizeStack(int stackBoxId, Rect bounds) { 8556 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8557 "resizeStackBox()"); 8558 long ident = Binder.clearCallingIdentity(); 8559 try { 8560 mWindowManager.resizeStack(stackBoxId, bounds); 8561 } finally { 8562 Binder.restoreCallingIdentity(ident); 8563 } 8564 } 8565 8566 @Override 8567 public List<StackInfo> getAllStackInfos() { 8568 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8569 "getAllStackInfos()"); 8570 long ident = Binder.clearCallingIdentity(); 8571 try { 8572 synchronized (this) { 8573 return mStackSupervisor.getAllStackInfosLocked(); 8574 } 8575 } finally { 8576 Binder.restoreCallingIdentity(ident); 8577 } 8578 } 8579 8580 @Override 8581 public StackInfo getStackInfo(int stackId) { 8582 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8583 "getStackInfo()"); 8584 long ident = Binder.clearCallingIdentity(); 8585 try { 8586 synchronized (this) { 8587 return mStackSupervisor.getStackInfoLocked(stackId); 8588 } 8589 } finally { 8590 Binder.restoreCallingIdentity(ident); 8591 } 8592 } 8593 8594 @Override 8595 public boolean isInHomeStack(int taskId) { 8596 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8597 "getStackInfo()"); 8598 long ident = Binder.clearCallingIdentity(); 8599 try { 8600 synchronized (this) { 8601 TaskRecord tr = recentTaskForIdLocked(taskId); 8602 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8603 } 8604 } finally { 8605 Binder.restoreCallingIdentity(ident); 8606 } 8607 } 8608 8609 @Override 8610 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8611 synchronized(this) { 8612 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8613 } 8614 } 8615 8616 private boolean isLockTaskAuthorized(String pkg) { 8617 final DevicePolicyManager dpm = (DevicePolicyManager) 8618 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8619 try { 8620 int uid = mContext.getPackageManager().getPackageUid(pkg, 8621 Binder.getCallingUserHandle().getIdentifier()); 8622 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8623 } catch (NameNotFoundException e) { 8624 return false; 8625 } 8626 } 8627 8628 void startLockTaskMode(TaskRecord task) { 8629 final String pkg; 8630 synchronized (this) { 8631 pkg = task.intent.getComponent().getPackageName(); 8632 } 8633 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8634 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8635 final TaskRecord taskRecord = task; 8636 mHandler.post(new Runnable() { 8637 @Override 8638 public void run() { 8639 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8640 } 8641 }); 8642 return; 8643 } 8644 long ident = Binder.clearCallingIdentity(); 8645 try { 8646 synchronized (this) { 8647 // Since we lost lock on task, make sure it is still there. 8648 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8649 if (task != null) { 8650 if (!isSystemInitiated 8651 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8652 throw new IllegalArgumentException("Invalid task, not in foreground"); 8653 } 8654 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8655 } 8656 } 8657 } finally { 8658 Binder.restoreCallingIdentity(ident); 8659 } 8660 } 8661 8662 @Override 8663 public void startLockTaskMode(int taskId) { 8664 final TaskRecord task; 8665 long ident = Binder.clearCallingIdentity(); 8666 try { 8667 synchronized (this) { 8668 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8669 } 8670 } finally { 8671 Binder.restoreCallingIdentity(ident); 8672 } 8673 if (task != null) { 8674 startLockTaskMode(task); 8675 } 8676 } 8677 8678 @Override 8679 public void startLockTaskMode(IBinder token) { 8680 final TaskRecord task; 8681 long ident = Binder.clearCallingIdentity(); 8682 try { 8683 synchronized (this) { 8684 final ActivityRecord r = ActivityRecord.forToken(token); 8685 if (r == null) { 8686 return; 8687 } 8688 task = r.task; 8689 } 8690 } finally { 8691 Binder.restoreCallingIdentity(ident); 8692 } 8693 if (task != null) { 8694 startLockTaskMode(task); 8695 } 8696 } 8697 8698 @Override 8699 public void startLockTaskModeOnCurrent() throws RemoteException { 8700 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8701 "startLockTaskModeOnCurrent"); 8702 ActivityRecord r = null; 8703 synchronized (this) { 8704 r = mStackSupervisor.topRunningActivityLocked(); 8705 } 8706 startLockTaskMode(r.task); 8707 } 8708 8709 @Override 8710 public void stopLockTaskMode() { 8711 // Verify that the user matches the package of the intent for the TaskRecord 8712 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8713 // and stopLockTaskMode. 8714 final int callingUid = Binder.getCallingUid(); 8715 if (callingUid != Process.SYSTEM_UID) { 8716 try { 8717 String pkg = 8718 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8719 int uid = mContext.getPackageManager().getPackageUid(pkg, 8720 Binder.getCallingUserHandle().getIdentifier()); 8721 if (uid != callingUid) { 8722 throw new SecurityException("Invalid uid, expected " + uid); 8723 } 8724 } catch (NameNotFoundException e) { 8725 Log.d(TAG, "stopLockTaskMode " + e); 8726 return; 8727 } 8728 } 8729 long ident = Binder.clearCallingIdentity(); 8730 try { 8731 Log.d(TAG, "stopLockTaskMode"); 8732 // Stop lock task 8733 synchronized (this) { 8734 mStackSupervisor.setLockTaskModeLocked(null, false); 8735 } 8736 } finally { 8737 Binder.restoreCallingIdentity(ident); 8738 } 8739 } 8740 8741 @Override 8742 public void stopLockTaskModeOnCurrent() throws RemoteException { 8743 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8744 "stopLockTaskModeOnCurrent"); 8745 long ident = Binder.clearCallingIdentity(); 8746 try { 8747 stopLockTaskMode(); 8748 } finally { 8749 Binder.restoreCallingIdentity(ident); 8750 } 8751 } 8752 8753 @Override 8754 public boolean isInLockTaskMode() { 8755 synchronized (this) { 8756 return mStackSupervisor.isInLockTaskMode(); 8757 } 8758 } 8759 8760 // ========================================================= 8761 // CONTENT PROVIDERS 8762 // ========================================================= 8763 8764 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8765 List<ProviderInfo> providers = null; 8766 try { 8767 providers = AppGlobals.getPackageManager(). 8768 queryContentProviders(app.processName, app.uid, 8769 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8770 } catch (RemoteException ex) { 8771 } 8772 if (DEBUG_MU) 8773 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8774 int userId = app.userId; 8775 if (providers != null) { 8776 int N = providers.size(); 8777 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8778 for (int i=0; i<N; i++) { 8779 ProviderInfo cpi = 8780 (ProviderInfo)providers.get(i); 8781 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8782 cpi.name, cpi.flags); 8783 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8784 // This is a singleton provider, but a user besides the 8785 // default user is asking to initialize a process it runs 8786 // in... well, no, it doesn't actually run in this process, 8787 // it runs in the process of the default user. Get rid of it. 8788 providers.remove(i); 8789 N--; 8790 i--; 8791 continue; 8792 } 8793 8794 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8795 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8796 if (cpr == null) { 8797 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8798 mProviderMap.putProviderByClass(comp, cpr); 8799 } 8800 if (DEBUG_MU) 8801 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8802 app.pubProviders.put(cpi.name, cpr); 8803 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8804 // Don't add this if it is a platform component that is marked 8805 // to run in multiple processes, because this is actually 8806 // part of the framework so doesn't make sense to track as a 8807 // separate apk in the process. 8808 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8809 mProcessStats); 8810 } 8811 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8812 } 8813 } 8814 return providers; 8815 } 8816 8817 /** 8818 * Check if {@link ProcessRecord} has a possible chance at accessing the 8819 * given {@link ProviderInfo}. Final permission checking is always done 8820 * in {@link ContentProvider}. 8821 */ 8822 private final String checkContentProviderPermissionLocked( 8823 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8824 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8825 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8826 boolean checkedGrants = false; 8827 if (checkUser) { 8828 // Looking for cross-user grants before enforcing the typical cross-users permissions 8829 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8830 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8831 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8832 return null; 8833 } 8834 checkedGrants = true; 8835 } 8836 userId = handleIncomingUser(callingPid, callingUid, userId, 8837 false, ALLOW_NON_FULL, 8838 "checkContentProviderPermissionLocked " + cpi.authority, null); 8839 if (userId != tmpTargetUserId) { 8840 // When we actually went to determine the final targer user ID, this ended 8841 // up different than our initial check for the authority. This is because 8842 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8843 // SELF. So we need to re-check the grants again. 8844 checkedGrants = false; 8845 } 8846 } 8847 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8848 cpi.applicationInfo.uid, cpi.exported) 8849 == PackageManager.PERMISSION_GRANTED) { 8850 return null; 8851 } 8852 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8853 cpi.applicationInfo.uid, cpi.exported) 8854 == PackageManager.PERMISSION_GRANTED) { 8855 return null; 8856 } 8857 8858 PathPermission[] pps = cpi.pathPermissions; 8859 if (pps != null) { 8860 int i = pps.length; 8861 while (i > 0) { 8862 i--; 8863 PathPermission pp = pps[i]; 8864 String pprperm = pp.getReadPermission(); 8865 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8866 cpi.applicationInfo.uid, cpi.exported) 8867 == PackageManager.PERMISSION_GRANTED) { 8868 return null; 8869 } 8870 String ppwperm = pp.getWritePermission(); 8871 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8872 cpi.applicationInfo.uid, cpi.exported) 8873 == PackageManager.PERMISSION_GRANTED) { 8874 return null; 8875 } 8876 } 8877 } 8878 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8879 return null; 8880 } 8881 8882 String msg; 8883 if (!cpi.exported) { 8884 msg = "Permission Denial: opening provider " + cpi.name 8885 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8886 + ", uid=" + callingUid + ") that is not exported from uid " 8887 + cpi.applicationInfo.uid; 8888 } else { 8889 msg = "Permission Denial: opening provider " + cpi.name 8890 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8891 + ", uid=" + callingUid + ") requires " 8892 + cpi.readPermission + " or " + cpi.writePermission; 8893 } 8894 Slog.w(TAG, msg); 8895 return msg; 8896 } 8897 8898 /** 8899 * Returns if the ContentProvider has granted a uri to callingUid 8900 */ 8901 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8902 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8903 if (perms != null) { 8904 for (int i=perms.size()-1; i>=0; i--) { 8905 GrantUri grantUri = perms.keyAt(i); 8906 if (grantUri.sourceUserId == userId || !checkUser) { 8907 if (matchesProvider(grantUri.uri, cpi)) { 8908 return true; 8909 } 8910 } 8911 } 8912 } 8913 return false; 8914 } 8915 8916 /** 8917 * Returns true if the uri authority is one of the authorities specified in the provider. 8918 */ 8919 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8920 String uriAuth = uri.getAuthority(); 8921 String cpiAuth = cpi.authority; 8922 if (cpiAuth.indexOf(';') == -1) { 8923 return cpiAuth.equals(uriAuth); 8924 } 8925 String[] cpiAuths = cpiAuth.split(";"); 8926 int length = cpiAuths.length; 8927 for (int i = 0; i < length; i++) { 8928 if (cpiAuths[i].equals(uriAuth)) return true; 8929 } 8930 return false; 8931 } 8932 8933 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8934 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8935 if (r != null) { 8936 for (int i=0; i<r.conProviders.size(); i++) { 8937 ContentProviderConnection conn = r.conProviders.get(i); 8938 if (conn.provider == cpr) { 8939 if (DEBUG_PROVIDER) Slog.v(TAG, 8940 "Adding provider requested by " 8941 + r.processName + " from process " 8942 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8943 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8944 if (stable) { 8945 conn.stableCount++; 8946 conn.numStableIncs++; 8947 } else { 8948 conn.unstableCount++; 8949 conn.numUnstableIncs++; 8950 } 8951 return conn; 8952 } 8953 } 8954 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8955 if (stable) { 8956 conn.stableCount = 1; 8957 conn.numStableIncs = 1; 8958 } else { 8959 conn.unstableCount = 1; 8960 conn.numUnstableIncs = 1; 8961 } 8962 cpr.connections.add(conn); 8963 r.conProviders.add(conn); 8964 return conn; 8965 } 8966 cpr.addExternalProcessHandleLocked(externalProcessToken); 8967 return null; 8968 } 8969 8970 boolean decProviderCountLocked(ContentProviderConnection conn, 8971 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8972 if (conn != null) { 8973 cpr = conn.provider; 8974 if (DEBUG_PROVIDER) Slog.v(TAG, 8975 "Removing provider requested by " 8976 + conn.client.processName + " from process " 8977 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8978 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8979 if (stable) { 8980 conn.stableCount--; 8981 } else { 8982 conn.unstableCount--; 8983 } 8984 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8985 cpr.connections.remove(conn); 8986 conn.client.conProviders.remove(conn); 8987 return true; 8988 } 8989 return false; 8990 } 8991 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8992 return false; 8993 } 8994 8995 private void checkTime(long startTime, String where) { 8996 long now = SystemClock.elapsedRealtime(); 8997 if ((now-startTime) > 1000) { 8998 // If we are taking more than a second, log about it. 8999 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where); 9000 } 9001 } 9002 9003 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 9004 String name, IBinder token, boolean stable, int userId) { 9005 ContentProviderRecord cpr; 9006 ContentProviderConnection conn = null; 9007 ProviderInfo cpi = null; 9008 9009 synchronized(this) { 9010 long startTime = SystemClock.elapsedRealtime(); 9011 9012 ProcessRecord r = null; 9013 if (caller != null) { 9014 r = getRecordForAppLocked(caller); 9015 if (r == null) { 9016 throw new SecurityException( 9017 "Unable to find app for caller " + caller 9018 + " (pid=" + Binder.getCallingPid() 9019 + ") when getting content provider " + name); 9020 } 9021 } 9022 9023 boolean checkCrossUser = true; 9024 9025 checkTime(startTime, "getContentProviderImpl: getProviderByName"); 9026 9027 // First check if this content provider has been published... 9028 cpr = mProviderMap.getProviderByName(name, userId); 9029 // If that didn't work, check if it exists for user 0 and then 9030 // verify that it's a singleton provider before using it. 9031 if (cpr == null && userId != UserHandle.USER_OWNER) { 9032 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 9033 if (cpr != null) { 9034 cpi = cpr.info; 9035 if (isSingleton(cpi.processName, cpi.applicationInfo, 9036 cpi.name, cpi.flags) 9037 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 9038 userId = UserHandle.USER_OWNER; 9039 checkCrossUser = false; 9040 } else { 9041 cpr = null; 9042 cpi = null; 9043 } 9044 } 9045 } 9046 9047 boolean providerRunning = cpr != null; 9048 if (providerRunning) { 9049 cpi = cpr.info; 9050 String msg; 9051 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9052 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9053 != null) { 9054 throw new SecurityException(msg); 9055 } 9056 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9057 9058 if (r != null && cpr.canRunHere(r)) { 9059 // This provider has been published or is in the process 9060 // of being published... but it is also allowed to run 9061 // in the caller's process, so don't make a connection 9062 // and just let the caller instantiate its own instance. 9063 ContentProviderHolder holder = cpr.newHolder(null); 9064 // don't give caller the provider object, it needs 9065 // to make its own. 9066 holder.provider = null; 9067 return holder; 9068 } 9069 9070 final long origId = Binder.clearCallingIdentity(); 9071 9072 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked"); 9073 9074 // In this case the provider instance already exists, so we can 9075 // return it right away. 9076 conn = incProviderCountLocked(r, cpr, token, stable); 9077 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9078 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9079 // If this is a perceptible app accessing the provider, 9080 // make sure to count it as being accessed and thus 9081 // back up on the LRU list. This is good because 9082 // content providers are often expensive to start. 9083 checkTime(startTime, "getContentProviderImpl: before updateLruProcess"); 9084 updateLruProcessLocked(cpr.proc, false, null); 9085 checkTime(startTime, "getContentProviderImpl: after updateLruProcess"); 9086 } 9087 } 9088 9089 if (cpr.proc != null) { 9090 if (false) { 9091 if (cpr.name.flattenToShortString().equals( 9092 "com.android.providers.calendar/.CalendarProvider2")) { 9093 Slog.v(TAG, "****************** KILLING " 9094 + cpr.name.flattenToShortString()); 9095 Process.killProcess(cpr.proc.pid); 9096 } 9097 } 9098 checkTime(startTime, "getContentProviderImpl: before updateOomAdj"); 9099 boolean success = updateOomAdjLocked(cpr.proc); 9100 checkTime(startTime, "getContentProviderImpl: after updateOomAdj"); 9101 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9102 // NOTE: there is still a race here where a signal could be 9103 // pending on the process even though we managed to update its 9104 // adj level. Not sure what to do about this, but at least 9105 // the race is now smaller. 9106 if (!success) { 9107 // Uh oh... it looks like the provider's process 9108 // has been killed on us. We need to wait for a new 9109 // process to be started, and make sure its death 9110 // doesn't kill our process. 9111 Slog.i(TAG, 9112 "Existing provider " + cpr.name.flattenToShortString() 9113 + " is crashing; detaching " + r); 9114 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9115 checkTime(startTime, "getContentProviderImpl: before appDied"); 9116 appDiedLocked(cpr.proc); 9117 checkTime(startTime, "getContentProviderImpl: after appDied"); 9118 if (!lastRef) { 9119 // This wasn't the last ref our process had on 9120 // the provider... we have now been killed, bail. 9121 return null; 9122 } 9123 providerRunning = false; 9124 conn = null; 9125 } 9126 } 9127 9128 Binder.restoreCallingIdentity(origId); 9129 } 9130 9131 boolean singleton; 9132 if (!providerRunning) { 9133 try { 9134 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider"); 9135 cpi = AppGlobals.getPackageManager(). 9136 resolveContentProvider(name, 9137 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9138 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider"); 9139 } catch (RemoteException ex) { 9140 } 9141 if (cpi == null) { 9142 return null; 9143 } 9144 // If the provider is a singleton AND 9145 // (it's a call within the same user || the provider is a 9146 // privileged app) 9147 // Then allow connecting to the singleton provider 9148 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9149 cpi.name, cpi.flags) 9150 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9151 if (singleton) { 9152 userId = UserHandle.USER_OWNER; 9153 } 9154 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9155 checkTime(startTime, "getContentProviderImpl: got app info for user"); 9156 9157 String msg; 9158 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission"); 9159 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9160 != null) { 9161 throw new SecurityException(msg); 9162 } 9163 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission"); 9164 9165 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9166 && !cpi.processName.equals("system")) { 9167 // If this content provider does not run in the system 9168 // process, and the system is not yet ready to run other 9169 // processes, then fail fast instead of hanging. 9170 throw new IllegalArgumentException( 9171 "Attempt to launch content provider before system ready"); 9172 } 9173 9174 // Make sure that the user who owns this provider is started. If not, 9175 // we don't want to allow it to run. 9176 if (mStartedUsers.get(userId) == null) { 9177 Slog.w(TAG, "Unable to launch app " 9178 + cpi.applicationInfo.packageName + "/" 9179 + cpi.applicationInfo.uid + " for provider " 9180 + name + ": user " + userId + " is stopped"); 9181 return null; 9182 } 9183 9184 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9185 checkTime(startTime, "getContentProviderImpl: before getProviderByClass"); 9186 cpr = mProviderMap.getProviderByClass(comp, userId); 9187 checkTime(startTime, "getContentProviderImpl: after getProviderByClass"); 9188 final boolean firstClass = cpr == null; 9189 if (firstClass) { 9190 try { 9191 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo"); 9192 ApplicationInfo ai = 9193 AppGlobals.getPackageManager(). 9194 getApplicationInfo( 9195 cpi.applicationInfo.packageName, 9196 STOCK_PM_FLAGS, userId); 9197 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo"); 9198 if (ai == null) { 9199 Slog.w(TAG, "No package info for content provider " 9200 + cpi.name); 9201 return null; 9202 } 9203 ai = getAppInfoForUser(ai, userId); 9204 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9205 } catch (RemoteException ex) { 9206 // pm is in same process, this will never happen. 9207 } 9208 } 9209 9210 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord"); 9211 9212 if (r != null && cpr.canRunHere(r)) { 9213 // If this is a multiprocess provider, then just return its 9214 // info and allow the caller to instantiate it. Only do 9215 // this if the provider is the same user as the caller's 9216 // process, or can run as root (so can be in any process). 9217 return cpr.newHolder(null); 9218 } 9219 9220 if (DEBUG_PROVIDER) { 9221 RuntimeException e = new RuntimeException("here"); 9222 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9223 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9224 } 9225 9226 // This is single process, and our app is now connecting to it. 9227 // See if we are already in the process of launching this 9228 // provider. 9229 final int N = mLaunchingProviders.size(); 9230 int i; 9231 for (i=0; i<N; i++) { 9232 if (mLaunchingProviders.get(i) == cpr) { 9233 break; 9234 } 9235 } 9236 9237 // If the provider is not already being launched, then get it 9238 // started. 9239 if (i >= N) { 9240 final long origId = Binder.clearCallingIdentity(); 9241 9242 try { 9243 // Content provider is now in use, its package can't be stopped. 9244 try { 9245 checkTime(startTime, "getContentProviderImpl: before set stopped state"); 9246 AppGlobals.getPackageManager().setPackageStoppedState( 9247 cpr.appInfo.packageName, false, userId); 9248 checkTime(startTime, "getContentProviderImpl: after set stopped state"); 9249 } catch (RemoteException e) { 9250 } catch (IllegalArgumentException e) { 9251 Slog.w(TAG, "Failed trying to unstop package " 9252 + cpr.appInfo.packageName + ": " + e); 9253 } 9254 9255 // Use existing process if already started 9256 checkTime(startTime, "getContentProviderImpl: looking for process record"); 9257 ProcessRecord proc = getProcessRecordLocked( 9258 cpi.processName, cpr.appInfo.uid, false); 9259 if (proc != null && proc.thread != null) { 9260 if (DEBUG_PROVIDER) { 9261 Slog.d(TAG, "Installing in existing process " + proc); 9262 } 9263 checkTime(startTime, "getContentProviderImpl: scheduling install"); 9264 proc.pubProviders.put(cpi.name, cpr); 9265 try { 9266 proc.thread.scheduleInstallProvider(cpi); 9267 } catch (RemoteException e) { 9268 } 9269 } else { 9270 checkTime(startTime, "getContentProviderImpl: before start process"); 9271 proc = startProcessLocked(cpi.processName, 9272 cpr.appInfo, false, 0, "content provider", 9273 new ComponentName(cpi.applicationInfo.packageName, 9274 cpi.name), false, false, false); 9275 checkTime(startTime, "getContentProviderImpl: after start process"); 9276 if (proc == null) { 9277 Slog.w(TAG, "Unable to launch app " 9278 + cpi.applicationInfo.packageName + "/" 9279 + cpi.applicationInfo.uid + " for provider " 9280 + name + ": process is bad"); 9281 return null; 9282 } 9283 } 9284 cpr.launchingApp = proc; 9285 mLaunchingProviders.add(cpr); 9286 } finally { 9287 Binder.restoreCallingIdentity(origId); 9288 } 9289 } 9290 9291 checkTime(startTime, "getContentProviderImpl: updating data structures"); 9292 9293 // Make sure the provider is published (the same provider class 9294 // may be published under multiple names). 9295 if (firstClass) { 9296 mProviderMap.putProviderByClass(comp, cpr); 9297 } 9298 9299 mProviderMap.putProviderByName(name, cpr); 9300 conn = incProviderCountLocked(r, cpr, token, stable); 9301 if (conn != null) { 9302 conn.waiting = true; 9303 } 9304 } 9305 checkTime(startTime, "getContentProviderImpl: done!"); 9306 } 9307 9308 // Wait for the provider to be published... 9309 synchronized (cpr) { 9310 while (cpr.provider == null) { 9311 if (cpr.launchingApp == null) { 9312 Slog.w(TAG, "Unable to launch app " 9313 + cpi.applicationInfo.packageName + "/" 9314 + cpi.applicationInfo.uid + " for provider " 9315 + name + ": launching app became null"); 9316 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9317 UserHandle.getUserId(cpi.applicationInfo.uid), 9318 cpi.applicationInfo.packageName, 9319 cpi.applicationInfo.uid, name); 9320 return null; 9321 } 9322 try { 9323 if (DEBUG_MU) { 9324 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9325 + cpr.launchingApp); 9326 } 9327 if (conn != null) { 9328 conn.waiting = true; 9329 } 9330 cpr.wait(); 9331 } catch (InterruptedException ex) { 9332 } finally { 9333 if (conn != null) { 9334 conn.waiting = false; 9335 } 9336 } 9337 } 9338 } 9339 return cpr != null ? cpr.newHolder(conn) : null; 9340 } 9341 9342 @Override 9343 public final ContentProviderHolder getContentProvider( 9344 IApplicationThread caller, String name, int userId, boolean stable) { 9345 enforceNotIsolatedCaller("getContentProvider"); 9346 if (caller == null) { 9347 String msg = "null IApplicationThread when getting content provider " 9348 + name; 9349 Slog.w(TAG, msg); 9350 throw new SecurityException(msg); 9351 } 9352 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9353 // with cross-user grant. 9354 return getContentProviderImpl(caller, name, null, stable, userId); 9355 } 9356 9357 public ContentProviderHolder getContentProviderExternal( 9358 String name, int userId, IBinder token) { 9359 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9360 "Do not have permission in call getContentProviderExternal()"); 9361 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9362 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9363 return getContentProviderExternalUnchecked(name, token, userId); 9364 } 9365 9366 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9367 IBinder token, int userId) { 9368 return getContentProviderImpl(null, name, token, true, userId); 9369 } 9370 9371 /** 9372 * Drop a content provider from a ProcessRecord's bookkeeping 9373 */ 9374 public void removeContentProvider(IBinder connection, boolean stable) { 9375 enforceNotIsolatedCaller("removeContentProvider"); 9376 long ident = Binder.clearCallingIdentity(); 9377 try { 9378 synchronized (this) { 9379 ContentProviderConnection conn; 9380 try { 9381 conn = (ContentProviderConnection)connection; 9382 } catch (ClassCastException e) { 9383 String msg ="removeContentProvider: " + connection 9384 + " not a ContentProviderConnection"; 9385 Slog.w(TAG, msg); 9386 throw new IllegalArgumentException(msg); 9387 } 9388 if (conn == null) { 9389 throw new NullPointerException("connection is null"); 9390 } 9391 if (decProviderCountLocked(conn, null, null, stable)) { 9392 updateOomAdjLocked(); 9393 } 9394 } 9395 } finally { 9396 Binder.restoreCallingIdentity(ident); 9397 } 9398 } 9399 9400 public void removeContentProviderExternal(String name, IBinder token) { 9401 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9402 "Do not have permission in call removeContentProviderExternal()"); 9403 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9404 } 9405 9406 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9407 synchronized (this) { 9408 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9409 if(cpr == null) { 9410 //remove from mProvidersByClass 9411 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9412 return; 9413 } 9414 9415 //update content provider record entry info 9416 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9417 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9418 if (localCpr.hasExternalProcessHandles()) { 9419 if (localCpr.removeExternalProcessHandleLocked(token)) { 9420 updateOomAdjLocked(); 9421 } else { 9422 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9423 + " with no external reference for token: " 9424 + token + "."); 9425 } 9426 } else { 9427 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9428 + " with no external references."); 9429 } 9430 } 9431 } 9432 9433 public final void publishContentProviders(IApplicationThread caller, 9434 List<ContentProviderHolder> providers) { 9435 if (providers == null) { 9436 return; 9437 } 9438 9439 enforceNotIsolatedCaller("publishContentProviders"); 9440 synchronized (this) { 9441 final ProcessRecord r = getRecordForAppLocked(caller); 9442 if (DEBUG_MU) 9443 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9444 if (r == null) { 9445 throw new SecurityException( 9446 "Unable to find app for caller " + caller 9447 + " (pid=" + Binder.getCallingPid() 9448 + ") when publishing content providers"); 9449 } 9450 9451 final long origId = Binder.clearCallingIdentity(); 9452 9453 final int N = providers.size(); 9454 for (int i=0; i<N; i++) { 9455 ContentProviderHolder src = providers.get(i); 9456 if (src == null || src.info == null || src.provider == null) { 9457 continue; 9458 } 9459 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9460 if (DEBUG_MU) 9461 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9462 if (dst != null) { 9463 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9464 mProviderMap.putProviderByClass(comp, dst); 9465 String names[] = dst.info.authority.split(";"); 9466 for (int j = 0; j < names.length; j++) { 9467 mProviderMap.putProviderByName(names[j], dst); 9468 } 9469 9470 int NL = mLaunchingProviders.size(); 9471 int j; 9472 for (j=0; j<NL; j++) { 9473 if (mLaunchingProviders.get(j) == dst) { 9474 mLaunchingProviders.remove(j); 9475 j--; 9476 NL--; 9477 } 9478 } 9479 synchronized (dst) { 9480 dst.provider = src.provider; 9481 dst.proc = r; 9482 dst.notifyAll(); 9483 } 9484 updateOomAdjLocked(r); 9485 } 9486 } 9487 9488 Binder.restoreCallingIdentity(origId); 9489 } 9490 } 9491 9492 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9493 ContentProviderConnection conn; 9494 try { 9495 conn = (ContentProviderConnection)connection; 9496 } catch (ClassCastException e) { 9497 String msg ="refContentProvider: " + connection 9498 + " not a ContentProviderConnection"; 9499 Slog.w(TAG, msg); 9500 throw new IllegalArgumentException(msg); 9501 } 9502 if (conn == null) { 9503 throw new NullPointerException("connection is null"); 9504 } 9505 9506 synchronized (this) { 9507 if (stable > 0) { 9508 conn.numStableIncs += stable; 9509 } 9510 stable = conn.stableCount + stable; 9511 if (stable < 0) { 9512 throw new IllegalStateException("stableCount < 0: " + stable); 9513 } 9514 9515 if (unstable > 0) { 9516 conn.numUnstableIncs += unstable; 9517 } 9518 unstable = conn.unstableCount + unstable; 9519 if (unstable < 0) { 9520 throw new IllegalStateException("unstableCount < 0: " + unstable); 9521 } 9522 9523 if ((stable+unstable) <= 0) { 9524 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9525 + stable + " unstable=" + unstable); 9526 } 9527 conn.stableCount = stable; 9528 conn.unstableCount = unstable; 9529 return !conn.dead; 9530 } 9531 } 9532 9533 public void unstableProviderDied(IBinder connection) { 9534 ContentProviderConnection conn; 9535 try { 9536 conn = (ContentProviderConnection)connection; 9537 } catch (ClassCastException e) { 9538 String msg ="refContentProvider: " + connection 9539 + " not a ContentProviderConnection"; 9540 Slog.w(TAG, msg); 9541 throw new IllegalArgumentException(msg); 9542 } 9543 if (conn == null) { 9544 throw new NullPointerException("connection is null"); 9545 } 9546 9547 // Safely retrieve the content provider associated with the connection. 9548 IContentProvider provider; 9549 synchronized (this) { 9550 provider = conn.provider.provider; 9551 } 9552 9553 if (provider == null) { 9554 // Um, yeah, we're way ahead of you. 9555 return; 9556 } 9557 9558 // Make sure the caller is being honest with us. 9559 if (provider.asBinder().pingBinder()) { 9560 // Er, no, still looks good to us. 9561 synchronized (this) { 9562 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9563 + " says " + conn + " died, but we don't agree"); 9564 return; 9565 } 9566 } 9567 9568 // Well look at that! It's dead! 9569 synchronized (this) { 9570 if (conn.provider.provider != provider) { 9571 // But something changed... good enough. 9572 return; 9573 } 9574 9575 ProcessRecord proc = conn.provider.proc; 9576 if (proc == null || proc.thread == null) { 9577 // Seems like the process is already cleaned up. 9578 return; 9579 } 9580 9581 // As far as we're concerned, this is just like receiving a 9582 // death notification... just a bit prematurely. 9583 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9584 + ") early provider death"); 9585 final long ident = Binder.clearCallingIdentity(); 9586 try { 9587 appDiedLocked(proc); 9588 } finally { 9589 Binder.restoreCallingIdentity(ident); 9590 } 9591 } 9592 } 9593 9594 @Override 9595 public void appNotRespondingViaProvider(IBinder connection) { 9596 enforceCallingPermission( 9597 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9598 9599 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9600 if (conn == null) { 9601 Slog.w(TAG, "ContentProviderConnection is null"); 9602 return; 9603 } 9604 9605 final ProcessRecord host = conn.provider.proc; 9606 if (host == null) { 9607 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9608 return; 9609 } 9610 9611 final long token = Binder.clearCallingIdentity(); 9612 try { 9613 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9614 } finally { 9615 Binder.restoreCallingIdentity(token); 9616 } 9617 } 9618 9619 public final void installSystemProviders() { 9620 List<ProviderInfo> providers; 9621 synchronized (this) { 9622 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9623 providers = generateApplicationProvidersLocked(app); 9624 if (providers != null) { 9625 for (int i=providers.size()-1; i>=0; i--) { 9626 ProviderInfo pi = (ProviderInfo)providers.get(i); 9627 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9628 Slog.w(TAG, "Not installing system proc provider " + pi.name 9629 + ": not system .apk"); 9630 providers.remove(i); 9631 } 9632 } 9633 } 9634 } 9635 if (providers != null) { 9636 mSystemThread.installSystemProviders(providers); 9637 } 9638 9639 mCoreSettingsObserver = new CoreSettingsObserver(this); 9640 9641 //mUsageStatsService.monitorPackages(); 9642 } 9643 9644 /** 9645 * Allows apps to retrieve the MIME type of a URI. 9646 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9647 * users, then it does not need permission to access the ContentProvider. 9648 * Either, it needs cross-user uri grants. 9649 * 9650 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9651 * 9652 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9653 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9654 */ 9655 public String getProviderMimeType(Uri uri, int userId) { 9656 enforceNotIsolatedCaller("getProviderMimeType"); 9657 final String name = uri.getAuthority(); 9658 int callingUid = Binder.getCallingUid(); 9659 int callingPid = Binder.getCallingPid(); 9660 long ident = 0; 9661 boolean clearedIdentity = false; 9662 userId = unsafeConvertIncomingUser(userId); 9663 if (UserHandle.getUserId(callingUid) != userId) { 9664 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9665 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9666 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9667 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9668 clearedIdentity = true; 9669 ident = Binder.clearCallingIdentity(); 9670 } 9671 } 9672 ContentProviderHolder holder = null; 9673 try { 9674 holder = getContentProviderExternalUnchecked(name, null, userId); 9675 if (holder != null) { 9676 return holder.provider.getType(uri); 9677 } 9678 } catch (RemoteException e) { 9679 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9680 return null; 9681 } finally { 9682 // We need to clear the identity to call removeContentProviderExternalUnchecked 9683 if (!clearedIdentity) { 9684 ident = Binder.clearCallingIdentity(); 9685 } 9686 try { 9687 if (holder != null) { 9688 removeContentProviderExternalUnchecked(name, null, userId); 9689 } 9690 } finally { 9691 Binder.restoreCallingIdentity(ident); 9692 } 9693 } 9694 9695 return null; 9696 } 9697 9698 // ========================================================= 9699 // GLOBAL MANAGEMENT 9700 // ========================================================= 9701 9702 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9703 boolean isolated, int isolatedUid) { 9704 String proc = customProcess != null ? customProcess : info.processName; 9705 BatteryStatsImpl.Uid.Proc ps = null; 9706 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9707 int uid = info.uid; 9708 if (isolated) { 9709 if (isolatedUid == 0) { 9710 int userId = UserHandle.getUserId(uid); 9711 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9712 while (true) { 9713 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9714 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9715 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9716 } 9717 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9718 mNextIsolatedProcessUid++; 9719 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9720 // No process for this uid, use it. 9721 break; 9722 } 9723 stepsLeft--; 9724 if (stepsLeft <= 0) { 9725 return null; 9726 } 9727 } 9728 } else { 9729 // Special case for startIsolatedProcess (internal only), where 9730 // the uid of the isolated process is specified by the caller. 9731 uid = isolatedUid; 9732 } 9733 } 9734 return new ProcessRecord(stats, info, proc, uid); 9735 } 9736 9737 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9738 String abiOverride) { 9739 ProcessRecord app; 9740 if (!isolated) { 9741 app = getProcessRecordLocked(info.processName, info.uid, true); 9742 } else { 9743 app = null; 9744 } 9745 9746 if (app == null) { 9747 app = newProcessRecordLocked(info, null, isolated, 0); 9748 mProcessNames.put(info.processName, app.uid, app); 9749 if (isolated) { 9750 mIsolatedProcesses.put(app.uid, app); 9751 } 9752 updateLruProcessLocked(app, false, null); 9753 updateOomAdjLocked(); 9754 } 9755 9756 // This package really, really can not be stopped. 9757 try { 9758 AppGlobals.getPackageManager().setPackageStoppedState( 9759 info.packageName, false, UserHandle.getUserId(app.uid)); 9760 } catch (RemoteException e) { 9761 } catch (IllegalArgumentException e) { 9762 Slog.w(TAG, "Failed trying to unstop package " 9763 + info.packageName + ": " + e); 9764 } 9765 9766 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9767 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9768 app.persistent = true; 9769 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9770 } 9771 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9772 mPersistentStartingProcesses.add(app); 9773 startProcessLocked(app, "added application", app.processName, abiOverride, 9774 null /* entryPoint */, null /* entryPointArgs */); 9775 } 9776 9777 return app; 9778 } 9779 9780 public void unhandledBack() { 9781 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9782 "unhandledBack()"); 9783 9784 synchronized(this) { 9785 final long origId = Binder.clearCallingIdentity(); 9786 try { 9787 getFocusedStack().unhandledBackLocked(); 9788 } finally { 9789 Binder.restoreCallingIdentity(origId); 9790 } 9791 } 9792 } 9793 9794 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9795 enforceNotIsolatedCaller("openContentUri"); 9796 final int userId = UserHandle.getCallingUserId(); 9797 String name = uri.getAuthority(); 9798 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9799 ParcelFileDescriptor pfd = null; 9800 if (cph != null) { 9801 // We record the binder invoker's uid in thread-local storage before 9802 // going to the content provider to open the file. Later, in the code 9803 // that handles all permissions checks, we look for this uid and use 9804 // that rather than the Activity Manager's own uid. The effect is that 9805 // we do the check against the caller's permissions even though it looks 9806 // to the content provider like the Activity Manager itself is making 9807 // the request. 9808 sCallerIdentity.set(new Identity( 9809 Binder.getCallingPid(), Binder.getCallingUid())); 9810 try { 9811 pfd = cph.provider.openFile(null, uri, "r", null); 9812 } catch (FileNotFoundException e) { 9813 // do nothing; pfd will be returned null 9814 } finally { 9815 // Ensure that whatever happens, we clean up the identity state 9816 sCallerIdentity.remove(); 9817 } 9818 9819 // We've got the fd now, so we're done with the provider. 9820 removeContentProviderExternalUnchecked(name, null, userId); 9821 } else { 9822 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9823 } 9824 return pfd; 9825 } 9826 9827 // Actually is sleeping or shutting down or whatever else in the future 9828 // is an inactive state. 9829 public boolean isSleepingOrShuttingDown() { 9830 return mSleeping || mShuttingDown; 9831 } 9832 9833 public boolean isSleeping() { 9834 return mSleeping; 9835 } 9836 9837 void goingToSleep() { 9838 synchronized(this) { 9839 mWentToSleep = true; 9840 updateEventDispatchingLocked(); 9841 goToSleepIfNeededLocked(); 9842 } 9843 } 9844 9845 void finishRunningVoiceLocked() { 9846 if (mRunningVoice) { 9847 mRunningVoice = false; 9848 goToSleepIfNeededLocked(); 9849 } 9850 } 9851 9852 void goToSleepIfNeededLocked() { 9853 if (mWentToSleep && !mRunningVoice) { 9854 if (!mSleeping) { 9855 mSleeping = true; 9856 mStackSupervisor.goingToSleepLocked(); 9857 9858 // Initialize the wake times of all processes. 9859 checkExcessivePowerUsageLocked(false); 9860 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9861 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9862 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9863 } 9864 } 9865 } 9866 9867 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9868 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9869 // Never persist the home stack. 9870 return; 9871 } 9872 mTaskPersister.wakeup(task, flush); 9873 } 9874 9875 @Override 9876 public boolean shutdown(int timeout) { 9877 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9878 != PackageManager.PERMISSION_GRANTED) { 9879 throw new SecurityException("Requires permission " 9880 + android.Manifest.permission.SHUTDOWN); 9881 } 9882 9883 boolean timedout = false; 9884 9885 synchronized(this) { 9886 mShuttingDown = true; 9887 updateEventDispatchingLocked(); 9888 timedout = mStackSupervisor.shutdownLocked(timeout); 9889 } 9890 9891 mAppOpsService.shutdown(); 9892 if (mUsageStatsService != null) { 9893 mUsageStatsService.prepareShutdown(); 9894 } 9895 mBatteryStatsService.shutdown(); 9896 synchronized (this) { 9897 mProcessStats.shutdownLocked(); 9898 } 9899 notifyTaskPersisterLocked(null, true); 9900 9901 return timedout; 9902 } 9903 9904 public final void activitySlept(IBinder token) { 9905 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9906 9907 final long origId = Binder.clearCallingIdentity(); 9908 9909 synchronized (this) { 9910 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9911 if (r != null) { 9912 mStackSupervisor.activitySleptLocked(r); 9913 } 9914 } 9915 9916 Binder.restoreCallingIdentity(origId); 9917 } 9918 9919 void logLockScreen(String msg) { 9920 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9921 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9922 mWentToSleep + " mSleeping=" + mSleeping); 9923 } 9924 9925 private void comeOutOfSleepIfNeededLocked() { 9926 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9927 if (mSleeping) { 9928 mSleeping = false; 9929 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9930 } 9931 } 9932 } 9933 9934 void wakingUp() { 9935 synchronized(this) { 9936 mWentToSleep = false; 9937 updateEventDispatchingLocked(); 9938 comeOutOfSleepIfNeededLocked(); 9939 } 9940 } 9941 9942 void startRunningVoiceLocked() { 9943 if (!mRunningVoice) { 9944 mRunningVoice = true; 9945 comeOutOfSleepIfNeededLocked(); 9946 } 9947 } 9948 9949 private void updateEventDispatchingLocked() { 9950 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9951 } 9952 9953 public void setLockScreenShown(boolean shown) { 9954 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9955 != PackageManager.PERMISSION_GRANTED) { 9956 throw new SecurityException("Requires permission " 9957 + android.Manifest.permission.DEVICE_POWER); 9958 } 9959 9960 synchronized(this) { 9961 long ident = Binder.clearCallingIdentity(); 9962 try { 9963 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9964 mLockScreenShown = shown; 9965 comeOutOfSleepIfNeededLocked(); 9966 } finally { 9967 Binder.restoreCallingIdentity(ident); 9968 } 9969 } 9970 } 9971 9972 @Override 9973 public void stopAppSwitches() { 9974 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9975 != PackageManager.PERMISSION_GRANTED) { 9976 throw new SecurityException("Requires permission " 9977 + android.Manifest.permission.STOP_APP_SWITCHES); 9978 } 9979 9980 synchronized(this) { 9981 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9982 + APP_SWITCH_DELAY_TIME; 9983 mDidAppSwitch = false; 9984 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9985 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9986 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9987 } 9988 } 9989 9990 public void resumeAppSwitches() { 9991 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9992 != PackageManager.PERMISSION_GRANTED) { 9993 throw new SecurityException("Requires permission " 9994 + android.Manifest.permission.STOP_APP_SWITCHES); 9995 } 9996 9997 synchronized(this) { 9998 // Note that we don't execute any pending app switches... we will 9999 // let those wait until either the timeout, or the next start 10000 // activity request. 10001 mAppSwitchesAllowedTime = 0; 10002 } 10003 } 10004 10005 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 10006 String name) { 10007 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 10008 return true; 10009 } 10010 10011 final int perm = checkComponentPermission( 10012 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 10013 callingUid, -1, true); 10014 if (perm == PackageManager.PERMISSION_GRANTED) { 10015 return true; 10016 } 10017 10018 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 10019 return false; 10020 } 10021 10022 public void setDebugApp(String packageName, boolean waitForDebugger, 10023 boolean persistent) { 10024 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 10025 "setDebugApp()"); 10026 10027 long ident = Binder.clearCallingIdentity(); 10028 try { 10029 // Note that this is not really thread safe if there are multiple 10030 // callers into it at the same time, but that's not a situation we 10031 // care about. 10032 if (persistent) { 10033 final ContentResolver resolver = mContext.getContentResolver(); 10034 Settings.Global.putString( 10035 resolver, Settings.Global.DEBUG_APP, 10036 packageName); 10037 Settings.Global.putInt( 10038 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 10039 waitForDebugger ? 1 : 0); 10040 } 10041 10042 synchronized (this) { 10043 if (!persistent) { 10044 mOrigDebugApp = mDebugApp; 10045 mOrigWaitForDebugger = mWaitForDebugger; 10046 } 10047 mDebugApp = packageName; 10048 mWaitForDebugger = waitForDebugger; 10049 mDebugTransient = !persistent; 10050 if (packageName != null) { 10051 forceStopPackageLocked(packageName, -1, false, false, true, true, 10052 false, UserHandle.USER_ALL, "set debug app"); 10053 } 10054 } 10055 } finally { 10056 Binder.restoreCallingIdentity(ident); 10057 } 10058 } 10059 10060 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 10061 synchronized (this) { 10062 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10063 if (!isDebuggable) { 10064 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10065 throw new SecurityException("Process not debuggable: " + app.packageName); 10066 } 10067 } 10068 10069 mOpenGlTraceApp = processName; 10070 } 10071 } 10072 10073 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 10074 synchronized (this) { 10075 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 10076 if (!isDebuggable) { 10077 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 10078 throw new SecurityException("Process not debuggable: " + app.packageName); 10079 } 10080 } 10081 mProfileApp = processName; 10082 mProfileFile = profilerInfo.profileFile; 10083 if (mProfileFd != null) { 10084 try { 10085 mProfileFd.close(); 10086 } catch (IOException e) { 10087 } 10088 mProfileFd = null; 10089 } 10090 mProfileFd = profilerInfo.profileFd; 10091 mSamplingInterval = profilerInfo.samplingInterval; 10092 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10093 mProfileType = 0; 10094 } 10095 } 10096 10097 @Override 10098 public void setAlwaysFinish(boolean enabled) { 10099 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10100 "setAlwaysFinish()"); 10101 10102 Settings.Global.putInt( 10103 mContext.getContentResolver(), 10104 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10105 10106 synchronized (this) { 10107 mAlwaysFinishActivities = enabled; 10108 } 10109 } 10110 10111 @Override 10112 public void setActivityController(IActivityController controller) { 10113 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10114 "setActivityController()"); 10115 synchronized (this) { 10116 mController = controller; 10117 Watchdog.getInstance().setActivityController(controller); 10118 } 10119 } 10120 10121 @Override 10122 public void setUserIsMonkey(boolean userIsMonkey) { 10123 synchronized (this) { 10124 synchronized (mPidsSelfLocked) { 10125 final int callingPid = Binder.getCallingPid(); 10126 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10127 if (precessRecord == null) { 10128 throw new SecurityException("Unknown process: " + callingPid); 10129 } 10130 if (precessRecord.instrumentationUiAutomationConnection == null) { 10131 throw new SecurityException("Only an instrumentation process " 10132 + "with a UiAutomation can call setUserIsMonkey"); 10133 } 10134 } 10135 mUserIsMonkey = userIsMonkey; 10136 } 10137 } 10138 10139 @Override 10140 public boolean isUserAMonkey() { 10141 synchronized (this) { 10142 // If there is a controller also implies the user is a monkey. 10143 return (mUserIsMonkey || mController != null); 10144 } 10145 } 10146 10147 public void requestBugReport() { 10148 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10149 SystemProperties.set("ctl.start", "bugreport"); 10150 } 10151 10152 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10153 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10154 } 10155 10156 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10157 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10158 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10159 } 10160 return KEY_DISPATCHING_TIMEOUT; 10161 } 10162 10163 @Override 10164 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10165 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10166 != PackageManager.PERMISSION_GRANTED) { 10167 throw new SecurityException("Requires permission " 10168 + android.Manifest.permission.FILTER_EVENTS); 10169 } 10170 ProcessRecord proc; 10171 long timeout; 10172 synchronized (this) { 10173 synchronized (mPidsSelfLocked) { 10174 proc = mPidsSelfLocked.get(pid); 10175 } 10176 timeout = getInputDispatchingTimeoutLocked(proc); 10177 } 10178 10179 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10180 return -1; 10181 } 10182 10183 return timeout; 10184 } 10185 10186 /** 10187 * Handle input dispatching timeouts. 10188 * Returns whether input dispatching should be aborted or not. 10189 */ 10190 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10191 final ActivityRecord activity, final ActivityRecord parent, 10192 final boolean aboveSystem, String reason) { 10193 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10194 != PackageManager.PERMISSION_GRANTED) { 10195 throw new SecurityException("Requires permission " 10196 + android.Manifest.permission.FILTER_EVENTS); 10197 } 10198 10199 final String annotation; 10200 if (reason == null) { 10201 annotation = "Input dispatching timed out"; 10202 } else { 10203 annotation = "Input dispatching timed out (" + reason + ")"; 10204 } 10205 10206 if (proc != null) { 10207 synchronized (this) { 10208 if (proc.debugging) { 10209 return false; 10210 } 10211 10212 if (mDidDexOpt) { 10213 // Give more time since we were dexopting. 10214 mDidDexOpt = false; 10215 return false; 10216 } 10217 10218 if (proc.instrumentationClass != null) { 10219 Bundle info = new Bundle(); 10220 info.putString("shortMsg", "keyDispatchingTimedOut"); 10221 info.putString("longMsg", annotation); 10222 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10223 return true; 10224 } 10225 } 10226 mHandler.post(new Runnable() { 10227 @Override 10228 public void run() { 10229 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10230 } 10231 }); 10232 } 10233 10234 return true; 10235 } 10236 10237 public Bundle getAssistContextExtras(int requestType) { 10238 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10239 "getAssistContextExtras()"); 10240 PendingAssistExtras pae; 10241 Bundle extras = new Bundle(); 10242 synchronized (this) { 10243 ActivityRecord activity = getFocusedStack().mResumedActivity; 10244 if (activity == null) { 10245 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10246 return null; 10247 } 10248 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10249 if (activity.app == null || activity.app.thread == null) { 10250 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10251 return extras; 10252 } 10253 if (activity.app.pid == Binder.getCallingPid()) { 10254 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10255 return extras; 10256 } 10257 pae = new PendingAssistExtras(activity); 10258 try { 10259 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10260 requestType); 10261 mPendingAssistExtras.add(pae); 10262 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10263 } catch (RemoteException e) { 10264 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10265 return extras; 10266 } 10267 } 10268 synchronized (pae) { 10269 while (!pae.haveResult) { 10270 try { 10271 pae.wait(); 10272 } catch (InterruptedException e) { 10273 } 10274 } 10275 if (pae.result != null) { 10276 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10277 } 10278 } 10279 synchronized (this) { 10280 mPendingAssistExtras.remove(pae); 10281 mHandler.removeCallbacks(pae); 10282 } 10283 return extras; 10284 } 10285 10286 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10287 PendingAssistExtras pae = (PendingAssistExtras)token; 10288 synchronized (pae) { 10289 pae.result = extras; 10290 pae.haveResult = true; 10291 pae.notifyAll(); 10292 } 10293 } 10294 10295 public void registerProcessObserver(IProcessObserver observer) { 10296 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10297 "registerProcessObserver()"); 10298 synchronized (this) { 10299 mProcessObservers.register(observer); 10300 } 10301 } 10302 10303 @Override 10304 public void unregisterProcessObserver(IProcessObserver observer) { 10305 synchronized (this) { 10306 mProcessObservers.unregister(observer); 10307 } 10308 } 10309 10310 @Override 10311 public boolean convertFromTranslucent(IBinder token) { 10312 final long origId = Binder.clearCallingIdentity(); 10313 try { 10314 synchronized (this) { 10315 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10316 if (r == null) { 10317 return false; 10318 } 10319 final boolean translucentChanged = r.changeWindowTranslucency(true); 10320 if (translucentChanged) { 10321 r.task.stack.releaseBackgroundResources(); 10322 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10323 } 10324 mWindowManager.setAppFullscreen(token, true); 10325 return translucentChanged; 10326 } 10327 } finally { 10328 Binder.restoreCallingIdentity(origId); 10329 } 10330 } 10331 10332 @Override 10333 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10334 final long origId = Binder.clearCallingIdentity(); 10335 try { 10336 synchronized (this) { 10337 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10338 if (r == null) { 10339 return false; 10340 } 10341 int index = r.task.mActivities.lastIndexOf(r); 10342 if (index > 0) { 10343 ActivityRecord under = r.task.mActivities.get(index - 1); 10344 under.returningOptions = options; 10345 } 10346 final boolean translucentChanged = r.changeWindowTranslucency(false); 10347 if (translucentChanged) { 10348 r.task.stack.convertToTranslucent(r); 10349 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10350 } 10351 mWindowManager.setAppFullscreen(token, false); 10352 return translucentChanged; 10353 } 10354 } finally { 10355 Binder.restoreCallingIdentity(origId); 10356 } 10357 } 10358 10359 @Override 10360 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10361 final long origId = Binder.clearCallingIdentity(); 10362 try { 10363 synchronized (this) { 10364 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10365 if (r != null) { 10366 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10367 } 10368 } 10369 return false; 10370 } finally { 10371 Binder.restoreCallingIdentity(origId); 10372 } 10373 } 10374 10375 @Override 10376 public boolean isBackgroundVisibleBehind(IBinder token) { 10377 final long origId = Binder.clearCallingIdentity(); 10378 try { 10379 synchronized (this) { 10380 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10381 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10382 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10383 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10384 return visible; 10385 } 10386 } finally { 10387 Binder.restoreCallingIdentity(origId); 10388 } 10389 } 10390 10391 @Override 10392 public ActivityOptions getActivityOptions(IBinder token) { 10393 final long origId = Binder.clearCallingIdentity(); 10394 try { 10395 synchronized (this) { 10396 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10397 if (r != null) { 10398 final ActivityOptions activityOptions = r.pendingOptions; 10399 r.pendingOptions = null; 10400 return activityOptions; 10401 } 10402 return null; 10403 } 10404 } finally { 10405 Binder.restoreCallingIdentity(origId); 10406 } 10407 } 10408 10409 @Override 10410 public void setImmersive(IBinder token, boolean immersive) { 10411 synchronized(this) { 10412 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10413 if (r == null) { 10414 throw new IllegalArgumentException(); 10415 } 10416 r.immersive = immersive; 10417 10418 // update associated state if we're frontmost 10419 if (r == mFocusedActivity) { 10420 if (DEBUG_IMMERSIVE) { 10421 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10422 } 10423 applyUpdateLockStateLocked(r); 10424 } 10425 } 10426 } 10427 10428 @Override 10429 public boolean isImmersive(IBinder token) { 10430 synchronized (this) { 10431 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10432 if (r == null) { 10433 throw new IllegalArgumentException(); 10434 } 10435 return r.immersive; 10436 } 10437 } 10438 10439 public boolean isTopActivityImmersive() { 10440 enforceNotIsolatedCaller("startActivity"); 10441 synchronized (this) { 10442 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10443 return (r != null) ? r.immersive : false; 10444 } 10445 } 10446 10447 @Override 10448 public boolean isTopOfTask(IBinder token) { 10449 synchronized (this) { 10450 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10451 if (r == null) { 10452 throw new IllegalArgumentException(); 10453 } 10454 return r.task.getTopActivity() == r; 10455 } 10456 } 10457 10458 public final void enterSafeMode() { 10459 synchronized(this) { 10460 // It only makes sense to do this before the system is ready 10461 // and started launching other packages. 10462 if (!mSystemReady) { 10463 try { 10464 AppGlobals.getPackageManager().enterSafeMode(); 10465 } catch (RemoteException e) { 10466 } 10467 } 10468 10469 mSafeMode = true; 10470 } 10471 } 10472 10473 public final void showSafeModeOverlay() { 10474 View v = LayoutInflater.from(mContext).inflate( 10475 com.android.internal.R.layout.safe_mode, null); 10476 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10477 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10478 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10479 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10480 lp.gravity = Gravity.BOTTOM | Gravity.START; 10481 lp.format = v.getBackground().getOpacity(); 10482 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10483 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10484 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10485 ((WindowManager)mContext.getSystemService( 10486 Context.WINDOW_SERVICE)).addView(v, lp); 10487 } 10488 10489 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10490 if (!(sender instanceof PendingIntentRecord)) { 10491 return; 10492 } 10493 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10494 synchronized (stats) { 10495 if (mBatteryStatsService.isOnBattery()) { 10496 mBatteryStatsService.enforceCallingPermission(); 10497 PendingIntentRecord rec = (PendingIntentRecord)sender; 10498 int MY_UID = Binder.getCallingUid(); 10499 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10500 BatteryStatsImpl.Uid.Pkg pkg = 10501 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10502 sourcePkg != null ? sourcePkg : rec.key.packageName); 10503 pkg.incWakeupsLocked(); 10504 } 10505 } 10506 } 10507 10508 public boolean killPids(int[] pids, String pReason, boolean secure) { 10509 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10510 throw new SecurityException("killPids only available to the system"); 10511 } 10512 String reason = (pReason == null) ? "Unknown" : pReason; 10513 // XXX Note: don't acquire main activity lock here, because the window 10514 // manager calls in with its locks held. 10515 10516 boolean killed = false; 10517 synchronized (mPidsSelfLocked) { 10518 int[] types = new int[pids.length]; 10519 int worstType = 0; 10520 for (int i=0; i<pids.length; i++) { 10521 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10522 if (proc != null) { 10523 int type = proc.setAdj; 10524 types[i] = type; 10525 if (type > worstType) { 10526 worstType = type; 10527 } 10528 } 10529 } 10530 10531 // If the worst oom_adj is somewhere in the cached proc LRU range, 10532 // then constrain it so we will kill all cached procs. 10533 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10534 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10535 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10536 } 10537 10538 // If this is not a secure call, don't let it kill processes that 10539 // are important. 10540 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10541 worstType = ProcessList.SERVICE_ADJ; 10542 } 10543 10544 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10545 for (int i=0; i<pids.length; i++) { 10546 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10547 if (proc == null) { 10548 continue; 10549 } 10550 int adj = proc.setAdj; 10551 if (adj >= worstType && !proc.killedByAm) { 10552 proc.kill(reason, true); 10553 killed = true; 10554 } 10555 } 10556 } 10557 return killed; 10558 } 10559 10560 @Override 10561 public void killUid(int uid, String reason) { 10562 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10563 throw new SecurityException("killUid only available to the system"); 10564 } 10565 synchronized (this) { 10566 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10567 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10568 reason != null ? reason : "kill uid"); 10569 } 10570 } 10571 10572 @Override 10573 public boolean killProcessesBelowForeground(String reason) { 10574 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10575 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10576 } 10577 10578 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10579 } 10580 10581 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10582 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10583 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10584 } 10585 10586 boolean killed = false; 10587 synchronized (mPidsSelfLocked) { 10588 final int size = mPidsSelfLocked.size(); 10589 for (int i = 0; i < size; i++) { 10590 final int pid = mPidsSelfLocked.keyAt(i); 10591 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10592 if (proc == null) continue; 10593 10594 final int adj = proc.setAdj; 10595 if (adj > belowAdj && !proc.killedByAm) { 10596 proc.kill(reason, true); 10597 killed = true; 10598 } 10599 } 10600 } 10601 return killed; 10602 } 10603 10604 @Override 10605 public void hang(final IBinder who, boolean allowRestart) { 10606 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10607 != PackageManager.PERMISSION_GRANTED) { 10608 throw new SecurityException("Requires permission " 10609 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10610 } 10611 10612 final IBinder.DeathRecipient death = new DeathRecipient() { 10613 @Override 10614 public void binderDied() { 10615 synchronized (this) { 10616 notifyAll(); 10617 } 10618 } 10619 }; 10620 10621 try { 10622 who.linkToDeath(death, 0); 10623 } catch (RemoteException e) { 10624 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10625 return; 10626 } 10627 10628 synchronized (this) { 10629 Watchdog.getInstance().setAllowRestart(allowRestart); 10630 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10631 synchronized (death) { 10632 while (who.isBinderAlive()) { 10633 try { 10634 death.wait(); 10635 } catch (InterruptedException e) { 10636 } 10637 } 10638 } 10639 Watchdog.getInstance().setAllowRestart(true); 10640 } 10641 } 10642 10643 @Override 10644 public void restart() { 10645 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10646 != PackageManager.PERMISSION_GRANTED) { 10647 throw new SecurityException("Requires permission " 10648 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10649 } 10650 10651 Log.i(TAG, "Sending shutdown broadcast..."); 10652 10653 BroadcastReceiver br = new BroadcastReceiver() { 10654 @Override public void onReceive(Context context, Intent intent) { 10655 // Now the broadcast is done, finish up the low-level shutdown. 10656 Log.i(TAG, "Shutting down activity manager..."); 10657 shutdown(10000); 10658 Log.i(TAG, "Shutdown complete, restarting!"); 10659 Process.killProcess(Process.myPid()); 10660 System.exit(10); 10661 } 10662 }; 10663 10664 // First send the high-level shut down broadcast. 10665 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10666 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10667 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10668 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10669 mContext.sendOrderedBroadcastAsUser(intent, 10670 UserHandle.ALL, null, br, mHandler, 0, null, null); 10671 */ 10672 br.onReceive(mContext, intent); 10673 } 10674 10675 private long getLowRamTimeSinceIdle(long now) { 10676 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10677 } 10678 10679 @Override 10680 public void performIdleMaintenance() { 10681 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10682 != PackageManager.PERMISSION_GRANTED) { 10683 throw new SecurityException("Requires permission " 10684 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10685 } 10686 10687 synchronized (this) { 10688 final long now = SystemClock.uptimeMillis(); 10689 final long timeSinceLastIdle = now - mLastIdleTime; 10690 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10691 mLastIdleTime = now; 10692 mLowRamTimeSinceLastIdle = 0; 10693 if (mLowRamStartTime != 0) { 10694 mLowRamStartTime = now; 10695 } 10696 10697 StringBuilder sb = new StringBuilder(128); 10698 sb.append("Idle maintenance over "); 10699 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10700 sb.append(" low RAM for "); 10701 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10702 Slog.i(TAG, sb.toString()); 10703 10704 // If at least 1/3 of our time since the last idle period has been spent 10705 // with RAM low, then we want to kill processes. 10706 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10707 10708 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10709 ProcessRecord proc = mLruProcesses.get(i); 10710 if (proc.notCachedSinceIdle) { 10711 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10712 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10713 if (doKilling && proc.initialIdlePss != 0 10714 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10715 proc.kill("idle maint (pss " + proc.lastPss 10716 + " from " + proc.initialIdlePss + ")", true); 10717 } 10718 } 10719 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10720 proc.notCachedSinceIdle = true; 10721 proc.initialIdlePss = 0; 10722 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10723 isSleeping(), now); 10724 } 10725 } 10726 10727 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10728 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10729 } 10730 } 10731 10732 private void retrieveSettings() { 10733 final ContentResolver resolver = mContext.getContentResolver(); 10734 String debugApp = Settings.Global.getString( 10735 resolver, Settings.Global.DEBUG_APP); 10736 boolean waitForDebugger = Settings.Global.getInt( 10737 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10738 boolean alwaysFinishActivities = Settings.Global.getInt( 10739 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10740 boolean forceRtl = Settings.Global.getInt( 10741 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10742 // Transfer any global setting for forcing RTL layout, into a System Property 10743 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10744 10745 Configuration configuration = new Configuration(); 10746 Settings.System.getConfiguration(resolver, configuration); 10747 if (forceRtl) { 10748 // This will take care of setting the correct layout direction flags 10749 configuration.setLayoutDirection(configuration.locale); 10750 } 10751 10752 synchronized (this) { 10753 mDebugApp = mOrigDebugApp = debugApp; 10754 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10755 mAlwaysFinishActivities = alwaysFinishActivities; 10756 // This happens before any activities are started, so we can 10757 // change mConfiguration in-place. 10758 updateConfigurationLocked(configuration, null, false, true); 10759 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10760 } 10761 } 10762 10763 /** Loads resources after the current configuration has been set. */ 10764 private void loadResourcesOnSystemReady() { 10765 final Resources res = mContext.getResources(); 10766 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 10767 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 10768 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 10769 } 10770 10771 public boolean testIsSystemReady() { 10772 // no need to synchronize(this) just to read & return the value 10773 return mSystemReady; 10774 } 10775 10776 private static File getCalledPreBootReceiversFile() { 10777 File dataDir = Environment.getDataDirectory(); 10778 File systemDir = new File(dataDir, "system"); 10779 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10780 return fname; 10781 } 10782 10783 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10784 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10785 File file = getCalledPreBootReceiversFile(); 10786 FileInputStream fis = null; 10787 try { 10788 fis = new FileInputStream(file); 10789 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10790 int fvers = dis.readInt(); 10791 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10792 String vers = dis.readUTF(); 10793 String codename = dis.readUTF(); 10794 String build = dis.readUTF(); 10795 if (android.os.Build.VERSION.RELEASE.equals(vers) 10796 && android.os.Build.VERSION.CODENAME.equals(codename) 10797 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10798 int num = dis.readInt(); 10799 while (num > 0) { 10800 num--; 10801 String pkg = dis.readUTF(); 10802 String cls = dis.readUTF(); 10803 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10804 } 10805 } 10806 } 10807 } catch (FileNotFoundException e) { 10808 } catch (IOException e) { 10809 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10810 } finally { 10811 if (fis != null) { 10812 try { 10813 fis.close(); 10814 } catch (IOException e) { 10815 } 10816 } 10817 } 10818 return lastDoneReceivers; 10819 } 10820 10821 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10822 File file = getCalledPreBootReceiversFile(); 10823 FileOutputStream fos = null; 10824 DataOutputStream dos = null; 10825 try { 10826 fos = new FileOutputStream(file); 10827 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10828 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10829 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10830 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10831 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10832 dos.writeInt(list.size()); 10833 for (int i=0; i<list.size(); i++) { 10834 dos.writeUTF(list.get(i).getPackageName()); 10835 dos.writeUTF(list.get(i).getClassName()); 10836 } 10837 } catch (IOException e) { 10838 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10839 file.delete(); 10840 } finally { 10841 FileUtils.sync(fos); 10842 if (dos != null) { 10843 try { 10844 dos.close(); 10845 } catch (IOException e) { 10846 // TODO Auto-generated catch block 10847 e.printStackTrace(); 10848 } 10849 } 10850 } 10851 } 10852 10853 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10854 ArrayList<ComponentName> doneReceivers, int userId) { 10855 boolean waitingUpdate = false; 10856 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10857 List<ResolveInfo> ris = null; 10858 try { 10859 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10860 intent, null, 0, userId); 10861 } catch (RemoteException e) { 10862 } 10863 if (ris != null) { 10864 for (int i=ris.size()-1; i>=0; i--) { 10865 if ((ris.get(i).activityInfo.applicationInfo.flags 10866 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10867 ris.remove(i); 10868 } 10869 } 10870 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10871 10872 // For User 0, load the version number. When delivering to a new user, deliver 10873 // to all receivers. 10874 if (userId == UserHandle.USER_OWNER) { 10875 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 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 if (lastDoneReceivers.contains(comp)) { 10880 // We already did the pre boot receiver for this app with the current 10881 // platform version, so don't do it again... 10882 ris.remove(i); 10883 i--; 10884 // ...however, do keep it as one that has been done, so we don't 10885 // forget about it when rewriting the file of last done receivers. 10886 doneReceivers.add(comp); 10887 } 10888 } 10889 } 10890 10891 // If primary user, send broadcast to all available users, else just to userId 10892 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10893 : new int[] { userId }; 10894 for (int i = 0; i < ris.size(); i++) { 10895 ActivityInfo ai = ris.get(i).activityInfo; 10896 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10897 doneReceivers.add(comp); 10898 intent.setComponent(comp); 10899 for (int j=0; j<users.length; j++) { 10900 IIntentReceiver finisher = null; 10901 // On last receiver and user, set up a completion callback 10902 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10903 finisher = new IIntentReceiver.Stub() { 10904 public void performReceive(Intent intent, int resultCode, 10905 String data, Bundle extras, boolean ordered, 10906 boolean sticky, int sendingUser) { 10907 // The raw IIntentReceiver interface is called 10908 // with the AM lock held, so redispatch to 10909 // execute our code without the lock. 10910 mHandler.post(onFinishCallback); 10911 } 10912 }; 10913 } 10914 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10915 + " for user " + users[j]); 10916 broadcastIntentLocked(null, null, intent, null, finisher, 10917 0, null, null, null, AppOpsManager.OP_NONE, 10918 true, false, MY_PID, Process.SYSTEM_UID, 10919 users[j]); 10920 if (finisher != null) { 10921 waitingUpdate = true; 10922 } 10923 } 10924 } 10925 } 10926 10927 return waitingUpdate; 10928 } 10929 10930 public void systemReady(final Runnable goingCallback) { 10931 synchronized(this) { 10932 if (mSystemReady) { 10933 // If we're done calling all the receivers, run the next "boot phase" passed in 10934 // by the SystemServer 10935 if (goingCallback != null) { 10936 goingCallback.run(); 10937 } 10938 return; 10939 } 10940 10941 // Make sure we have the current profile info, since it is needed for 10942 // security checks. 10943 updateCurrentProfileIdsLocked(); 10944 10945 if (mRecentTasks == null) { 10946 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10947 if (!mRecentTasks.isEmpty()) { 10948 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10949 } 10950 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10951 mTaskPersister.startPersisting(); 10952 } 10953 10954 // Check to see if there are any update receivers to run. 10955 if (!mDidUpdate) { 10956 if (mWaitingUpdate) { 10957 return; 10958 } 10959 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10960 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10961 public void run() { 10962 synchronized (ActivityManagerService.this) { 10963 mDidUpdate = true; 10964 } 10965 writeLastDonePreBootReceivers(doneReceivers); 10966 showBootMessage(mContext.getText( 10967 R.string.android_upgrading_complete), 10968 false); 10969 systemReady(goingCallback); 10970 } 10971 }, doneReceivers, UserHandle.USER_OWNER); 10972 10973 if (mWaitingUpdate) { 10974 return; 10975 } 10976 mDidUpdate = true; 10977 } 10978 10979 mAppOpsService.systemReady(); 10980 mSystemReady = true; 10981 } 10982 10983 ArrayList<ProcessRecord> procsToKill = null; 10984 synchronized(mPidsSelfLocked) { 10985 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10986 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10987 if (!isAllowedWhileBooting(proc.info)){ 10988 if (procsToKill == null) { 10989 procsToKill = new ArrayList<ProcessRecord>(); 10990 } 10991 procsToKill.add(proc); 10992 } 10993 } 10994 } 10995 10996 synchronized(this) { 10997 if (procsToKill != null) { 10998 for (int i=procsToKill.size()-1; i>=0; i--) { 10999 ProcessRecord proc = procsToKill.get(i); 11000 Slog.i(TAG, "Removing system update proc: " + proc); 11001 removeProcessLocked(proc, true, false, "system update done"); 11002 } 11003 } 11004 11005 // Now that we have cleaned up any update processes, we 11006 // are ready to start launching real processes and know that 11007 // we won't trample on them any more. 11008 mProcessesReady = true; 11009 } 11010 11011 Slog.i(TAG, "System now ready"); 11012 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 11013 SystemClock.uptimeMillis()); 11014 11015 synchronized(this) { 11016 // Make sure we have no pre-ready processes sitting around. 11017 11018 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11019 ResolveInfo ri = mContext.getPackageManager() 11020 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 11021 STOCK_PM_FLAGS); 11022 CharSequence errorMsg = null; 11023 if (ri != null) { 11024 ActivityInfo ai = ri.activityInfo; 11025 ApplicationInfo app = ai.applicationInfo; 11026 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 11027 mTopAction = Intent.ACTION_FACTORY_TEST; 11028 mTopData = null; 11029 mTopComponent = new ComponentName(app.packageName, 11030 ai.name); 11031 } else { 11032 errorMsg = mContext.getResources().getText( 11033 com.android.internal.R.string.factorytest_not_system); 11034 } 11035 } else { 11036 errorMsg = mContext.getResources().getText( 11037 com.android.internal.R.string.factorytest_no_action); 11038 } 11039 if (errorMsg != null) { 11040 mTopAction = null; 11041 mTopData = null; 11042 mTopComponent = null; 11043 Message msg = Message.obtain(); 11044 msg.what = SHOW_FACTORY_ERROR_MSG; 11045 msg.getData().putCharSequence("msg", errorMsg); 11046 mHandler.sendMessage(msg); 11047 } 11048 } 11049 } 11050 11051 retrieveSettings(); 11052 loadResourcesOnSystemReady(); 11053 11054 synchronized (this) { 11055 readGrantedUriPermissionsLocked(); 11056 } 11057 11058 if (goingCallback != null) goingCallback.run(); 11059 11060 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 11061 Integer.toString(mCurrentUserId), mCurrentUserId); 11062 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 11063 Integer.toString(mCurrentUserId), mCurrentUserId); 11064 mSystemServiceManager.startUser(mCurrentUserId); 11065 11066 synchronized (this) { 11067 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 11068 try { 11069 List apps = AppGlobals.getPackageManager(). 11070 getPersistentApplications(STOCK_PM_FLAGS); 11071 if (apps != null) { 11072 int N = apps.size(); 11073 int i; 11074 for (i=0; i<N; i++) { 11075 ApplicationInfo info 11076 = (ApplicationInfo)apps.get(i); 11077 if (info != null && 11078 !info.packageName.equals("android")) { 11079 addAppLocked(info, false, null /* ABI override */); 11080 } 11081 } 11082 } 11083 } catch (RemoteException ex) { 11084 // pm is in same process, this will never happen. 11085 } 11086 } 11087 11088 // Start up initial activity. 11089 mBooting = true; 11090 11091 try { 11092 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11093 Message msg = Message.obtain(); 11094 msg.what = SHOW_UID_ERROR_MSG; 11095 mHandler.sendMessage(msg); 11096 } 11097 } catch (RemoteException e) { 11098 } 11099 11100 long ident = Binder.clearCallingIdentity(); 11101 try { 11102 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11103 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11104 | Intent.FLAG_RECEIVER_FOREGROUND); 11105 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11106 broadcastIntentLocked(null, null, intent, 11107 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11108 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11109 intent = new Intent(Intent.ACTION_USER_STARTING); 11110 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11111 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11112 broadcastIntentLocked(null, null, intent, 11113 null, new IIntentReceiver.Stub() { 11114 @Override 11115 public void performReceive(Intent intent, int resultCode, String data, 11116 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11117 throws RemoteException { 11118 } 11119 }, 0, null, null, 11120 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11121 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11122 } catch (Throwable t) { 11123 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11124 } finally { 11125 Binder.restoreCallingIdentity(ident); 11126 } 11127 mStackSupervisor.resumeTopActivitiesLocked(); 11128 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11129 } 11130 } 11131 11132 private boolean makeAppCrashingLocked(ProcessRecord app, 11133 String shortMsg, String longMsg, String stackTrace) { 11134 app.crashing = true; 11135 app.crashingReport = generateProcessError(app, 11136 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11137 startAppProblemLocked(app); 11138 app.stopFreezingAllLocked(); 11139 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11140 } 11141 11142 private void makeAppNotRespondingLocked(ProcessRecord app, 11143 String activity, String shortMsg, String longMsg) { 11144 app.notResponding = true; 11145 app.notRespondingReport = generateProcessError(app, 11146 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11147 activity, shortMsg, longMsg, null); 11148 startAppProblemLocked(app); 11149 app.stopFreezingAllLocked(); 11150 } 11151 11152 /** 11153 * Generate a process error record, suitable for attachment to a ProcessRecord. 11154 * 11155 * @param app The ProcessRecord in which the error occurred. 11156 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11157 * ActivityManager.AppErrorStateInfo 11158 * @param activity The activity associated with the crash, if known. 11159 * @param shortMsg Short message describing the crash. 11160 * @param longMsg Long message describing the crash. 11161 * @param stackTrace Full crash stack trace, may be null. 11162 * 11163 * @return Returns a fully-formed AppErrorStateInfo record. 11164 */ 11165 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11166 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11167 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11168 11169 report.condition = condition; 11170 report.processName = app.processName; 11171 report.pid = app.pid; 11172 report.uid = app.info.uid; 11173 report.tag = activity; 11174 report.shortMsg = shortMsg; 11175 report.longMsg = longMsg; 11176 report.stackTrace = stackTrace; 11177 11178 return report; 11179 } 11180 11181 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11182 synchronized (this) { 11183 app.crashing = false; 11184 app.crashingReport = null; 11185 app.notResponding = false; 11186 app.notRespondingReport = null; 11187 if (app.anrDialog == fromDialog) { 11188 app.anrDialog = null; 11189 } 11190 if (app.waitDialog == fromDialog) { 11191 app.waitDialog = null; 11192 } 11193 if (app.pid > 0 && app.pid != MY_PID) { 11194 handleAppCrashLocked(app, null, null, null); 11195 app.kill("user request after error", true); 11196 } 11197 } 11198 } 11199 11200 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11201 String stackTrace) { 11202 long now = SystemClock.uptimeMillis(); 11203 11204 Long crashTime; 11205 if (!app.isolated) { 11206 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11207 } else { 11208 crashTime = null; 11209 } 11210 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11211 // This process loses! 11212 Slog.w(TAG, "Process " + app.info.processName 11213 + " has crashed too many times: killing!"); 11214 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11215 app.userId, app.info.processName, app.uid); 11216 mStackSupervisor.handleAppCrashLocked(app); 11217 if (!app.persistent) { 11218 // We don't want to start this process again until the user 11219 // explicitly does so... but for persistent process, we really 11220 // need to keep it running. If a persistent process is actually 11221 // repeatedly crashing, then badness for everyone. 11222 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11223 app.info.processName); 11224 if (!app.isolated) { 11225 // XXX We don't have a way to mark isolated processes 11226 // as bad, since they don't have a peristent identity. 11227 mBadProcesses.put(app.info.processName, app.uid, 11228 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11229 mProcessCrashTimes.remove(app.info.processName, app.uid); 11230 } 11231 app.bad = true; 11232 app.removed = true; 11233 // Don't let services in this process be restarted and potentially 11234 // annoy the user repeatedly. Unless it is persistent, since those 11235 // processes run critical code. 11236 removeProcessLocked(app, false, false, "crash"); 11237 mStackSupervisor.resumeTopActivitiesLocked(); 11238 return false; 11239 } 11240 mStackSupervisor.resumeTopActivitiesLocked(); 11241 } else { 11242 mStackSupervisor.finishTopRunningActivityLocked(app); 11243 } 11244 11245 // Bump up the crash count of any services currently running in the proc. 11246 for (int i=app.services.size()-1; i>=0; i--) { 11247 // Any services running in the application need to be placed 11248 // back in the pending list. 11249 ServiceRecord sr = app.services.valueAt(i); 11250 sr.crashCount++; 11251 } 11252 11253 // If the crashing process is what we consider to be the "home process" and it has been 11254 // replaced by a third-party app, clear the package preferred activities from packages 11255 // with a home activity running in the process to prevent a repeatedly crashing app 11256 // from blocking the user to manually clear the list. 11257 final ArrayList<ActivityRecord> activities = app.activities; 11258 if (app == mHomeProcess && activities.size() > 0 11259 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11260 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11261 final ActivityRecord r = activities.get(activityNdx); 11262 if (r.isHomeActivity()) { 11263 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11264 try { 11265 ActivityThread.getPackageManager() 11266 .clearPackagePreferredActivities(r.packageName); 11267 } catch (RemoteException c) { 11268 // pm is in same process, this will never happen. 11269 } 11270 } 11271 } 11272 } 11273 11274 if (!app.isolated) { 11275 // XXX Can't keep track of crash times for isolated processes, 11276 // because they don't have a perisistent identity. 11277 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11278 } 11279 11280 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11281 return true; 11282 } 11283 11284 void startAppProblemLocked(ProcessRecord app) { 11285 // If this app is not running under the current user, then we 11286 // can't give it a report button because that would require 11287 // launching the report UI under a different user. 11288 app.errorReportReceiver = null; 11289 11290 for (int userId : mCurrentProfileIds) { 11291 if (app.userId == userId) { 11292 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11293 mContext, app.info.packageName, app.info.flags); 11294 } 11295 } 11296 skipCurrentReceiverLocked(app); 11297 } 11298 11299 void skipCurrentReceiverLocked(ProcessRecord app) { 11300 for (BroadcastQueue queue : mBroadcastQueues) { 11301 queue.skipCurrentReceiverLocked(app); 11302 } 11303 } 11304 11305 /** 11306 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11307 * The application process will exit immediately after this call returns. 11308 * @param app object of the crashing app, null for the system server 11309 * @param crashInfo describing the exception 11310 */ 11311 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11312 ProcessRecord r = findAppProcess(app, "Crash"); 11313 final String processName = app == null ? "system_server" 11314 : (r == null ? "unknown" : r.processName); 11315 11316 handleApplicationCrashInner("crash", r, processName, crashInfo); 11317 } 11318 11319 /* Native crash reporting uses this inner version because it needs to be somewhat 11320 * decoupled from the AM-managed cleanup lifecycle 11321 */ 11322 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11323 ApplicationErrorReport.CrashInfo crashInfo) { 11324 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11325 UserHandle.getUserId(Binder.getCallingUid()), processName, 11326 r == null ? -1 : r.info.flags, 11327 crashInfo.exceptionClassName, 11328 crashInfo.exceptionMessage, 11329 crashInfo.throwFileName, 11330 crashInfo.throwLineNumber); 11331 11332 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11333 11334 crashApplication(r, crashInfo); 11335 } 11336 11337 public void handleApplicationStrictModeViolation( 11338 IBinder app, 11339 int violationMask, 11340 StrictMode.ViolationInfo info) { 11341 ProcessRecord r = findAppProcess(app, "StrictMode"); 11342 if (r == null) { 11343 return; 11344 } 11345 11346 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11347 Integer stackFingerprint = info.hashCode(); 11348 boolean logIt = true; 11349 synchronized (mAlreadyLoggedViolatedStacks) { 11350 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11351 logIt = false; 11352 // TODO: sub-sample into EventLog for these, with 11353 // the info.durationMillis? Then we'd get 11354 // the relative pain numbers, without logging all 11355 // the stack traces repeatedly. We'd want to do 11356 // likewise in the client code, which also does 11357 // dup suppression, before the Binder call. 11358 } else { 11359 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11360 mAlreadyLoggedViolatedStacks.clear(); 11361 } 11362 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11363 } 11364 } 11365 if (logIt) { 11366 logStrictModeViolationToDropBox(r, info); 11367 } 11368 } 11369 11370 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11371 AppErrorResult result = new AppErrorResult(); 11372 synchronized (this) { 11373 final long origId = Binder.clearCallingIdentity(); 11374 11375 Message msg = Message.obtain(); 11376 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11377 HashMap<String, Object> data = new HashMap<String, Object>(); 11378 data.put("result", result); 11379 data.put("app", r); 11380 data.put("violationMask", violationMask); 11381 data.put("info", info); 11382 msg.obj = data; 11383 mHandler.sendMessage(msg); 11384 11385 Binder.restoreCallingIdentity(origId); 11386 } 11387 int res = result.get(); 11388 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11389 } 11390 } 11391 11392 // Depending on the policy in effect, there could be a bunch of 11393 // these in quick succession so we try to batch these together to 11394 // minimize disk writes, number of dropbox entries, and maximize 11395 // compression, by having more fewer, larger records. 11396 private void logStrictModeViolationToDropBox( 11397 ProcessRecord process, 11398 StrictMode.ViolationInfo info) { 11399 if (info == null) { 11400 return; 11401 } 11402 final boolean isSystemApp = process == null || 11403 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11404 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11405 final String processName = process == null ? "unknown" : process.processName; 11406 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11407 final DropBoxManager dbox = (DropBoxManager) 11408 mContext.getSystemService(Context.DROPBOX_SERVICE); 11409 11410 // Exit early if the dropbox isn't configured to accept this report type. 11411 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11412 11413 boolean bufferWasEmpty; 11414 boolean needsFlush; 11415 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11416 synchronized (sb) { 11417 bufferWasEmpty = sb.length() == 0; 11418 appendDropBoxProcessHeaders(process, processName, sb); 11419 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11420 sb.append("System-App: ").append(isSystemApp).append("\n"); 11421 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11422 if (info.violationNumThisLoop != 0) { 11423 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11424 } 11425 if (info.numAnimationsRunning != 0) { 11426 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11427 } 11428 if (info.broadcastIntentAction != null) { 11429 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11430 } 11431 if (info.durationMillis != -1) { 11432 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11433 } 11434 if (info.numInstances != -1) { 11435 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11436 } 11437 if (info.tags != null) { 11438 for (String tag : info.tags) { 11439 sb.append("Span-Tag: ").append(tag).append("\n"); 11440 } 11441 } 11442 sb.append("\n"); 11443 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11444 sb.append(info.crashInfo.stackTrace); 11445 } 11446 sb.append("\n"); 11447 11448 // Only buffer up to ~64k. Various logging bits truncate 11449 // things at 128k. 11450 needsFlush = (sb.length() > 64 * 1024); 11451 } 11452 11453 // Flush immediately if the buffer's grown too large, or this 11454 // is a non-system app. Non-system apps are isolated with a 11455 // different tag & policy and not batched. 11456 // 11457 // Batching is useful during internal testing with 11458 // StrictMode settings turned up high. Without batching, 11459 // thousands of separate files could be created on boot. 11460 if (!isSystemApp || needsFlush) { 11461 new Thread("Error dump: " + dropboxTag) { 11462 @Override 11463 public void run() { 11464 String report; 11465 synchronized (sb) { 11466 report = sb.toString(); 11467 sb.delete(0, sb.length()); 11468 sb.trimToSize(); 11469 } 11470 if (report.length() != 0) { 11471 dbox.addText(dropboxTag, report); 11472 } 11473 } 11474 }.start(); 11475 return; 11476 } 11477 11478 // System app batching: 11479 if (!bufferWasEmpty) { 11480 // An existing dropbox-writing thread is outstanding, so 11481 // we don't need to start it up. The existing thread will 11482 // catch the buffer appends we just did. 11483 return; 11484 } 11485 11486 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11487 // (After this point, we shouldn't access AMS internal data structures.) 11488 new Thread("Error dump: " + dropboxTag) { 11489 @Override 11490 public void run() { 11491 // 5 second sleep to let stacks arrive and be batched together 11492 try { 11493 Thread.sleep(5000); // 5 seconds 11494 } catch (InterruptedException e) {} 11495 11496 String errorReport; 11497 synchronized (mStrictModeBuffer) { 11498 errorReport = mStrictModeBuffer.toString(); 11499 if (errorReport.length() == 0) { 11500 return; 11501 } 11502 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11503 mStrictModeBuffer.trimToSize(); 11504 } 11505 dbox.addText(dropboxTag, errorReport); 11506 } 11507 }.start(); 11508 } 11509 11510 /** 11511 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11512 * @param app object of the crashing app, null for the system server 11513 * @param tag reported by the caller 11514 * @param system whether this wtf is coming from the system 11515 * @param crashInfo describing the context of the error 11516 * @return true if the process should exit immediately (WTF is fatal) 11517 */ 11518 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11519 final ApplicationErrorReport.CrashInfo crashInfo) { 11520 final ProcessRecord r = findAppProcess(app, "WTF"); 11521 final String processName = app == null ? "system_server" 11522 : (r == null ? "unknown" : r.processName); 11523 11524 EventLog.writeEvent(EventLogTags.AM_WTF, 11525 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11526 processName, 11527 r == null ? -1 : r.info.flags, 11528 tag, crashInfo.exceptionMessage); 11529 11530 if (system) { 11531 // If this is coming from the system, we could very well have low-level 11532 // system locks held, so we want to do this all asynchronously. And we 11533 // never want this to become fatal, so there is that too. 11534 mHandler.post(new Runnable() { 11535 @Override public void run() { 11536 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11537 crashInfo); 11538 } 11539 }); 11540 return false; 11541 } 11542 11543 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11544 11545 if (r != null && r.pid != Process.myPid() && 11546 Settings.Global.getInt(mContext.getContentResolver(), 11547 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11548 crashApplication(r, crashInfo); 11549 return true; 11550 } else { 11551 return false; 11552 } 11553 } 11554 11555 /** 11556 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11557 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11558 */ 11559 private ProcessRecord findAppProcess(IBinder app, String reason) { 11560 if (app == null) { 11561 return null; 11562 } 11563 11564 synchronized (this) { 11565 final int NP = mProcessNames.getMap().size(); 11566 for (int ip=0; ip<NP; ip++) { 11567 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11568 final int NA = apps.size(); 11569 for (int ia=0; ia<NA; ia++) { 11570 ProcessRecord p = apps.valueAt(ia); 11571 if (p.thread != null && p.thread.asBinder() == app) { 11572 return p; 11573 } 11574 } 11575 } 11576 11577 Slog.w(TAG, "Can't find mystery application for " + reason 11578 + " from pid=" + Binder.getCallingPid() 11579 + " uid=" + Binder.getCallingUid() + ": " + app); 11580 return null; 11581 } 11582 } 11583 11584 /** 11585 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11586 * to append various headers to the dropbox log text. 11587 */ 11588 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11589 StringBuilder sb) { 11590 // Watchdog thread ends up invoking this function (with 11591 // a null ProcessRecord) to add the stack file to dropbox. 11592 // Do not acquire a lock on this (am) in such cases, as it 11593 // could cause a potential deadlock, if and when watchdog 11594 // is invoked due to unavailability of lock on am and it 11595 // would prevent watchdog from killing system_server. 11596 if (process == null) { 11597 sb.append("Process: ").append(processName).append("\n"); 11598 return; 11599 } 11600 // Note: ProcessRecord 'process' is guarded by the service 11601 // instance. (notably process.pkgList, which could otherwise change 11602 // concurrently during execution of this method) 11603 synchronized (this) { 11604 sb.append("Process: ").append(processName).append("\n"); 11605 int flags = process.info.flags; 11606 IPackageManager pm = AppGlobals.getPackageManager(); 11607 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11608 for (int ip=0; ip<process.pkgList.size(); ip++) { 11609 String pkg = process.pkgList.keyAt(ip); 11610 sb.append("Package: ").append(pkg); 11611 try { 11612 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11613 if (pi != null) { 11614 sb.append(" v").append(pi.versionCode); 11615 if (pi.versionName != null) { 11616 sb.append(" (").append(pi.versionName).append(")"); 11617 } 11618 } 11619 } catch (RemoteException e) { 11620 Slog.e(TAG, "Error getting package info: " + pkg, e); 11621 } 11622 sb.append("\n"); 11623 } 11624 } 11625 } 11626 11627 private static String processClass(ProcessRecord process) { 11628 if (process == null || process.pid == MY_PID) { 11629 return "system_server"; 11630 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11631 return "system_app"; 11632 } else { 11633 return "data_app"; 11634 } 11635 } 11636 11637 /** 11638 * Write a description of an error (crash, WTF, ANR) to the drop box. 11639 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11640 * @param process which caused the error, null means the system server 11641 * @param activity which triggered the error, null if unknown 11642 * @param parent activity related to the error, null if unknown 11643 * @param subject line related to the error, null if absent 11644 * @param report in long form describing the error, null if absent 11645 * @param logFile to include in the report, null if none 11646 * @param crashInfo giving an application stack trace, null if absent 11647 */ 11648 public void addErrorToDropBox(String eventType, 11649 ProcessRecord process, String processName, ActivityRecord activity, 11650 ActivityRecord parent, String subject, 11651 final String report, final File logFile, 11652 final ApplicationErrorReport.CrashInfo crashInfo) { 11653 // NOTE -- this must never acquire the ActivityManagerService lock, 11654 // otherwise the watchdog may be prevented from resetting the system. 11655 11656 final String dropboxTag = processClass(process) + "_" + eventType; 11657 final DropBoxManager dbox = (DropBoxManager) 11658 mContext.getSystemService(Context.DROPBOX_SERVICE); 11659 11660 // Exit early if the dropbox isn't configured to accept this report type. 11661 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11662 11663 final StringBuilder sb = new StringBuilder(1024); 11664 appendDropBoxProcessHeaders(process, processName, sb); 11665 if (activity != null) { 11666 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11667 } 11668 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11669 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11670 } 11671 if (parent != null && parent != activity) { 11672 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11673 } 11674 if (subject != null) { 11675 sb.append("Subject: ").append(subject).append("\n"); 11676 } 11677 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11678 if (Debug.isDebuggerConnected()) { 11679 sb.append("Debugger: Connected\n"); 11680 } 11681 sb.append("\n"); 11682 11683 // Do the rest in a worker thread to avoid blocking the caller on I/O 11684 // (After this point, we shouldn't access AMS internal data structures.) 11685 Thread worker = new Thread("Error dump: " + dropboxTag) { 11686 @Override 11687 public void run() { 11688 if (report != null) { 11689 sb.append(report); 11690 } 11691 if (logFile != null) { 11692 try { 11693 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11694 "\n\n[[TRUNCATED]]")); 11695 } catch (IOException e) { 11696 Slog.e(TAG, "Error reading " + logFile, e); 11697 } 11698 } 11699 if (crashInfo != null && crashInfo.stackTrace != null) { 11700 sb.append(crashInfo.stackTrace); 11701 } 11702 11703 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11704 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11705 if (lines > 0) { 11706 sb.append("\n"); 11707 11708 // Merge several logcat streams, and take the last N lines 11709 InputStreamReader input = null; 11710 try { 11711 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11712 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11713 "-b", "crash", 11714 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11715 11716 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11717 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11718 input = new InputStreamReader(logcat.getInputStream()); 11719 11720 int num; 11721 char[] buf = new char[8192]; 11722 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11723 } catch (IOException e) { 11724 Slog.e(TAG, "Error running logcat", e); 11725 } finally { 11726 if (input != null) try { input.close(); } catch (IOException e) {} 11727 } 11728 } 11729 11730 dbox.addText(dropboxTag, sb.toString()); 11731 } 11732 }; 11733 11734 if (process == null) { 11735 // If process is null, we are being called from some internal code 11736 // and may be about to die -- run this synchronously. 11737 worker.run(); 11738 } else { 11739 worker.start(); 11740 } 11741 } 11742 11743 /** 11744 * Bring up the "unexpected error" dialog box for a crashing app. 11745 * Deal with edge cases (intercepts from instrumented applications, 11746 * ActivityController, error intent receivers, that sort of thing). 11747 * @param r the application crashing 11748 * @param crashInfo describing the failure 11749 */ 11750 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11751 long timeMillis = System.currentTimeMillis(); 11752 String shortMsg = crashInfo.exceptionClassName; 11753 String longMsg = crashInfo.exceptionMessage; 11754 String stackTrace = crashInfo.stackTrace; 11755 if (shortMsg != null && longMsg != null) { 11756 longMsg = shortMsg + ": " + longMsg; 11757 } else if (shortMsg != null) { 11758 longMsg = shortMsg; 11759 } 11760 11761 AppErrorResult result = new AppErrorResult(); 11762 synchronized (this) { 11763 if (mController != null) { 11764 try { 11765 String name = r != null ? r.processName : null; 11766 int pid = r != null ? r.pid : Binder.getCallingPid(); 11767 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11768 if (!mController.appCrashed(name, pid, 11769 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11770 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11771 && "Native crash".equals(crashInfo.exceptionClassName)) { 11772 Slog.w(TAG, "Skip killing native crashed app " + name 11773 + "(" + pid + ") during testing"); 11774 } else { 11775 Slog.w(TAG, "Force-killing crashed app " + name 11776 + " at watcher's request"); 11777 if (r != null) { 11778 r.kill("crash", true); 11779 } else { 11780 // Huh. 11781 Process.killProcess(pid); 11782 Process.killProcessGroup(uid, pid); 11783 } 11784 } 11785 return; 11786 } 11787 } catch (RemoteException e) { 11788 mController = null; 11789 Watchdog.getInstance().setActivityController(null); 11790 } 11791 } 11792 11793 final long origId = Binder.clearCallingIdentity(); 11794 11795 // If this process is running instrumentation, finish it. 11796 if (r != null && r.instrumentationClass != null) { 11797 Slog.w(TAG, "Error in app " + r.processName 11798 + " running instrumentation " + r.instrumentationClass + ":"); 11799 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11800 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11801 Bundle info = new Bundle(); 11802 info.putString("shortMsg", shortMsg); 11803 info.putString("longMsg", longMsg); 11804 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11805 Binder.restoreCallingIdentity(origId); 11806 return; 11807 } 11808 11809 // If we can't identify the process or it's already exceeded its crash quota, 11810 // quit right away without showing a crash dialog. 11811 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11812 Binder.restoreCallingIdentity(origId); 11813 return; 11814 } 11815 11816 Message msg = Message.obtain(); 11817 msg.what = SHOW_ERROR_MSG; 11818 HashMap data = new HashMap(); 11819 data.put("result", result); 11820 data.put("app", r); 11821 msg.obj = data; 11822 mHandler.sendMessage(msg); 11823 11824 Binder.restoreCallingIdentity(origId); 11825 } 11826 11827 int res = result.get(); 11828 11829 Intent appErrorIntent = null; 11830 synchronized (this) { 11831 if (r != null && !r.isolated) { 11832 // XXX Can't keep track of crash time for isolated processes, 11833 // since they don't have a persistent identity. 11834 mProcessCrashTimes.put(r.info.processName, r.uid, 11835 SystemClock.uptimeMillis()); 11836 } 11837 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11838 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11839 } 11840 } 11841 11842 if (appErrorIntent != null) { 11843 try { 11844 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11845 } catch (ActivityNotFoundException e) { 11846 Slog.w(TAG, "bug report receiver dissappeared", e); 11847 } 11848 } 11849 } 11850 11851 Intent createAppErrorIntentLocked(ProcessRecord r, 11852 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11853 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11854 if (report == null) { 11855 return null; 11856 } 11857 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11858 result.setComponent(r.errorReportReceiver); 11859 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11860 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11861 return result; 11862 } 11863 11864 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11865 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11866 if (r.errorReportReceiver == null) { 11867 return null; 11868 } 11869 11870 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11871 return null; 11872 } 11873 11874 ApplicationErrorReport report = new ApplicationErrorReport(); 11875 report.packageName = r.info.packageName; 11876 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11877 report.processName = r.processName; 11878 report.time = timeMillis; 11879 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11880 11881 if (r.crashing || r.forceCrashReport) { 11882 report.type = ApplicationErrorReport.TYPE_CRASH; 11883 report.crashInfo = crashInfo; 11884 } else if (r.notResponding) { 11885 report.type = ApplicationErrorReport.TYPE_ANR; 11886 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11887 11888 report.anrInfo.activity = r.notRespondingReport.tag; 11889 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11890 report.anrInfo.info = r.notRespondingReport.longMsg; 11891 } 11892 11893 return report; 11894 } 11895 11896 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11897 enforceNotIsolatedCaller("getProcessesInErrorState"); 11898 // assume our apps are happy - lazy create the list 11899 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11900 11901 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11902 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11903 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11904 11905 synchronized (this) { 11906 11907 // iterate across all processes 11908 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11909 ProcessRecord app = mLruProcesses.get(i); 11910 if (!allUsers && app.userId != userId) { 11911 continue; 11912 } 11913 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11914 // This one's in trouble, so we'll generate a report for it 11915 // crashes are higher priority (in case there's a crash *and* an anr) 11916 ActivityManager.ProcessErrorStateInfo report = null; 11917 if (app.crashing) { 11918 report = app.crashingReport; 11919 } else if (app.notResponding) { 11920 report = app.notRespondingReport; 11921 } 11922 11923 if (report != null) { 11924 if (errList == null) { 11925 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11926 } 11927 errList.add(report); 11928 } else { 11929 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11930 " crashing = " + app.crashing + 11931 " notResponding = " + app.notResponding); 11932 } 11933 } 11934 } 11935 } 11936 11937 return errList; 11938 } 11939 11940 static int procStateToImportance(int procState, int memAdj, 11941 ActivityManager.RunningAppProcessInfo currApp) { 11942 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11943 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11944 currApp.lru = memAdj; 11945 } else { 11946 currApp.lru = 0; 11947 } 11948 return imp; 11949 } 11950 11951 private void fillInProcMemInfo(ProcessRecord app, 11952 ActivityManager.RunningAppProcessInfo outInfo) { 11953 outInfo.pid = app.pid; 11954 outInfo.uid = app.info.uid; 11955 if (mHeavyWeightProcess == app) { 11956 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11957 } 11958 if (app.persistent) { 11959 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11960 } 11961 if (app.activities.size() > 0) { 11962 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11963 } 11964 outInfo.lastTrimLevel = app.trimMemoryLevel; 11965 int adj = app.curAdj; 11966 int procState = app.curProcState; 11967 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11968 outInfo.importanceReasonCode = app.adjTypeCode; 11969 outInfo.processState = app.curProcState; 11970 } 11971 11972 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11973 enforceNotIsolatedCaller("getRunningAppProcesses"); 11974 // Lazy instantiation of list 11975 List<ActivityManager.RunningAppProcessInfo> runList = null; 11976 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11977 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11978 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11979 synchronized (this) { 11980 // Iterate across all processes 11981 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11982 ProcessRecord app = mLruProcesses.get(i); 11983 if (!allUsers && app.userId != userId) { 11984 continue; 11985 } 11986 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11987 // Generate process state info for running application 11988 ActivityManager.RunningAppProcessInfo currApp = 11989 new ActivityManager.RunningAppProcessInfo(app.processName, 11990 app.pid, app.getPackageList()); 11991 fillInProcMemInfo(app, currApp); 11992 if (app.adjSource instanceof ProcessRecord) { 11993 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11994 currApp.importanceReasonImportance = 11995 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11996 app.adjSourceProcState); 11997 } else if (app.adjSource instanceof ActivityRecord) { 11998 ActivityRecord r = (ActivityRecord)app.adjSource; 11999 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 12000 } 12001 if (app.adjTarget instanceof ComponentName) { 12002 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 12003 } 12004 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 12005 // + " lru=" + currApp.lru); 12006 if (runList == null) { 12007 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 12008 } 12009 runList.add(currApp); 12010 } 12011 } 12012 } 12013 return runList; 12014 } 12015 12016 public List<ApplicationInfo> getRunningExternalApplications() { 12017 enforceNotIsolatedCaller("getRunningExternalApplications"); 12018 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 12019 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 12020 if (runningApps != null && runningApps.size() > 0) { 12021 Set<String> extList = new HashSet<String>(); 12022 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 12023 if (app.pkgList != null) { 12024 for (String pkg : app.pkgList) { 12025 extList.add(pkg); 12026 } 12027 } 12028 } 12029 IPackageManager pm = AppGlobals.getPackageManager(); 12030 for (String pkg : extList) { 12031 try { 12032 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 12033 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 12034 retList.add(info); 12035 } 12036 } catch (RemoteException e) { 12037 } 12038 } 12039 } 12040 return retList; 12041 } 12042 12043 @Override 12044 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 12045 enforceNotIsolatedCaller("getMyMemoryState"); 12046 synchronized (this) { 12047 ProcessRecord proc; 12048 synchronized (mPidsSelfLocked) { 12049 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 12050 } 12051 fillInProcMemInfo(proc, outInfo); 12052 } 12053 } 12054 12055 @Override 12056 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 12057 if (checkCallingPermission(android.Manifest.permission.DUMP) 12058 != PackageManager.PERMISSION_GRANTED) { 12059 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 12060 + Binder.getCallingPid() 12061 + ", uid=" + Binder.getCallingUid() 12062 + " without permission " 12063 + android.Manifest.permission.DUMP); 12064 return; 12065 } 12066 12067 boolean dumpAll = false; 12068 boolean dumpClient = false; 12069 String dumpPackage = null; 12070 12071 int opti = 0; 12072 while (opti < args.length) { 12073 String opt = args[opti]; 12074 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12075 break; 12076 } 12077 opti++; 12078 if ("-a".equals(opt)) { 12079 dumpAll = true; 12080 } else if ("-c".equals(opt)) { 12081 dumpClient = true; 12082 } else if ("-h".equals(opt)) { 12083 pw.println("Activity manager dump options:"); 12084 pw.println(" [-a] [-c] [-h] [cmd] ..."); 12085 pw.println(" cmd may be one of:"); 12086 pw.println(" a[ctivities]: activity stack state"); 12087 pw.println(" r[recents]: recent activities state"); 12088 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12089 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12090 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12091 pw.println(" o[om]: out of memory management"); 12092 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12093 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12094 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12095 pw.println(" service [COMP_SPEC]: service client-side state"); 12096 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12097 pw.println(" all: dump all activities"); 12098 pw.println(" top: dump the top activity"); 12099 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12100 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12101 pw.println(" a partial substring in a component name, a"); 12102 pw.println(" hex object identifier."); 12103 pw.println(" -a: include all available server state."); 12104 pw.println(" -c: include client state."); 12105 return; 12106 } else { 12107 pw.println("Unknown argument: " + opt + "; use -h for help"); 12108 } 12109 } 12110 12111 long origId = Binder.clearCallingIdentity(); 12112 boolean more = false; 12113 // Is the caller requesting to dump a particular piece of data? 12114 if (opti < args.length) { 12115 String cmd = args[opti]; 12116 opti++; 12117 if ("activities".equals(cmd) || "a".equals(cmd)) { 12118 synchronized (this) { 12119 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12120 } 12121 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12122 synchronized (this) { 12123 dumpRecentsLocked(fd, pw, args, opti, true, null); 12124 } 12125 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12126 String[] newArgs; 12127 String name; 12128 if (opti >= args.length) { 12129 name = null; 12130 newArgs = EMPTY_STRING_ARRAY; 12131 } else { 12132 name = args[opti]; 12133 opti++; 12134 newArgs = new String[args.length - opti]; 12135 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12136 args.length - opti); 12137 } 12138 synchronized (this) { 12139 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12140 } 12141 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12142 String[] newArgs; 12143 String name; 12144 if (opti >= args.length) { 12145 name = null; 12146 newArgs = EMPTY_STRING_ARRAY; 12147 } else { 12148 name = args[opti]; 12149 opti++; 12150 newArgs = new String[args.length - opti]; 12151 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12152 args.length - opti); 12153 } 12154 synchronized (this) { 12155 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12156 } 12157 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12158 String[] newArgs; 12159 String name; 12160 if (opti >= args.length) { 12161 name = null; 12162 newArgs = EMPTY_STRING_ARRAY; 12163 } else { 12164 name = args[opti]; 12165 opti++; 12166 newArgs = new String[args.length - opti]; 12167 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12168 args.length - opti); 12169 } 12170 synchronized (this) { 12171 dumpProcessesLocked(fd, pw, args, opti, true, name); 12172 } 12173 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12174 synchronized (this) { 12175 dumpOomLocked(fd, pw, args, opti, true); 12176 } 12177 } else if ("provider".equals(cmd)) { 12178 String[] newArgs; 12179 String name; 12180 if (opti >= args.length) { 12181 name = null; 12182 newArgs = EMPTY_STRING_ARRAY; 12183 } else { 12184 name = args[opti]; 12185 opti++; 12186 newArgs = new String[args.length - opti]; 12187 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12188 } 12189 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12190 pw.println("No providers match: " + name); 12191 pw.println("Use -h for help."); 12192 } 12193 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12194 synchronized (this) { 12195 dumpProvidersLocked(fd, pw, args, opti, true, null); 12196 } 12197 } else if ("service".equals(cmd)) { 12198 String[] newArgs; 12199 String name; 12200 if (opti >= args.length) { 12201 name = null; 12202 newArgs = EMPTY_STRING_ARRAY; 12203 } else { 12204 name = args[opti]; 12205 opti++; 12206 newArgs = new String[args.length - opti]; 12207 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12208 args.length - opti); 12209 } 12210 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12211 pw.println("No services match: " + name); 12212 pw.println("Use -h for help."); 12213 } 12214 } else if ("package".equals(cmd)) { 12215 String[] newArgs; 12216 if (opti >= args.length) { 12217 pw.println("package: no package name specified"); 12218 pw.println("Use -h for help."); 12219 } else { 12220 dumpPackage = args[opti]; 12221 opti++; 12222 newArgs = new String[args.length - opti]; 12223 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12224 args.length - opti); 12225 args = newArgs; 12226 opti = 0; 12227 more = true; 12228 } 12229 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12230 synchronized (this) { 12231 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12232 } 12233 } else { 12234 // Dumping a single activity? 12235 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12236 pw.println("Bad activity command, or no activities match: " + cmd); 12237 pw.println("Use -h for help."); 12238 } 12239 } 12240 if (!more) { 12241 Binder.restoreCallingIdentity(origId); 12242 return; 12243 } 12244 } 12245 12246 // No piece of data specified, dump everything. 12247 synchronized (this) { 12248 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12249 pw.println(); 12250 if (dumpAll) { 12251 pw.println("-------------------------------------------------------------------------------"); 12252 } 12253 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12254 pw.println(); 12255 if (dumpAll) { 12256 pw.println("-------------------------------------------------------------------------------"); 12257 } 12258 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12259 pw.println(); 12260 if (dumpAll) { 12261 pw.println("-------------------------------------------------------------------------------"); 12262 } 12263 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12264 pw.println(); 12265 if (dumpAll) { 12266 pw.println("-------------------------------------------------------------------------------"); 12267 } 12268 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12269 pw.println(); 12270 if (dumpAll) { 12271 pw.println("-------------------------------------------------------------------------------"); 12272 } 12273 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12274 pw.println(); 12275 if (dumpAll) { 12276 pw.println("-------------------------------------------------------------------------------"); 12277 } 12278 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12279 } 12280 Binder.restoreCallingIdentity(origId); 12281 } 12282 12283 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12284 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12285 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12286 12287 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12288 dumpPackage); 12289 boolean needSep = printedAnything; 12290 12291 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12292 dumpPackage, needSep, " mFocusedActivity: "); 12293 if (printed) { 12294 printedAnything = true; 12295 needSep = false; 12296 } 12297 12298 if (dumpPackage == null) { 12299 if (needSep) { 12300 pw.println(); 12301 } 12302 needSep = true; 12303 printedAnything = true; 12304 mStackSupervisor.dump(pw, " "); 12305 } 12306 12307 if (!printedAnything) { 12308 pw.println(" (nothing)"); 12309 } 12310 } 12311 12312 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12313 int opti, boolean dumpAll, String dumpPackage) { 12314 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12315 12316 boolean printedAnything = false; 12317 12318 if (mRecentTasks.size() > 0) { 12319 boolean printedHeader = false; 12320 12321 final int N = mRecentTasks.size(); 12322 for (int i=0; i<N; i++) { 12323 TaskRecord tr = mRecentTasks.get(i); 12324 if (dumpPackage != null) { 12325 if (tr.realActivity == null || 12326 !dumpPackage.equals(tr.realActivity)) { 12327 continue; 12328 } 12329 } 12330 if (!printedHeader) { 12331 pw.println(" Recent tasks:"); 12332 printedHeader = true; 12333 printedAnything = true; 12334 } 12335 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12336 pw.println(tr); 12337 if (dumpAll) { 12338 mRecentTasks.get(i).dump(pw, " "); 12339 } 12340 } 12341 } 12342 12343 if (!printedAnything) { 12344 pw.println(" (nothing)"); 12345 } 12346 } 12347 12348 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12349 int opti, boolean dumpAll, String dumpPackage) { 12350 boolean needSep = false; 12351 boolean printedAnything = false; 12352 int numPers = 0; 12353 12354 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12355 12356 if (dumpAll) { 12357 final int NP = mProcessNames.getMap().size(); 12358 for (int ip=0; ip<NP; ip++) { 12359 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12360 final int NA = procs.size(); 12361 for (int ia=0; ia<NA; ia++) { 12362 ProcessRecord r = procs.valueAt(ia); 12363 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12364 continue; 12365 } 12366 if (!needSep) { 12367 pw.println(" All known processes:"); 12368 needSep = true; 12369 printedAnything = true; 12370 } 12371 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12372 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12373 pw.print(" "); pw.println(r); 12374 r.dump(pw, " "); 12375 if (r.persistent) { 12376 numPers++; 12377 } 12378 } 12379 } 12380 } 12381 12382 if (mIsolatedProcesses.size() > 0) { 12383 boolean printed = false; 12384 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12385 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12386 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12387 continue; 12388 } 12389 if (!printed) { 12390 if (needSep) { 12391 pw.println(); 12392 } 12393 pw.println(" Isolated process list (sorted by uid):"); 12394 printedAnything = true; 12395 printed = true; 12396 needSep = true; 12397 } 12398 pw.println(String.format("%sIsolated #%2d: %s", 12399 " ", i, r.toString())); 12400 } 12401 } 12402 12403 if (mLruProcesses.size() > 0) { 12404 if (needSep) { 12405 pw.println(); 12406 } 12407 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12408 pw.print(" total, non-act at "); 12409 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12410 pw.print(", non-svc at "); 12411 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12412 pw.println("):"); 12413 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12414 needSep = true; 12415 printedAnything = true; 12416 } 12417 12418 if (dumpAll || dumpPackage != null) { 12419 synchronized (mPidsSelfLocked) { 12420 boolean printed = false; 12421 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12422 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12423 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12424 continue; 12425 } 12426 if (!printed) { 12427 if (needSep) pw.println(); 12428 needSep = true; 12429 pw.println(" PID mappings:"); 12430 printed = true; 12431 printedAnything = true; 12432 } 12433 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12434 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12435 } 12436 } 12437 } 12438 12439 if (mForegroundProcesses.size() > 0) { 12440 synchronized (mPidsSelfLocked) { 12441 boolean printed = false; 12442 for (int i=0; i<mForegroundProcesses.size(); i++) { 12443 ProcessRecord r = mPidsSelfLocked.get( 12444 mForegroundProcesses.valueAt(i).pid); 12445 if (dumpPackage != null && (r == null 12446 || !r.pkgList.containsKey(dumpPackage))) { 12447 continue; 12448 } 12449 if (!printed) { 12450 if (needSep) pw.println(); 12451 needSep = true; 12452 pw.println(" Foreground Processes:"); 12453 printed = true; 12454 printedAnything = true; 12455 } 12456 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12457 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12458 } 12459 } 12460 } 12461 12462 if (mPersistentStartingProcesses.size() > 0) { 12463 if (needSep) pw.println(); 12464 needSep = true; 12465 printedAnything = true; 12466 pw.println(" Persisent processes that are starting:"); 12467 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12468 "Starting Norm", "Restarting PERS", dumpPackage); 12469 } 12470 12471 if (mRemovedProcesses.size() > 0) { 12472 if (needSep) pw.println(); 12473 needSep = true; 12474 printedAnything = true; 12475 pw.println(" Processes that are being removed:"); 12476 dumpProcessList(pw, this, mRemovedProcesses, " ", 12477 "Removed Norm", "Removed PERS", dumpPackage); 12478 } 12479 12480 if (mProcessesOnHold.size() > 0) { 12481 if (needSep) pw.println(); 12482 needSep = true; 12483 printedAnything = true; 12484 pw.println(" Processes that are on old until the system is ready:"); 12485 dumpProcessList(pw, this, mProcessesOnHold, " ", 12486 "OnHold Norm", "OnHold PERS", dumpPackage); 12487 } 12488 12489 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12490 12491 if (mProcessCrashTimes.getMap().size() > 0) { 12492 boolean printed = false; 12493 long now = SystemClock.uptimeMillis(); 12494 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12495 final int NP = pmap.size(); 12496 for (int ip=0; ip<NP; ip++) { 12497 String pname = pmap.keyAt(ip); 12498 SparseArray<Long> uids = pmap.valueAt(ip); 12499 final int N = uids.size(); 12500 for (int i=0; i<N; i++) { 12501 int puid = uids.keyAt(i); 12502 ProcessRecord r = mProcessNames.get(pname, puid); 12503 if (dumpPackage != null && (r == null 12504 || !r.pkgList.containsKey(dumpPackage))) { 12505 continue; 12506 } 12507 if (!printed) { 12508 if (needSep) pw.println(); 12509 needSep = true; 12510 pw.println(" Time since processes crashed:"); 12511 printed = true; 12512 printedAnything = true; 12513 } 12514 pw.print(" Process "); pw.print(pname); 12515 pw.print(" uid "); pw.print(puid); 12516 pw.print(": last crashed "); 12517 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12518 pw.println(" ago"); 12519 } 12520 } 12521 } 12522 12523 if (mBadProcesses.getMap().size() > 0) { 12524 boolean printed = false; 12525 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12526 final int NP = pmap.size(); 12527 for (int ip=0; ip<NP; ip++) { 12528 String pname = pmap.keyAt(ip); 12529 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12530 final int N = uids.size(); 12531 for (int i=0; i<N; i++) { 12532 int puid = uids.keyAt(i); 12533 ProcessRecord r = mProcessNames.get(pname, puid); 12534 if (dumpPackage != null && (r == null 12535 || !r.pkgList.containsKey(dumpPackage))) { 12536 continue; 12537 } 12538 if (!printed) { 12539 if (needSep) pw.println(); 12540 needSep = true; 12541 pw.println(" Bad processes:"); 12542 printedAnything = true; 12543 } 12544 BadProcessInfo info = uids.valueAt(i); 12545 pw.print(" Bad process "); pw.print(pname); 12546 pw.print(" uid "); pw.print(puid); 12547 pw.print(": crashed at time "); pw.println(info.time); 12548 if (info.shortMsg != null) { 12549 pw.print(" Short msg: "); pw.println(info.shortMsg); 12550 } 12551 if (info.longMsg != null) { 12552 pw.print(" Long msg: "); pw.println(info.longMsg); 12553 } 12554 if (info.stack != null) { 12555 pw.println(" Stack:"); 12556 int lastPos = 0; 12557 for (int pos=0; pos<info.stack.length(); pos++) { 12558 if (info.stack.charAt(pos) == '\n') { 12559 pw.print(" "); 12560 pw.write(info.stack, lastPos, pos-lastPos); 12561 pw.println(); 12562 lastPos = pos+1; 12563 } 12564 } 12565 if (lastPos < info.stack.length()) { 12566 pw.print(" "); 12567 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12568 pw.println(); 12569 } 12570 } 12571 } 12572 } 12573 } 12574 12575 if (dumpPackage == null) { 12576 pw.println(); 12577 needSep = false; 12578 pw.println(" mStartedUsers:"); 12579 for (int i=0; i<mStartedUsers.size(); i++) { 12580 UserStartedState uss = mStartedUsers.valueAt(i); 12581 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12582 pw.print(": "); uss.dump("", pw); 12583 } 12584 pw.print(" mStartedUserArray: ["); 12585 for (int i=0; i<mStartedUserArray.length; i++) { 12586 if (i > 0) pw.print(", "); 12587 pw.print(mStartedUserArray[i]); 12588 } 12589 pw.println("]"); 12590 pw.print(" mUserLru: ["); 12591 for (int i=0; i<mUserLru.size(); i++) { 12592 if (i > 0) pw.print(", "); 12593 pw.print(mUserLru.get(i)); 12594 } 12595 pw.println("]"); 12596 if (dumpAll) { 12597 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12598 } 12599 synchronized (mUserProfileGroupIdsSelfLocked) { 12600 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12601 pw.println(" mUserProfileGroupIds:"); 12602 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12603 pw.print(" User #"); 12604 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12605 pw.print(" -> profile #"); 12606 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12607 } 12608 } 12609 } 12610 } 12611 if (mHomeProcess != null && (dumpPackage == null 12612 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12613 if (needSep) { 12614 pw.println(); 12615 needSep = false; 12616 } 12617 pw.println(" mHomeProcess: " + mHomeProcess); 12618 } 12619 if (mPreviousProcess != null && (dumpPackage == null 12620 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12621 if (needSep) { 12622 pw.println(); 12623 needSep = false; 12624 } 12625 pw.println(" mPreviousProcess: " + mPreviousProcess); 12626 } 12627 if (dumpAll) { 12628 StringBuilder sb = new StringBuilder(128); 12629 sb.append(" mPreviousProcessVisibleTime: "); 12630 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12631 pw.println(sb); 12632 } 12633 if (mHeavyWeightProcess != null && (dumpPackage == null 12634 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12635 if (needSep) { 12636 pw.println(); 12637 needSep = false; 12638 } 12639 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12640 } 12641 if (dumpPackage == null) { 12642 pw.println(" mConfiguration: " + mConfiguration); 12643 } 12644 if (dumpAll) { 12645 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12646 if (mCompatModePackages.getPackages().size() > 0) { 12647 boolean printed = false; 12648 for (Map.Entry<String, Integer> entry 12649 : mCompatModePackages.getPackages().entrySet()) { 12650 String pkg = entry.getKey(); 12651 int mode = entry.getValue(); 12652 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12653 continue; 12654 } 12655 if (!printed) { 12656 pw.println(" mScreenCompatPackages:"); 12657 printed = true; 12658 } 12659 pw.print(" "); pw.print(pkg); pw.print(": "); 12660 pw.print(mode); pw.println(); 12661 } 12662 } 12663 } 12664 if (dumpPackage == null) { 12665 if (mSleeping || mWentToSleep || mLockScreenShown) { 12666 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12667 + " mLockScreenShown " + mLockScreenShown); 12668 } 12669 if (mShuttingDown || mRunningVoice) { 12670 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12671 } 12672 } 12673 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12674 || mOrigWaitForDebugger) { 12675 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12676 || dumpPackage.equals(mOrigDebugApp)) { 12677 if (needSep) { 12678 pw.println(); 12679 needSep = false; 12680 } 12681 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12682 + " mDebugTransient=" + mDebugTransient 12683 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12684 } 12685 } 12686 if (mOpenGlTraceApp != null) { 12687 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12688 if (needSep) { 12689 pw.println(); 12690 needSep = false; 12691 } 12692 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12693 } 12694 } 12695 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12696 || mProfileFd != null) { 12697 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12698 if (needSep) { 12699 pw.println(); 12700 needSep = false; 12701 } 12702 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12703 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12704 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12705 + mAutoStopProfiler); 12706 pw.println(" mProfileType=" + mProfileType); 12707 } 12708 } 12709 if (dumpPackage == null) { 12710 if (mAlwaysFinishActivities || mController != null) { 12711 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12712 + " mController=" + mController); 12713 } 12714 if (dumpAll) { 12715 pw.println(" Total persistent processes: " + numPers); 12716 pw.println(" mProcessesReady=" + mProcessesReady 12717 + " mSystemReady=" + mSystemReady); 12718 pw.println(" mBooting=" + mBooting 12719 + " mBooted=" + mBooted 12720 + " mFactoryTest=" + mFactoryTest); 12721 pw.print(" mLastPowerCheckRealtime="); 12722 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12723 pw.println(""); 12724 pw.print(" mLastPowerCheckUptime="); 12725 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12726 pw.println(""); 12727 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12728 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12729 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12730 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12731 + " (" + mLruProcesses.size() + " total)" 12732 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12733 + " mNumServiceProcs=" + mNumServiceProcs 12734 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12735 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12736 + " mLastMemoryLevel" + mLastMemoryLevel 12737 + " mLastNumProcesses" + mLastNumProcesses); 12738 long now = SystemClock.uptimeMillis(); 12739 pw.print(" mLastIdleTime="); 12740 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12741 pw.print(" mLowRamSinceLastIdle="); 12742 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12743 pw.println(); 12744 } 12745 } 12746 12747 if (!printedAnything) { 12748 pw.println(" (nothing)"); 12749 } 12750 } 12751 12752 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12753 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12754 if (mProcessesToGc.size() > 0) { 12755 boolean printed = false; 12756 long now = SystemClock.uptimeMillis(); 12757 for (int i=0; i<mProcessesToGc.size(); i++) { 12758 ProcessRecord proc = mProcessesToGc.get(i); 12759 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12760 continue; 12761 } 12762 if (!printed) { 12763 if (needSep) pw.println(); 12764 needSep = true; 12765 pw.println(" Processes that are waiting to GC:"); 12766 printed = true; 12767 } 12768 pw.print(" Process "); pw.println(proc); 12769 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12770 pw.print(", last gced="); 12771 pw.print(now-proc.lastRequestedGc); 12772 pw.print(" ms ago, last lowMem="); 12773 pw.print(now-proc.lastLowMemory); 12774 pw.println(" ms ago"); 12775 12776 } 12777 } 12778 return needSep; 12779 } 12780 12781 void printOomLevel(PrintWriter pw, String name, int adj) { 12782 pw.print(" "); 12783 if (adj >= 0) { 12784 pw.print(' '); 12785 if (adj < 10) pw.print(' '); 12786 } else { 12787 if (adj > -10) pw.print(' '); 12788 } 12789 pw.print(adj); 12790 pw.print(": "); 12791 pw.print(name); 12792 pw.print(" ("); 12793 pw.print(mProcessList.getMemLevel(adj)/1024); 12794 pw.println(" kB)"); 12795 } 12796 12797 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12798 int opti, boolean dumpAll) { 12799 boolean needSep = false; 12800 12801 if (mLruProcesses.size() > 0) { 12802 if (needSep) pw.println(); 12803 needSep = true; 12804 pw.println(" OOM levels:"); 12805 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12806 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12807 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12808 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12809 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12810 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12811 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12812 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12813 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12814 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12815 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12816 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12817 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12818 12819 if (needSep) pw.println(); 12820 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12821 pw.print(" total, non-act at "); 12822 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12823 pw.print(", non-svc at "); 12824 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12825 pw.println("):"); 12826 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12827 needSep = true; 12828 } 12829 12830 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12831 12832 pw.println(); 12833 pw.println(" mHomeProcess: " + mHomeProcess); 12834 pw.println(" mPreviousProcess: " + mPreviousProcess); 12835 if (mHeavyWeightProcess != null) { 12836 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12837 } 12838 12839 return true; 12840 } 12841 12842 /** 12843 * There are three ways to call this: 12844 * - no provider specified: dump all the providers 12845 * - a flattened component name that matched an existing provider was specified as the 12846 * first arg: dump that one provider 12847 * - the first arg isn't the flattened component name of an existing provider: 12848 * dump all providers whose component contains the first arg as a substring 12849 */ 12850 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12851 int opti, boolean dumpAll) { 12852 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12853 } 12854 12855 static class ItemMatcher { 12856 ArrayList<ComponentName> components; 12857 ArrayList<String> strings; 12858 ArrayList<Integer> objects; 12859 boolean all; 12860 12861 ItemMatcher() { 12862 all = true; 12863 } 12864 12865 void build(String name) { 12866 ComponentName componentName = ComponentName.unflattenFromString(name); 12867 if (componentName != null) { 12868 if (components == null) { 12869 components = new ArrayList<ComponentName>(); 12870 } 12871 components.add(componentName); 12872 all = false; 12873 } else { 12874 int objectId = 0; 12875 // Not a '/' separated full component name; maybe an object ID? 12876 try { 12877 objectId = Integer.parseInt(name, 16); 12878 if (objects == null) { 12879 objects = new ArrayList<Integer>(); 12880 } 12881 objects.add(objectId); 12882 all = false; 12883 } catch (RuntimeException e) { 12884 // Not an integer; just do string match. 12885 if (strings == null) { 12886 strings = new ArrayList<String>(); 12887 } 12888 strings.add(name); 12889 all = false; 12890 } 12891 } 12892 } 12893 12894 int build(String[] args, int opti) { 12895 for (; opti<args.length; opti++) { 12896 String name = args[opti]; 12897 if ("--".equals(name)) { 12898 return opti+1; 12899 } 12900 build(name); 12901 } 12902 return opti; 12903 } 12904 12905 boolean match(Object object, ComponentName comp) { 12906 if (all) { 12907 return true; 12908 } 12909 if (components != null) { 12910 for (int i=0; i<components.size(); i++) { 12911 if (components.get(i).equals(comp)) { 12912 return true; 12913 } 12914 } 12915 } 12916 if (objects != null) { 12917 for (int i=0; i<objects.size(); i++) { 12918 if (System.identityHashCode(object) == objects.get(i)) { 12919 return true; 12920 } 12921 } 12922 } 12923 if (strings != null) { 12924 String flat = comp.flattenToString(); 12925 for (int i=0; i<strings.size(); i++) { 12926 if (flat.contains(strings.get(i))) { 12927 return true; 12928 } 12929 } 12930 } 12931 return false; 12932 } 12933 } 12934 12935 /** 12936 * There are three things that cmd can be: 12937 * - a flattened component name that matches an existing activity 12938 * - the cmd arg isn't the flattened component name of an existing activity: 12939 * dump all activity whose component contains the cmd as a substring 12940 * - A hex number of the ActivityRecord object instance. 12941 */ 12942 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12943 int opti, boolean dumpAll) { 12944 ArrayList<ActivityRecord> activities; 12945 12946 synchronized (this) { 12947 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12948 } 12949 12950 if (activities.size() <= 0) { 12951 return false; 12952 } 12953 12954 String[] newArgs = new String[args.length - opti]; 12955 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12956 12957 TaskRecord lastTask = null; 12958 boolean needSep = false; 12959 for (int i=activities.size()-1; i>=0; i--) { 12960 ActivityRecord r = activities.get(i); 12961 if (needSep) { 12962 pw.println(); 12963 } 12964 needSep = true; 12965 synchronized (this) { 12966 if (lastTask != r.task) { 12967 lastTask = r.task; 12968 pw.print("TASK "); pw.print(lastTask.affinity); 12969 pw.print(" id="); pw.println(lastTask.taskId); 12970 if (dumpAll) { 12971 lastTask.dump(pw, " "); 12972 } 12973 } 12974 } 12975 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12976 } 12977 return true; 12978 } 12979 12980 /** 12981 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12982 * there is a thread associated with the activity. 12983 */ 12984 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12985 final ActivityRecord r, String[] args, boolean dumpAll) { 12986 String innerPrefix = prefix + " "; 12987 synchronized (this) { 12988 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12989 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12990 pw.print(" pid="); 12991 if (r.app != null) pw.println(r.app.pid); 12992 else pw.println("(not running)"); 12993 if (dumpAll) { 12994 r.dump(pw, innerPrefix); 12995 } 12996 } 12997 if (r.app != null && r.app.thread != null) { 12998 // flush anything that is already in the PrintWriter since the thread is going 12999 // to write to the file descriptor directly 13000 pw.flush(); 13001 try { 13002 TransferPipe tp = new TransferPipe(); 13003 try { 13004 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 13005 r.appToken, innerPrefix, args); 13006 tp.go(fd); 13007 } finally { 13008 tp.kill(); 13009 } 13010 } catch (IOException e) { 13011 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 13012 } catch (RemoteException e) { 13013 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 13014 } 13015 } 13016 } 13017 13018 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13019 int opti, boolean dumpAll, String dumpPackage) { 13020 boolean needSep = false; 13021 boolean onlyHistory = false; 13022 boolean printedAnything = false; 13023 13024 if ("history".equals(dumpPackage)) { 13025 if (opti < args.length && "-s".equals(args[opti])) { 13026 dumpAll = false; 13027 } 13028 onlyHistory = true; 13029 dumpPackage = null; 13030 } 13031 13032 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 13033 if (!onlyHistory && dumpAll) { 13034 if (mRegisteredReceivers.size() > 0) { 13035 boolean printed = false; 13036 Iterator it = mRegisteredReceivers.values().iterator(); 13037 while (it.hasNext()) { 13038 ReceiverList r = (ReceiverList)it.next(); 13039 if (dumpPackage != null && (r.app == null || 13040 !dumpPackage.equals(r.app.info.packageName))) { 13041 continue; 13042 } 13043 if (!printed) { 13044 pw.println(" Registered Receivers:"); 13045 needSep = true; 13046 printed = true; 13047 printedAnything = true; 13048 } 13049 pw.print(" * "); pw.println(r); 13050 r.dump(pw, " "); 13051 } 13052 } 13053 13054 if (mReceiverResolver.dump(pw, needSep ? 13055 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 13056 " ", dumpPackage, false)) { 13057 needSep = true; 13058 printedAnything = true; 13059 } 13060 } 13061 13062 for (BroadcastQueue q : mBroadcastQueues) { 13063 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 13064 printedAnything |= needSep; 13065 } 13066 13067 needSep = true; 13068 13069 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 13070 for (int user=0; user<mStickyBroadcasts.size(); user++) { 13071 if (needSep) { 13072 pw.println(); 13073 } 13074 needSep = true; 13075 printedAnything = true; 13076 pw.print(" Sticky broadcasts for user "); 13077 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 13078 StringBuilder sb = new StringBuilder(128); 13079 for (Map.Entry<String, ArrayList<Intent>> ent 13080 : mStickyBroadcasts.valueAt(user).entrySet()) { 13081 pw.print(" * Sticky action "); pw.print(ent.getKey()); 13082 if (dumpAll) { 13083 pw.println(":"); 13084 ArrayList<Intent> intents = ent.getValue(); 13085 final int N = intents.size(); 13086 for (int i=0; i<N; i++) { 13087 sb.setLength(0); 13088 sb.append(" Intent: "); 13089 intents.get(i).toShortString(sb, false, true, false, false); 13090 pw.println(sb.toString()); 13091 Bundle bundle = intents.get(i).getExtras(); 13092 if (bundle != null) { 13093 pw.print(" "); 13094 pw.println(bundle.toString()); 13095 } 13096 } 13097 } else { 13098 pw.println(""); 13099 } 13100 } 13101 } 13102 } 13103 13104 if (!onlyHistory && dumpAll) { 13105 pw.println(); 13106 for (BroadcastQueue queue : mBroadcastQueues) { 13107 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13108 + queue.mBroadcastsScheduled); 13109 } 13110 pw.println(" mHandler:"); 13111 mHandler.dump(new PrintWriterPrinter(pw), " "); 13112 needSep = true; 13113 printedAnything = true; 13114 } 13115 13116 if (!printedAnything) { 13117 pw.println(" (nothing)"); 13118 } 13119 } 13120 13121 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13122 int opti, boolean dumpAll, String dumpPackage) { 13123 boolean needSep; 13124 boolean printedAnything = false; 13125 13126 ItemMatcher matcher = new ItemMatcher(); 13127 matcher.build(args, opti); 13128 13129 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13130 13131 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13132 printedAnything |= needSep; 13133 13134 if (mLaunchingProviders.size() > 0) { 13135 boolean printed = false; 13136 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13137 ContentProviderRecord r = mLaunchingProviders.get(i); 13138 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13139 continue; 13140 } 13141 if (!printed) { 13142 if (needSep) pw.println(); 13143 needSep = true; 13144 pw.println(" Launching content providers:"); 13145 printed = true; 13146 printedAnything = true; 13147 } 13148 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13149 pw.println(r); 13150 } 13151 } 13152 13153 if (mGrantedUriPermissions.size() > 0) { 13154 boolean printed = false; 13155 int dumpUid = -2; 13156 if (dumpPackage != null) { 13157 try { 13158 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13159 } catch (NameNotFoundException e) { 13160 dumpUid = -1; 13161 } 13162 } 13163 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13164 int uid = mGrantedUriPermissions.keyAt(i); 13165 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13166 continue; 13167 } 13168 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13169 if (!printed) { 13170 if (needSep) pw.println(); 13171 needSep = true; 13172 pw.println(" Granted Uri Permissions:"); 13173 printed = true; 13174 printedAnything = true; 13175 } 13176 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13177 for (UriPermission perm : perms.values()) { 13178 pw.print(" "); pw.println(perm); 13179 if (dumpAll) { 13180 perm.dump(pw, " "); 13181 } 13182 } 13183 } 13184 } 13185 13186 if (!printedAnything) { 13187 pw.println(" (nothing)"); 13188 } 13189 } 13190 13191 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13192 int opti, boolean dumpAll, String dumpPackage) { 13193 boolean printed = false; 13194 13195 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13196 13197 if (mIntentSenderRecords.size() > 0) { 13198 Iterator<WeakReference<PendingIntentRecord>> it 13199 = mIntentSenderRecords.values().iterator(); 13200 while (it.hasNext()) { 13201 WeakReference<PendingIntentRecord> ref = it.next(); 13202 PendingIntentRecord rec = ref != null ? ref.get(): null; 13203 if (dumpPackage != null && (rec == null 13204 || !dumpPackage.equals(rec.key.packageName))) { 13205 continue; 13206 } 13207 printed = true; 13208 if (rec != null) { 13209 pw.print(" * "); pw.println(rec); 13210 if (dumpAll) { 13211 rec.dump(pw, " "); 13212 } 13213 } else { 13214 pw.print(" * "); pw.println(ref); 13215 } 13216 } 13217 } 13218 13219 if (!printed) { 13220 pw.println(" (nothing)"); 13221 } 13222 } 13223 13224 private static final int dumpProcessList(PrintWriter pw, 13225 ActivityManagerService service, List list, 13226 String prefix, String normalLabel, String persistentLabel, 13227 String dumpPackage) { 13228 int numPers = 0; 13229 final int N = list.size()-1; 13230 for (int i=N; i>=0; i--) { 13231 ProcessRecord r = (ProcessRecord)list.get(i); 13232 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13233 continue; 13234 } 13235 pw.println(String.format("%s%s #%2d: %s", 13236 prefix, (r.persistent ? persistentLabel : normalLabel), 13237 i, r.toString())); 13238 if (r.persistent) { 13239 numPers++; 13240 } 13241 } 13242 return numPers; 13243 } 13244 13245 private static final boolean dumpProcessOomList(PrintWriter pw, 13246 ActivityManagerService service, List<ProcessRecord> origList, 13247 String prefix, String normalLabel, String persistentLabel, 13248 boolean inclDetails, String dumpPackage) { 13249 13250 ArrayList<Pair<ProcessRecord, Integer>> list 13251 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13252 for (int i=0; i<origList.size(); i++) { 13253 ProcessRecord r = origList.get(i); 13254 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13255 continue; 13256 } 13257 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13258 } 13259 13260 if (list.size() <= 0) { 13261 return false; 13262 } 13263 13264 Comparator<Pair<ProcessRecord, Integer>> comparator 13265 = new Comparator<Pair<ProcessRecord, Integer>>() { 13266 @Override 13267 public int compare(Pair<ProcessRecord, Integer> object1, 13268 Pair<ProcessRecord, Integer> object2) { 13269 if (object1.first.setAdj != object2.first.setAdj) { 13270 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13271 } 13272 if (object1.second.intValue() != object2.second.intValue()) { 13273 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13274 } 13275 return 0; 13276 } 13277 }; 13278 13279 Collections.sort(list, comparator); 13280 13281 final long curRealtime = SystemClock.elapsedRealtime(); 13282 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13283 final long curUptime = SystemClock.uptimeMillis(); 13284 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13285 13286 for (int i=list.size()-1; i>=0; i--) { 13287 ProcessRecord r = list.get(i).first; 13288 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13289 char schedGroup; 13290 switch (r.setSchedGroup) { 13291 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13292 schedGroup = 'B'; 13293 break; 13294 case Process.THREAD_GROUP_DEFAULT: 13295 schedGroup = 'F'; 13296 break; 13297 default: 13298 schedGroup = '?'; 13299 break; 13300 } 13301 char foreground; 13302 if (r.foregroundActivities) { 13303 foreground = 'A'; 13304 } else if (r.foregroundServices) { 13305 foreground = 'S'; 13306 } else { 13307 foreground = ' '; 13308 } 13309 String procState = ProcessList.makeProcStateString(r.curProcState); 13310 pw.print(prefix); 13311 pw.print(r.persistent ? persistentLabel : normalLabel); 13312 pw.print(" #"); 13313 int num = (origList.size()-1)-list.get(i).second; 13314 if (num < 10) pw.print(' '); 13315 pw.print(num); 13316 pw.print(": "); 13317 pw.print(oomAdj); 13318 pw.print(' '); 13319 pw.print(schedGroup); 13320 pw.print('/'); 13321 pw.print(foreground); 13322 pw.print('/'); 13323 pw.print(procState); 13324 pw.print(" trm:"); 13325 if (r.trimMemoryLevel < 10) pw.print(' '); 13326 pw.print(r.trimMemoryLevel); 13327 pw.print(' '); 13328 pw.print(r.toShortString()); 13329 pw.print(" ("); 13330 pw.print(r.adjType); 13331 pw.println(')'); 13332 if (r.adjSource != null || r.adjTarget != null) { 13333 pw.print(prefix); 13334 pw.print(" "); 13335 if (r.adjTarget instanceof ComponentName) { 13336 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13337 } else if (r.adjTarget != null) { 13338 pw.print(r.adjTarget.toString()); 13339 } else { 13340 pw.print("{null}"); 13341 } 13342 pw.print("<="); 13343 if (r.adjSource instanceof ProcessRecord) { 13344 pw.print("Proc{"); 13345 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13346 pw.println("}"); 13347 } else if (r.adjSource != null) { 13348 pw.println(r.adjSource.toString()); 13349 } else { 13350 pw.println("{null}"); 13351 } 13352 } 13353 if (inclDetails) { 13354 pw.print(prefix); 13355 pw.print(" "); 13356 pw.print("oom: max="); pw.print(r.maxAdj); 13357 pw.print(" curRaw="); pw.print(r.curRawAdj); 13358 pw.print(" setRaw="); pw.print(r.setRawAdj); 13359 pw.print(" cur="); pw.print(r.curAdj); 13360 pw.print(" set="); pw.println(r.setAdj); 13361 pw.print(prefix); 13362 pw.print(" "); 13363 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13364 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13365 pw.print(" lastPss="); pw.print(r.lastPss); 13366 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13367 pw.print(prefix); 13368 pw.print(" "); 13369 pw.print("cached="); pw.print(r.cached); 13370 pw.print(" empty="); pw.print(r.empty); 13371 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13372 13373 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13374 if (r.lastWakeTime != 0) { 13375 long wtime; 13376 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13377 synchronized (stats) { 13378 wtime = stats.getProcessWakeTime(r.info.uid, 13379 r.pid, curRealtime); 13380 } 13381 long timeUsed = wtime - r.lastWakeTime; 13382 pw.print(prefix); 13383 pw.print(" "); 13384 pw.print("keep awake over "); 13385 TimeUtils.formatDuration(realtimeSince, pw); 13386 pw.print(" used "); 13387 TimeUtils.formatDuration(timeUsed, pw); 13388 pw.print(" ("); 13389 pw.print((timeUsed*100)/realtimeSince); 13390 pw.println("%)"); 13391 } 13392 if (r.lastCpuTime != 0) { 13393 long timeUsed = r.curCpuTime - r.lastCpuTime; 13394 pw.print(prefix); 13395 pw.print(" "); 13396 pw.print("run cpu over "); 13397 TimeUtils.formatDuration(uptimeSince, pw); 13398 pw.print(" used "); 13399 TimeUtils.formatDuration(timeUsed, pw); 13400 pw.print(" ("); 13401 pw.print((timeUsed*100)/uptimeSince); 13402 pw.println("%)"); 13403 } 13404 } 13405 } 13406 } 13407 return true; 13408 } 13409 13410 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13411 ArrayList<ProcessRecord> procs; 13412 synchronized (this) { 13413 if (args != null && args.length > start 13414 && args[start].charAt(0) != '-') { 13415 procs = new ArrayList<ProcessRecord>(); 13416 int pid = -1; 13417 try { 13418 pid = Integer.parseInt(args[start]); 13419 } catch (NumberFormatException e) { 13420 } 13421 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13422 ProcessRecord proc = mLruProcesses.get(i); 13423 if (proc.pid == pid) { 13424 procs.add(proc); 13425 } else if (proc.processName.equals(args[start])) { 13426 procs.add(proc); 13427 } 13428 } 13429 if (procs.size() <= 0) { 13430 return null; 13431 } 13432 } else { 13433 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13434 } 13435 } 13436 return procs; 13437 } 13438 13439 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13440 PrintWriter pw, String[] args) { 13441 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13442 if (procs == null) { 13443 pw.println("No process found for: " + args[0]); 13444 return; 13445 } 13446 13447 long uptime = SystemClock.uptimeMillis(); 13448 long realtime = SystemClock.elapsedRealtime(); 13449 pw.println("Applications Graphics Acceleration Info:"); 13450 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13451 13452 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13453 ProcessRecord r = procs.get(i); 13454 if (r.thread != null) { 13455 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13456 pw.flush(); 13457 try { 13458 TransferPipe tp = new TransferPipe(); 13459 try { 13460 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13461 tp.go(fd); 13462 } finally { 13463 tp.kill(); 13464 } 13465 } catch (IOException e) { 13466 pw.println("Failure while dumping the app: " + r); 13467 pw.flush(); 13468 } catch (RemoteException e) { 13469 pw.println("Got a RemoteException while dumping the app " + r); 13470 pw.flush(); 13471 } 13472 } 13473 } 13474 } 13475 13476 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13477 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13478 if (procs == null) { 13479 pw.println("No process found for: " + args[0]); 13480 return; 13481 } 13482 13483 pw.println("Applications Database Info:"); 13484 13485 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13486 ProcessRecord r = procs.get(i); 13487 if (r.thread != null) { 13488 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13489 pw.flush(); 13490 try { 13491 TransferPipe tp = new TransferPipe(); 13492 try { 13493 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13494 tp.go(fd); 13495 } finally { 13496 tp.kill(); 13497 } 13498 } catch (IOException e) { 13499 pw.println("Failure while dumping the app: " + r); 13500 pw.flush(); 13501 } catch (RemoteException e) { 13502 pw.println("Got a RemoteException while dumping the app " + r); 13503 pw.flush(); 13504 } 13505 } 13506 } 13507 } 13508 13509 final static class MemItem { 13510 final boolean isProc; 13511 final String label; 13512 final String shortLabel; 13513 final long pss; 13514 final int id; 13515 final boolean hasActivities; 13516 ArrayList<MemItem> subitems; 13517 13518 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13519 boolean _hasActivities) { 13520 isProc = true; 13521 label = _label; 13522 shortLabel = _shortLabel; 13523 pss = _pss; 13524 id = _id; 13525 hasActivities = _hasActivities; 13526 } 13527 13528 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13529 isProc = false; 13530 label = _label; 13531 shortLabel = _shortLabel; 13532 pss = _pss; 13533 id = _id; 13534 hasActivities = false; 13535 } 13536 } 13537 13538 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13539 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13540 if (sort && !isCompact) { 13541 Collections.sort(items, new Comparator<MemItem>() { 13542 @Override 13543 public int compare(MemItem lhs, MemItem rhs) { 13544 if (lhs.pss < rhs.pss) { 13545 return 1; 13546 } else if (lhs.pss > rhs.pss) { 13547 return -1; 13548 } 13549 return 0; 13550 } 13551 }); 13552 } 13553 13554 for (int i=0; i<items.size(); i++) { 13555 MemItem mi = items.get(i); 13556 if (!isCompact) { 13557 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13558 } else if (mi.isProc) { 13559 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13560 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13561 pw.println(mi.hasActivities ? ",a" : ",e"); 13562 } else { 13563 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13564 pw.println(mi.pss); 13565 } 13566 if (mi.subitems != null) { 13567 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13568 true, isCompact); 13569 } 13570 } 13571 } 13572 13573 // These are in KB. 13574 static final long[] DUMP_MEM_BUCKETS = new long[] { 13575 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13576 120*1024, 160*1024, 200*1024, 13577 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13578 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13579 }; 13580 13581 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13582 boolean stackLike) { 13583 int start = label.lastIndexOf('.'); 13584 if (start >= 0) start++; 13585 else start = 0; 13586 int end = label.length(); 13587 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13588 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13589 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13590 out.append(bucket); 13591 out.append(stackLike ? "MB." : "MB "); 13592 out.append(label, start, end); 13593 return; 13594 } 13595 } 13596 out.append(memKB/1024); 13597 out.append(stackLike ? "MB." : "MB "); 13598 out.append(label, start, end); 13599 } 13600 13601 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13602 ProcessList.NATIVE_ADJ, 13603 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13604 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13605 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13606 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13607 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13608 }; 13609 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13610 "Native", 13611 "System", "Persistent", "Foreground", 13612 "Visible", "Perceptible", 13613 "Heavy Weight", "Backup", 13614 "A Services", "Home", 13615 "Previous", "B Services", "Cached" 13616 }; 13617 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13618 "native", 13619 "sys", "pers", "fore", 13620 "vis", "percept", 13621 "heavy", "backup", 13622 "servicea", "home", 13623 "prev", "serviceb", "cached" 13624 }; 13625 13626 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13627 long realtime, boolean isCheckinRequest, boolean isCompact) { 13628 if (isCheckinRequest || isCompact) { 13629 // short checkin version 13630 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13631 } else { 13632 pw.println("Applications Memory Usage (kB):"); 13633 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13634 } 13635 } 13636 13637 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13638 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13639 boolean dumpDetails = false; 13640 boolean dumpFullDetails = false; 13641 boolean dumpDalvik = false; 13642 boolean oomOnly = false; 13643 boolean isCompact = false; 13644 boolean localOnly = false; 13645 13646 int opti = 0; 13647 while (opti < args.length) { 13648 String opt = args[opti]; 13649 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13650 break; 13651 } 13652 opti++; 13653 if ("-a".equals(opt)) { 13654 dumpDetails = true; 13655 dumpFullDetails = true; 13656 dumpDalvik = true; 13657 } else if ("-d".equals(opt)) { 13658 dumpDalvik = true; 13659 } else if ("-c".equals(opt)) { 13660 isCompact = true; 13661 } else if ("--oom".equals(opt)) { 13662 oomOnly = true; 13663 } else if ("--local".equals(opt)) { 13664 localOnly = true; 13665 } else if ("-h".equals(opt)) { 13666 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13667 pw.println(" -a: include all available information for each process."); 13668 pw.println(" -d: include dalvik details when dumping process details."); 13669 pw.println(" -c: dump in a compact machine-parseable representation."); 13670 pw.println(" --oom: only show processes organized by oom adj."); 13671 pw.println(" --local: only collect details locally, don't call process."); 13672 pw.println("If [process] is specified it can be the name or "); 13673 pw.println("pid of a specific process to dump."); 13674 return; 13675 } else { 13676 pw.println("Unknown argument: " + opt + "; use -h for help"); 13677 } 13678 } 13679 13680 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13681 long uptime = SystemClock.uptimeMillis(); 13682 long realtime = SystemClock.elapsedRealtime(); 13683 final long[] tmpLong = new long[1]; 13684 13685 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13686 if (procs == null) { 13687 // No Java processes. Maybe they want to print a native process. 13688 if (args != null && args.length > opti 13689 && args[opti].charAt(0) != '-') { 13690 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13691 = new ArrayList<ProcessCpuTracker.Stats>(); 13692 updateCpuStatsNow(); 13693 int findPid = -1; 13694 try { 13695 findPid = Integer.parseInt(args[opti]); 13696 } catch (NumberFormatException e) { 13697 } 13698 synchronized (mProcessCpuThread) { 13699 final int N = mProcessCpuTracker.countStats(); 13700 for (int i=0; i<N; i++) { 13701 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13702 if (st.pid == findPid || (st.baseName != null 13703 && st.baseName.equals(args[opti]))) { 13704 nativeProcs.add(st); 13705 } 13706 } 13707 } 13708 if (nativeProcs.size() > 0) { 13709 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13710 isCompact); 13711 Debug.MemoryInfo mi = null; 13712 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13713 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13714 final int pid = r.pid; 13715 if (!isCheckinRequest && dumpDetails) { 13716 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13717 } 13718 if (mi == null) { 13719 mi = new Debug.MemoryInfo(); 13720 } 13721 if (dumpDetails || (!brief && !oomOnly)) { 13722 Debug.getMemoryInfo(pid, mi); 13723 } else { 13724 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13725 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13726 } 13727 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13728 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13729 if (isCheckinRequest) { 13730 pw.println(); 13731 } 13732 } 13733 return; 13734 } 13735 } 13736 pw.println("No process found for: " + args[opti]); 13737 return; 13738 } 13739 13740 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13741 dumpDetails = true; 13742 } 13743 13744 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13745 13746 String[] innerArgs = new String[args.length-opti]; 13747 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13748 13749 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13750 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13751 long nativePss=0, dalvikPss=0, otherPss=0; 13752 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13753 13754 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13755 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13756 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13757 13758 long totalPss = 0; 13759 long cachedPss = 0; 13760 13761 Debug.MemoryInfo mi = null; 13762 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13763 final ProcessRecord r = procs.get(i); 13764 final IApplicationThread thread; 13765 final int pid; 13766 final int oomAdj; 13767 final boolean hasActivities; 13768 synchronized (this) { 13769 thread = r.thread; 13770 pid = r.pid; 13771 oomAdj = r.getSetAdjWithServices(); 13772 hasActivities = r.activities.size() > 0; 13773 } 13774 if (thread != null) { 13775 if (!isCheckinRequest && dumpDetails) { 13776 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13777 } 13778 if (mi == null) { 13779 mi = new Debug.MemoryInfo(); 13780 } 13781 if (dumpDetails || (!brief && !oomOnly)) { 13782 Debug.getMemoryInfo(pid, mi); 13783 } else { 13784 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13785 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13786 } 13787 if (dumpDetails) { 13788 if (localOnly) { 13789 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13790 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13791 if (isCheckinRequest) { 13792 pw.println(); 13793 } 13794 } else { 13795 try { 13796 pw.flush(); 13797 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13798 dumpDalvik, innerArgs); 13799 } catch (RemoteException e) { 13800 if (!isCheckinRequest) { 13801 pw.println("Got RemoteException!"); 13802 pw.flush(); 13803 } 13804 } 13805 } 13806 } 13807 13808 final long myTotalPss = mi.getTotalPss(); 13809 final long myTotalUss = mi.getTotalUss(); 13810 13811 synchronized (this) { 13812 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13813 // Record this for posterity if the process has been stable. 13814 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13815 } 13816 } 13817 13818 if (!isCheckinRequest && mi != null) { 13819 totalPss += myTotalPss; 13820 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13821 (hasActivities ? " / activities)" : ")"), 13822 r.processName, myTotalPss, pid, hasActivities); 13823 procMems.add(pssItem); 13824 procMemsMap.put(pid, pssItem); 13825 13826 nativePss += mi.nativePss; 13827 dalvikPss += mi.dalvikPss; 13828 otherPss += mi.otherPss; 13829 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13830 long mem = mi.getOtherPss(j); 13831 miscPss[j] += mem; 13832 otherPss -= mem; 13833 } 13834 13835 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13836 cachedPss += myTotalPss; 13837 } 13838 13839 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13840 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13841 || oomIndex == (oomPss.length-1)) { 13842 oomPss[oomIndex] += myTotalPss; 13843 if (oomProcs[oomIndex] == null) { 13844 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13845 } 13846 oomProcs[oomIndex].add(pssItem); 13847 break; 13848 } 13849 } 13850 } 13851 } 13852 } 13853 13854 long nativeProcTotalPss = 0; 13855 13856 if (!isCheckinRequest && procs.size() > 1) { 13857 // If we are showing aggregations, also look for native processes to 13858 // include so that our aggregations are more accurate. 13859 updateCpuStatsNow(); 13860 synchronized (mProcessCpuThread) { 13861 final int N = mProcessCpuTracker.countStats(); 13862 for (int i=0; i<N; i++) { 13863 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13864 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13865 if (mi == null) { 13866 mi = new Debug.MemoryInfo(); 13867 } 13868 if (!brief && !oomOnly) { 13869 Debug.getMemoryInfo(st.pid, mi); 13870 } else { 13871 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13872 mi.nativePrivateDirty = (int)tmpLong[0]; 13873 } 13874 13875 final long myTotalPss = mi.getTotalPss(); 13876 totalPss += myTotalPss; 13877 nativeProcTotalPss += myTotalPss; 13878 13879 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13880 st.name, myTotalPss, st.pid, false); 13881 procMems.add(pssItem); 13882 13883 nativePss += mi.nativePss; 13884 dalvikPss += mi.dalvikPss; 13885 otherPss += mi.otherPss; 13886 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13887 long mem = mi.getOtherPss(j); 13888 miscPss[j] += mem; 13889 otherPss -= mem; 13890 } 13891 oomPss[0] += myTotalPss; 13892 if (oomProcs[0] == null) { 13893 oomProcs[0] = new ArrayList<MemItem>(); 13894 } 13895 oomProcs[0].add(pssItem); 13896 } 13897 } 13898 } 13899 13900 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13901 13902 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13903 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13904 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13905 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13906 String label = Debug.MemoryInfo.getOtherLabel(j); 13907 catMems.add(new MemItem(label, label, miscPss[j], j)); 13908 } 13909 13910 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13911 for (int j=0; j<oomPss.length; j++) { 13912 if (oomPss[j] != 0) { 13913 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13914 : DUMP_MEM_OOM_LABEL[j]; 13915 MemItem item = new MemItem(label, label, oomPss[j], 13916 DUMP_MEM_OOM_ADJ[j]); 13917 item.subitems = oomProcs[j]; 13918 oomMems.add(item); 13919 } 13920 } 13921 13922 if (!brief && !oomOnly && !isCompact) { 13923 pw.println(); 13924 pw.println("Total PSS by process:"); 13925 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13926 pw.println(); 13927 } 13928 if (!isCompact) { 13929 pw.println("Total PSS by OOM adjustment:"); 13930 } 13931 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13932 if (!brief && !oomOnly) { 13933 PrintWriter out = categoryPw != null ? categoryPw : pw; 13934 if (!isCompact) { 13935 out.println(); 13936 out.println("Total PSS by category:"); 13937 } 13938 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13939 } 13940 if (!isCompact) { 13941 pw.println(); 13942 } 13943 MemInfoReader memInfo = new MemInfoReader(); 13944 memInfo.readMemInfo(); 13945 if (nativeProcTotalPss > 0) { 13946 synchronized (this) { 13947 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13948 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13949 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13950 nativeProcTotalPss); 13951 } 13952 } 13953 if (!brief) { 13954 if (!isCompact) { 13955 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13956 pw.print(" kB (status "); 13957 switch (mLastMemoryLevel) { 13958 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13959 pw.println("normal)"); 13960 break; 13961 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13962 pw.println("moderate)"); 13963 break; 13964 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13965 pw.println("low)"); 13966 break; 13967 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13968 pw.println("critical)"); 13969 break; 13970 default: 13971 pw.print(mLastMemoryLevel); 13972 pw.println(")"); 13973 break; 13974 } 13975 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13976 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13977 pw.print(cachedPss); pw.print(" cached pss + "); 13978 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13979 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13980 } else { 13981 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13982 pw.print(cachedPss + memInfo.getCachedSizeKb() 13983 + memInfo.getFreeSizeKb()); pw.print(","); 13984 pw.println(totalPss - cachedPss); 13985 } 13986 } 13987 if (!isCompact) { 13988 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13989 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13990 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13991 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13992 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13993 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13994 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13995 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13996 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13997 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13998 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13999 } 14000 if (!brief) { 14001 if (memInfo.getZramTotalSizeKb() != 0) { 14002 if (!isCompact) { 14003 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 14004 pw.print(" kB physical used for "); 14005 pw.print(memInfo.getSwapTotalSizeKb() 14006 - memInfo.getSwapFreeSizeKb()); 14007 pw.print(" kB in swap ("); 14008 pw.print(memInfo.getSwapTotalSizeKb()); 14009 pw.println(" kB total swap)"); 14010 } else { 14011 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 14012 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 14013 pw.println(memInfo.getSwapFreeSizeKb()); 14014 } 14015 } 14016 final int[] SINGLE_LONG_FORMAT = new int[] { 14017 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 14018 }; 14019 long[] longOut = new long[1]; 14020 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 14021 SINGLE_LONG_FORMAT, null, longOut, null); 14022 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14023 longOut[0] = 0; 14024 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 14025 SINGLE_LONG_FORMAT, null, longOut, null); 14026 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14027 longOut[0] = 0; 14028 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 14029 SINGLE_LONG_FORMAT, null, longOut, null); 14030 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14031 longOut[0] = 0; 14032 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 14033 SINGLE_LONG_FORMAT, null, longOut, null); 14034 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 14035 if (!isCompact) { 14036 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 14037 pw.print(" KSM: "); pw.print(sharing); 14038 pw.print(" kB saved from shared "); 14039 pw.print(shared); pw.println(" kB"); 14040 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 14041 pw.print(voltile); pw.println(" kB volatile"); 14042 } 14043 pw.print(" Tuning: "); 14044 pw.print(ActivityManager.staticGetMemoryClass()); 14045 pw.print(" (large "); 14046 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14047 pw.print("), oom "); 14048 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14049 pw.print(" kB"); 14050 pw.print(", restore limit "); 14051 pw.print(mProcessList.getCachedRestoreThresholdKb()); 14052 pw.print(" kB"); 14053 if (ActivityManager.isLowRamDeviceStatic()) { 14054 pw.print(" (low-ram)"); 14055 } 14056 if (ActivityManager.isHighEndGfx()) { 14057 pw.print(" (high-end-gfx)"); 14058 } 14059 pw.println(); 14060 } else { 14061 pw.print("ksm,"); pw.print(sharing); pw.print(","); 14062 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 14063 pw.println(voltile); 14064 pw.print("tuning,"); 14065 pw.print(ActivityManager.staticGetMemoryClass()); 14066 pw.print(','); 14067 pw.print(ActivityManager.staticGetLargeMemoryClass()); 14068 pw.print(','); 14069 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 14070 if (ActivityManager.isLowRamDeviceStatic()) { 14071 pw.print(",low-ram"); 14072 } 14073 if (ActivityManager.isHighEndGfx()) { 14074 pw.print(",high-end-gfx"); 14075 } 14076 pw.println(); 14077 } 14078 } 14079 } 14080 } 14081 14082 /** 14083 * Searches array of arguments for the specified string 14084 * @param args array of argument strings 14085 * @param value value to search for 14086 * @return true if the value is contained in the array 14087 */ 14088 private static boolean scanArgs(String[] args, String value) { 14089 if (args != null) { 14090 for (String arg : args) { 14091 if (value.equals(arg)) { 14092 return true; 14093 } 14094 } 14095 } 14096 return false; 14097 } 14098 14099 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14100 ContentProviderRecord cpr, boolean always) { 14101 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14102 14103 if (!inLaunching || always) { 14104 synchronized (cpr) { 14105 cpr.launchingApp = null; 14106 cpr.notifyAll(); 14107 } 14108 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14109 String names[] = cpr.info.authority.split(";"); 14110 for (int j = 0; j < names.length; j++) { 14111 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14112 } 14113 } 14114 14115 for (int i=0; i<cpr.connections.size(); i++) { 14116 ContentProviderConnection conn = cpr.connections.get(i); 14117 if (conn.waiting) { 14118 // If this connection is waiting for the provider, then we don't 14119 // need to mess with its process unless we are always removing 14120 // or for some reason the provider is not currently launching. 14121 if (inLaunching && !always) { 14122 continue; 14123 } 14124 } 14125 ProcessRecord capp = conn.client; 14126 conn.dead = true; 14127 if (conn.stableCount > 0) { 14128 if (!capp.persistent && capp.thread != null 14129 && capp.pid != 0 14130 && capp.pid != MY_PID) { 14131 capp.kill("depends on provider " 14132 + cpr.name.flattenToShortString() 14133 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14134 } 14135 } else if (capp.thread != null && conn.provider.provider != null) { 14136 try { 14137 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14138 } catch (RemoteException e) { 14139 } 14140 // In the protocol here, we don't expect the client to correctly 14141 // clean up this connection, we'll just remove it. 14142 cpr.connections.remove(i); 14143 conn.client.conProviders.remove(conn); 14144 } 14145 } 14146 14147 if (inLaunching && always) { 14148 mLaunchingProviders.remove(cpr); 14149 } 14150 return inLaunching; 14151 } 14152 14153 /** 14154 * Main code for cleaning up a process when it has gone away. This is 14155 * called both as a result of the process dying, or directly when stopping 14156 * a process when running in single process mode. 14157 */ 14158 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14159 boolean restarting, boolean allowRestart, int index) { 14160 if (index >= 0) { 14161 removeLruProcessLocked(app); 14162 ProcessList.remove(app.pid); 14163 } 14164 14165 mProcessesToGc.remove(app); 14166 mPendingPssProcesses.remove(app); 14167 14168 // Dismiss any open dialogs. 14169 if (app.crashDialog != null && !app.forceCrashReport) { 14170 app.crashDialog.dismiss(); 14171 app.crashDialog = null; 14172 } 14173 if (app.anrDialog != null) { 14174 app.anrDialog.dismiss(); 14175 app.anrDialog = null; 14176 } 14177 if (app.waitDialog != null) { 14178 app.waitDialog.dismiss(); 14179 app.waitDialog = null; 14180 } 14181 14182 app.crashing = false; 14183 app.notResponding = false; 14184 14185 app.resetPackageList(mProcessStats); 14186 app.unlinkDeathRecipient(); 14187 app.makeInactive(mProcessStats); 14188 app.waitingToKill = null; 14189 app.forcingToForeground = null; 14190 updateProcessForegroundLocked(app, false, false); 14191 app.foregroundActivities = false; 14192 app.hasShownUi = false; 14193 app.treatLikeActivity = false; 14194 app.hasAboveClient = false; 14195 app.hasClientActivities = false; 14196 14197 mServices.killServicesLocked(app, allowRestart); 14198 14199 boolean restart = false; 14200 14201 // Remove published content providers. 14202 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14203 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14204 final boolean always = app.bad || !allowRestart; 14205 if (removeDyingProviderLocked(app, cpr, always) || always) { 14206 // We left the provider in the launching list, need to 14207 // restart it. 14208 restart = true; 14209 } 14210 14211 cpr.provider = null; 14212 cpr.proc = null; 14213 } 14214 app.pubProviders.clear(); 14215 14216 // Take care of any launching providers waiting for this process. 14217 if (checkAppInLaunchingProvidersLocked(app, false)) { 14218 restart = true; 14219 } 14220 14221 // Unregister from connected content providers. 14222 if (!app.conProviders.isEmpty()) { 14223 for (int i=0; i<app.conProviders.size(); i++) { 14224 ContentProviderConnection conn = app.conProviders.get(i); 14225 conn.provider.connections.remove(conn); 14226 } 14227 app.conProviders.clear(); 14228 } 14229 14230 // At this point there may be remaining entries in mLaunchingProviders 14231 // where we were the only one waiting, so they are no longer of use. 14232 // Look for these and clean up if found. 14233 // XXX Commented out for now. Trying to figure out a way to reproduce 14234 // the actual situation to identify what is actually going on. 14235 if (false) { 14236 for (int i=0; i<mLaunchingProviders.size(); i++) { 14237 ContentProviderRecord cpr = (ContentProviderRecord) 14238 mLaunchingProviders.get(i); 14239 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14240 synchronized (cpr) { 14241 cpr.launchingApp = null; 14242 cpr.notifyAll(); 14243 } 14244 } 14245 } 14246 } 14247 14248 skipCurrentReceiverLocked(app); 14249 14250 // Unregister any receivers. 14251 for (int i=app.receivers.size()-1; i>=0; i--) { 14252 removeReceiverLocked(app.receivers.valueAt(i)); 14253 } 14254 app.receivers.clear(); 14255 14256 // If the app is undergoing backup, tell the backup manager about it 14257 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14258 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14259 + mBackupTarget.appInfo + " died during backup"); 14260 try { 14261 IBackupManager bm = IBackupManager.Stub.asInterface( 14262 ServiceManager.getService(Context.BACKUP_SERVICE)); 14263 bm.agentDisconnected(app.info.packageName); 14264 } catch (RemoteException e) { 14265 // can't happen; backup manager is local 14266 } 14267 } 14268 14269 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14270 ProcessChangeItem item = mPendingProcessChanges.get(i); 14271 if (item.pid == app.pid) { 14272 mPendingProcessChanges.remove(i); 14273 mAvailProcessChanges.add(item); 14274 } 14275 } 14276 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14277 14278 // If the caller is restarting this app, then leave it in its 14279 // current lists and let the caller take care of it. 14280 if (restarting) { 14281 return; 14282 } 14283 14284 if (!app.persistent || app.isolated) { 14285 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14286 "Removing non-persistent process during cleanup: " + app); 14287 mProcessNames.remove(app.processName, app.uid); 14288 mIsolatedProcesses.remove(app.uid); 14289 if (mHeavyWeightProcess == app) { 14290 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14291 mHeavyWeightProcess.userId, 0)); 14292 mHeavyWeightProcess = null; 14293 } 14294 } else if (!app.removed) { 14295 // This app is persistent, so we need to keep its record around. 14296 // If it is not already on the pending app list, add it there 14297 // and start a new process for it. 14298 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14299 mPersistentStartingProcesses.add(app); 14300 restart = true; 14301 } 14302 } 14303 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14304 "Clean-up removing on hold: " + app); 14305 mProcessesOnHold.remove(app); 14306 14307 if (app == mHomeProcess) { 14308 mHomeProcess = null; 14309 } 14310 if (app == mPreviousProcess) { 14311 mPreviousProcess = null; 14312 } 14313 14314 if (restart && !app.isolated) { 14315 // We have components that still need to be running in the 14316 // process, so re-launch it. 14317 mProcessNames.put(app.processName, app.uid, app); 14318 startProcessLocked(app, "restart", app.processName); 14319 } else if (app.pid > 0 && app.pid != MY_PID) { 14320 // Goodbye! 14321 boolean removed; 14322 synchronized (mPidsSelfLocked) { 14323 mPidsSelfLocked.remove(app.pid); 14324 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14325 } 14326 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14327 if (app.isolated) { 14328 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14329 } 14330 app.setPid(0); 14331 } 14332 } 14333 14334 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14335 // Look through the content providers we are waiting to have launched, 14336 // and if any run in this process then either schedule a restart of 14337 // the process or kill the client waiting for it if this process has 14338 // gone bad. 14339 int NL = mLaunchingProviders.size(); 14340 boolean restart = false; 14341 for (int i=0; i<NL; i++) { 14342 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14343 if (cpr.launchingApp == app) { 14344 if (!alwaysBad && !app.bad) { 14345 restart = true; 14346 } else { 14347 removeDyingProviderLocked(app, cpr, true); 14348 // cpr should have been removed from mLaunchingProviders 14349 NL = mLaunchingProviders.size(); 14350 i--; 14351 } 14352 } 14353 } 14354 return restart; 14355 } 14356 14357 // ========================================================= 14358 // SERVICES 14359 // ========================================================= 14360 14361 @Override 14362 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14363 int flags) { 14364 enforceNotIsolatedCaller("getServices"); 14365 synchronized (this) { 14366 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14367 } 14368 } 14369 14370 @Override 14371 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14372 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14373 synchronized (this) { 14374 return mServices.getRunningServiceControlPanelLocked(name); 14375 } 14376 } 14377 14378 @Override 14379 public ComponentName startService(IApplicationThread caller, Intent service, 14380 String resolvedType, int userId) { 14381 enforceNotIsolatedCaller("startService"); 14382 // Refuse possible leaked file descriptors 14383 if (service != null && service.hasFileDescriptors() == true) { 14384 throw new IllegalArgumentException("File descriptors passed in Intent"); 14385 } 14386 14387 if (DEBUG_SERVICE) 14388 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14389 synchronized(this) { 14390 final int callingPid = Binder.getCallingPid(); 14391 final int callingUid = Binder.getCallingUid(); 14392 final long origId = Binder.clearCallingIdentity(); 14393 ComponentName res = mServices.startServiceLocked(caller, service, 14394 resolvedType, callingPid, callingUid, userId); 14395 Binder.restoreCallingIdentity(origId); 14396 return res; 14397 } 14398 } 14399 14400 ComponentName startServiceInPackage(int uid, 14401 Intent service, String resolvedType, int userId) { 14402 synchronized(this) { 14403 if (DEBUG_SERVICE) 14404 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14405 final long origId = Binder.clearCallingIdentity(); 14406 ComponentName res = mServices.startServiceLocked(null, service, 14407 resolvedType, -1, uid, userId); 14408 Binder.restoreCallingIdentity(origId); 14409 return res; 14410 } 14411 } 14412 14413 @Override 14414 public int stopService(IApplicationThread caller, Intent service, 14415 String resolvedType, int userId) { 14416 enforceNotIsolatedCaller("stopService"); 14417 // Refuse possible leaked file descriptors 14418 if (service != null && service.hasFileDescriptors() == true) { 14419 throw new IllegalArgumentException("File descriptors passed in Intent"); 14420 } 14421 14422 synchronized(this) { 14423 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14424 } 14425 } 14426 14427 @Override 14428 public IBinder peekService(Intent service, String resolvedType) { 14429 enforceNotIsolatedCaller("peekService"); 14430 // Refuse possible leaked file descriptors 14431 if (service != null && service.hasFileDescriptors() == true) { 14432 throw new IllegalArgumentException("File descriptors passed in Intent"); 14433 } 14434 synchronized(this) { 14435 return mServices.peekServiceLocked(service, resolvedType); 14436 } 14437 } 14438 14439 @Override 14440 public boolean stopServiceToken(ComponentName className, IBinder token, 14441 int startId) { 14442 synchronized(this) { 14443 return mServices.stopServiceTokenLocked(className, token, startId); 14444 } 14445 } 14446 14447 @Override 14448 public void setServiceForeground(ComponentName className, IBinder token, 14449 int id, Notification notification, boolean removeNotification) { 14450 synchronized(this) { 14451 mServices.setServiceForegroundLocked(className, token, id, notification, 14452 removeNotification); 14453 } 14454 } 14455 14456 @Override 14457 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14458 boolean requireFull, String name, String callerPackage) { 14459 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14460 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14461 } 14462 14463 int unsafeConvertIncomingUser(int userId) { 14464 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14465 ? mCurrentUserId : userId; 14466 } 14467 14468 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14469 int allowMode, String name, String callerPackage) { 14470 final int callingUserId = UserHandle.getUserId(callingUid); 14471 if (callingUserId == userId) { 14472 return userId; 14473 } 14474 14475 // Note that we may be accessing mCurrentUserId outside of a lock... 14476 // shouldn't be a big deal, if this is being called outside 14477 // of a locked context there is intrinsically a race with 14478 // the value the caller will receive and someone else changing it. 14479 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14480 // we will switch to the calling user if access to the current user fails. 14481 int targetUserId = unsafeConvertIncomingUser(userId); 14482 14483 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14484 final boolean allow; 14485 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14486 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14487 // If the caller has this permission, they always pass go. And collect $200. 14488 allow = true; 14489 } else if (allowMode == ALLOW_FULL_ONLY) { 14490 // We require full access, sucks to be you. 14491 allow = false; 14492 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14493 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14494 // If the caller does not have either permission, they are always doomed. 14495 allow = false; 14496 } else if (allowMode == ALLOW_NON_FULL) { 14497 // We are blanket allowing non-full access, you lucky caller! 14498 allow = true; 14499 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14500 // We may or may not allow this depending on whether the two users are 14501 // in the same profile. 14502 synchronized (mUserProfileGroupIdsSelfLocked) { 14503 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14504 UserInfo.NO_PROFILE_GROUP_ID); 14505 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14506 UserInfo.NO_PROFILE_GROUP_ID); 14507 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14508 && callingProfile == targetProfile; 14509 } 14510 } else { 14511 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14512 } 14513 if (!allow) { 14514 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14515 // In this case, they would like to just execute as their 14516 // owner user instead of failing. 14517 targetUserId = callingUserId; 14518 } else { 14519 StringBuilder builder = new StringBuilder(128); 14520 builder.append("Permission Denial: "); 14521 builder.append(name); 14522 if (callerPackage != null) { 14523 builder.append(" from "); 14524 builder.append(callerPackage); 14525 } 14526 builder.append(" asks to run as user "); 14527 builder.append(userId); 14528 builder.append(" but is calling from user "); 14529 builder.append(UserHandle.getUserId(callingUid)); 14530 builder.append("; this requires "); 14531 builder.append(INTERACT_ACROSS_USERS_FULL); 14532 if (allowMode != ALLOW_FULL_ONLY) { 14533 builder.append(" or "); 14534 builder.append(INTERACT_ACROSS_USERS); 14535 } 14536 String msg = builder.toString(); 14537 Slog.w(TAG, msg); 14538 throw new SecurityException(msg); 14539 } 14540 } 14541 } 14542 if (!allowAll && targetUserId < 0) { 14543 throw new IllegalArgumentException( 14544 "Call does not support special user #" + targetUserId); 14545 } 14546 return targetUserId; 14547 } 14548 14549 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14550 String className, int flags) { 14551 boolean result = false; 14552 // For apps that don't have pre-defined UIDs, check for permission 14553 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14554 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14555 if (ActivityManager.checkUidPermission( 14556 INTERACT_ACROSS_USERS, 14557 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14558 ComponentName comp = new ComponentName(aInfo.packageName, className); 14559 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14560 + " requests FLAG_SINGLE_USER, but app does not hold " 14561 + INTERACT_ACROSS_USERS; 14562 Slog.w(TAG, msg); 14563 throw new SecurityException(msg); 14564 } 14565 // Permission passed 14566 result = true; 14567 } 14568 } else if ("system".equals(componentProcessName)) { 14569 result = true; 14570 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14571 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14572 // Phone app is allowed to export singleuser providers. 14573 result = true; 14574 } else { 14575 // App with pre-defined UID, check if it's a persistent app 14576 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14577 } 14578 if (DEBUG_MU) { 14579 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14580 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14581 } 14582 return result; 14583 } 14584 14585 /** 14586 * Checks to see if the caller is in the same app as the singleton 14587 * component, or the component is in a special app. It allows special apps 14588 * to export singleton components but prevents exporting singleton 14589 * components for regular apps. 14590 */ 14591 boolean isValidSingletonCall(int callingUid, int componentUid) { 14592 int componentAppId = UserHandle.getAppId(componentUid); 14593 return UserHandle.isSameApp(callingUid, componentUid) 14594 || componentAppId == Process.SYSTEM_UID 14595 || componentAppId == Process.PHONE_UID 14596 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14597 == PackageManager.PERMISSION_GRANTED; 14598 } 14599 14600 public int bindService(IApplicationThread caller, IBinder token, 14601 Intent service, String resolvedType, 14602 IServiceConnection connection, int flags, int userId) { 14603 enforceNotIsolatedCaller("bindService"); 14604 // Refuse possible leaked file descriptors 14605 if (service != null && service.hasFileDescriptors() == true) { 14606 throw new IllegalArgumentException("File descriptors passed in Intent"); 14607 } 14608 14609 synchronized(this) { 14610 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14611 connection, flags, userId); 14612 } 14613 } 14614 14615 public boolean unbindService(IServiceConnection connection) { 14616 synchronized (this) { 14617 return mServices.unbindServiceLocked(connection); 14618 } 14619 } 14620 14621 public void publishService(IBinder token, Intent intent, IBinder service) { 14622 // Refuse possible leaked file descriptors 14623 if (intent != null && intent.hasFileDescriptors() == true) { 14624 throw new IllegalArgumentException("File descriptors passed in Intent"); 14625 } 14626 14627 synchronized(this) { 14628 if (!(token instanceof ServiceRecord)) { 14629 throw new IllegalArgumentException("Invalid service token"); 14630 } 14631 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14632 } 14633 } 14634 14635 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14636 // Refuse possible leaked file descriptors 14637 if (intent != null && intent.hasFileDescriptors() == true) { 14638 throw new IllegalArgumentException("File descriptors passed in Intent"); 14639 } 14640 14641 synchronized(this) { 14642 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14643 } 14644 } 14645 14646 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14647 synchronized(this) { 14648 if (!(token instanceof ServiceRecord)) { 14649 throw new IllegalArgumentException("Invalid service token"); 14650 } 14651 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14652 } 14653 } 14654 14655 // ========================================================= 14656 // BACKUP AND RESTORE 14657 // ========================================================= 14658 14659 // Cause the target app to be launched if necessary and its backup agent 14660 // instantiated. The backup agent will invoke backupAgentCreated() on the 14661 // activity manager to announce its creation. 14662 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14663 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14664 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14665 14666 synchronized(this) { 14667 // !!! TODO: currently no check here that we're already bound 14668 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14669 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14670 synchronized (stats) { 14671 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14672 } 14673 14674 // Backup agent is now in use, its package can't be stopped. 14675 try { 14676 AppGlobals.getPackageManager().setPackageStoppedState( 14677 app.packageName, false, UserHandle.getUserId(app.uid)); 14678 } catch (RemoteException e) { 14679 } catch (IllegalArgumentException e) { 14680 Slog.w(TAG, "Failed trying to unstop package " 14681 + app.packageName + ": " + e); 14682 } 14683 14684 BackupRecord r = new BackupRecord(ss, app, backupMode); 14685 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14686 ? new ComponentName(app.packageName, app.backupAgentName) 14687 : new ComponentName("android", "FullBackupAgent"); 14688 // startProcessLocked() returns existing proc's record if it's already running 14689 ProcessRecord proc = startProcessLocked(app.processName, app, 14690 false, 0, "backup", hostingName, false, false, false); 14691 if (proc == null) { 14692 Slog.e(TAG, "Unable to start backup agent process " + r); 14693 return false; 14694 } 14695 14696 r.app = proc; 14697 mBackupTarget = r; 14698 mBackupAppName = app.packageName; 14699 14700 // Try not to kill the process during backup 14701 updateOomAdjLocked(proc); 14702 14703 // If the process is already attached, schedule the creation of the backup agent now. 14704 // If it is not yet live, this will be done when it attaches to the framework. 14705 if (proc.thread != null) { 14706 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14707 try { 14708 proc.thread.scheduleCreateBackupAgent(app, 14709 compatibilityInfoForPackageLocked(app), backupMode); 14710 } catch (RemoteException e) { 14711 // Will time out on the backup manager side 14712 } 14713 } else { 14714 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14715 } 14716 // Invariants: at this point, the target app process exists and the application 14717 // is either already running or in the process of coming up. mBackupTarget and 14718 // mBackupAppName describe the app, so that when it binds back to the AM we 14719 // know that it's scheduled for a backup-agent operation. 14720 } 14721 14722 return true; 14723 } 14724 14725 @Override 14726 public void clearPendingBackup() { 14727 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14728 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14729 14730 synchronized (this) { 14731 mBackupTarget = null; 14732 mBackupAppName = null; 14733 } 14734 } 14735 14736 // A backup agent has just come up 14737 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14738 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14739 + " = " + agent); 14740 14741 synchronized(this) { 14742 if (!agentPackageName.equals(mBackupAppName)) { 14743 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14744 return; 14745 } 14746 } 14747 14748 long oldIdent = Binder.clearCallingIdentity(); 14749 try { 14750 IBackupManager bm = IBackupManager.Stub.asInterface( 14751 ServiceManager.getService(Context.BACKUP_SERVICE)); 14752 bm.agentConnected(agentPackageName, agent); 14753 } catch (RemoteException e) { 14754 // can't happen; the backup manager service is local 14755 } catch (Exception e) { 14756 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14757 e.printStackTrace(); 14758 } finally { 14759 Binder.restoreCallingIdentity(oldIdent); 14760 } 14761 } 14762 14763 // done with this agent 14764 public void unbindBackupAgent(ApplicationInfo appInfo) { 14765 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14766 if (appInfo == null) { 14767 Slog.w(TAG, "unbind backup agent for null app"); 14768 return; 14769 } 14770 14771 synchronized(this) { 14772 try { 14773 if (mBackupAppName == null) { 14774 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14775 return; 14776 } 14777 14778 if (!mBackupAppName.equals(appInfo.packageName)) { 14779 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14780 return; 14781 } 14782 14783 // Not backing this app up any more; reset its OOM adjustment 14784 final ProcessRecord proc = mBackupTarget.app; 14785 updateOomAdjLocked(proc); 14786 14787 // If the app crashed during backup, 'thread' will be null here 14788 if (proc.thread != null) { 14789 try { 14790 proc.thread.scheduleDestroyBackupAgent(appInfo, 14791 compatibilityInfoForPackageLocked(appInfo)); 14792 } catch (Exception e) { 14793 Slog.e(TAG, "Exception when unbinding backup agent:"); 14794 e.printStackTrace(); 14795 } 14796 } 14797 } finally { 14798 mBackupTarget = null; 14799 mBackupAppName = null; 14800 } 14801 } 14802 } 14803 // ========================================================= 14804 // BROADCASTS 14805 // ========================================================= 14806 14807 private final List getStickiesLocked(String action, IntentFilter filter, 14808 List cur, int userId) { 14809 final ContentResolver resolver = mContext.getContentResolver(); 14810 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14811 if (stickies == null) { 14812 return cur; 14813 } 14814 final ArrayList<Intent> list = stickies.get(action); 14815 if (list == null) { 14816 return cur; 14817 } 14818 int N = list.size(); 14819 for (int i=0; i<N; i++) { 14820 Intent intent = list.get(i); 14821 if (filter.match(resolver, intent, true, TAG) >= 0) { 14822 if (cur == null) { 14823 cur = new ArrayList<Intent>(); 14824 } 14825 cur.add(intent); 14826 } 14827 } 14828 return cur; 14829 } 14830 14831 boolean isPendingBroadcastProcessLocked(int pid) { 14832 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14833 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14834 } 14835 14836 void skipPendingBroadcastLocked(int pid) { 14837 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14838 for (BroadcastQueue queue : mBroadcastQueues) { 14839 queue.skipPendingBroadcastLocked(pid); 14840 } 14841 } 14842 14843 // The app just attached; send any pending broadcasts that it should receive 14844 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14845 boolean didSomething = false; 14846 for (BroadcastQueue queue : mBroadcastQueues) { 14847 didSomething |= queue.sendPendingBroadcastsLocked(app); 14848 } 14849 return didSomething; 14850 } 14851 14852 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14853 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14854 enforceNotIsolatedCaller("registerReceiver"); 14855 int callingUid; 14856 int callingPid; 14857 synchronized(this) { 14858 ProcessRecord callerApp = null; 14859 if (caller != null) { 14860 callerApp = getRecordForAppLocked(caller); 14861 if (callerApp == null) { 14862 throw new SecurityException( 14863 "Unable to find app for caller " + caller 14864 + " (pid=" + Binder.getCallingPid() 14865 + ") when registering receiver " + receiver); 14866 } 14867 if (callerApp.info.uid != Process.SYSTEM_UID && 14868 !callerApp.pkgList.containsKey(callerPackage) && 14869 !"android".equals(callerPackage)) { 14870 throw new SecurityException("Given caller package " + callerPackage 14871 + " is not running in process " + callerApp); 14872 } 14873 callingUid = callerApp.info.uid; 14874 callingPid = callerApp.pid; 14875 } else { 14876 callerPackage = null; 14877 callingUid = Binder.getCallingUid(); 14878 callingPid = Binder.getCallingPid(); 14879 } 14880 14881 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14882 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14883 14884 List allSticky = null; 14885 14886 // Look for any matching sticky broadcasts... 14887 Iterator actions = filter.actionsIterator(); 14888 if (actions != null) { 14889 while (actions.hasNext()) { 14890 String action = (String)actions.next(); 14891 allSticky = getStickiesLocked(action, filter, allSticky, 14892 UserHandle.USER_ALL); 14893 allSticky = getStickiesLocked(action, filter, allSticky, 14894 UserHandle.getUserId(callingUid)); 14895 } 14896 } else { 14897 allSticky = getStickiesLocked(null, filter, allSticky, 14898 UserHandle.USER_ALL); 14899 allSticky = getStickiesLocked(null, filter, allSticky, 14900 UserHandle.getUserId(callingUid)); 14901 } 14902 14903 // The first sticky in the list is returned directly back to 14904 // the client. 14905 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14906 14907 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14908 + ": " + sticky); 14909 14910 if (receiver == null) { 14911 return sticky; 14912 } 14913 14914 ReceiverList rl 14915 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14916 if (rl == null) { 14917 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14918 userId, receiver); 14919 if (rl.app != null) { 14920 rl.app.receivers.add(rl); 14921 } else { 14922 try { 14923 receiver.asBinder().linkToDeath(rl, 0); 14924 } catch (RemoteException e) { 14925 return sticky; 14926 } 14927 rl.linkedToDeath = true; 14928 } 14929 mRegisteredReceivers.put(receiver.asBinder(), rl); 14930 } else if (rl.uid != callingUid) { 14931 throw new IllegalArgumentException( 14932 "Receiver requested to register for uid " + callingUid 14933 + " was previously registered for uid " + rl.uid); 14934 } else if (rl.pid != callingPid) { 14935 throw new IllegalArgumentException( 14936 "Receiver requested to register for pid " + callingPid 14937 + " was previously registered for pid " + rl.pid); 14938 } else if (rl.userId != userId) { 14939 throw new IllegalArgumentException( 14940 "Receiver requested to register for user " + userId 14941 + " was previously registered for user " + rl.userId); 14942 } 14943 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14944 permission, callingUid, userId); 14945 rl.add(bf); 14946 if (!bf.debugCheck()) { 14947 Slog.w(TAG, "==> For Dynamic broadast"); 14948 } 14949 mReceiverResolver.addFilter(bf); 14950 14951 // Enqueue broadcasts for all existing stickies that match 14952 // this filter. 14953 if (allSticky != null) { 14954 ArrayList receivers = new ArrayList(); 14955 receivers.add(bf); 14956 14957 int N = allSticky.size(); 14958 for (int i=0; i<N; i++) { 14959 Intent intent = (Intent)allSticky.get(i); 14960 BroadcastQueue queue = broadcastQueueForIntent(intent); 14961 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14962 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14963 null, null, false, true, true, -1); 14964 queue.enqueueParallelBroadcastLocked(r); 14965 queue.scheduleBroadcastsLocked(); 14966 } 14967 } 14968 14969 return sticky; 14970 } 14971 } 14972 14973 public void unregisterReceiver(IIntentReceiver receiver) { 14974 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14975 14976 final long origId = Binder.clearCallingIdentity(); 14977 try { 14978 boolean doTrim = false; 14979 14980 synchronized(this) { 14981 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14982 if (rl != null) { 14983 if (rl.curBroadcast != null) { 14984 BroadcastRecord r = rl.curBroadcast; 14985 final boolean doNext = finishReceiverLocked( 14986 receiver.asBinder(), r.resultCode, r.resultData, 14987 r.resultExtras, r.resultAbort); 14988 if (doNext) { 14989 doTrim = true; 14990 r.queue.processNextBroadcast(false); 14991 } 14992 } 14993 14994 if (rl.app != null) { 14995 rl.app.receivers.remove(rl); 14996 } 14997 removeReceiverLocked(rl); 14998 if (rl.linkedToDeath) { 14999 rl.linkedToDeath = false; 15000 rl.receiver.asBinder().unlinkToDeath(rl, 0); 15001 } 15002 } 15003 } 15004 15005 // If we actually concluded any broadcasts, we might now be able 15006 // to trim the recipients' apps from our working set 15007 if (doTrim) { 15008 trimApplications(); 15009 return; 15010 } 15011 15012 } finally { 15013 Binder.restoreCallingIdentity(origId); 15014 } 15015 } 15016 15017 void removeReceiverLocked(ReceiverList rl) { 15018 mRegisteredReceivers.remove(rl.receiver.asBinder()); 15019 int N = rl.size(); 15020 for (int i=0; i<N; i++) { 15021 mReceiverResolver.removeFilter(rl.get(i)); 15022 } 15023 } 15024 15025 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 15026 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 15027 ProcessRecord r = mLruProcesses.get(i); 15028 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 15029 try { 15030 r.thread.dispatchPackageBroadcast(cmd, packages); 15031 } catch (RemoteException ex) { 15032 } 15033 } 15034 } 15035 } 15036 15037 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 15038 int[] users) { 15039 List<ResolveInfo> receivers = null; 15040 try { 15041 HashSet<ComponentName> singleUserReceivers = null; 15042 boolean scannedFirstReceivers = false; 15043 for (int user : users) { 15044 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 15045 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 15046 if (user != 0 && newReceivers != null) { 15047 // If this is not the primary user, we need to check for 15048 // any receivers that should be filtered out. 15049 for (int i=0; i<newReceivers.size(); i++) { 15050 ResolveInfo ri = newReceivers.get(i); 15051 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 15052 newReceivers.remove(i); 15053 i--; 15054 } 15055 } 15056 } 15057 if (newReceivers != null && newReceivers.size() == 0) { 15058 newReceivers = null; 15059 } 15060 if (receivers == null) { 15061 receivers = newReceivers; 15062 } else if (newReceivers != null) { 15063 // We need to concatenate the additional receivers 15064 // found with what we have do far. This would be easy, 15065 // but we also need to de-dup any receivers that are 15066 // singleUser. 15067 if (!scannedFirstReceivers) { 15068 // Collect any single user receivers we had already retrieved. 15069 scannedFirstReceivers = true; 15070 for (int i=0; i<receivers.size(); i++) { 15071 ResolveInfo ri = receivers.get(i); 15072 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15073 ComponentName cn = new ComponentName( 15074 ri.activityInfo.packageName, ri.activityInfo.name); 15075 if (singleUserReceivers == null) { 15076 singleUserReceivers = new HashSet<ComponentName>(); 15077 } 15078 singleUserReceivers.add(cn); 15079 } 15080 } 15081 } 15082 // Add the new results to the existing results, tracking 15083 // and de-dupping single user receivers. 15084 for (int i=0; i<newReceivers.size(); i++) { 15085 ResolveInfo ri = newReceivers.get(i); 15086 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 15087 ComponentName cn = new ComponentName( 15088 ri.activityInfo.packageName, ri.activityInfo.name); 15089 if (singleUserReceivers == null) { 15090 singleUserReceivers = new HashSet<ComponentName>(); 15091 } 15092 if (!singleUserReceivers.contains(cn)) { 15093 singleUserReceivers.add(cn); 15094 receivers.add(ri); 15095 } 15096 } else { 15097 receivers.add(ri); 15098 } 15099 } 15100 } 15101 } 15102 } catch (RemoteException ex) { 15103 // pm is in same process, this will never happen. 15104 } 15105 return receivers; 15106 } 15107 15108 private final int broadcastIntentLocked(ProcessRecord callerApp, 15109 String callerPackage, Intent intent, String resolvedType, 15110 IIntentReceiver resultTo, int resultCode, String resultData, 15111 Bundle map, String requiredPermission, int appOp, 15112 boolean ordered, boolean sticky, int callingPid, int callingUid, 15113 int userId) { 15114 intent = new Intent(intent); 15115 15116 // By default broadcasts do not go to stopped apps. 15117 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15118 15119 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15120 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15121 + " ordered=" + ordered + " userid=" + userId); 15122 if ((resultTo != null) && !ordered) { 15123 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15124 } 15125 15126 userId = handleIncomingUser(callingPid, callingUid, userId, 15127 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15128 15129 // Make sure that the user who is receiving this broadcast is started. 15130 // If not, we will just skip it. 15131 15132 15133 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15134 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15135 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15136 Slog.w(TAG, "Skipping broadcast of " + intent 15137 + ": user " + userId + " is stopped"); 15138 return ActivityManager.BROADCAST_SUCCESS; 15139 } 15140 } 15141 15142 /* 15143 * Prevent non-system code (defined here to be non-persistent 15144 * processes) from sending protected broadcasts. 15145 */ 15146 int callingAppId = UserHandle.getAppId(callingUid); 15147 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15148 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15149 || callingAppId == Process.NFC_UID || callingUid == 0) { 15150 // Always okay. 15151 } else if (callerApp == null || !callerApp.persistent) { 15152 try { 15153 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15154 intent.getAction())) { 15155 String msg = "Permission Denial: not allowed to send broadcast " 15156 + intent.getAction() + " from pid=" 15157 + callingPid + ", uid=" + callingUid; 15158 Slog.w(TAG, msg); 15159 throw new SecurityException(msg); 15160 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15161 // Special case for compatibility: we don't want apps to send this, 15162 // but historically it has not been protected and apps may be using it 15163 // to poke their own app widget. So, instead of making it protected, 15164 // just limit it to the caller. 15165 if (callerApp == null) { 15166 String msg = "Permission Denial: not allowed to send broadcast " 15167 + intent.getAction() + " from unknown caller."; 15168 Slog.w(TAG, msg); 15169 throw new SecurityException(msg); 15170 } else if (intent.getComponent() != null) { 15171 // They are good enough to send to an explicit component... verify 15172 // it is being sent to the calling app. 15173 if (!intent.getComponent().getPackageName().equals( 15174 callerApp.info.packageName)) { 15175 String msg = "Permission Denial: not allowed to send broadcast " 15176 + intent.getAction() + " to " 15177 + intent.getComponent().getPackageName() + " from " 15178 + callerApp.info.packageName; 15179 Slog.w(TAG, msg); 15180 throw new SecurityException(msg); 15181 } 15182 } else { 15183 // Limit broadcast to their own package. 15184 intent.setPackage(callerApp.info.packageName); 15185 } 15186 } 15187 } catch (RemoteException e) { 15188 Slog.w(TAG, "Remote exception", e); 15189 return ActivityManager.BROADCAST_SUCCESS; 15190 } 15191 } 15192 15193 // Handle special intents: if this broadcast is from the package 15194 // manager about a package being removed, we need to remove all of 15195 // its activities from the history stack. 15196 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15197 intent.getAction()); 15198 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15199 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15200 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15201 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15202 || uidRemoved) { 15203 if (checkComponentPermission( 15204 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15205 callingPid, callingUid, -1, true) 15206 == PackageManager.PERMISSION_GRANTED) { 15207 if (uidRemoved) { 15208 final Bundle intentExtras = intent.getExtras(); 15209 final int uid = intentExtras != null 15210 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15211 if (uid >= 0) { 15212 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15213 synchronized (bs) { 15214 bs.removeUidStatsLocked(uid); 15215 } 15216 mAppOpsService.uidRemoved(uid); 15217 } 15218 } else { 15219 // If resources are unavailable just force stop all 15220 // those packages and flush the attribute cache as well. 15221 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15222 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15223 if (list != null && (list.length > 0)) { 15224 for (String pkg : list) { 15225 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15226 "storage unmount"); 15227 } 15228 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15229 sendPackageBroadcastLocked( 15230 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15231 } 15232 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15233 intent.getAction())) { 15234 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15235 } else { 15236 Uri data = intent.getData(); 15237 String ssp; 15238 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15239 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15240 intent.getAction()); 15241 boolean fullUninstall = removed && 15242 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15243 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15244 forceStopPackageLocked(ssp, UserHandle.getAppId( 15245 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15246 false, fullUninstall, userId, 15247 removed ? "pkg removed" : "pkg changed"); 15248 } 15249 if (removed) { 15250 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15251 new String[] {ssp}, userId); 15252 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15253 mAppOpsService.packageRemoved( 15254 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15255 15256 // Remove all permissions granted from/to this package 15257 removeUriPermissionsForPackageLocked(ssp, userId, true); 15258 } 15259 } 15260 } 15261 } 15262 } 15263 } else { 15264 String msg = "Permission Denial: " + intent.getAction() 15265 + " broadcast from " + callerPackage + " (pid=" + callingPid 15266 + ", uid=" + callingUid + ")" 15267 + " requires " 15268 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15269 Slog.w(TAG, msg); 15270 throw new SecurityException(msg); 15271 } 15272 15273 // Special case for adding a package: by default turn on compatibility 15274 // mode. 15275 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15276 Uri data = intent.getData(); 15277 String ssp; 15278 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15279 mCompatModePackages.handlePackageAddedLocked(ssp, 15280 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15281 } 15282 } 15283 15284 /* 15285 * If this is the time zone changed action, queue up a message that will reset the timezone 15286 * of all currently running processes. This message will get queued up before the broadcast 15287 * happens. 15288 */ 15289 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15290 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15291 } 15292 15293 /* 15294 * If the user set the time, let all running processes know. 15295 */ 15296 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15297 final int is24Hour = intent.getBooleanExtra( 15298 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15299 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15300 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15301 synchronized (stats) { 15302 stats.noteCurrentTimeChangedLocked(); 15303 } 15304 } 15305 15306 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15307 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15308 } 15309 15310 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15311 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15312 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15313 } 15314 15315 // Add to the sticky list if requested. 15316 if (sticky) { 15317 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15318 callingPid, callingUid) 15319 != PackageManager.PERMISSION_GRANTED) { 15320 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15321 + callingPid + ", uid=" + callingUid 15322 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15323 Slog.w(TAG, msg); 15324 throw new SecurityException(msg); 15325 } 15326 if (requiredPermission != null) { 15327 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15328 + " and enforce permission " + requiredPermission); 15329 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15330 } 15331 if (intent.getComponent() != null) { 15332 throw new SecurityException( 15333 "Sticky broadcasts can't target a specific component"); 15334 } 15335 // We use userId directly here, since the "all" target is maintained 15336 // as a separate set of sticky broadcasts. 15337 if (userId != UserHandle.USER_ALL) { 15338 // But first, if this is not a broadcast to all users, then 15339 // make sure it doesn't conflict with an existing broadcast to 15340 // all users. 15341 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15342 UserHandle.USER_ALL); 15343 if (stickies != null) { 15344 ArrayList<Intent> list = stickies.get(intent.getAction()); 15345 if (list != null) { 15346 int N = list.size(); 15347 int i; 15348 for (i=0; i<N; i++) { 15349 if (intent.filterEquals(list.get(i))) { 15350 throw new IllegalArgumentException( 15351 "Sticky broadcast " + intent + " for user " 15352 + userId + " conflicts with existing global broadcast"); 15353 } 15354 } 15355 } 15356 } 15357 } 15358 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15359 if (stickies == null) { 15360 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15361 mStickyBroadcasts.put(userId, stickies); 15362 } 15363 ArrayList<Intent> list = stickies.get(intent.getAction()); 15364 if (list == null) { 15365 list = new ArrayList<Intent>(); 15366 stickies.put(intent.getAction(), list); 15367 } 15368 int N = list.size(); 15369 int i; 15370 for (i=0; i<N; i++) { 15371 if (intent.filterEquals(list.get(i))) { 15372 // This sticky already exists, replace it. 15373 list.set(i, new Intent(intent)); 15374 break; 15375 } 15376 } 15377 if (i >= N) { 15378 list.add(new Intent(intent)); 15379 } 15380 } 15381 15382 int[] users; 15383 if (userId == UserHandle.USER_ALL) { 15384 // Caller wants broadcast to go to all started users. 15385 users = mStartedUserArray; 15386 } else { 15387 // Caller wants broadcast to go to one specific user. 15388 users = new int[] {userId}; 15389 } 15390 15391 // Figure out who all will receive this broadcast. 15392 List receivers = null; 15393 List<BroadcastFilter> registeredReceivers = null; 15394 // Need to resolve the intent to interested receivers... 15395 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15396 == 0) { 15397 receivers = collectReceiverComponents(intent, resolvedType, users); 15398 } 15399 if (intent.getComponent() == null) { 15400 registeredReceivers = mReceiverResolver.queryIntent(intent, 15401 resolvedType, false, userId); 15402 } 15403 15404 final boolean replacePending = 15405 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15406 15407 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15408 + " replacePending=" + replacePending); 15409 15410 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15411 if (!ordered && NR > 0) { 15412 // If we are not serializing this broadcast, then send the 15413 // registered receivers separately so they don't wait for the 15414 // components to be launched. 15415 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15416 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15417 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15418 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15419 ordered, sticky, false, userId); 15420 if (DEBUG_BROADCAST) Slog.v( 15421 TAG, "Enqueueing parallel broadcast " + r); 15422 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15423 if (!replaced) { 15424 queue.enqueueParallelBroadcastLocked(r); 15425 queue.scheduleBroadcastsLocked(); 15426 } 15427 registeredReceivers = null; 15428 NR = 0; 15429 } 15430 15431 // Merge into one list. 15432 int ir = 0; 15433 if (receivers != null) { 15434 // A special case for PACKAGE_ADDED: do not allow the package 15435 // being added to see this broadcast. This prevents them from 15436 // using this as a back door to get run as soon as they are 15437 // installed. Maybe in the future we want to have a special install 15438 // broadcast or such for apps, but we'd like to deliberately make 15439 // this decision. 15440 String skipPackages[] = null; 15441 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15442 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15443 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15444 Uri data = intent.getData(); 15445 if (data != null) { 15446 String pkgName = data.getSchemeSpecificPart(); 15447 if (pkgName != null) { 15448 skipPackages = new String[] { pkgName }; 15449 } 15450 } 15451 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15452 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15453 } 15454 if (skipPackages != null && (skipPackages.length > 0)) { 15455 for (String skipPackage : skipPackages) { 15456 if (skipPackage != null) { 15457 int NT = receivers.size(); 15458 for (int it=0; it<NT; it++) { 15459 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15460 if (curt.activityInfo.packageName.equals(skipPackage)) { 15461 receivers.remove(it); 15462 it--; 15463 NT--; 15464 } 15465 } 15466 } 15467 } 15468 } 15469 15470 int NT = receivers != null ? receivers.size() : 0; 15471 int it = 0; 15472 ResolveInfo curt = null; 15473 BroadcastFilter curr = null; 15474 while (it < NT && ir < NR) { 15475 if (curt == null) { 15476 curt = (ResolveInfo)receivers.get(it); 15477 } 15478 if (curr == null) { 15479 curr = registeredReceivers.get(ir); 15480 } 15481 if (curr.getPriority() >= curt.priority) { 15482 // Insert this broadcast record into the final list. 15483 receivers.add(it, curr); 15484 ir++; 15485 curr = null; 15486 it++; 15487 NT++; 15488 } else { 15489 // Skip to the next ResolveInfo in the final list. 15490 it++; 15491 curt = null; 15492 } 15493 } 15494 } 15495 while (ir < NR) { 15496 if (receivers == null) { 15497 receivers = new ArrayList(); 15498 } 15499 receivers.add(registeredReceivers.get(ir)); 15500 ir++; 15501 } 15502 15503 if ((receivers != null && receivers.size() > 0) 15504 || resultTo != null) { 15505 BroadcastQueue queue = broadcastQueueForIntent(intent); 15506 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15507 callerPackage, callingPid, callingUid, resolvedType, 15508 requiredPermission, appOp, receivers, resultTo, resultCode, 15509 resultData, map, ordered, sticky, false, userId); 15510 if (DEBUG_BROADCAST) Slog.v( 15511 TAG, "Enqueueing ordered broadcast " + r 15512 + ": prev had " + queue.mOrderedBroadcasts.size()); 15513 if (DEBUG_BROADCAST) { 15514 int seq = r.intent.getIntExtra("seq", -1); 15515 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15516 } 15517 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15518 if (!replaced) { 15519 queue.enqueueOrderedBroadcastLocked(r); 15520 queue.scheduleBroadcastsLocked(); 15521 } 15522 } 15523 15524 return ActivityManager.BROADCAST_SUCCESS; 15525 } 15526 15527 final Intent verifyBroadcastLocked(Intent intent) { 15528 // Refuse possible leaked file descriptors 15529 if (intent != null && intent.hasFileDescriptors() == true) { 15530 throw new IllegalArgumentException("File descriptors passed in Intent"); 15531 } 15532 15533 int flags = intent.getFlags(); 15534 15535 if (!mProcessesReady) { 15536 // if the caller really truly claims to know what they're doing, go 15537 // ahead and allow the broadcast without launching any receivers 15538 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15539 intent = new Intent(intent); 15540 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15541 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15542 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15543 + " before boot completion"); 15544 throw new IllegalStateException("Cannot broadcast before boot completed"); 15545 } 15546 } 15547 15548 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15549 throw new IllegalArgumentException( 15550 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15551 } 15552 15553 return intent; 15554 } 15555 15556 public final int broadcastIntent(IApplicationThread caller, 15557 Intent intent, String resolvedType, IIntentReceiver resultTo, 15558 int resultCode, String resultData, Bundle map, 15559 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15560 enforceNotIsolatedCaller("broadcastIntent"); 15561 synchronized(this) { 15562 intent = verifyBroadcastLocked(intent); 15563 15564 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15565 final int callingPid = Binder.getCallingPid(); 15566 final int callingUid = Binder.getCallingUid(); 15567 final long origId = Binder.clearCallingIdentity(); 15568 int res = broadcastIntentLocked(callerApp, 15569 callerApp != null ? callerApp.info.packageName : null, 15570 intent, resolvedType, resultTo, 15571 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15572 callingPid, callingUid, userId); 15573 Binder.restoreCallingIdentity(origId); 15574 return res; 15575 } 15576 } 15577 15578 int broadcastIntentInPackage(String packageName, int uid, 15579 Intent intent, String resolvedType, IIntentReceiver resultTo, 15580 int resultCode, String resultData, Bundle map, 15581 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15582 synchronized(this) { 15583 intent = verifyBroadcastLocked(intent); 15584 15585 final long origId = Binder.clearCallingIdentity(); 15586 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15587 resultTo, resultCode, resultData, map, requiredPermission, 15588 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15589 Binder.restoreCallingIdentity(origId); 15590 return res; 15591 } 15592 } 15593 15594 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15595 // Refuse possible leaked file descriptors 15596 if (intent != null && intent.hasFileDescriptors() == true) { 15597 throw new IllegalArgumentException("File descriptors passed in Intent"); 15598 } 15599 15600 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15601 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15602 15603 synchronized(this) { 15604 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15605 != PackageManager.PERMISSION_GRANTED) { 15606 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15607 + Binder.getCallingPid() 15608 + ", uid=" + Binder.getCallingUid() 15609 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15610 Slog.w(TAG, msg); 15611 throw new SecurityException(msg); 15612 } 15613 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15614 if (stickies != null) { 15615 ArrayList<Intent> list = stickies.get(intent.getAction()); 15616 if (list != null) { 15617 int N = list.size(); 15618 int i; 15619 for (i=0; i<N; i++) { 15620 if (intent.filterEquals(list.get(i))) { 15621 list.remove(i); 15622 break; 15623 } 15624 } 15625 if (list.size() <= 0) { 15626 stickies.remove(intent.getAction()); 15627 } 15628 } 15629 if (stickies.size() <= 0) { 15630 mStickyBroadcasts.remove(userId); 15631 } 15632 } 15633 } 15634 } 15635 15636 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15637 String resultData, Bundle resultExtras, boolean resultAbort) { 15638 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15639 if (r == null) { 15640 Slog.w(TAG, "finishReceiver called but not found on queue"); 15641 return false; 15642 } 15643 15644 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15645 } 15646 15647 void backgroundServicesFinishedLocked(int userId) { 15648 for (BroadcastQueue queue : mBroadcastQueues) { 15649 queue.backgroundServicesFinishedLocked(userId); 15650 } 15651 } 15652 15653 public void finishReceiver(IBinder who, int resultCode, String resultData, 15654 Bundle resultExtras, boolean resultAbort) { 15655 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15656 15657 // Refuse possible leaked file descriptors 15658 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15659 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15660 } 15661 15662 final long origId = Binder.clearCallingIdentity(); 15663 try { 15664 boolean doNext = false; 15665 BroadcastRecord r; 15666 15667 synchronized(this) { 15668 r = broadcastRecordForReceiverLocked(who); 15669 if (r != null) { 15670 doNext = r.queue.finishReceiverLocked(r, resultCode, 15671 resultData, resultExtras, resultAbort, true); 15672 } 15673 } 15674 15675 if (doNext) { 15676 r.queue.processNextBroadcast(false); 15677 } 15678 trimApplications(); 15679 } finally { 15680 Binder.restoreCallingIdentity(origId); 15681 } 15682 } 15683 15684 // ========================================================= 15685 // INSTRUMENTATION 15686 // ========================================================= 15687 15688 public boolean startInstrumentation(ComponentName className, 15689 String profileFile, int flags, Bundle arguments, 15690 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15691 int userId, String abiOverride) { 15692 enforceNotIsolatedCaller("startInstrumentation"); 15693 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15694 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15695 // Refuse possible leaked file descriptors 15696 if (arguments != null && arguments.hasFileDescriptors()) { 15697 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15698 } 15699 15700 synchronized(this) { 15701 InstrumentationInfo ii = null; 15702 ApplicationInfo ai = null; 15703 try { 15704 ii = mContext.getPackageManager().getInstrumentationInfo( 15705 className, STOCK_PM_FLAGS); 15706 ai = AppGlobals.getPackageManager().getApplicationInfo( 15707 ii.targetPackage, STOCK_PM_FLAGS, userId); 15708 } catch (PackageManager.NameNotFoundException e) { 15709 } catch (RemoteException e) { 15710 } 15711 if (ii == null) { 15712 reportStartInstrumentationFailure(watcher, className, 15713 "Unable to find instrumentation info for: " + className); 15714 return false; 15715 } 15716 if (ai == null) { 15717 reportStartInstrumentationFailure(watcher, className, 15718 "Unable to find instrumentation target package: " + ii.targetPackage); 15719 return false; 15720 } 15721 15722 int match = mContext.getPackageManager().checkSignatures( 15723 ii.targetPackage, ii.packageName); 15724 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15725 String msg = "Permission Denial: starting instrumentation " 15726 + className + " from pid=" 15727 + Binder.getCallingPid() 15728 + ", uid=" + Binder.getCallingPid() 15729 + " not allowed because package " + ii.packageName 15730 + " does not have a signature matching the target " 15731 + ii.targetPackage; 15732 reportStartInstrumentationFailure(watcher, className, msg); 15733 throw new SecurityException(msg); 15734 } 15735 15736 final long origId = Binder.clearCallingIdentity(); 15737 // Instrumentation can kill and relaunch even persistent processes 15738 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15739 "start instr"); 15740 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15741 app.instrumentationClass = className; 15742 app.instrumentationInfo = ai; 15743 app.instrumentationProfileFile = profileFile; 15744 app.instrumentationArguments = arguments; 15745 app.instrumentationWatcher = watcher; 15746 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15747 app.instrumentationResultClass = className; 15748 Binder.restoreCallingIdentity(origId); 15749 } 15750 15751 return true; 15752 } 15753 15754 /** 15755 * Report errors that occur while attempting to start Instrumentation. Always writes the 15756 * error to the logs, but if somebody is watching, send the report there too. This enables 15757 * the "am" command to report errors with more information. 15758 * 15759 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15760 * @param cn The component name of the instrumentation. 15761 * @param report The error report. 15762 */ 15763 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15764 ComponentName cn, String report) { 15765 Slog.w(TAG, report); 15766 try { 15767 if (watcher != null) { 15768 Bundle results = new Bundle(); 15769 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15770 results.putString("Error", report); 15771 watcher.instrumentationStatus(cn, -1, results); 15772 } 15773 } catch (RemoteException e) { 15774 Slog.w(TAG, e); 15775 } 15776 } 15777 15778 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15779 if (app.instrumentationWatcher != null) { 15780 try { 15781 // NOTE: IInstrumentationWatcher *must* be oneway here 15782 app.instrumentationWatcher.instrumentationFinished( 15783 app.instrumentationClass, 15784 resultCode, 15785 results); 15786 } catch (RemoteException e) { 15787 } 15788 } 15789 if (app.instrumentationUiAutomationConnection != null) { 15790 try { 15791 app.instrumentationUiAutomationConnection.shutdown(); 15792 } catch (RemoteException re) { 15793 /* ignore */ 15794 } 15795 // Only a UiAutomation can set this flag and now that 15796 // it is finished we make sure it is reset to its default. 15797 mUserIsMonkey = false; 15798 } 15799 app.instrumentationWatcher = null; 15800 app.instrumentationUiAutomationConnection = null; 15801 app.instrumentationClass = null; 15802 app.instrumentationInfo = null; 15803 app.instrumentationProfileFile = null; 15804 app.instrumentationArguments = null; 15805 15806 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15807 "finished inst"); 15808 } 15809 15810 public void finishInstrumentation(IApplicationThread target, 15811 int resultCode, Bundle results) { 15812 int userId = UserHandle.getCallingUserId(); 15813 // Refuse possible leaked file descriptors 15814 if (results != null && results.hasFileDescriptors()) { 15815 throw new IllegalArgumentException("File descriptors passed in Intent"); 15816 } 15817 15818 synchronized(this) { 15819 ProcessRecord app = getRecordForAppLocked(target); 15820 if (app == null) { 15821 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15822 return; 15823 } 15824 final long origId = Binder.clearCallingIdentity(); 15825 finishInstrumentationLocked(app, resultCode, results); 15826 Binder.restoreCallingIdentity(origId); 15827 } 15828 } 15829 15830 // ========================================================= 15831 // CONFIGURATION 15832 // ========================================================= 15833 15834 public ConfigurationInfo getDeviceConfigurationInfo() { 15835 ConfigurationInfo config = new ConfigurationInfo(); 15836 synchronized (this) { 15837 config.reqTouchScreen = mConfiguration.touchscreen; 15838 config.reqKeyboardType = mConfiguration.keyboard; 15839 config.reqNavigation = mConfiguration.navigation; 15840 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15841 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15842 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15843 } 15844 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15845 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15846 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15847 } 15848 config.reqGlEsVersion = GL_ES_VERSION; 15849 } 15850 return config; 15851 } 15852 15853 ActivityStack getFocusedStack() { 15854 return mStackSupervisor.getFocusedStack(); 15855 } 15856 15857 public Configuration getConfiguration() { 15858 Configuration ci; 15859 synchronized(this) { 15860 ci = new Configuration(mConfiguration); 15861 } 15862 return ci; 15863 } 15864 15865 public void updatePersistentConfiguration(Configuration values) { 15866 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15867 "updateConfiguration()"); 15868 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15869 "updateConfiguration()"); 15870 if (values == null) { 15871 throw new NullPointerException("Configuration must not be null"); 15872 } 15873 15874 synchronized(this) { 15875 final long origId = Binder.clearCallingIdentity(); 15876 updateConfigurationLocked(values, null, true, false); 15877 Binder.restoreCallingIdentity(origId); 15878 } 15879 } 15880 15881 public void updateConfiguration(Configuration values) { 15882 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15883 "updateConfiguration()"); 15884 15885 synchronized(this) { 15886 if (values == null && mWindowManager != null) { 15887 // sentinel: fetch the current configuration from the window manager 15888 values = mWindowManager.computeNewConfiguration(); 15889 } 15890 15891 if (mWindowManager != null) { 15892 mProcessList.applyDisplaySize(mWindowManager); 15893 } 15894 15895 final long origId = Binder.clearCallingIdentity(); 15896 if (values != null) { 15897 Settings.System.clearConfiguration(values); 15898 } 15899 updateConfigurationLocked(values, null, false, false); 15900 Binder.restoreCallingIdentity(origId); 15901 } 15902 } 15903 15904 /** 15905 * Do either or both things: (1) change the current configuration, and (2) 15906 * make sure the given activity is running with the (now) current 15907 * configuration. Returns true if the activity has been left running, or 15908 * false if <var>starting</var> is being destroyed to match the new 15909 * configuration. 15910 * @param persistent TODO 15911 */ 15912 boolean updateConfigurationLocked(Configuration values, 15913 ActivityRecord starting, boolean persistent, boolean initLocale) { 15914 int changes = 0; 15915 15916 if (values != null) { 15917 Configuration newConfig = new Configuration(mConfiguration); 15918 changes = newConfig.updateFrom(values); 15919 if (changes != 0) { 15920 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15921 Slog.i(TAG, "Updating configuration to: " + values); 15922 } 15923 15924 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15925 15926 if (values.locale != null && !initLocale) { 15927 saveLocaleLocked(values.locale, 15928 !values.locale.equals(mConfiguration.locale), 15929 values.userSetLocale); 15930 } 15931 15932 mConfigurationSeq++; 15933 if (mConfigurationSeq <= 0) { 15934 mConfigurationSeq = 1; 15935 } 15936 newConfig.seq = mConfigurationSeq; 15937 mConfiguration = newConfig; 15938 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15939 //mUsageStatsService.noteStartConfig(newConfig); 15940 15941 final Configuration configCopy = new Configuration(mConfiguration); 15942 15943 // TODO: If our config changes, should we auto dismiss any currently 15944 // showing dialogs? 15945 mShowDialogs = shouldShowDialogs(newConfig); 15946 15947 AttributeCache ac = AttributeCache.instance(); 15948 if (ac != null) { 15949 ac.updateConfiguration(configCopy); 15950 } 15951 15952 // Make sure all resources in our process are updated 15953 // right now, so that anyone who is going to retrieve 15954 // resource values after we return will be sure to get 15955 // the new ones. This is especially important during 15956 // boot, where the first config change needs to guarantee 15957 // all resources have that config before following boot 15958 // code is executed. 15959 mSystemThread.applyConfigurationToResources(configCopy); 15960 15961 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15962 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15963 msg.obj = new Configuration(configCopy); 15964 mHandler.sendMessage(msg); 15965 } 15966 15967 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15968 ProcessRecord app = mLruProcesses.get(i); 15969 try { 15970 if (app.thread != null) { 15971 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15972 + app.processName + " new config " + mConfiguration); 15973 app.thread.scheduleConfigurationChanged(configCopy); 15974 } 15975 } catch (Exception e) { 15976 } 15977 } 15978 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15979 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15980 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15981 | Intent.FLAG_RECEIVER_FOREGROUND); 15982 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15983 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15984 Process.SYSTEM_UID, UserHandle.USER_ALL); 15985 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15986 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15987 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15988 broadcastIntentLocked(null, null, intent, 15989 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15990 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15991 } 15992 } 15993 } 15994 15995 boolean kept = true; 15996 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15997 // mainStack is null during startup. 15998 if (mainStack != null) { 15999 if (changes != 0 && starting == null) { 16000 // If the configuration changed, and the caller is not already 16001 // in the process of starting an activity, then find the top 16002 // activity to check if its configuration needs to change. 16003 starting = mainStack.topRunningActivityLocked(null); 16004 } 16005 16006 if (starting != null) { 16007 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 16008 // And we need to make sure at this point that all other activities 16009 // are made visible with the correct configuration. 16010 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 16011 } 16012 } 16013 16014 if (values != null && mWindowManager != null) { 16015 mWindowManager.setNewConfiguration(mConfiguration); 16016 } 16017 16018 return kept; 16019 } 16020 16021 /** 16022 * Decide based on the configuration whether we should shouw the ANR, 16023 * crash, etc dialogs. The idea is that if there is no affordnace to 16024 * press the on-screen buttons, we shouldn't show the dialog. 16025 * 16026 * A thought: SystemUI might also want to get told about this, the Power 16027 * dialog / global actions also might want different behaviors. 16028 */ 16029 private static final boolean shouldShowDialogs(Configuration config) { 16030 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 16031 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 16032 } 16033 16034 /** 16035 * Save the locale. You must be inside a synchronized (this) block. 16036 */ 16037 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 16038 if(isDiff) { 16039 SystemProperties.set("user.language", l.getLanguage()); 16040 SystemProperties.set("user.region", l.getCountry()); 16041 } 16042 16043 if(isPersist) { 16044 SystemProperties.set("persist.sys.language", l.getLanguage()); 16045 SystemProperties.set("persist.sys.country", l.getCountry()); 16046 SystemProperties.set("persist.sys.localevar", l.getVariant()); 16047 } 16048 } 16049 16050 @Override 16051 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 16052 synchronized (this) { 16053 ActivityRecord srec = ActivityRecord.forToken(token); 16054 if (srec.task != null && srec.task.stack != null) { 16055 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 16056 } 16057 } 16058 return false; 16059 } 16060 16061 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 16062 Intent resultData) { 16063 16064 synchronized (this) { 16065 final ActivityStack stack = ActivityRecord.getStackLocked(token); 16066 if (stack != null) { 16067 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 16068 } 16069 return false; 16070 } 16071 } 16072 16073 public int getLaunchedFromUid(IBinder activityToken) { 16074 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16075 if (srec == null) { 16076 return -1; 16077 } 16078 return srec.launchedFromUid; 16079 } 16080 16081 public String getLaunchedFromPackage(IBinder activityToken) { 16082 ActivityRecord srec = ActivityRecord.forToken(activityToken); 16083 if (srec == null) { 16084 return null; 16085 } 16086 return srec.launchedFromPackage; 16087 } 16088 16089 // ========================================================= 16090 // LIFETIME MANAGEMENT 16091 // ========================================================= 16092 16093 // Returns which broadcast queue the app is the current [or imminent] receiver 16094 // on, or 'null' if the app is not an active broadcast recipient. 16095 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16096 BroadcastRecord r = app.curReceiver; 16097 if (r != null) { 16098 return r.queue; 16099 } 16100 16101 // It's not the current receiver, but it might be starting up to become one 16102 synchronized (this) { 16103 for (BroadcastQueue queue : mBroadcastQueues) { 16104 r = queue.mPendingBroadcast; 16105 if (r != null && r.curApp == app) { 16106 // found it; report which queue it's in 16107 return queue; 16108 } 16109 } 16110 } 16111 16112 return null; 16113 } 16114 16115 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16116 boolean doingAll, long now) { 16117 if (mAdjSeq == app.adjSeq) { 16118 // This adjustment has already been computed. 16119 return app.curRawAdj; 16120 } 16121 16122 if (app.thread == null) { 16123 app.adjSeq = mAdjSeq; 16124 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16125 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16126 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16127 } 16128 16129 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16130 app.adjSource = null; 16131 app.adjTarget = null; 16132 app.empty = false; 16133 app.cached = false; 16134 16135 final int activitiesSize = app.activities.size(); 16136 16137 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16138 // The max adjustment doesn't allow this app to be anything 16139 // below foreground, so it is not worth doing work for it. 16140 app.adjType = "fixed"; 16141 app.adjSeq = mAdjSeq; 16142 app.curRawAdj = app.maxAdj; 16143 app.foregroundActivities = false; 16144 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16145 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16146 // System processes can do UI, and when they do we want to have 16147 // them trim their memory after the user leaves the UI. To 16148 // facilitate this, here we need to determine whether or not it 16149 // is currently showing UI. 16150 app.systemNoUi = true; 16151 if (app == TOP_APP) { 16152 app.systemNoUi = false; 16153 } else if (activitiesSize > 0) { 16154 for (int j = 0; j < activitiesSize; j++) { 16155 final ActivityRecord r = app.activities.get(j); 16156 if (r.visible) { 16157 app.systemNoUi = false; 16158 } 16159 } 16160 } 16161 if (!app.systemNoUi) { 16162 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16163 } 16164 return (app.curAdj=app.maxAdj); 16165 } 16166 16167 app.systemNoUi = false; 16168 16169 // Determine the importance of the process, starting with most 16170 // important to least, and assign an appropriate OOM adjustment. 16171 int adj; 16172 int schedGroup; 16173 int procState; 16174 boolean foregroundActivities = false; 16175 BroadcastQueue queue; 16176 if (app == TOP_APP) { 16177 // The last app on the list is the foreground app. 16178 adj = ProcessList.FOREGROUND_APP_ADJ; 16179 schedGroup = Process.THREAD_GROUP_DEFAULT; 16180 app.adjType = "top-activity"; 16181 foregroundActivities = true; 16182 procState = ActivityManager.PROCESS_STATE_TOP; 16183 } else if (app.instrumentationClass != null) { 16184 // Don't want to kill running instrumentation. 16185 adj = ProcessList.FOREGROUND_APP_ADJ; 16186 schedGroup = Process.THREAD_GROUP_DEFAULT; 16187 app.adjType = "instrumentation"; 16188 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16189 } else if ((queue = isReceivingBroadcast(app)) != null) { 16190 // An app that is currently receiving a broadcast also 16191 // counts as being in the foreground for OOM killer purposes. 16192 // It's placed in a sched group based on the nature of the 16193 // broadcast as reflected by which queue it's active in. 16194 adj = ProcessList.FOREGROUND_APP_ADJ; 16195 schedGroup = (queue == mFgBroadcastQueue) 16196 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16197 app.adjType = "broadcast"; 16198 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16199 } else if (app.executingServices.size() > 0) { 16200 // An app that is currently executing a service callback also 16201 // counts as being in the foreground. 16202 adj = ProcessList.FOREGROUND_APP_ADJ; 16203 schedGroup = app.execServicesFg ? 16204 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16205 app.adjType = "exec-service"; 16206 procState = ActivityManager.PROCESS_STATE_SERVICE; 16207 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16208 } else { 16209 // As far as we know the process is empty. We may change our mind later. 16210 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16211 // At this point we don't actually know the adjustment. Use the cached adj 16212 // value that the caller wants us to. 16213 adj = cachedAdj; 16214 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16215 app.cached = true; 16216 app.empty = true; 16217 app.adjType = "cch-empty"; 16218 } 16219 16220 // Examine all activities if not already foreground. 16221 if (!foregroundActivities && activitiesSize > 0) { 16222 for (int j = 0; j < activitiesSize; j++) { 16223 final ActivityRecord r = app.activities.get(j); 16224 if (r.app != app) { 16225 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16226 + app + "?!?"); 16227 continue; 16228 } 16229 if (r.visible) { 16230 // App has a visible activity; only upgrade adjustment. 16231 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16232 adj = ProcessList.VISIBLE_APP_ADJ; 16233 app.adjType = "visible"; 16234 } 16235 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16236 procState = ActivityManager.PROCESS_STATE_TOP; 16237 } 16238 schedGroup = Process.THREAD_GROUP_DEFAULT; 16239 app.cached = false; 16240 app.empty = false; 16241 foregroundActivities = true; 16242 break; 16243 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16244 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16245 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16246 app.adjType = "pausing"; 16247 } 16248 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16249 procState = ActivityManager.PROCESS_STATE_TOP; 16250 } 16251 schedGroup = Process.THREAD_GROUP_DEFAULT; 16252 app.cached = false; 16253 app.empty = false; 16254 foregroundActivities = true; 16255 } else if (r.state == ActivityState.STOPPING) { 16256 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16257 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16258 app.adjType = "stopping"; 16259 } 16260 // For the process state, we will at this point consider the 16261 // process to be cached. It will be cached either as an activity 16262 // or empty depending on whether the activity is finishing. We do 16263 // this so that we can treat the process as cached for purposes of 16264 // memory trimming (determing current memory level, trim command to 16265 // send to process) since there can be an arbitrary number of stopping 16266 // processes and they should soon all go into the cached state. 16267 if (!r.finishing) { 16268 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16269 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16270 } 16271 } 16272 app.cached = false; 16273 app.empty = false; 16274 foregroundActivities = true; 16275 } else { 16276 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16277 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16278 app.adjType = "cch-act"; 16279 } 16280 } 16281 } 16282 } 16283 16284 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16285 if (app.foregroundServices) { 16286 // The user is aware of this app, so make it visible. 16287 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16288 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16289 app.cached = false; 16290 app.adjType = "fg-service"; 16291 schedGroup = Process.THREAD_GROUP_DEFAULT; 16292 } else if (app.forcingToForeground != null) { 16293 // The user is aware of this app, so make it visible. 16294 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16295 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16296 app.cached = false; 16297 app.adjType = "force-fg"; 16298 app.adjSource = app.forcingToForeground; 16299 schedGroup = Process.THREAD_GROUP_DEFAULT; 16300 } 16301 } 16302 16303 if (app == mHeavyWeightProcess) { 16304 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16305 // We don't want to kill the current heavy-weight process. 16306 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16307 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16308 app.cached = false; 16309 app.adjType = "heavy"; 16310 } 16311 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16312 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16313 } 16314 } 16315 16316 if (app == mHomeProcess) { 16317 if (adj > ProcessList.HOME_APP_ADJ) { 16318 // This process is hosting what we currently consider to be the 16319 // home app, so we don't want to let it go into the background. 16320 adj = ProcessList.HOME_APP_ADJ; 16321 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16322 app.cached = false; 16323 app.adjType = "home"; 16324 } 16325 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16326 procState = ActivityManager.PROCESS_STATE_HOME; 16327 } 16328 } 16329 16330 if (app == mPreviousProcess && app.activities.size() > 0) { 16331 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16332 // This was the previous process that showed UI to the user. 16333 // We want to try to keep it around more aggressively, to give 16334 // a good experience around switching between two apps. 16335 adj = ProcessList.PREVIOUS_APP_ADJ; 16336 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16337 app.cached = false; 16338 app.adjType = "previous"; 16339 } 16340 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16341 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16342 } 16343 } 16344 16345 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16346 + " reason=" + app.adjType); 16347 16348 // By default, we use the computed adjustment. It may be changed if 16349 // there are applications dependent on our services or providers, but 16350 // this gives us a baseline and makes sure we don't get into an 16351 // infinite recursion. 16352 app.adjSeq = mAdjSeq; 16353 app.curRawAdj = adj; 16354 app.hasStartedServices = false; 16355 16356 if (mBackupTarget != null && app == mBackupTarget.app) { 16357 // If possible we want to avoid killing apps while they're being backed up 16358 if (adj > ProcessList.BACKUP_APP_ADJ) { 16359 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16360 adj = ProcessList.BACKUP_APP_ADJ; 16361 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16362 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16363 } 16364 app.adjType = "backup"; 16365 app.cached = false; 16366 } 16367 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16368 procState = ActivityManager.PROCESS_STATE_BACKUP; 16369 } 16370 } 16371 16372 boolean mayBeTop = false; 16373 16374 for (int is = app.services.size()-1; 16375 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16376 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16377 || procState > ActivityManager.PROCESS_STATE_TOP); 16378 is--) { 16379 ServiceRecord s = app.services.valueAt(is); 16380 if (s.startRequested) { 16381 app.hasStartedServices = true; 16382 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16383 procState = ActivityManager.PROCESS_STATE_SERVICE; 16384 } 16385 if (app.hasShownUi && app != mHomeProcess) { 16386 // If this process has shown some UI, let it immediately 16387 // go to the LRU list because it may be pretty heavy with 16388 // UI stuff. We'll tag it with a label just to help 16389 // debug and understand what is going on. 16390 if (adj > ProcessList.SERVICE_ADJ) { 16391 app.adjType = "cch-started-ui-services"; 16392 } 16393 } else { 16394 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16395 // This service has seen some activity within 16396 // recent memory, so we will keep its process ahead 16397 // of the background processes. 16398 if (adj > ProcessList.SERVICE_ADJ) { 16399 adj = ProcessList.SERVICE_ADJ; 16400 app.adjType = "started-services"; 16401 app.cached = false; 16402 } 16403 } 16404 // If we have let the service slide into the background 16405 // state, still have some text describing what it is doing 16406 // even though the service no longer has an impact. 16407 if (adj > ProcessList.SERVICE_ADJ) { 16408 app.adjType = "cch-started-services"; 16409 } 16410 } 16411 } 16412 for (int conni = s.connections.size()-1; 16413 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16414 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16415 || procState > ActivityManager.PROCESS_STATE_TOP); 16416 conni--) { 16417 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16418 for (int i = 0; 16419 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16420 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16421 || procState > ActivityManager.PROCESS_STATE_TOP); 16422 i++) { 16423 // XXX should compute this based on the max of 16424 // all connected clients. 16425 ConnectionRecord cr = clist.get(i); 16426 if (cr.binding.client == app) { 16427 // Binding to ourself is not interesting. 16428 continue; 16429 } 16430 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16431 ProcessRecord client = cr.binding.client; 16432 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16433 TOP_APP, doingAll, now); 16434 int clientProcState = client.curProcState; 16435 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16436 // If the other app is cached for any reason, for purposes here 16437 // we are going to consider it empty. The specific cached state 16438 // doesn't propagate except under certain conditions. 16439 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16440 } 16441 String adjType = null; 16442 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16443 // Not doing bind OOM management, so treat 16444 // this guy more like a started service. 16445 if (app.hasShownUi && app != mHomeProcess) { 16446 // If this process has shown some UI, let it immediately 16447 // go to the LRU list because it may be pretty heavy with 16448 // UI stuff. We'll tag it with a label just to help 16449 // debug and understand what is going on. 16450 if (adj > clientAdj) { 16451 adjType = "cch-bound-ui-services"; 16452 } 16453 app.cached = false; 16454 clientAdj = adj; 16455 clientProcState = procState; 16456 } else { 16457 if (now >= (s.lastActivity 16458 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16459 // This service has not seen activity within 16460 // recent memory, so allow it to drop to the 16461 // LRU list if there is no other reason to keep 16462 // it around. We'll also tag it with a label just 16463 // to help debug and undertand what is going on. 16464 if (adj > clientAdj) { 16465 adjType = "cch-bound-services"; 16466 } 16467 clientAdj = adj; 16468 } 16469 } 16470 } 16471 if (adj > clientAdj) { 16472 // If this process has recently shown UI, and 16473 // the process that is binding to it is less 16474 // important than being visible, then we don't 16475 // care about the binding as much as we care 16476 // about letting this process get into the LRU 16477 // list to be killed and restarted if needed for 16478 // memory. 16479 if (app.hasShownUi && app != mHomeProcess 16480 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16481 adjType = "cch-bound-ui-services"; 16482 } else { 16483 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16484 |Context.BIND_IMPORTANT)) != 0) { 16485 adj = clientAdj; 16486 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16487 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16488 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16489 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16490 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16491 adj = clientAdj; 16492 } else { 16493 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16494 adj = ProcessList.VISIBLE_APP_ADJ; 16495 } 16496 } 16497 if (!client.cached) { 16498 app.cached = false; 16499 } 16500 adjType = "service"; 16501 } 16502 } 16503 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16504 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16505 schedGroup = Process.THREAD_GROUP_DEFAULT; 16506 } 16507 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16508 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16509 // Special handling of clients who are in the top state. 16510 // We *may* want to consider this process to be in the 16511 // top state as well, but only if there is not another 16512 // reason for it to be running. Being on the top is a 16513 // special state, meaning you are specifically running 16514 // for the current top app. If the process is already 16515 // running in the background for some other reason, it 16516 // is more important to continue considering it to be 16517 // in the background state. 16518 mayBeTop = true; 16519 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16520 } else { 16521 // Special handling for above-top states (persistent 16522 // processes). These should not bring the current process 16523 // into the top state, since they are not on top. Instead 16524 // give them the best state after that. 16525 clientProcState = 16526 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16527 } 16528 } 16529 } else { 16530 if (clientProcState < 16531 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16532 clientProcState = 16533 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16534 } 16535 } 16536 if (procState > clientProcState) { 16537 procState = clientProcState; 16538 } 16539 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16540 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16541 app.pendingUiClean = true; 16542 } 16543 if (adjType != null) { 16544 app.adjType = adjType; 16545 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16546 .REASON_SERVICE_IN_USE; 16547 app.adjSource = cr.binding.client; 16548 app.adjSourceProcState = clientProcState; 16549 app.adjTarget = s.name; 16550 } 16551 } 16552 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16553 app.treatLikeActivity = true; 16554 } 16555 final ActivityRecord a = cr.activity; 16556 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16557 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16558 (a.visible || a.state == ActivityState.RESUMED 16559 || a.state == ActivityState.PAUSING)) { 16560 adj = ProcessList.FOREGROUND_APP_ADJ; 16561 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16562 schedGroup = Process.THREAD_GROUP_DEFAULT; 16563 } 16564 app.cached = false; 16565 app.adjType = "service"; 16566 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16567 .REASON_SERVICE_IN_USE; 16568 app.adjSource = a; 16569 app.adjSourceProcState = procState; 16570 app.adjTarget = s.name; 16571 } 16572 } 16573 } 16574 } 16575 } 16576 16577 for (int provi = app.pubProviders.size()-1; 16578 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16579 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16580 || procState > ActivityManager.PROCESS_STATE_TOP); 16581 provi--) { 16582 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16583 for (int i = cpr.connections.size()-1; 16584 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16585 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16586 || procState > ActivityManager.PROCESS_STATE_TOP); 16587 i--) { 16588 ContentProviderConnection conn = cpr.connections.get(i); 16589 ProcessRecord client = conn.client; 16590 if (client == app) { 16591 // Being our own client is not interesting. 16592 continue; 16593 } 16594 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16595 int clientProcState = client.curProcState; 16596 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16597 // If the other app is cached for any reason, for purposes here 16598 // we are going to consider it empty. 16599 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16600 } 16601 if (adj > clientAdj) { 16602 if (app.hasShownUi && app != mHomeProcess 16603 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16604 app.adjType = "cch-ui-provider"; 16605 } else { 16606 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16607 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16608 app.adjType = "provider"; 16609 } 16610 app.cached &= client.cached; 16611 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16612 .REASON_PROVIDER_IN_USE; 16613 app.adjSource = client; 16614 app.adjSourceProcState = clientProcState; 16615 app.adjTarget = cpr.name; 16616 } 16617 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16618 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16619 // Special handling of clients who are in the top state. 16620 // We *may* want to consider this process to be in the 16621 // top state as well, but only if there is not another 16622 // reason for it to be running. Being on the top is a 16623 // special state, meaning you are specifically running 16624 // for the current top app. If the process is already 16625 // running in the background for some other reason, it 16626 // is more important to continue considering it to be 16627 // in the background state. 16628 mayBeTop = true; 16629 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16630 } else { 16631 // Special handling for above-top states (persistent 16632 // processes). These should not bring the current process 16633 // into the top state, since they are not on top. Instead 16634 // give them the best state after that. 16635 clientProcState = 16636 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16637 } 16638 } 16639 if (procState > clientProcState) { 16640 procState = clientProcState; 16641 } 16642 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16643 schedGroup = Process.THREAD_GROUP_DEFAULT; 16644 } 16645 } 16646 // If the provider has external (non-framework) process 16647 // dependencies, ensure that its adjustment is at least 16648 // FOREGROUND_APP_ADJ. 16649 if (cpr.hasExternalProcessHandles()) { 16650 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16651 adj = ProcessList.FOREGROUND_APP_ADJ; 16652 schedGroup = Process.THREAD_GROUP_DEFAULT; 16653 app.cached = false; 16654 app.adjType = "provider"; 16655 app.adjTarget = cpr.name; 16656 } 16657 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16658 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16659 } 16660 } 16661 } 16662 16663 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16664 // A client of one of our services or providers is in the top state. We 16665 // *may* want to be in the top state, but not if we are already running in 16666 // the background for some other reason. For the decision here, we are going 16667 // to pick out a few specific states that we want to remain in when a client 16668 // is top (states that tend to be longer-term) and otherwise allow it to go 16669 // to the top state. 16670 switch (procState) { 16671 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16672 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16673 case ActivityManager.PROCESS_STATE_SERVICE: 16674 // These all are longer-term states, so pull them up to the top 16675 // of the background states, but not all the way to the top state. 16676 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16677 break; 16678 default: 16679 // Otherwise, top is a better choice, so take it. 16680 procState = ActivityManager.PROCESS_STATE_TOP; 16681 break; 16682 } 16683 } 16684 16685 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16686 if (app.hasClientActivities) { 16687 // This is a cached process, but with client activities. Mark it so. 16688 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16689 app.adjType = "cch-client-act"; 16690 } else if (app.treatLikeActivity) { 16691 // This is a cached process, but somebody wants us to treat it like it has 16692 // an activity, okay! 16693 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16694 app.adjType = "cch-as-act"; 16695 } 16696 } 16697 16698 if (adj == ProcessList.SERVICE_ADJ) { 16699 if (doingAll) { 16700 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16701 mNewNumServiceProcs++; 16702 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16703 if (!app.serviceb) { 16704 // This service isn't far enough down on the LRU list to 16705 // normally be a B service, but if we are low on RAM and it 16706 // is large we want to force it down since we would prefer to 16707 // keep launcher over it. 16708 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16709 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16710 app.serviceHighRam = true; 16711 app.serviceb = true; 16712 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16713 } else { 16714 mNewNumAServiceProcs++; 16715 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16716 } 16717 } else { 16718 app.serviceHighRam = false; 16719 } 16720 } 16721 if (app.serviceb) { 16722 adj = ProcessList.SERVICE_B_ADJ; 16723 } 16724 } 16725 16726 app.curRawAdj = adj; 16727 16728 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16729 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16730 if (adj > app.maxAdj) { 16731 adj = app.maxAdj; 16732 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16733 schedGroup = Process.THREAD_GROUP_DEFAULT; 16734 } 16735 } 16736 16737 // Do final modification to adj. Everything we do between here and applying 16738 // the final setAdj must be done in this function, because we will also use 16739 // it when computing the final cached adj later. Note that we don't need to 16740 // worry about this for max adj above, since max adj will always be used to 16741 // keep it out of the cached vaues. 16742 app.curAdj = app.modifyRawOomAdj(adj); 16743 app.curSchedGroup = schedGroup; 16744 app.curProcState = procState; 16745 app.foregroundActivities = foregroundActivities; 16746 16747 return app.curRawAdj; 16748 } 16749 16750 /** 16751 * Schedule PSS collection of a process. 16752 */ 16753 void requestPssLocked(ProcessRecord proc, int procState) { 16754 if (mPendingPssProcesses.contains(proc)) { 16755 return; 16756 } 16757 if (mPendingPssProcesses.size() == 0) { 16758 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16759 } 16760 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16761 proc.pssProcState = procState; 16762 mPendingPssProcesses.add(proc); 16763 } 16764 16765 /** 16766 * Schedule PSS collection of all processes. 16767 */ 16768 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16769 if (!always) { 16770 if (now < (mLastFullPssTime + 16771 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16772 return; 16773 } 16774 } 16775 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16776 mLastFullPssTime = now; 16777 mFullPssPending = true; 16778 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16779 mPendingPssProcesses.clear(); 16780 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16781 ProcessRecord app = mLruProcesses.get(i); 16782 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16783 app.pssProcState = app.setProcState; 16784 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16785 isSleeping(), now); 16786 mPendingPssProcesses.add(app); 16787 } 16788 } 16789 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16790 } 16791 16792 /** 16793 * Ask a given process to GC right now. 16794 */ 16795 final void performAppGcLocked(ProcessRecord app) { 16796 try { 16797 app.lastRequestedGc = SystemClock.uptimeMillis(); 16798 if (app.thread != null) { 16799 if (app.reportLowMemory) { 16800 app.reportLowMemory = false; 16801 app.thread.scheduleLowMemory(); 16802 } else { 16803 app.thread.processInBackground(); 16804 } 16805 } 16806 } catch (Exception e) { 16807 // whatever. 16808 } 16809 } 16810 16811 /** 16812 * Returns true if things are idle enough to perform GCs. 16813 */ 16814 private final boolean canGcNowLocked() { 16815 boolean processingBroadcasts = false; 16816 for (BroadcastQueue q : mBroadcastQueues) { 16817 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16818 processingBroadcasts = true; 16819 } 16820 } 16821 return !processingBroadcasts 16822 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16823 } 16824 16825 /** 16826 * Perform GCs on all processes that are waiting for it, but only 16827 * if things are idle. 16828 */ 16829 final void performAppGcsLocked() { 16830 final int N = mProcessesToGc.size(); 16831 if (N <= 0) { 16832 return; 16833 } 16834 if (canGcNowLocked()) { 16835 while (mProcessesToGc.size() > 0) { 16836 ProcessRecord proc = mProcessesToGc.remove(0); 16837 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16838 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16839 <= SystemClock.uptimeMillis()) { 16840 // To avoid spamming the system, we will GC processes one 16841 // at a time, waiting a few seconds between each. 16842 performAppGcLocked(proc); 16843 scheduleAppGcsLocked(); 16844 return; 16845 } else { 16846 // It hasn't been long enough since we last GCed this 16847 // process... put it in the list to wait for its time. 16848 addProcessToGcListLocked(proc); 16849 break; 16850 } 16851 } 16852 } 16853 16854 scheduleAppGcsLocked(); 16855 } 16856 } 16857 16858 /** 16859 * If all looks good, perform GCs on all processes waiting for them. 16860 */ 16861 final void performAppGcsIfAppropriateLocked() { 16862 if (canGcNowLocked()) { 16863 performAppGcsLocked(); 16864 return; 16865 } 16866 // Still not idle, wait some more. 16867 scheduleAppGcsLocked(); 16868 } 16869 16870 /** 16871 * Schedule the execution of all pending app GCs. 16872 */ 16873 final void scheduleAppGcsLocked() { 16874 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16875 16876 if (mProcessesToGc.size() > 0) { 16877 // Schedule a GC for the time to the next process. 16878 ProcessRecord proc = mProcessesToGc.get(0); 16879 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16880 16881 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16882 long now = SystemClock.uptimeMillis(); 16883 if (when < (now+GC_TIMEOUT)) { 16884 when = now + GC_TIMEOUT; 16885 } 16886 mHandler.sendMessageAtTime(msg, when); 16887 } 16888 } 16889 16890 /** 16891 * Add a process to the array of processes waiting to be GCed. Keeps the 16892 * list in sorted order by the last GC time. The process can't already be 16893 * on the list. 16894 */ 16895 final void addProcessToGcListLocked(ProcessRecord proc) { 16896 boolean added = false; 16897 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16898 if (mProcessesToGc.get(i).lastRequestedGc < 16899 proc.lastRequestedGc) { 16900 added = true; 16901 mProcessesToGc.add(i+1, proc); 16902 break; 16903 } 16904 } 16905 if (!added) { 16906 mProcessesToGc.add(0, proc); 16907 } 16908 } 16909 16910 /** 16911 * Set up to ask a process to GC itself. This will either do it 16912 * immediately, or put it on the list of processes to gc the next 16913 * time things are idle. 16914 */ 16915 final void scheduleAppGcLocked(ProcessRecord app) { 16916 long now = SystemClock.uptimeMillis(); 16917 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16918 return; 16919 } 16920 if (!mProcessesToGc.contains(app)) { 16921 addProcessToGcListLocked(app); 16922 scheduleAppGcsLocked(); 16923 } 16924 } 16925 16926 final void checkExcessivePowerUsageLocked(boolean doKills) { 16927 updateCpuStatsNow(); 16928 16929 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16930 boolean doWakeKills = doKills; 16931 boolean doCpuKills = doKills; 16932 if (mLastPowerCheckRealtime == 0) { 16933 doWakeKills = false; 16934 } 16935 if (mLastPowerCheckUptime == 0) { 16936 doCpuKills = false; 16937 } 16938 if (stats.isScreenOn()) { 16939 doWakeKills = false; 16940 } 16941 final long curRealtime = SystemClock.elapsedRealtime(); 16942 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16943 final long curUptime = SystemClock.uptimeMillis(); 16944 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16945 mLastPowerCheckRealtime = curRealtime; 16946 mLastPowerCheckUptime = curUptime; 16947 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16948 doWakeKills = false; 16949 } 16950 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16951 doCpuKills = false; 16952 } 16953 int i = mLruProcesses.size(); 16954 while (i > 0) { 16955 i--; 16956 ProcessRecord app = mLruProcesses.get(i); 16957 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16958 long wtime; 16959 synchronized (stats) { 16960 wtime = stats.getProcessWakeTime(app.info.uid, 16961 app.pid, curRealtime); 16962 } 16963 long wtimeUsed = wtime - app.lastWakeTime; 16964 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16965 if (DEBUG_POWER) { 16966 StringBuilder sb = new StringBuilder(128); 16967 sb.append("Wake for "); 16968 app.toShortString(sb); 16969 sb.append(": over "); 16970 TimeUtils.formatDuration(realtimeSince, sb); 16971 sb.append(" used "); 16972 TimeUtils.formatDuration(wtimeUsed, sb); 16973 sb.append(" ("); 16974 sb.append((wtimeUsed*100)/realtimeSince); 16975 sb.append("%)"); 16976 Slog.i(TAG, sb.toString()); 16977 sb.setLength(0); 16978 sb.append("CPU for "); 16979 app.toShortString(sb); 16980 sb.append(": over "); 16981 TimeUtils.formatDuration(uptimeSince, sb); 16982 sb.append(" used "); 16983 TimeUtils.formatDuration(cputimeUsed, sb); 16984 sb.append(" ("); 16985 sb.append((cputimeUsed*100)/uptimeSince); 16986 sb.append("%)"); 16987 Slog.i(TAG, sb.toString()); 16988 } 16989 // If a process has held a wake lock for more 16990 // than 50% of the time during this period, 16991 // that sounds bad. Kill! 16992 if (doWakeKills && realtimeSince > 0 16993 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16994 synchronized (stats) { 16995 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16996 realtimeSince, wtimeUsed); 16997 } 16998 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16999 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 17000 } else if (doCpuKills && uptimeSince > 0 17001 && ((cputimeUsed*100)/uptimeSince) >= 25) { 17002 synchronized (stats) { 17003 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 17004 uptimeSince, cputimeUsed); 17005 } 17006 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 17007 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 17008 } else { 17009 app.lastWakeTime = wtime; 17010 app.lastCpuTime = app.curCpuTime; 17011 } 17012 } 17013 } 17014 } 17015 17016 private final boolean applyOomAdjLocked(ProcessRecord app, 17017 ProcessRecord TOP_APP, boolean doingAll, long now) { 17018 boolean success = true; 17019 17020 if (app.curRawAdj != app.setRawAdj) { 17021 app.setRawAdj = app.curRawAdj; 17022 } 17023 17024 int changes = 0; 17025 17026 if (app.curAdj != app.setAdj) { 17027 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 17028 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 17029 TAG, "Set " + app.pid + " " + app.processName + 17030 " adj " + app.curAdj + ": " + app.adjType); 17031 app.setAdj = app.curAdj; 17032 } 17033 17034 if (app.setSchedGroup != app.curSchedGroup) { 17035 app.setSchedGroup = app.curSchedGroup; 17036 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17037 "Setting process group of " + app.processName 17038 + " to " + app.curSchedGroup); 17039 if (app.waitingToKill != null && 17040 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 17041 app.kill(app.waitingToKill, true); 17042 success = false; 17043 } else { 17044 if (true) { 17045 long oldId = Binder.clearCallingIdentity(); 17046 try { 17047 Process.setProcessGroup(app.pid, app.curSchedGroup); 17048 } catch (Exception e) { 17049 Slog.w(TAG, "Failed setting process group of " + app.pid 17050 + " to " + app.curSchedGroup); 17051 e.printStackTrace(); 17052 } finally { 17053 Binder.restoreCallingIdentity(oldId); 17054 } 17055 } else { 17056 if (app.thread != null) { 17057 try { 17058 app.thread.setSchedulingGroup(app.curSchedGroup); 17059 } catch (RemoteException e) { 17060 } 17061 } 17062 } 17063 Process.setSwappiness(app.pid, 17064 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 17065 } 17066 } 17067 if (app.repForegroundActivities != app.foregroundActivities) { 17068 app.repForegroundActivities = app.foregroundActivities; 17069 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 17070 } 17071 if (app.repProcState != app.curProcState) { 17072 app.repProcState = app.curProcState; 17073 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 17074 if (app.thread != null) { 17075 try { 17076 if (false) { 17077 //RuntimeException h = new RuntimeException("here"); 17078 Slog.i(TAG, "Sending new process state " + app.repProcState 17079 + " to " + app /*, h*/); 17080 } 17081 app.thread.setProcessState(app.repProcState); 17082 } catch (RemoteException e) { 17083 } 17084 } 17085 } 17086 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 17087 app.setProcState)) { 17088 app.lastStateTime = now; 17089 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 17090 isSleeping(), now); 17091 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 17092 + ProcessList.makeProcStateString(app.setProcState) + " to " 17093 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17094 + (app.nextPssTime-now) + ": " + app); 17095 } else { 17096 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17097 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17098 requestPssLocked(app, app.setProcState); 17099 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17100 isSleeping(), now); 17101 } else if (false && DEBUG_PSS) { 17102 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17103 } 17104 } 17105 if (app.setProcState != app.curProcState) { 17106 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17107 "Proc state change of " + app.processName 17108 + " to " + app.curProcState); 17109 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17110 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17111 if (setImportant && !curImportant) { 17112 // This app is no longer something we consider important enough to allow to 17113 // use arbitrary amounts of battery power. Note 17114 // its current wake lock time to later know to kill it if 17115 // it is not behaving well. 17116 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17117 synchronized (stats) { 17118 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17119 app.pid, SystemClock.elapsedRealtime()); 17120 } 17121 app.lastCpuTime = app.curCpuTime; 17122 17123 } 17124 app.setProcState = app.curProcState; 17125 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17126 app.notCachedSinceIdle = false; 17127 } 17128 if (!doingAll) { 17129 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17130 } else { 17131 app.procStateChanged = true; 17132 } 17133 } 17134 17135 if (changes != 0) { 17136 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17137 int i = mPendingProcessChanges.size()-1; 17138 ProcessChangeItem item = null; 17139 while (i >= 0) { 17140 item = mPendingProcessChanges.get(i); 17141 if (item.pid == app.pid) { 17142 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17143 break; 17144 } 17145 i--; 17146 } 17147 if (i < 0) { 17148 // No existing item in pending changes; need a new one. 17149 final int NA = mAvailProcessChanges.size(); 17150 if (NA > 0) { 17151 item = mAvailProcessChanges.remove(NA-1); 17152 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17153 } else { 17154 item = new ProcessChangeItem(); 17155 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17156 } 17157 item.changes = 0; 17158 item.pid = app.pid; 17159 item.uid = app.info.uid; 17160 if (mPendingProcessChanges.size() == 0) { 17161 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17162 "*** Enqueueing dispatch processes changed!"); 17163 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17164 } 17165 mPendingProcessChanges.add(item); 17166 } 17167 item.changes |= changes; 17168 item.processState = app.repProcState; 17169 item.foregroundActivities = app.repForegroundActivities; 17170 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17171 + Integer.toHexString(System.identityHashCode(item)) 17172 + " " + app.toShortString() + ": changes=" + item.changes 17173 + " procState=" + item.processState 17174 + " foreground=" + item.foregroundActivities 17175 + " type=" + app.adjType + " source=" + app.adjSource 17176 + " target=" + app.adjTarget); 17177 } 17178 17179 return success; 17180 } 17181 17182 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17183 if (proc.thread != null) { 17184 if (proc.baseProcessTracker != null) { 17185 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17186 } 17187 if (proc.repProcState >= 0) { 17188 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17189 proc.repProcState); 17190 } 17191 } 17192 } 17193 17194 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17195 ProcessRecord TOP_APP, boolean doingAll, long now) { 17196 if (app.thread == null) { 17197 return false; 17198 } 17199 17200 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17201 17202 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17203 } 17204 17205 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17206 boolean oomAdj) { 17207 if (isForeground != proc.foregroundServices) { 17208 proc.foregroundServices = isForeground; 17209 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17210 proc.info.uid); 17211 if (isForeground) { 17212 if (curProcs == null) { 17213 curProcs = new ArrayList<ProcessRecord>(); 17214 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17215 } 17216 if (!curProcs.contains(proc)) { 17217 curProcs.add(proc); 17218 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17219 proc.info.packageName, proc.info.uid); 17220 } 17221 } else { 17222 if (curProcs != null) { 17223 if (curProcs.remove(proc)) { 17224 mBatteryStatsService.noteEvent( 17225 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17226 proc.info.packageName, proc.info.uid); 17227 if (curProcs.size() <= 0) { 17228 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17229 } 17230 } 17231 } 17232 } 17233 if (oomAdj) { 17234 updateOomAdjLocked(); 17235 } 17236 } 17237 } 17238 17239 private final ActivityRecord resumedAppLocked() { 17240 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17241 String pkg; 17242 int uid; 17243 if (act != null) { 17244 pkg = act.packageName; 17245 uid = act.info.applicationInfo.uid; 17246 } else { 17247 pkg = null; 17248 uid = -1; 17249 } 17250 // Has the UID or resumed package name changed? 17251 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17252 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17253 if (mCurResumedPackage != null) { 17254 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17255 mCurResumedPackage, mCurResumedUid); 17256 } 17257 mCurResumedPackage = pkg; 17258 mCurResumedUid = uid; 17259 if (mCurResumedPackage != null) { 17260 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17261 mCurResumedPackage, mCurResumedUid); 17262 } 17263 } 17264 return act; 17265 } 17266 17267 final boolean updateOomAdjLocked(ProcessRecord app) { 17268 final ActivityRecord TOP_ACT = resumedAppLocked(); 17269 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17270 final boolean wasCached = app.cached; 17271 17272 mAdjSeq++; 17273 17274 // This is the desired cached adjusment we want to tell it to use. 17275 // If our app is currently cached, we know it, and that is it. Otherwise, 17276 // we don't know it yet, and it needs to now be cached we will then 17277 // need to do a complete oom adj. 17278 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17279 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17280 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17281 SystemClock.uptimeMillis()); 17282 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17283 // Changed to/from cached state, so apps after it in the LRU 17284 // list may also be changed. 17285 updateOomAdjLocked(); 17286 } 17287 return success; 17288 } 17289 17290 final void updateOomAdjLocked() { 17291 final ActivityRecord TOP_ACT = resumedAppLocked(); 17292 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17293 final long now = SystemClock.uptimeMillis(); 17294 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17295 final int N = mLruProcesses.size(); 17296 17297 if (false) { 17298 RuntimeException e = new RuntimeException(); 17299 e.fillInStackTrace(); 17300 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17301 } 17302 17303 mAdjSeq++; 17304 mNewNumServiceProcs = 0; 17305 mNewNumAServiceProcs = 0; 17306 17307 final int emptyProcessLimit; 17308 final int cachedProcessLimit; 17309 if (mProcessLimit <= 0) { 17310 emptyProcessLimit = cachedProcessLimit = 0; 17311 } else if (mProcessLimit == 1) { 17312 emptyProcessLimit = 1; 17313 cachedProcessLimit = 0; 17314 } else { 17315 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17316 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17317 } 17318 17319 // Let's determine how many processes we have running vs. 17320 // how many slots we have for background processes; we may want 17321 // to put multiple processes in a slot of there are enough of 17322 // them. 17323 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17324 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17325 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17326 if (numEmptyProcs > cachedProcessLimit) { 17327 // If there are more empty processes than our limit on cached 17328 // processes, then use the cached process limit for the factor. 17329 // This ensures that the really old empty processes get pushed 17330 // down to the bottom, so if we are running low on memory we will 17331 // have a better chance at keeping around more cached processes 17332 // instead of a gazillion empty processes. 17333 numEmptyProcs = cachedProcessLimit; 17334 } 17335 int emptyFactor = numEmptyProcs/numSlots; 17336 if (emptyFactor < 1) emptyFactor = 1; 17337 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17338 if (cachedFactor < 1) cachedFactor = 1; 17339 int stepCached = 0; 17340 int stepEmpty = 0; 17341 int numCached = 0; 17342 int numEmpty = 0; 17343 int numTrimming = 0; 17344 17345 mNumNonCachedProcs = 0; 17346 mNumCachedHiddenProcs = 0; 17347 17348 // First update the OOM adjustment for each of the 17349 // application processes based on their current state. 17350 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17351 int nextCachedAdj = curCachedAdj+1; 17352 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17353 int nextEmptyAdj = curEmptyAdj+2; 17354 for (int i=N-1; i>=0; i--) { 17355 ProcessRecord app = mLruProcesses.get(i); 17356 if (!app.killedByAm && app.thread != null) { 17357 app.procStateChanged = false; 17358 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17359 17360 // If we haven't yet assigned the final cached adj 17361 // to the process, do that now. 17362 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17363 switch (app.curProcState) { 17364 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17365 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17366 // This process is a cached process holding activities... 17367 // assign it the next cached value for that type, and then 17368 // step that cached level. 17369 app.curRawAdj = curCachedAdj; 17370 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17371 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17372 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17373 + ")"); 17374 if (curCachedAdj != nextCachedAdj) { 17375 stepCached++; 17376 if (stepCached >= cachedFactor) { 17377 stepCached = 0; 17378 curCachedAdj = nextCachedAdj; 17379 nextCachedAdj += 2; 17380 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17381 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17382 } 17383 } 17384 } 17385 break; 17386 default: 17387 // For everything else, assign next empty cached process 17388 // level and bump that up. Note that this means that 17389 // long-running services that have dropped down to the 17390 // cached level will be treated as empty (since their process 17391 // state is still as a service), which is what we want. 17392 app.curRawAdj = curEmptyAdj; 17393 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17394 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17395 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17396 + ")"); 17397 if (curEmptyAdj != nextEmptyAdj) { 17398 stepEmpty++; 17399 if (stepEmpty >= emptyFactor) { 17400 stepEmpty = 0; 17401 curEmptyAdj = nextEmptyAdj; 17402 nextEmptyAdj += 2; 17403 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17404 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17405 } 17406 } 17407 } 17408 break; 17409 } 17410 } 17411 17412 applyOomAdjLocked(app, TOP_APP, true, now); 17413 17414 // Count the number of process types. 17415 switch (app.curProcState) { 17416 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17417 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17418 mNumCachedHiddenProcs++; 17419 numCached++; 17420 if (numCached > cachedProcessLimit) { 17421 app.kill("cached #" + numCached, true); 17422 } 17423 break; 17424 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17425 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17426 && app.lastActivityTime < oldTime) { 17427 app.kill("empty for " 17428 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17429 / 1000) + "s", true); 17430 } else { 17431 numEmpty++; 17432 if (numEmpty > emptyProcessLimit) { 17433 app.kill("empty #" + numEmpty, true); 17434 } 17435 } 17436 break; 17437 default: 17438 mNumNonCachedProcs++; 17439 break; 17440 } 17441 17442 if (app.isolated && app.services.size() <= 0) { 17443 // If this is an isolated process, and there are no 17444 // services running in it, then the process is no longer 17445 // needed. We agressively kill these because we can by 17446 // definition not re-use the same process again, and it is 17447 // good to avoid having whatever code was running in them 17448 // left sitting around after no longer needed. 17449 app.kill("isolated not needed", true); 17450 } 17451 17452 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17453 && !app.killedByAm) { 17454 numTrimming++; 17455 } 17456 } 17457 } 17458 17459 mNumServiceProcs = mNewNumServiceProcs; 17460 17461 // Now determine the memory trimming level of background processes. 17462 // Unfortunately we need to start at the back of the list to do this 17463 // properly. We only do this if the number of background apps we 17464 // are managing to keep around is less than half the maximum we desire; 17465 // if we are keeping a good number around, we'll let them use whatever 17466 // memory they want. 17467 final int numCachedAndEmpty = numCached + numEmpty; 17468 int memFactor; 17469 if (numCached <= ProcessList.TRIM_CACHED_APPS 17470 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17471 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17472 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17473 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17474 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17475 } else { 17476 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17477 } 17478 } else { 17479 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17480 } 17481 // We always allow the memory level to go up (better). We only allow it to go 17482 // down if we are in a state where that is allowed, *and* the total number of processes 17483 // has gone down since last time. 17484 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17485 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17486 + " last=" + mLastNumProcesses); 17487 if (memFactor > mLastMemoryLevel) { 17488 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17489 memFactor = mLastMemoryLevel; 17490 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17491 } 17492 } 17493 mLastMemoryLevel = memFactor; 17494 mLastNumProcesses = mLruProcesses.size(); 17495 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17496 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17497 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17498 if (mLowRamStartTime == 0) { 17499 mLowRamStartTime = now; 17500 } 17501 int step = 0; 17502 int fgTrimLevel; 17503 switch (memFactor) { 17504 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17505 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17506 break; 17507 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17508 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17509 break; 17510 default: 17511 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17512 break; 17513 } 17514 int factor = numTrimming/3; 17515 int minFactor = 2; 17516 if (mHomeProcess != null) minFactor++; 17517 if (mPreviousProcess != null) minFactor++; 17518 if (factor < minFactor) factor = minFactor; 17519 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17520 for (int i=N-1; i>=0; i--) { 17521 ProcessRecord app = mLruProcesses.get(i); 17522 if (allChanged || app.procStateChanged) { 17523 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17524 app.procStateChanged = false; 17525 } 17526 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17527 && !app.killedByAm) { 17528 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17529 try { 17530 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17531 "Trimming memory of " + app.processName 17532 + " to " + curLevel); 17533 app.thread.scheduleTrimMemory(curLevel); 17534 } catch (RemoteException e) { 17535 } 17536 if (false) { 17537 // For now we won't do this; our memory trimming seems 17538 // to be good enough at this point that destroying 17539 // activities causes more harm than good. 17540 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17541 && app != mHomeProcess && app != mPreviousProcess) { 17542 // Need to do this on its own message because the stack may not 17543 // be in a consistent state at this point. 17544 // For these apps we will also finish their activities 17545 // to help them free memory. 17546 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17547 } 17548 } 17549 } 17550 app.trimMemoryLevel = curLevel; 17551 step++; 17552 if (step >= factor) { 17553 step = 0; 17554 switch (curLevel) { 17555 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17556 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17557 break; 17558 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17559 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17560 break; 17561 } 17562 } 17563 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17564 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17565 && app.thread != null) { 17566 try { 17567 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17568 "Trimming memory of heavy-weight " + app.processName 17569 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17570 app.thread.scheduleTrimMemory( 17571 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17572 } catch (RemoteException e) { 17573 } 17574 } 17575 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17576 } else { 17577 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17578 || app.systemNoUi) && app.pendingUiClean) { 17579 // If this application is now in the background and it 17580 // had done UI, then give it the special trim level to 17581 // have it free UI resources. 17582 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17583 if (app.trimMemoryLevel < level && app.thread != null) { 17584 try { 17585 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17586 "Trimming memory of bg-ui " + app.processName 17587 + " to " + level); 17588 app.thread.scheduleTrimMemory(level); 17589 } catch (RemoteException e) { 17590 } 17591 } 17592 app.pendingUiClean = false; 17593 } 17594 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17595 try { 17596 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17597 "Trimming memory of fg " + app.processName 17598 + " to " + fgTrimLevel); 17599 app.thread.scheduleTrimMemory(fgTrimLevel); 17600 } catch (RemoteException e) { 17601 } 17602 } 17603 app.trimMemoryLevel = fgTrimLevel; 17604 } 17605 } 17606 } else { 17607 if (mLowRamStartTime != 0) { 17608 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17609 mLowRamStartTime = 0; 17610 } 17611 for (int i=N-1; i>=0; i--) { 17612 ProcessRecord app = mLruProcesses.get(i); 17613 if (allChanged || app.procStateChanged) { 17614 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17615 app.procStateChanged = false; 17616 } 17617 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17618 || app.systemNoUi) && app.pendingUiClean) { 17619 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17620 && app.thread != null) { 17621 try { 17622 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17623 "Trimming memory of ui hidden " + app.processName 17624 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17625 app.thread.scheduleTrimMemory( 17626 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17627 } catch (RemoteException e) { 17628 } 17629 } 17630 app.pendingUiClean = false; 17631 } 17632 app.trimMemoryLevel = 0; 17633 } 17634 } 17635 17636 if (mAlwaysFinishActivities) { 17637 // Need to do this on its own message because the stack may not 17638 // be in a consistent state at this point. 17639 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17640 } 17641 17642 if (allChanged) { 17643 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17644 } 17645 17646 if (mProcessStats.shouldWriteNowLocked(now)) { 17647 mHandler.post(new Runnable() { 17648 @Override public void run() { 17649 synchronized (ActivityManagerService.this) { 17650 mProcessStats.writeStateAsyncLocked(); 17651 } 17652 } 17653 }); 17654 } 17655 17656 if (DEBUG_OOM_ADJ) { 17657 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17658 } 17659 } 17660 17661 final void trimApplications() { 17662 synchronized (this) { 17663 int i; 17664 17665 // First remove any unused application processes whose package 17666 // has been removed. 17667 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17668 final ProcessRecord app = mRemovedProcesses.get(i); 17669 if (app.activities.size() == 0 17670 && app.curReceiver == null && app.services.size() == 0) { 17671 Slog.i( 17672 TAG, "Exiting empty application process " 17673 + app.processName + " (" 17674 + (app.thread != null ? app.thread.asBinder() : null) 17675 + ")\n"); 17676 if (app.pid > 0 && app.pid != MY_PID) { 17677 app.kill("empty", false); 17678 } else { 17679 try { 17680 app.thread.scheduleExit(); 17681 } catch (Exception e) { 17682 // Ignore exceptions. 17683 } 17684 } 17685 cleanUpApplicationRecordLocked(app, false, true, -1); 17686 mRemovedProcesses.remove(i); 17687 17688 if (app.persistent) { 17689 addAppLocked(app.info, false, null /* ABI override */); 17690 } 17691 } 17692 } 17693 17694 // Now update the oom adj for all processes. 17695 updateOomAdjLocked(); 17696 } 17697 } 17698 17699 /** This method sends the specified signal to each of the persistent apps */ 17700 public void signalPersistentProcesses(int sig) throws RemoteException { 17701 if (sig != Process.SIGNAL_USR1) { 17702 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17703 } 17704 17705 synchronized (this) { 17706 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17707 != PackageManager.PERMISSION_GRANTED) { 17708 throw new SecurityException("Requires permission " 17709 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17710 } 17711 17712 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17713 ProcessRecord r = mLruProcesses.get(i); 17714 if (r.thread != null && r.persistent) { 17715 Process.sendSignal(r.pid, sig); 17716 } 17717 } 17718 } 17719 } 17720 17721 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17722 if (proc == null || proc == mProfileProc) { 17723 proc = mProfileProc; 17724 profileType = mProfileType; 17725 clearProfilerLocked(); 17726 } 17727 if (proc == null) { 17728 return; 17729 } 17730 try { 17731 proc.thread.profilerControl(false, null, profileType); 17732 } catch (RemoteException e) { 17733 throw new IllegalStateException("Process disappeared"); 17734 } 17735 } 17736 17737 private void clearProfilerLocked() { 17738 if (mProfileFd != null) { 17739 try { 17740 mProfileFd.close(); 17741 } catch (IOException e) { 17742 } 17743 } 17744 mProfileApp = null; 17745 mProfileProc = null; 17746 mProfileFile = null; 17747 mProfileType = 0; 17748 mAutoStopProfiler = false; 17749 mSamplingInterval = 0; 17750 } 17751 17752 public boolean profileControl(String process, int userId, boolean start, 17753 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17754 17755 try { 17756 synchronized (this) { 17757 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17758 // its own permission. 17759 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17760 != PackageManager.PERMISSION_GRANTED) { 17761 throw new SecurityException("Requires permission " 17762 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17763 } 17764 17765 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17766 throw new IllegalArgumentException("null profile info or fd"); 17767 } 17768 17769 ProcessRecord proc = null; 17770 if (process != null) { 17771 proc = findProcessLocked(process, userId, "profileControl"); 17772 } 17773 17774 if (start && (proc == null || proc.thread == null)) { 17775 throw new IllegalArgumentException("Unknown process: " + process); 17776 } 17777 17778 if (start) { 17779 stopProfilerLocked(null, 0); 17780 setProfileApp(proc.info, proc.processName, profilerInfo); 17781 mProfileProc = proc; 17782 mProfileType = profileType; 17783 ParcelFileDescriptor fd = profilerInfo.profileFd; 17784 try { 17785 fd = fd.dup(); 17786 } catch (IOException e) { 17787 fd = null; 17788 } 17789 profilerInfo.profileFd = fd; 17790 proc.thread.profilerControl(start, profilerInfo, profileType); 17791 fd = null; 17792 mProfileFd = null; 17793 } else { 17794 stopProfilerLocked(proc, profileType); 17795 if (profilerInfo != null && profilerInfo.profileFd != null) { 17796 try { 17797 profilerInfo.profileFd.close(); 17798 } catch (IOException e) { 17799 } 17800 } 17801 } 17802 17803 return true; 17804 } 17805 } catch (RemoteException e) { 17806 throw new IllegalStateException("Process disappeared"); 17807 } finally { 17808 if (profilerInfo != null && profilerInfo.profileFd != null) { 17809 try { 17810 profilerInfo.profileFd.close(); 17811 } catch (IOException e) { 17812 } 17813 } 17814 } 17815 } 17816 17817 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17818 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17819 userId, true, ALLOW_FULL_ONLY, callName, null); 17820 ProcessRecord proc = null; 17821 try { 17822 int pid = Integer.parseInt(process); 17823 synchronized (mPidsSelfLocked) { 17824 proc = mPidsSelfLocked.get(pid); 17825 } 17826 } catch (NumberFormatException e) { 17827 } 17828 17829 if (proc == null) { 17830 ArrayMap<String, SparseArray<ProcessRecord>> all 17831 = mProcessNames.getMap(); 17832 SparseArray<ProcessRecord> procs = all.get(process); 17833 if (procs != null && procs.size() > 0) { 17834 proc = procs.valueAt(0); 17835 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17836 for (int i=1; i<procs.size(); i++) { 17837 ProcessRecord thisProc = procs.valueAt(i); 17838 if (thisProc.userId == userId) { 17839 proc = thisProc; 17840 break; 17841 } 17842 } 17843 } 17844 } 17845 } 17846 17847 return proc; 17848 } 17849 17850 public boolean dumpHeap(String process, int userId, boolean managed, 17851 String path, ParcelFileDescriptor fd) throws RemoteException { 17852 17853 try { 17854 synchronized (this) { 17855 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17856 // its own permission (same as profileControl). 17857 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17858 != PackageManager.PERMISSION_GRANTED) { 17859 throw new SecurityException("Requires permission " 17860 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17861 } 17862 17863 if (fd == null) { 17864 throw new IllegalArgumentException("null fd"); 17865 } 17866 17867 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17868 if (proc == null || proc.thread == null) { 17869 throw new IllegalArgumentException("Unknown process: " + process); 17870 } 17871 17872 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17873 if (!isDebuggable) { 17874 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17875 throw new SecurityException("Process not debuggable: " + proc); 17876 } 17877 } 17878 17879 proc.thread.dumpHeap(managed, path, fd); 17880 fd = null; 17881 return true; 17882 } 17883 } catch (RemoteException e) { 17884 throw new IllegalStateException("Process disappeared"); 17885 } finally { 17886 if (fd != null) { 17887 try { 17888 fd.close(); 17889 } catch (IOException e) { 17890 } 17891 } 17892 } 17893 } 17894 17895 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17896 public void monitor() { 17897 synchronized (this) { } 17898 } 17899 17900 void onCoreSettingsChange(Bundle settings) { 17901 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17902 ProcessRecord processRecord = mLruProcesses.get(i); 17903 try { 17904 if (processRecord.thread != null) { 17905 processRecord.thread.setCoreSettings(settings); 17906 } 17907 } catch (RemoteException re) { 17908 /* ignore */ 17909 } 17910 } 17911 } 17912 17913 // Multi-user methods 17914 17915 /** 17916 * Start user, if its not already running, but don't bring it to foreground. 17917 */ 17918 @Override 17919 public boolean startUserInBackground(final int userId) { 17920 return startUser(userId, /* foreground */ false); 17921 } 17922 17923 /** 17924 * Start user, if its not already running, and bring it to foreground. 17925 */ 17926 boolean startUserInForeground(final int userId, Dialog dlg) { 17927 boolean result = startUser(userId, /* foreground */ true); 17928 dlg.dismiss(); 17929 return result; 17930 } 17931 17932 /** 17933 * Refreshes the list of users related to the current user when either a 17934 * user switch happens or when a new related user is started in the 17935 * background. 17936 */ 17937 private void updateCurrentProfileIdsLocked() { 17938 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17939 mCurrentUserId, false /* enabledOnly */); 17940 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17941 for (int i = 0; i < currentProfileIds.length; i++) { 17942 currentProfileIds[i] = profiles.get(i).id; 17943 } 17944 mCurrentProfileIds = currentProfileIds; 17945 17946 synchronized (mUserProfileGroupIdsSelfLocked) { 17947 mUserProfileGroupIdsSelfLocked.clear(); 17948 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17949 for (int i = 0; i < users.size(); i++) { 17950 UserInfo user = users.get(i); 17951 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17952 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17953 } 17954 } 17955 } 17956 } 17957 17958 private Set getProfileIdsLocked(int userId) { 17959 Set userIds = new HashSet<Integer>(); 17960 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17961 userId, false /* enabledOnly */); 17962 for (UserInfo user : profiles) { 17963 userIds.add(Integer.valueOf(user.id)); 17964 } 17965 return userIds; 17966 } 17967 17968 @Override 17969 public boolean switchUser(final int userId) { 17970 String userName; 17971 synchronized (this) { 17972 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17973 if (userInfo == null) { 17974 Slog.w(TAG, "No user info for user #" + userId); 17975 return false; 17976 } 17977 if (userInfo.isManagedProfile()) { 17978 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17979 return false; 17980 } 17981 userName = userInfo.name; 17982 mTargetUserId = userId; 17983 } 17984 mHandler.removeMessages(START_USER_SWITCH_MSG); 17985 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17986 return true; 17987 } 17988 17989 private void showUserSwitchDialog(int userId, String userName) { 17990 // The dialog will show and then initiate the user switch by calling startUserInForeground 17991 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17992 true /* above system */); 17993 d.show(); 17994 } 17995 17996 private boolean startUser(final int userId, final boolean foreground) { 17997 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17998 != PackageManager.PERMISSION_GRANTED) { 17999 String msg = "Permission Denial: switchUser() from pid=" 18000 + Binder.getCallingPid() 18001 + ", uid=" + Binder.getCallingUid() 18002 + " requires " + INTERACT_ACROSS_USERS_FULL; 18003 Slog.w(TAG, msg); 18004 throw new SecurityException(msg); 18005 } 18006 18007 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 18008 18009 final long ident = Binder.clearCallingIdentity(); 18010 try { 18011 synchronized (this) { 18012 final int oldUserId = mCurrentUserId; 18013 if (oldUserId == userId) { 18014 return true; 18015 } 18016 18017 mStackSupervisor.setLockTaskModeLocked(null, false); 18018 18019 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 18020 if (userInfo == null) { 18021 Slog.w(TAG, "No user info for user #" + userId); 18022 return false; 18023 } 18024 if (foreground && userInfo.isManagedProfile()) { 18025 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 18026 return false; 18027 } 18028 18029 if (foreground) { 18030 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 18031 R.anim.screen_user_enter); 18032 } 18033 18034 boolean needStart = false; 18035 18036 // If the user we are switching to is not currently started, then 18037 // we need to start it now. 18038 if (mStartedUsers.get(userId) == null) { 18039 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 18040 updateStartedUserArrayLocked(); 18041 needStart = true; 18042 } 18043 18044 final Integer userIdInt = Integer.valueOf(userId); 18045 mUserLru.remove(userIdInt); 18046 mUserLru.add(userIdInt); 18047 18048 if (foreground) { 18049 mCurrentUserId = userId; 18050 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up 18051 updateCurrentProfileIdsLocked(); 18052 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 18053 // Once the internal notion of the active user has switched, we lock the device 18054 // with the option to show the user switcher on the keyguard. 18055 mWindowManager.lockNow(null); 18056 } else { 18057 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 18058 updateCurrentProfileIdsLocked(); 18059 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 18060 mUserLru.remove(currentUserIdInt); 18061 mUserLru.add(currentUserIdInt); 18062 } 18063 18064 final UserStartedState uss = mStartedUsers.get(userId); 18065 18066 // Make sure user is in the started state. If it is currently 18067 // stopping, we need to knock that off. 18068 if (uss.mState == UserStartedState.STATE_STOPPING) { 18069 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 18070 // so we can just fairly silently bring the user back from 18071 // the almost-dead. 18072 uss.mState = UserStartedState.STATE_RUNNING; 18073 updateStartedUserArrayLocked(); 18074 needStart = true; 18075 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 18076 // This means ACTION_SHUTDOWN has been sent, so we will 18077 // need to treat this as a new boot of the user. 18078 uss.mState = UserStartedState.STATE_BOOTING; 18079 updateStartedUserArrayLocked(); 18080 needStart = true; 18081 } 18082 18083 if (uss.mState == UserStartedState.STATE_BOOTING) { 18084 // Booting up a new user, need to tell system services about it. 18085 // Note that this is on the same handler as scheduling of broadcasts, 18086 // which is important because it needs to go first. 18087 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 18088 } 18089 18090 if (foreground) { 18091 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 18092 oldUserId)); 18093 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 18094 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18095 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18096 oldUserId, userId, uss)); 18097 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18098 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18099 } 18100 18101 if (needStart) { 18102 // Send USER_STARTED broadcast 18103 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18104 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18105 | Intent.FLAG_RECEIVER_FOREGROUND); 18106 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18107 broadcastIntentLocked(null, null, intent, 18108 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18109 false, false, MY_PID, Process.SYSTEM_UID, userId); 18110 } 18111 18112 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18113 if (userId != UserHandle.USER_OWNER) { 18114 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18115 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18116 broadcastIntentLocked(null, null, intent, null, 18117 new IIntentReceiver.Stub() { 18118 public void performReceive(Intent intent, int resultCode, 18119 String data, Bundle extras, boolean ordered, 18120 boolean sticky, int sendingUser) { 18121 onUserInitialized(uss, foreground, oldUserId, userId); 18122 } 18123 }, 0, null, null, null, AppOpsManager.OP_NONE, 18124 true, false, MY_PID, Process.SYSTEM_UID, 18125 userId); 18126 uss.initializing = true; 18127 } else { 18128 getUserManagerLocked().makeInitialized(userInfo.id); 18129 } 18130 } 18131 18132 if (foreground) { 18133 if (!uss.initializing) { 18134 moveUserToForeground(uss, oldUserId, userId); 18135 } 18136 } else { 18137 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18138 } 18139 18140 if (needStart) { 18141 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18142 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18143 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18144 broadcastIntentLocked(null, null, intent, 18145 null, new IIntentReceiver.Stub() { 18146 @Override 18147 public void performReceive(Intent intent, int resultCode, String data, 18148 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18149 throws RemoteException { 18150 } 18151 }, 0, null, null, 18152 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18153 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18154 } 18155 } 18156 } finally { 18157 Binder.restoreCallingIdentity(ident); 18158 } 18159 18160 return true; 18161 } 18162 18163 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18164 long ident = Binder.clearCallingIdentity(); 18165 try { 18166 Intent intent; 18167 if (oldUserId >= 0) { 18168 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18169 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18170 int count = profiles.size(); 18171 for (int i = 0; i < count; i++) { 18172 int profileUserId = profiles.get(i).id; 18173 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18174 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18175 | Intent.FLAG_RECEIVER_FOREGROUND); 18176 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18177 broadcastIntentLocked(null, null, intent, 18178 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18179 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18180 } 18181 } 18182 if (newUserId >= 0) { 18183 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18184 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18185 int count = profiles.size(); 18186 for (int i = 0; i < count; i++) { 18187 int profileUserId = profiles.get(i).id; 18188 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18189 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18190 | Intent.FLAG_RECEIVER_FOREGROUND); 18191 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18192 broadcastIntentLocked(null, null, intent, 18193 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18194 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18195 } 18196 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18197 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18198 | Intent.FLAG_RECEIVER_FOREGROUND); 18199 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18200 broadcastIntentLocked(null, null, intent, 18201 null, null, 0, null, null, 18202 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18203 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18204 } 18205 } finally { 18206 Binder.restoreCallingIdentity(ident); 18207 } 18208 } 18209 18210 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18211 final int newUserId) { 18212 final int N = mUserSwitchObservers.beginBroadcast(); 18213 if (N > 0) { 18214 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18215 int mCount = 0; 18216 @Override 18217 public void sendResult(Bundle data) throws RemoteException { 18218 synchronized (ActivityManagerService.this) { 18219 if (mCurUserSwitchCallback == this) { 18220 mCount++; 18221 if (mCount == N) { 18222 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18223 } 18224 } 18225 } 18226 } 18227 }; 18228 synchronized (this) { 18229 uss.switching = true; 18230 mCurUserSwitchCallback = callback; 18231 } 18232 for (int i=0; i<N; i++) { 18233 try { 18234 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18235 newUserId, callback); 18236 } catch (RemoteException e) { 18237 } 18238 } 18239 } else { 18240 synchronized (this) { 18241 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18242 } 18243 } 18244 mUserSwitchObservers.finishBroadcast(); 18245 } 18246 18247 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18248 synchronized (this) { 18249 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18250 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18251 } 18252 } 18253 18254 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18255 mCurUserSwitchCallback = null; 18256 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18257 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18258 oldUserId, newUserId, uss)); 18259 } 18260 18261 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18262 synchronized (this) { 18263 if (foreground) { 18264 moveUserToForeground(uss, oldUserId, newUserId); 18265 } 18266 } 18267 18268 completeSwitchAndInitalize(uss, newUserId, true, false); 18269 } 18270 18271 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18272 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18273 if (homeInFront) { 18274 startHomeActivityLocked(newUserId); 18275 } else { 18276 mStackSupervisor.resumeTopActivitiesLocked(); 18277 } 18278 EventLogTags.writeAmSwitchUser(newUserId); 18279 getUserManagerLocked().userForeground(newUserId); 18280 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18281 } 18282 18283 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18284 completeSwitchAndInitalize(uss, newUserId, false, true); 18285 } 18286 18287 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18288 boolean clearInitializing, boolean clearSwitching) { 18289 boolean unfrozen = false; 18290 synchronized (this) { 18291 if (clearInitializing) { 18292 uss.initializing = false; 18293 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18294 } 18295 if (clearSwitching) { 18296 uss.switching = false; 18297 } 18298 if (!uss.switching && !uss.initializing) { 18299 mWindowManager.stopFreezingScreen(); 18300 unfrozen = true; 18301 } 18302 } 18303 if (unfrozen) { 18304 final int N = mUserSwitchObservers.beginBroadcast(); 18305 for (int i=0; i<N; i++) { 18306 try { 18307 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18308 } catch (RemoteException e) { 18309 } 18310 } 18311 mUserSwitchObservers.finishBroadcast(); 18312 } 18313 } 18314 18315 void scheduleStartProfilesLocked() { 18316 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18317 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18318 DateUtils.SECOND_IN_MILLIS); 18319 } 18320 } 18321 18322 void startProfilesLocked() { 18323 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18324 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18325 mCurrentUserId, false /* enabledOnly */); 18326 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18327 for (UserInfo user : profiles) { 18328 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18329 && user.id != mCurrentUserId) { 18330 toStart.add(user); 18331 } 18332 } 18333 final int n = toStart.size(); 18334 int i = 0; 18335 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18336 startUserInBackground(toStart.get(i).id); 18337 } 18338 if (i < n) { 18339 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18340 } 18341 } 18342 18343 void finishUserBoot(UserStartedState uss) { 18344 synchronized (this) { 18345 if (uss.mState == UserStartedState.STATE_BOOTING 18346 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18347 uss.mState = UserStartedState.STATE_RUNNING; 18348 final int userId = uss.mHandle.getIdentifier(); 18349 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18350 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18351 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18352 broadcastIntentLocked(null, null, intent, 18353 null, null, 0, null, null, 18354 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18355 true, false, MY_PID, Process.SYSTEM_UID, userId); 18356 } 18357 } 18358 } 18359 18360 void finishUserSwitch(UserStartedState uss) { 18361 synchronized (this) { 18362 finishUserBoot(uss); 18363 18364 startProfilesLocked(); 18365 18366 int num = mUserLru.size(); 18367 int i = 0; 18368 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18369 Integer oldUserId = mUserLru.get(i); 18370 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18371 if (oldUss == null) { 18372 // Shouldn't happen, but be sane if it does. 18373 mUserLru.remove(i); 18374 num--; 18375 continue; 18376 } 18377 if (oldUss.mState == UserStartedState.STATE_STOPPING 18378 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18379 // This user is already stopping, doesn't count. 18380 num--; 18381 i++; 18382 continue; 18383 } 18384 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18385 // Owner and current can't be stopped, but count as running. 18386 i++; 18387 continue; 18388 } 18389 // This is a user to be stopped. 18390 stopUserLocked(oldUserId, null); 18391 num--; 18392 i++; 18393 } 18394 } 18395 } 18396 18397 @Override 18398 public int stopUser(final int userId, final IStopUserCallback callback) { 18399 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18400 != PackageManager.PERMISSION_GRANTED) { 18401 String msg = "Permission Denial: switchUser() from pid=" 18402 + Binder.getCallingPid() 18403 + ", uid=" + Binder.getCallingUid() 18404 + " requires " + INTERACT_ACROSS_USERS_FULL; 18405 Slog.w(TAG, msg); 18406 throw new SecurityException(msg); 18407 } 18408 if (userId <= 0) { 18409 throw new IllegalArgumentException("Can't stop primary user " + userId); 18410 } 18411 synchronized (this) { 18412 return stopUserLocked(userId, callback); 18413 } 18414 } 18415 18416 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18417 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18418 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) { 18419 return ActivityManager.USER_OP_IS_CURRENT; 18420 } 18421 18422 final UserStartedState uss = mStartedUsers.get(userId); 18423 if (uss == null) { 18424 // User is not started, nothing to do... but we do need to 18425 // callback if requested. 18426 if (callback != null) { 18427 mHandler.post(new Runnable() { 18428 @Override 18429 public void run() { 18430 try { 18431 callback.userStopped(userId); 18432 } catch (RemoteException e) { 18433 } 18434 } 18435 }); 18436 } 18437 return ActivityManager.USER_OP_SUCCESS; 18438 } 18439 18440 if (callback != null) { 18441 uss.mStopCallbacks.add(callback); 18442 } 18443 18444 if (uss.mState != UserStartedState.STATE_STOPPING 18445 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18446 uss.mState = UserStartedState.STATE_STOPPING; 18447 updateStartedUserArrayLocked(); 18448 18449 long ident = Binder.clearCallingIdentity(); 18450 try { 18451 // We are going to broadcast ACTION_USER_STOPPING and then 18452 // once that is done send a final ACTION_SHUTDOWN and then 18453 // stop the user. 18454 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18455 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18456 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18457 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18458 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18459 // This is the result receiver for the final shutdown broadcast. 18460 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18461 @Override 18462 public void performReceive(Intent intent, int resultCode, String data, 18463 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18464 finishUserStop(uss); 18465 } 18466 }; 18467 // This is the result receiver for the initial stopping broadcast. 18468 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18469 @Override 18470 public void performReceive(Intent intent, int resultCode, String data, 18471 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18472 // On to the next. 18473 synchronized (ActivityManagerService.this) { 18474 if (uss.mState != UserStartedState.STATE_STOPPING) { 18475 // Whoops, we are being started back up. Abort, abort! 18476 return; 18477 } 18478 uss.mState = UserStartedState.STATE_SHUTDOWN; 18479 } 18480 mBatteryStatsService.noteEvent( 18481 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18482 Integer.toString(userId), userId); 18483 mSystemServiceManager.stopUser(userId); 18484 broadcastIntentLocked(null, null, shutdownIntent, 18485 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18486 true, false, MY_PID, Process.SYSTEM_UID, userId); 18487 } 18488 }; 18489 // Kick things off. 18490 broadcastIntentLocked(null, null, stoppingIntent, 18491 null, stoppingReceiver, 0, null, null, 18492 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18493 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18494 } finally { 18495 Binder.restoreCallingIdentity(ident); 18496 } 18497 } 18498 18499 return ActivityManager.USER_OP_SUCCESS; 18500 } 18501 18502 void finishUserStop(UserStartedState uss) { 18503 final int userId = uss.mHandle.getIdentifier(); 18504 boolean stopped; 18505 ArrayList<IStopUserCallback> callbacks; 18506 synchronized (this) { 18507 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18508 if (mStartedUsers.get(userId) != uss) { 18509 stopped = false; 18510 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18511 stopped = false; 18512 } else { 18513 stopped = true; 18514 // User can no longer run. 18515 mStartedUsers.remove(userId); 18516 mUserLru.remove(Integer.valueOf(userId)); 18517 updateStartedUserArrayLocked(); 18518 18519 // Clean up all state and processes associated with the user. 18520 // Kill all the processes for the user. 18521 forceStopUserLocked(userId, "finish user"); 18522 } 18523 18524 // Explicitly remove the old information in mRecentTasks. 18525 removeRecentTasksForUserLocked(userId); 18526 } 18527 18528 for (int i=0; i<callbacks.size(); i++) { 18529 try { 18530 if (stopped) callbacks.get(i).userStopped(userId); 18531 else callbacks.get(i).userStopAborted(userId); 18532 } catch (RemoteException e) { 18533 } 18534 } 18535 18536 if (stopped) { 18537 mSystemServiceManager.cleanupUser(userId); 18538 synchronized (this) { 18539 mStackSupervisor.removeUserLocked(userId); 18540 } 18541 } 18542 } 18543 18544 @Override 18545 public UserInfo getCurrentUser() { 18546 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18547 != PackageManager.PERMISSION_GRANTED) && ( 18548 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18549 != PackageManager.PERMISSION_GRANTED)) { 18550 String msg = "Permission Denial: getCurrentUser() 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 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18559 return getUserManagerLocked().getUserInfo(userId); 18560 } 18561 } 18562 18563 int getCurrentUserIdLocked() { 18564 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId; 18565 } 18566 18567 @Override 18568 public boolean isUserRunning(int userId, boolean orStopped) { 18569 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18570 != PackageManager.PERMISSION_GRANTED) { 18571 String msg = "Permission Denial: isUserRunning() from pid=" 18572 + Binder.getCallingPid() 18573 + ", uid=" + Binder.getCallingUid() 18574 + " requires " + INTERACT_ACROSS_USERS; 18575 Slog.w(TAG, msg); 18576 throw new SecurityException(msg); 18577 } 18578 synchronized (this) { 18579 return isUserRunningLocked(userId, orStopped); 18580 } 18581 } 18582 18583 boolean isUserRunningLocked(int userId, boolean orStopped) { 18584 UserStartedState state = mStartedUsers.get(userId); 18585 if (state == null) { 18586 return false; 18587 } 18588 if (orStopped) { 18589 return true; 18590 } 18591 return state.mState != UserStartedState.STATE_STOPPING 18592 && state.mState != UserStartedState.STATE_SHUTDOWN; 18593 } 18594 18595 @Override 18596 public int[] getRunningUserIds() { 18597 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18598 != PackageManager.PERMISSION_GRANTED) { 18599 String msg = "Permission Denial: isUserRunning() from pid=" 18600 + Binder.getCallingPid() 18601 + ", uid=" + Binder.getCallingUid() 18602 + " requires " + INTERACT_ACROSS_USERS; 18603 Slog.w(TAG, msg); 18604 throw new SecurityException(msg); 18605 } 18606 synchronized (this) { 18607 return mStartedUserArray; 18608 } 18609 } 18610 18611 private void updateStartedUserArrayLocked() { 18612 int num = 0; 18613 for (int i=0; i<mStartedUsers.size(); i++) { 18614 UserStartedState uss = mStartedUsers.valueAt(i); 18615 // This list does not include stopping users. 18616 if (uss.mState != UserStartedState.STATE_STOPPING 18617 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18618 num++; 18619 } 18620 } 18621 mStartedUserArray = new int[num]; 18622 num = 0; 18623 for (int i=0; i<mStartedUsers.size(); i++) { 18624 UserStartedState uss = mStartedUsers.valueAt(i); 18625 if (uss.mState != UserStartedState.STATE_STOPPING 18626 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18627 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18628 num++; 18629 } 18630 } 18631 } 18632 18633 @Override 18634 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18635 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18636 != PackageManager.PERMISSION_GRANTED) { 18637 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18638 + Binder.getCallingPid() 18639 + ", uid=" + Binder.getCallingUid() 18640 + " requires " + INTERACT_ACROSS_USERS_FULL; 18641 Slog.w(TAG, msg); 18642 throw new SecurityException(msg); 18643 } 18644 18645 mUserSwitchObservers.register(observer); 18646 } 18647 18648 @Override 18649 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18650 mUserSwitchObservers.unregister(observer); 18651 } 18652 18653 private boolean userExists(int userId) { 18654 if (userId == 0) { 18655 return true; 18656 } 18657 UserManagerService ums = getUserManagerLocked(); 18658 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18659 } 18660 18661 int[] getUsersLocked() { 18662 UserManagerService ums = getUserManagerLocked(); 18663 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18664 } 18665 18666 UserManagerService getUserManagerLocked() { 18667 if (mUserManager == null) { 18668 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18669 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18670 } 18671 return mUserManager; 18672 } 18673 18674 private int applyUserId(int uid, int userId) { 18675 return UserHandle.getUid(userId, uid); 18676 } 18677 18678 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18679 if (info == null) return null; 18680 ApplicationInfo newInfo = new ApplicationInfo(info); 18681 newInfo.uid = applyUserId(info.uid, userId); 18682 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18683 + info.packageName; 18684 return newInfo; 18685 } 18686 18687 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18688 if (aInfo == null 18689 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18690 return aInfo; 18691 } 18692 18693 ActivityInfo info = new ActivityInfo(aInfo); 18694 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18695 return info; 18696 } 18697 18698 private final class LocalService extends ActivityManagerInternal { 18699 @Override 18700 public void goingToSleep() { 18701 ActivityManagerService.this.goingToSleep(); 18702 } 18703 18704 @Override 18705 public void wakingUp() { 18706 ActivityManagerService.this.wakingUp(); 18707 } 18708 18709 @Override 18710 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18711 String processName, String abiOverride, int uid, Runnable crashHandler) { 18712 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18713 processName, abiOverride, uid, crashHandler); 18714 } 18715 } 18716 18717 /** 18718 * An implementation of IAppTask, that allows an app to manage its own tasks via 18719 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18720 * only the process that calls getAppTasks() can call the AppTask methods. 18721 */ 18722 class AppTaskImpl extends IAppTask.Stub { 18723 private int mTaskId; 18724 private int mCallingUid; 18725 18726 public AppTaskImpl(int taskId, int callingUid) { 18727 mTaskId = taskId; 18728 mCallingUid = callingUid; 18729 } 18730 18731 private void checkCaller() { 18732 if (mCallingUid != Binder.getCallingUid()) { 18733 throw new SecurityException("Caller " + mCallingUid 18734 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18735 } 18736 } 18737 18738 @Override 18739 public void finishAndRemoveTask() { 18740 checkCaller(); 18741 18742 synchronized (ActivityManagerService.this) { 18743 long origId = Binder.clearCallingIdentity(); 18744 try { 18745 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18746 if (tr == null) { 18747 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18748 } 18749 // Only kill the process if we are not a new document 18750 int flags = tr.getBaseIntent().getFlags(); 18751 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18752 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18753 removeTaskByIdLocked(mTaskId, 18754 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18755 } finally { 18756 Binder.restoreCallingIdentity(origId); 18757 } 18758 } 18759 } 18760 18761 @Override 18762 public ActivityManager.RecentTaskInfo getTaskInfo() { 18763 checkCaller(); 18764 18765 synchronized (ActivityManagerService.this) { 18766 long origId = Binder.clearCallingIdentity(); 18767 try { 18768 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18769 if (tr == null) { 18770 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18771 } 18772 return createRecentTaskInfoFromTaskRecord(tr); 18773 } finally { 18774 Binder.restoreCallingIdentity(origId); 18775 } 18776 } 18777 } 18778 18779 @Override 18780 public void moveToFront() { 18781 checkCaller(); 18782 18783 final TaskRecord tr; 18784 synchronized (ActivityManagerService.this) { 18785 tr = recentTaskForIdLocked(mTaskId); 18786 if (tr == null) { 18787 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18788 } 18789 if (tr.getRootActivity() != null) { 18790 long origId = Binder.clearCallingIdentity(); 18791 try { 18792 moveTaskToFrontLocked(tr.taskId, 0, null); 18793 return; 18794 } finally { 18795 Binder.restoreCallingIdentity(origId); 18796 } 18797 } 18798 } 18799 18800 startActivityFromRecentsInner(tr.taskId, null); 18801 } 18802 18803 @Override 18804 public int startActivity(IBinder whoThread, String callingPackage, 18805 Intent intent, String resolvedType, Bundle options) { 18806 checkCaller(); 18807 18808 int callingUser = UserHandle.getCallingUserId(); 18809 TaskRecord tr; 18810 IApplicationThread appThread; 18811 synchronized (ActivityManagerService.this) { 18812 tr = recentTaskForIdLocked(mTaskId); 18813 if (tr == null) { 18814 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18815 } 18816 appThread = ApplicationThreadNative.asInterface(whoThread); 18817 if (appThread == null) { 18818 throw new IllegalArgumentException("Bad app thread " + appThread); 18819 } 18820 } 18821 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18822 resolvedType, null, null, null, null, 0, 0, null, null, 18823 null, options, callingUser, null, tr); 18824 } 18825 18826 @Override 18827 public void setExcludeFromRecents(boolean exclude) { 18828 checkCaller(); 18829 18830 synchronized (ActivityManagerService.this) { 18831 long origId = Binder.clearCallingIdentity(); 18832 try { 18833 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18834 if (tr == null) { 18835 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18836 } 18837 Intent intent = tr.getBaseIntent(); 18838 if (exclude) { 18839 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18840 } else { 18841 intent.setFlags(intent.getFlags() 18842 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18843 } 18844 } finally { 18845 Binder.restoreCallingIdentity(origId); 18846 } 18847 } 18848 } 18849 } 18850} 18851