ActivityManagerService.java revision 53dc7eac05324261a51443059b5fb5d468f33594
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 21import static android.Manifest.permission.START_TASKS_FROM_RECENTS; 22import static android.content.pm.PackageManager.PERMISSION_GRANTED; 23import static com.android.internal.util.XmlUtils.readBooleanAttribute; 24import static com.android.internal.util.XmlUtils.readIntAttribute; 25import static com.android.internal.util.XmlUtils.readLongAttribute; 26import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 27import static com.android.internal.util.XmlUtils.writeIntAttribute; 28import static com.android.internal.util.XmlUtils.writeLongAttribute; 29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 31import static org.xmlpull.v1.XmlPullParser.START_TAG; 32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 33 34import android.Manifest; 35import android.app.AppOpsManager; 36import android.app.ApplicationThreadNative; 37import android.app.IActivityContainer; 38import android.app.IActivityContainerCallback; 39import android.app.IAppTask; 40import android.app.ProfilerInfo; 41import android.app.admin.DevicePolicyManager; 42import android.app.usage.UsageEvents; 43import android.app.usage.UsageStatsManagerInternal; 44import android.appwidget.AppWidgetManager; 45import android.content.res.Resources; 46import android.graphics.Bitmap; 47import android.graphics.Point; 48import android.graphics.Rect; 49import android.os.BatteryStats; 50import android.os.PersistableBundle; 51import android.service.voice.IVoiceInteractionSession; 52import android.util.ArrayMap; 53import android.util.ArraySet; 54import android.util.SparseIntArray; 55 56import com.android.internal.R; 57import com.android.internal.annotations.GuardedBy; 58import com.android.internal.app.IAppOpsService; 59import com.android.internal.app.IVoiceInteractor; 60import com.android.internal.app.ProcessMap; 61import com.android.internal.app.ProcessStats; 62import com.android.internal.content.PackageMonitor; 63import com.android.internal.os.BackgroundThread; 64import com.android.internal.os.BatteryStatsImpl; 65import com.android.internal.os.ProcessCpuTracker; 66import com.android.internal.os.TransferPipe; 67import com.android.internal.os.Zygote; 68import com.android.internal.util.FastPrintWriter; 69import com.android.internal.util.FastXmlSerializer; 70import com.android.internal.util.MemInfoReader; 71import com.android.internal.util.Preconditions; 72import com.android.server.AppOpsService; 73import com.android.server.AttributeCache; 74import com.android.server.IntentResolver; 75import com.android.server.LocalServices; 76import com.android.server.ServiceThread; 77import com.android.server.SystemService; 78import com.android.server.SystemServiceManager; 79import com.android.server.Watchdog; 80import com.android.server.am.ActivityStack.ActivityState; 81import com.android.server.firewall.IntentFirewall; 82import com.android.server.pm.UserManagerService; 83import com.android.server.wm.AppTransition; 84import com.android.server.wm.WindowManagerService; 85import com.google.android.collect.Lists; 86import com.google.android.collect.Maps; 87 88import libcore.io.IoUtils; 89 90import org.xmlpull.v1.XmlPullParser; 91import org.xmlpull.v1.XmlPullParserException; 92import org.xmlpull.v1.XmlSerializer; 93 94import android.app.Activity; 95import android.app.ActivityManager; 96import android.app.ActivityManager.RunningTaskInfo; 97import android.app.ActivityManager.StackInfo; 98import android.app.ActivityManagerInternal; 99import android.app.ActivityManagerNative; 100import android.app.ActivityOptions; 101import android.app.ActivityThread; 102import android.app.AlertDialog; 103import android.app.AppGlobals; 104import android.app.ApplicationErrorReport; 105import android.app.Dialog; 106import android.app.IActivityController; 107import android.app.IApplicationThread; 108import android.app.IInstrumentationWatcher; 109import android.app.INotificationManager; 110import android.app.IProcessObserver; 111import android.app.IServiceConnection; 112import android.app.IStopUserCallback; 113import android.app.IUiAutomationConnection; 114import android.app.IUserSwitchObserver; 115import android.app.Instrumentation; 116import android.app.Notification; 117import android.app.NotificationManager; 118import android.app.PendingIntent; 119import android.app.backup.IBackupManager; 120import android.content.ActivityNotFoundException; 121import android.content.BroadcastReceiver; 122import android.content.ClipData; 123import android.content.ComponentCallbacks2; 124import android.content.ComponentName; 125import android.content.ContentProvider; 126import android.content.ContentResolver; 127import android.content.Context; 128import android.content.DialogInterface; 129import android.content.IContentProvider; 130import android.content.IIntentReceiver; 131import android.content.IIntentSender; 132import android.content.Intent; 133import android.content.IntentFilter; 134import android.content.IntentSender; 135import android.content.pm.ActivityInfo; 136import android.content.pm.ApplicationInfo; 137import android.content.pm.ConfigurationInfo; 138import android.content.pm.IPackageDataObserver; 139import android.content.pm.IPackageManager; 140import android.content.pm.InstrumentationInfo; 141import android.content.pm.PackageInfo; 142import android.content.pm.PackageManager; 143import android.content.pm.ParceledListSlice; 144import android.content.pm.UserInfo; 145import android.content.pm.PackageManager.NameNotFoundException; 146import android.content.pm.PathPermission; 147import android.content.pm.ProviderInfo; 148import android.content.pm.ResolveInfo; 149import android.content.pm.ServiceInfo; 150import android.content.res.CompatibilityInfo; 151import android.content.res.Configuration; 152import android.net.Proxy; 153import android.net.ProxyInfo; 154import android.net.Uri; 155import android.os.Binder; 156import android.os.Build; 157import android.os.Bundle; 158import android.os.Debug; 159import android.os.DropBoxManager; 160import android.os.Environment; 161import android.os.FactoryTest; 162import android.os.FileObserver; 163import android.os.FileUtils; 164import android.os.Handler; 165import android.os.IBinder; 166import android.os.IPermissionController; 167import android.os.IRemoteCallback; 168import android.os.IUserManager; 169import android.os.Looper; 170import android.os.Message; 171import android.os.Parcel; 172import android.os.ParcelFileDescriptor; 173import android.os.Process; 174import android.os.RemoteCallbackList; 175import android.os.RemoteException; 176import android.os.SELinux; 177import android.os.ServiceManager; 178import android.os.StrictMode; 179import android.os.SystemClock; 180import android.os.SystemProperties; 181import android.os.UpdateLock; 182import android.os.UserHandle; 183import android.provider.Settings; 184import android.text.format.DateUtils; 185import android.text.format.Time; 186import android.util.AtomicFile; 187import android.util.EventLog; 188import android.util.Log; 189import android.util.Pair; 190import android.util.PrintWriterPrinter; 191import android.util.Slog; 192import android.util.SparseArray; 193import android.util.TimeUtils; 194import android.util.Xml; 195import android.view.Gravity; 196import android.view.LayoutInflater; 197import android.view.View; 198import android.view.WindowManager; 199 200import java.io.BufferedInputStream; 201import java.io.BufferedOutputStream; 202import java.io.DataInputStream; 203import java.io.DataOutputStream; 204import java.io.File; 205import java.io.FileDescriptor; 206import java.io.FileInputStream; 207import java.io.FileNotFoundException; 208import java.io.FileOutputStream; 209import java.io.IOException; 210import java.io.InputStreamReader; 211import java.io.PrintWriter; 212import java.io.StringWriter; 213import java.lang.ref.WeakReference; 214import java.util.ArrayList; 215import java.util.Arrays; 216import java.util.Collections; 217import java.util.Comparator; 218import java.util.HashMap; 219import java.util.HashSet; 220import java.util.Iterator; 221import java.util.List; 222import java.util.Locale; 223import java.util.Map; 224import java.util.Set; 225import java.util.concurrent.atomic.AtomicBoolean; 226import java.util.concurrent.atomic.AtomicLong; 227 228public final class ActivityManagerService extends ActivityManagerNative 229 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 230 231 private static final String USER_DATA_DIR = "/data/user/"; 232 // File that stores last updated system version and called preboot receivers 233 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat"; 234 235 static final String TAG = "ActivityManager"; 236 static final String TAG_MU = "ActivityManagerServiceMU"; 237 static final boolean DEBUG = false; 238 static final boolean localLOGV = DEBUG; 239 static final boolean DEBUG_BACKUP = localLOGV || false; 240 static final boolean DEBUG_BROADCAST = localLOGV || false; 241 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 242 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 243 static final boolean DEBUG_CLEANUP = localLOGV || false; 244 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 245 static final boolean DEBUG_FOCUS = false; 246 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 247 static final boolean DEBUG_MU = localLOGV || false; 248 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 249 static final boolean DEBUG_LRU = localLOGV || false; 250 static final boolean DEBUG_PAUSE = localLOGV || false; 251 static final boolean DEBUG_POWER = localLOGV || false; 252 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 253 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 254 static final boolean DEBUG_PROCESSES = localLOGV || false; 255 static final boolean DEBUG_PROVIDER = localLOGV || false; 256 static final boolean DEBUG_RESULTS = localLOGV || false; 257 static final boolean DEBUG_SERVICE = localLOGV || false; 258 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 259 static final boolean DEBUG_STACK = localLOGV || false; 260 static final boolean DEBUG_SWITCH = localLOGV || false; 261 static final boolean DEBUG_TASKS = localLOGV || false; 262 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 263 static final boolean DEBUG_TRANSITION = localLOGV || false; 264 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 265 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 266 static final boolean DEBUG_VISBILITY = localLOGV || false; 267 static final boolean DEBUG_PSS = localLOGV || false; 268 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 269 static final boolean DEBUG_RECENTS = localLOGV || false; 270 static final boolean VALIDATE_TOKENS = false; 271 static final boolean SHOW_ACTIVITY_START_TIME = true; 272 273 // Control over CPU and battery monitoring. 274 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 275 static final boolean MONITOR_CPU_USAGE = true; 276 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 277 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 278 static final boolean MONITOR_THREAD_CPU_USAGE = false; 279 280 // The flags that are set for all calls we make to the package manager. 281 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 282 283 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 284 285 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 286 287 // Maximum number recent bitmaps to keep in memory. 288 static final int MAX_RECENT_BITMAPS = 5; 289 290 // Amount of time after a call to stopAppSwitches() during which we will 291 // prevent further untrusted switches from happening. 292 static final long APP_SWITCH_DELAY_TIME = 5*1000; 293 294 // How long we wait for a launched process to attach to the activity manager 295 // before we decide it's never going to come up for real. 296 static final int PROC_START_TIMEOUT = 10*1000; 297 298 // How long we wait for a launched process to attach to the activity manager 299 // before we decide it's never going to come up for real, when the process was 300 // started with a wrapper for instrumentation (such as Valgrind) because it 301 // could take much longer than usual. 302 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 303 304 // How long to wait after going idle before forcing apps to GC. 305 static final int GC_TIMEOUT = 5*1000; 306 307 // The minimum amount of time between successive GC requests for a process. 308 static final int GC_MIN_INTERVAL = 60*1000; 309 310 // The minimum amount of time between successive PSS requests for a process. 311 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 312 313 // The minimum amount of time between successive PSS requests for a process 314 // when the request is due to the memory state being lowered. 315 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 316 317 // The rate at which we check for apps using excessive power -- 15 mins. 318 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 319 320 // The minimum sample duration we will allow before deciding we have 321 // enough data on wake locks to start killing things. 322 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 323 324 // The minimum sample duration we will allow before deciding we have 325 // enough data on CPU usage to start killing things. 326 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 327 328 // How long we allow a receiver to run before giving up on it. 329 static final int BROADCAST_FG_TIMEOUT = 10*1000; 330 static final int BROADCAST_BG_TIMEOUT = 60*1000; 331 332 // How long we wait until we timeout on key dispatching. 333 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 334 335 // How long we wait until we timeout on key dispatching during instrumentation. 336 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 337 338 // Amount of time we wait for observers to handle a user switch before 339 // giving up on them and unfreezing the screen. 340 static final int USER_SWITCH_TIMEOUT = 2*1000; 341 342 // Maximum number of users we allow to be running at a time. 343 static final int MAX_RUNNING_USERS = 3; 344 345 // How long to wait in getAssistContextExtras for the activity and foreground services 346 // to respond with the result. 347 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 348 349 // Maximum number of persisted Uri grants a package is allowed 350 static final int MAX_PERSISTED_URI_GRANTS = 128; 351 352 static final int MY_PID = Process.myPid(); 353 354 static final String[] EMPTY_STRING_ARRAY = new String[0]; 355 356 // How many bytes to write into the dropbox log before truncating 357 static final int DROPBOX_MAX_SIZE = 256 * 1024; 358 359 // Access modes for handleIncomingUser. 360 static final int ALLOW_NON_FULL = 0; 361 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 362 static final int ALLOW_FULL_ONLY = 2; 363 364 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000; 365 366 /** All system services */ 367 SystemServiceManager mSystemServiceManager; 368 369 /** Run all ActivityStacks through this */ 370 ActivityStackSupervisor mStackSupervisor; 371 372 public IntentFirewall mIntentFirewall; 373 374 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 375 // default actuion automatically. Important for devices without direct input 376 // devices. 377 private boolean mShowDialogs = true; 378 379 BroadcastQueue mFgBroadcastQueue; 380 BroadcastQueue mBgBroadcastQueue; 381 // Convenient for easy iteration over the queues. Foreground is first 382 // so that dispatch of foreground broadcasts gets precedence. 383 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 384 385 BroadcastQueue broadcastQueueForIntent(Intent intent) { 386 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 387 if (DEBUG_BACKGROUND_BROADCAST) { 388 Slog.i(TAG, "Broadcast intent " + intent + " on " 389 + (isFg ? "foreground" : "background") 390 + " queue"); 391 } 392 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 393 } 394 395 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 396 for (BroadcastQueue queue : mBroadcastQueues) { 397 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 398 if (r != null) { 399 return r; 400 } 401 } 402 return null; 403 } 404 405 /** 406 * Activity we have told the window manager to have key focus. 407 */ 408 ActivityRecord mFocusedActivity = null; 409 410 /** 411 * List of intents that were used to start the most recent tasks. 412 */ 413 ArrayList<TaskRecord> mRecentTasks; 414 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 415 416 /** 417 * For addAppTask: cached of the last activity component that was added. 418 */ 419 ComponentName mLastAddedTaskComponent; 420 421 /** 422 * For addAppTask: cached of the last activity uid that was added. 423 */ 424 int mLastAddedTaskUid; 425 426 /** 427 * For addAppTask: cached of the last ActivityInfo that was added. 428 */ 429 ActivityInfo mLastAddedTaskActivity; 430 431 public class PendingAssistExtras extends Binder implements Runnable { 432 public final ActivityRecord activity; 433 public boolean haveResult = false; 434 public Bundle result = null; 435 public PendingAssistExtras(ActivityRecord _activity) { 436 activity = _activity; 437 } 438 @Override 439 public void run() { 440 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 441 synchronized (this) { 442 haveResult = true; 443 notifyAll(); 444 } 445 } 446 } 447 448 final ArrayList<PendingAssistExtras> mPendingAssistExtras 449 = new ArrayList<PendingAssistExtras>(); 450 451 /** 452 * Process management. 453 */ 454 final ProcessList mProcessList = new ProcessList(); 455 456 /** 457 * All of the applications we currently have running organized by name. 458 * The keys are strings of the application package name (as 459 * returned by the package manager), and the keys are ApplicationRecord 460 * objects. 461 */ 462 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 463 464 /** 465 * Tracking long-term execution of processes to look for abuse and other 466 * bad app behavior. 467 */ 468 final ProcessStatsService mProcessStats; 469 470 /** 471 * The currently running isolated processes. 472 */ 473 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 474 475 /** 476 * Counter for assigning isolated process uids, to avoid frequently reusing the 477 * same ones. 478 */ 479 int mNextIsolatedProcessUid = 0; 480 481 /** 482 * The currently running heavy-weight process, if any. 483 */ 484 ProcessRecord mHeavyWeightProcess = null; 485 486 /** 487 * The last time that various processes have crashed. 488 */ 489 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 490 491 /** 492 * Information about a process that is currently marked as bad. 493 */ 494 static final class BadProcessInfo { 495 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 496 this.time = time; 497 this.shortMsg = shortMsg; 498 this.longMsg = longMsg; 499 this.stack = stack; 500 } 501 502 final long time; 503 final String shortMsg; 504 final String longMsg; 505 final String stack; 506 } 507 508 /** 509 * Set of applications that we consider to be bad, and will reject 510 * incoming broadcasts from (which the user has no control over). 511 * Processes are added to this set when they have crashed twice within 512 * a minimum amount of time; they are removed from it when they are 513 * later restarted (hopefully due to some user action). The value is the 514 * time it was added to the list. 515 */ 516 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 517 518 /** 519 * All of the processes we currently have running organized by pid. 520 * The keys are the pid running the application. 521 * 522 * <p>NOTE: This object is protected by its own lock, NOT the global 523 * activity manager lock! 524 */ 525 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 526 527 /** 528 * All of the processes that have been forced to be foreground. The key 529 * is the pid of the caller who requested it (we hold a death 530 * link on it). 531 */ 532 abstract class ForegroundToken implements IBinder.DeathRecipient { 533 int pid; 534 IBinder token; 535 } 536 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 537 538 /** 539 * List of records for processes that someone had tried to start before the 540 * system was ready. We don't start them at that point, but ensure they 541 * are started by the time booting is complete. 542 */ 543 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 544 545 /** 546 * List of persistent applications that are in the process 547 * of being started. 548 */ 549 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes that are being forcibly torn down. 553 */ 554 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * List of running applications, sorted by recent usage. 558 * The first entry in the list is the least recently used. 559 */ 560 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 561 562 /** 563 * Where in mLruProcesses that the processes hosting activities start. 564 */ 565 int mLruProcessActivityStart = 0; 566 567 /** 568 * Where in mLruProcesses that the processes hosting services start. 569 * This is after (lower index) than mLruProcessesActivityStart. 570 */ 571 int mLruProcessServiceStart = 0; 572 573 /** 574 * List of processes that should gc as soon as things are idle. 575 */ 576 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 577 578 /** 579 * Processes we want to collect PSS data from. 580 */ 581 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 582 583 /** 584 * Last time we requested PSS data of all processes. 585 */ 586 long mLastFullPssTime = SystemClock.uptimeMillis(); 587 588 /** 589 * If set, the next time we collect PSS data we should do a full collection 590 * with data from native processes and the kernel. 591 */ 592 boolean mFullPssPending = false; 593 594 /** 595 * This is the process holding what we currently consider to be 596 * the "home" activity. 597 */ 598 ProcessRecord mHomeProcess; 599 600 /** 601 * This is the process holding the activity the user last visited that 602 * is in a different process from the one they are currently in. 603 */ 604 ProcessRecord mPreviousProcess; 605 606 /** 607 * The time at which the previous process was last visible. 608 */ 609 long mPreviousProcessVisibleTime; 610 611 /** 612 * Which uses have been started, so are allowed to run code. 613 */ 614 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 615 616 /** 617 * LRU list of history of current users. Most recently current is at the end. 618 */ 619 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 620 621 /** 622 * Constant array of the users that are currently started. 623 */ 624 int[] mStartedUserArray = new int[] { 0 }; 625 626 /** 627 * Registered observers of the user switching mechanics. 628 */ 629 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 630 = new RemoteCallbackList<IUserSwitchObserver>(); 631 632 /** 633 * Currently active user switch. 634 */ 635 Object mCurUserSwitchCallback; 636 637 /** 638 * Packages that the user has asked to have run in screen size 639 * compatibility mode instead of filling the screen. 640 */ 641 final CompatModePackages mCompatModePackages; 642 643 /** 644 * Set of IntentSenderRecord objects that are currently active. 645 */ 646 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 647 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 648 649 /** 650 * Fingerprints (hashCode()) of stack traces that we've 651 * already logged DropBox entries for. Guarded by itself. If 652 * something (rogue user app) forces this over 653 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 654 */ 655 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 656 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 657 658 /** 659 * Strict Mode background batched logging state. 660 * 661 * The string buffer is guarded by itself, and its lock is also 662 * used to determine if another batched write is already 663 * in-flight. 664 */ 665 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 666 667 /** 668 * Keeps track of all IIntentReceivers that have been registered for 669 * broadcasts. Hash keys are the receiver IBinder, hash value is 670 * a ReceiverList. 671 */ 672 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 673 new HashMap<IBinder, ReceiverList>(); 674 675 /** 676 * Resolver for broadcast intents to registered receivers. 677 * Holds BroadcastFilter (subclass of IntentFilter). 678 */ 679 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 680 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 681 @Override 682 protected boolean allowFilterResult( 683 BroadcastFilter filter, List<BroadcastFilter> dest) { 684 IBinder target = filter.receiverList.receiver.asBinder(); 685 for (int i=dest.size()-1; i>=0; i--) { 686 if (dest.get(i).receiverList.receiver.asBinder() == target) { 687 return false; 688 } 689 } 690 return true; 691 } 692 693 @Override 694 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 695 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 696 || userId == filter.owningUserId) { 697 return super.newResult(filter, match, userId); 698 } 699 return null; 700 } 701 702 @Override 703 protected BroadcastFilter[] newArray(int size) { 704 return new BroadcastFilter[size]; 705 } 706 707 @Override 708 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 709 return packageName.equals(filter.packageName); 710 } 711 }; 712 713 /** 714 * State of all active sticky broadcasts per user. Keys are the action of the 715 * sticky Intent, values are an ArrayList of all broadcasted intents with 716 * that action (which should usually be one). The SparseArray is keyed 717 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 718 * for stickies that are sent to all users. 719 */ 720 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 721 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 722 723 final ActiveServices mServices; 724 725 /** 726 * Backup/restore process management 727 */ 728 String mBackupAppName = null; 729 BackupRecord mBackupTarget = null; 730 731 final ProviderMap mProviderMap; 732 733 /** 734 * List of content providers who have clients waiting for them. The 735 * application is currently being launched and the provider will be 736 * removed from this list once it is published. 737 */ 738 final ArrayList<ContentProviderRecord> mLaunchingProviders 739 = new ArrayList<ContentProviderRecord>(); 740 741 /** 742 * File storing persisted {@link #mGrantedUriPermissions}. 743 */ 744 private final AtomicFile mGrantFile; 745 746 /** XML constants used in {@link #mGrantFile} */ 747 private static final String TAG_URI_GRANTS = "uri-grants"; 748 private static final String TAG_URI_GRANT = "uri-grant"; 749 private static final String ATTR_USER_HANDLE = "userHandle"; 750 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 751 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 752 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 753 private static final String ATTR_TARGET_PKG = "targetPkg"; 754 private static final String ATTR_URI = "uri"; 755 private static final String ATTR_MODE_FLAGS = "modeFlags"; 756 private static final String ATTR_CREATED_TIME = "createdTime"; 757 private static final String ATTR_PREFIX = "prefix"; 758 759 /** 760 * Global set of specific {@link Uri} permissions that have been granted. 761 * This optimized lookup structure maps from {@link UriPermission#targetUid} 762 * to {@link UriPermission#uri} to {@link UriPermission}. 763 */ 764 @GuardedBy("this") 765 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 766 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 767 768 public static class GrantUri { 769 public final int sourceUserId; 770 public final Uri uri; 771 public boolean prefix; 772 773 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 774 this.sourceUserId = sourceUserId; 775 this.uri = uri; 776 this.prefix = prefix; 777 } 778 779 @Override 780 public int hashCode() { 781 return toString().hashCode(); 782 } 783 784 @Override 785 public boolean equals(Object o) { 786 if (o instanceof GrantUri) { 787 GrantUri other = (GrantUri) o; 788 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 789 && prefix == other.prefix; 790 } 791 return false; 792 } 793 794 @Override 795 public String toString() { 796 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 797 if (prefix) result += " [prefix]"; 798 return result; 799 } 800 801 public String toSafeString() { 802 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 803 if (prefix) result += " [prefix]"; 804 return result; 805 } 806 807 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 808 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 809 ContentProvider.getUriWithoutUserId(uri), false); 810 } 811 } 812 813 CoreSettingsObserver mCoreSettingsObserver; 814 815 /** 816 * Thread-local storage used to carry caller permissions over through 817 * indirect content-provider access. 818 */ 819 private class Identity { 820 public int pid; 821 public int uid; 822 823 Identity(int _pid, int _uid) { 824 pid = _pid; 825 uid = _uid; 826 } 827 } 828 829 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 830 831 /** 832 * All information we have collected about the runtime performance of 833 * any user id that can impact battery performance. 834 */ 835 final BatteryStatsService mBatteryStatsService; 836 837 /** 838 * Information about component usage 839 */ 840 UsageStatsManagerInternal mUsageStatsService; 841 842 /** 843 * Information about and control over application operations 844 */ 845 final AppOpsService mAppOpsService; 846 847 /** 848 * Save recent tasks information across reboots. 849 */ 850 final TaskPersister mTaskPersister; 851 852 /** 853 * Current configuration information. HistoryRecord objects are given 854 * a reference to this object to indicate which configuration they are 855 * currently running in, so this object must be kept immutable. 856 */ 857 Configuration mConfiguration = new Configuration(); 858 859 /** 860 * Current sequencing integer of the configuration, for skipping old 861 * configurations. 862 */ 863 int mConfigurationSeq = 0; 864 865 /** 866 * Hardware-reported OpenGLES version. 867 */ 868 final int GL_ES_VERSION; 869 870 /** 871 * List of initialization arguments to pass to all processes when binding applications to them. 872 * For example, references to the commonly used services. 873 */ 874 HashMap<String, IBinder> mAppBindArgs; 875 876 /** 877 * Temporary to avoid allocations. Protected by main lock. 878 */ 879 final StringBuilder mStringBuilder = new StringBuilder(256); 880 881 /** 882 * Used to control how we initialize the service. 883 */ 884 ComponentName mTopComponent; 885 String mTopAction = Intent.ACTION_MAIN; 886 String mTopData; 887 boolean mProcessesReady = false; 888 boolean mSystemReady = false; 889 boolean mBooting = false; 890 boolean mWaitingUpdate = false; 891 boolean mDidUpdate = false; 892 boolean mOnBattery = false; 893 boolean mLaunchWarningShown = false; 894 895 Context mContext; 896 897 int mFactoryTest; 898 899 boolean mCheckedForSetup; 900 901 /** 902 * The time at which we will allow normal application switches again, 903 * after a call to {@link #stopAppSwitches()}. 904 */ 905 long mAppSwitchesAllowedTime; 906 907 /** 908 * This is set to true after the first switch after mAppSwitchesAllowedTime 909 * is set; any switches after that will clear the time. 910 */ 911 boolean mDidAppSwitch; 912 913 /** 914 * Last time (in realtime) at which we checked for power usage. 915 */ 916 long mLastPowerCheckRealtime; 917 918 /** 919 * Last time (in uptime) at which we checked for power usage. 920 */ 921 long mLastPowerCheckUptime; 922 923 /** 924 * Set while we are wanting to sleep, to prevent any 925 * activities from being started/resumed. 926 */ 927 private boolean mSleeping = false; 928 929 /** 930 * Set while we are running a voice interaction. This overrides 931 * sleeping while it is active. 932 */ 933 private boolean mRunningVoice = false; 934 935 /** 936 * State of external calls telling us if the device is asleep. 937 */ 938 private boolean mWentToSleep = false; 939 940 /** 941 * State of external call telling us if the lock screen is shown. 942 */ 943 private boolean mLockScreenShown = false; 944 945 /** 946 * Set if we are shutting down the system, similar to sleeping. 947 */ 948 boolean mShuttingDown = false; 949 950 /** 951 * Current sequence id for oom_adj computation traversal. 952 */ 953 int mAdjSeq = 0; 954 955 /** 956 * Current sequence id for process LRU updating. 957 */ 958 int mLruSeq = 0; 959 960 /** 961 * Keep track of the non-cached/empty process we last found, to help 962 * determine how to distribute cached/empty processes next time. 963 */ 964 int mNumNonCachedProcs = 0; 965 966 /** 967 * Keep track of the number of cached hidden procs, to balance oom adj 968 * distribution between those and empty procs. 969 */ 970 int mNumCachedHiddenProcs = 0; 971 972 /** 973 * Keep track of the number of service processes we last found, to 974 * determine on the next iteration which should be B services. 975 */ 976 int mNumServiceProcs = 0; 977 int mNewNumAServiceProcs = 0; 978 int mNewNumServiceProcs = 0; 979 980 /** 981 * Allow the current computed overall memory level of the system to go down? 982 * This is set to false when we are killing processes for reasons other than 983 * memory management, so that the now smaller process list will not be taken as 984 * an indication that memory is tighter. 985 */ 986 boolean mAllowLowerMemLevel = false; 987 988 /** 989 * The last computed memory level, for holding when we are in a state that 990 * processes are going away for other reasons. 991 */ 992 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 993 994 /** 995 * The last total number of process we have, to determine if changes actually look 996 * like a shrinking number of process due to lower RAM. 997 */ 998 int mLastNumProcesses; 999 1000 /** 1001 * The uptime of the last time we performed idle maintenance. 1002 */ 1003 long mLastIdleTime = SystemClock.uptimeMillis(); 1004 1005 /** 1006 * Total time spent with RAM that has been added in the past since the last idle time. 1007 */ 1008 long mLowRamTimeSinceLastIdle = 0; 1009 1010 /** 1011 * If RAM is currently low, when that horrible situation started. 1012 */ 1013 long mLowRamStartTime = 0; 1014 1015 /** 1016 * For reporting to battery stats the current top application. 1017 */ 1018 private String mCurResumedPackage = null; 1019 private int mCurResumedUid = -1; 1020 1021 /** 1022 * For reporting to battery stats the apps currently running foreground 1023 * service. The ProcessMap is package/uid tuples; each of these contain 1024 * an array of the currently foreground processes. 1025 */ 1026 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1027 = new ProcessMap<ArrayList<ProcessRecord>>(); 1028 1029 /** 1030 * This is set if we had to do a delayed dexopt of an app before launching 1031 * it, to increase the ANR timeouts in that case. 1032 */ 1033 boolean mDidDexOpt; 1034 1035 /** 1036 * Set if the systemServer made a call to enterSafeMode. 1037 */ 1038 boolean mSafeMode; 1039 1040 String mDebugApp = null; 1041 boolean mWaitForDebugger = false; 1042 boolean mDebugTransient = false; 1043 String mOrigDebugApp = null; 1044 boolean mOrigWaitForDebugger = false; 1045 boolean mAlwaysFinishActivities = false; 1046 IActivityController mController = null; 1047 String mProfileApp = null; 1048 ProcessRecord mProfileProc = null; 1049 String mProfileFile; 1050 ParcelFileDescriptor mProfileFd; 1051 int mSamplingInterval = 0; 1052 boolean mAutoStopProfiler = false; 1053 int mProfileType = 0; 1054 String mOpenGlTraceApp = null; 1055 1056 static class ProcessChangeItem { 1057 static final int CHANGE_ACTIVITIES = 1<<0; 1058 static final int CHANGE_PROCESS_STATE = 1<<1; 1059 int changes; 1060 int uid; 1061 int pid; 1062 int processState; 1063 boolean foregroundActivities; 1064 } 1065 1066 final RemoteCallbackList<IProcessObserver> mProcessObservers 1067 = new RemoteCallbackList<IProcessObserver>(); 1068 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1069 1070 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1071 = new ArrayList<ProcessChangeItem>(); 1072 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1073 = new ArrayList<ProcessChangeItem>(); 1074 1075 /** 1076 * Runtime CPU use collection thread. This object's lock is used to 1077 * protect all related state. 1078 */ 1079 final Thread mProcessCpuThread; 1080 1081 /** 1082 * Used to collect process stats when showing not responding dialog. 1083 * Protected by mProcessCpuThread. 1084 */ 1085 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1086 MONITOR_THREAD_CPU_USAGE); 1087 final AtomicLong mLastCpuTime = new AtomicLong(0); 1088 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1089 1090 long mLastWriteTime = 0; 1091 1092 /** 1093 * Used to retain an update lock when the foreground activity is in 1094 * immersive mode. 1095 */ 1096 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1097 1098 /** 1099 * Set to true after the system has finished booting. 1100 */ 1101 boolean mBooted = false; 1102 1103 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1104 int mProcessLimitOverride = -1; 1105 1106 WindowManagerService mWindowManager; 1107 1108 final ActivityThread mSystemThread; 1109 1110 int mCurrentUserId = 0; 1111 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1112 1113 /** 1114 * Mapping from each known user ID to the profile group ID it is associated with. 1115 */ 1116 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1117 1118 private UserManagerService mUserManager; 1119 1120 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1121 final ProcessRecord mApp; 1122 final int mPid; 1123 final IApplicationThread mAppThread; 1124 1125 AppDeathRecipient(ProcessRecord app, int pid, 1126 IApplicationThread thread) { 1127 if (localLOGV) Slog.v( 1128 TAG, "New death recipient " + this 1129 + " for thread " + thread.asBinder()); 1130 mApp = app; 1131 mPid = pid; 1132 mAppThread = thread; 1133 } 1134 1135 @Override 1136 public void binderDied() { 1137 if (localLOGV) Slog.v( 1138 TAG, "Death received in " + this 1139 + " for thread " + mAppThread.asBinder()); 1140 synchronized(ActivityManagerService.this) { 1141 appDiedLocked(mApp, mPid, mAppThread); 1142 } 1143 } 1144 } 1145 1146 static final int SHOW_ERROR_MSG = 1; 1147 static final int SHOW_NOT_RESPONDING_MSG = 2; 1148 static final int SHOW_FACTORY_ERROR_MSG = 3; 1149 static final int UPDATE_CONFIGURATION_MSG = 4; 1150 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1151 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1152 static final int SERVICE_TIMEOUT_MSG = 12; 1153 static final int UPDATE_TIME_ZONE = 13; 1154 static final int SHOW_UID_ERROR_MSG = 14; 1155 static final int IM_FEELING_LUCKY_MSG = 15; 1156 static final int PROC_START_TIMEOUT_MSG = 20; 1157 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1158 static final int KILL_APPLICATION_MSG = 22; 1159 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1160 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1161 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1162 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1163 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1164 static final int CLEAR_DNS_CACHE_MSG = 28; 1165 static final int UPDATE_HTTP_PROXY_MSG = 29; 1166 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1167 static final int DISPATCH_PROCESSES_CHANGED = 31; 1168 static final int DISPATCH_PROCESS_DIED = 32; 1169 static final int REPORT_MEM_USAGE_MSG = 33; 1170 static final int REPORT_USER_SWITCH_MSG = 34; 1171 static final int CONTINUE_USER_SWITCH_MSG = 35; 1172 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1173 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1174 static final int PERSIST_URI_GRANTS_MSG = 38; 1175 static final int REQUEST_ALL_PSS_MSG = 39; 1176 static final int START_PROFILES_MSG = 40; 1177 static final int UPDATE_TIME = 41; 1178 static final int SYSTEM_USER_START_MSG = 42; 1179 static final int SYSTEM_USER_CURRENT_MSG = 43; 1180 static final int ENTER_ANIMATION_COMPLETE_MSG = 44; 1181 static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45; 1182 static final int START_USER_SWITCH_MSG = 46; 1183 1184 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1185 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1186 static final int FIRST_COMPAT_MODE_MSG = 300; 1187 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1188 1189 AlertDialog mUidAlert; 1190 CompatModeDialog mCompatModeDialog; 1191 long mLastMemUsageReportTime = 0; 1192 1193 private LockToAppRequestDialog mLockToAppRequest; 1194 1195 /** 1196 * Flag whether the current user is a "monkey", i.e. whether 1197 * the UI is driven by a UI automation tool. 1198 */ 1199 private boolean mUserIsMonkey; 1200 1201 /** Flag whether the device has a recents UI */ 1202 final boolean mHasRecents; 1203 1204 final int mThumbnailWidth; 1205 final int mThumbnailHeight; 1206 1207 final ServiceThread mHandlerThread; 1208 final MainHandler mHandler; 1209 1210 final class MainHandler extends Handler { 1211 public MainHandler(Looper looper) { 1212 super(looper, null, true); 1213 } 1214 1215 @Override 1216 public void handleMessage(Message msg) { 1217 switch (msg.what) { 1218 case SHOW_ERROR_MSG: { 1219 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1220 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1221 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1222 synchronized (ActivityManagerService.this) { 1223 ProcessRecord proc = (ProcessRecord)data.get("app"); 1224 AppErrorResult res = (AppErrorResult) data.get("result"); 1225 if (proc != null && proc.crashDialog != null) { 1226 Slog.e(TAG, "App already has crash dialog: " + proc); 1227 if (res != null) { 1228 res.set(0); 1229 } 1230 return; 1231 } 1232 boolean isBackground = (UserHandle.getAppId(proc.uid) 1233 >= Process.FIRST_APPLICATION_UID 1234 && proc.pid != MY_PID); 1235 for (int userId : mCurrentProfileIds) { 1236 isBackground &= (proc.userId != userId); 1237 } 1238 if (isBackground && !showBackground) { 1239 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1240 if (res != null) { 1241 res.set(0); 1242 } 1243 return; 1244 } 1245 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1246 Dialog d = new AppErrorDialog(mContext, 1247 ActivityManagerService.this, res, proc); 1248 d.show(); 1249 proc.crashDialog = d; 1250 } else { 1251 // The device is asleep, so just pretend that the user 1252 // saw a crash dialog and hit "force quit". 1253 if (res != null) { 1254 res.set(0); 1255 } 1256 } 1257 } 1258 1259 ensureBootCompleted(); 1260 } break; 1261 case SHOW_NOT_RESPONDING_MSG: { 1262 synchronized (ActivityManagerService.this) { 1263 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1264 ProcessRecord proc = (ProcessRecord)data.get("app"); 1265 if (proc != null && proc.anrDialog != null) { 1266 Slog.e(TAG, "App already has anr dialog: " + proc); 1267 return; 1268 } 1269 1270 Intent intent = new Intent("android.intent.action.ANR"); 1271 if (!mProcessesReady) { 1272 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1273 | Intent.FLAG_RECEIVER_FOREGROUND); 1274 } 1275 broadcastIntentLocked(null, null, intent, 1276 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1277 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1278 1279 if (mShowDialogs) { 1280 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1281 mContext, proc, (ActivityRecord)data.get("activity"), 1282 msg.arg1 != 0); 1283 d.show(); 1284 proc.anrDialog = d; 1285 } else { 1286 // Just kill the app if there is no dialog to be shown. 1287 killAppAtUsersRequest(proc, null); 1288 } 1289 } 1290 1291 ensureBootCompleted(); 1292 } break; 1293 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1294 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1295 synchronized (ActivityManagerService.this) { 1296 ProcessRecord proc = (ProcessRecord) data.get("app"); 1297 if (proc == null) { 1298 Slog.e(TAG, "App not found when showing strict mode dialog."); 1299 break; 1300 } 1301 if (proc.crashDialog != null) { 1302 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1303 return; 1304 } 1305 AppErrorResult res = (AppErrorResult) data.get("result"); 1306 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1307 Dialog d = new StrictModeViolationDialog(mContext, 1308 ActivityManagerService.this, res, proc); 1309 d.show(); 1310 proc.crashDialog = d; 1311 } else { 1312 // The device is asleep, so just pretend that the user 1313 // saw a crash dialog and hit "force quit". 1314 res.set(0); 1315 } 1316 } 1317 ensureBootCompleted(); 1318 } break; 1319 case SHOW_FACTORY_ERROR_MSG: { 1320 Dialog d = new FactoryErrorDialog( 1321 mContext, msg.getData().getCharSequence("msg")); 1322 d.show(); 1323 ensureBootCompleted(); 1324 } break; 1325 case UPDATE_CONFIGURATION_MSG: { 1326 final ContentResolver resolver = mContext.getContentResolver(); 1327 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1328 } break; 1329 case GC_BACKGROUND_PROCESSES_MSG: { 1330 synchronized (ActivityManagerService.this) { 1331 performAppGcsIfAppropriateLocked(); 1332 } 1333 } break; 1334 case WAIT_FOR_DEBUGGER_MSG: { 1335 synchronized (ActivityManagerService.this) { 1336 ProcessRecord app = (ProcessRecord)msg.obj; 1337 if (msg.arg1 != 0) { 1338 if (!app.waitedForDebugger) { 1339 Dialog d = new AppWaitingForDebuggerDialog( 1340 ActivityManagerService.this, 1341 mContext, app); 1342 app.waitDialog = d; 1343 app.waitedForDebugger = true; 1344 d.show(); 1345 } 1346 } else { 1347 if (app.waitDialog != null) { 1348 app.waitDialog.dismiss(); 1349 app.waitDialog = null; 1350 } 1351 } 1352 } 1353 } break; 1354 case SERVICE_TIMEOUT_MSG: { 1355 if (mDidDexOpt) { 1356 mDidDexOpt = false; 1357 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1358 nmsg.obj = msg.obj; 1359 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1360 return; 1361 } 1362 mServices.serviceTimeout((ProcessRecord)msg.obj); 1363 } break; 1364 case UPDATE_TIME_ZONE: { 1365 synchronized (ActivityManagerService.this) { 1366 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1367 ProcessRecord r = mLruProcesses.get(i); 1368 if (r.thread != null) { 1369 try { 1370 r.thread.updateTimeZone(); 1371 } catch (RemoteException ex) { 1372 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1373 } 1374 } 1375 } 1376 } 1377 } break; 1378 case CLEAR_DNS_CACHE_MSG: { 1379 synchronized (ActivityManagerService.this) { 1380 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1381 ProcessRecord r = mLruProcesses.get(i); 1382 if (r.thread != null) { 1383 try { 1384 r.thread.clearDnsCache(); 1385 } catch (RemoteException ex) { 1386 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1387 } 1388 } 1389 } 1390 } 1391 } break; 1392 case UPDATE_HTTP_PROXY_MSG: { 1393 ProxyInfo proxy = (ProxyInfo)msg.obj; 1394 String host = ""; 1395 String port = ""; 1396 String exclList = ""; 1397 Uri pacFileUrl = Uri.EMPTY; 1398 if (proxy != null) { 1399 host = proxy.getHost(); 1400 port = Integer.toString(proxy.getPort()); 1401 exclList = proxy.getExclusionListAsString(); 1402 pacFileUrl = proxy.getPacFileUrl(); 1403 } 1404 synchronized (ActivityManagerService.this) { 1405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1406 ProcessRecord r = mLruProcesses.get(i); 1407 if (r.thread != null) { 1408 try { 1409 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1410 } catch (RemoteException ex) { 1411 Slog.w(TAG, "Failed to update http proxy for: " + 1412 r.info.processName); 1413 } 1414 } 1415 } 1416 } 1417 } break; 1418 case SHOW_UID_ERROR_MSG: { 1419 String title = "System UIDs Inconsistent"; 1420 String text = "UIDs on the system are inconsistent, you need to wipe your" 1421 + " data partition or your device will be unstable."; 1422 Log.e(TAG, title + ": " + text); 1423 if (mShowDialogs) { 1424 // XXX This is a temporary dialog, no need to localize. 1425 AlertDialog d = new BaseErrorDialog(mContext); 1426 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1427 d.setCancelable(false); 1428 d.setTitle(title); 1429 d.setMessage(text); 1430 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1431 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1432 mUidAlert = d; 1433 d.show(); 1434 } 1435 } break; 1436 case IM_FEELING_LUCKY_MSG: { 1437 if (mUidAlert != null) { 1438 mUidAlert.dismiss(); 1439 mUidAlert = null; 1440 } 1441 } break; 1442 case PROC_START_TIMEOUT_MSG: { 1443 if (mDidDexOpt) { 1444 mDidDexOpt = false; 1445 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1446 nmsg.obj = msg.obj; 1447 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1448 return; 1449 } 1450 ProcessRecord app = (ProcessRecord)msg.obj; 1451 synchronized (ActivityManagerService.this) { 1452 processStartTimedOutLocked(app); 1453 } 1454 } break; 1455 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1456 synchronized (ActivityManagerService.this) { 1457 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1458 } 1459 } break; 1460 case KILL_APPLICATION_MSG: { 1461 synchronized (ActivityManagerService.this) { 1462 int appid = msg.arg1; 1463 boolean restart = (msg.arg2 == 1); 1464 Bundle bundle = (Bundle)msg.obj; 1465 String pkg = bundle.getString("pkg"); 1466 String reason = bundle.getString("reason"); 1467 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1468 false, UserHandle.USER_ALL, reason); 1469 } 1470 } break; 1471 case FINALIZE_PENDING_INTENT_MSG: { 1472 ((PendingIntentRecord)msg.obj).completeFinalize(); 1473 } break; 1474 case POST_HEAVY_NOTIFICATION_MSG: { 1475 INotificationManager inm = NotificationManager.getService(); 1476 if (inm == null) { 1477 return; 1478 } 1479 1480 ActivityRecord root = (ActivityRecord)msg.obj; 1481 ProcessRecord process = root.app; 1482 if (process == null) { 1483 return; 1484 } 1485 1486 try { 1487 Context context = mContext.createPackageContext(process.info.packageName, 0); 1488 String text = mContext.getString(R.string.heavy_weight_notification, 1489 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1490 Notification notification = new Notification(); 1491 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1492 notification.when = 0; 1493 notification.flags = Notification.FLAG_ONGOING_EVENT; 1494 notification.tickerText = text; 1495 notification.defaults = 0; // please be quiet 1496 notification.sound = null; 1497 notification.vibrate = null; 1498 notification.color = mContext.getResources().getColor( 1499 com.android.internal.R.color.system_notification_accent_color); 1500 notification.setLatestEventInfo(context, text, 1501 mContext.getText(R.string.heavy_weight_notification_detail), 1502 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1503 PendingIntent.FLAG_CANCEL_CURRENT, null, 1504 new UserHandle(root.userId))); 1505 1506 try { 1507 int[] outId = new int[1]; 1508 inm.enqueueNotificationWithTag("android", "android", null, 1509 R.string.heavy_weight_notification, 1510 notification, outId, root.userId); 1511 } catch (RuntimeException e) { 1512 Slog.w(ActivityManagerService.TAG, 1513 "Error showing notification for heavy-weight app", e); 1514 } catch (RemoteException e) { 1515 } 1516 } catch (NameNotFoundException e) { 1517 Slog.w(TAG, "Unable to create context for heavy notification", e); 1518 } 1519 } break; 1520 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1521 INotificationManager inm = NotificationManager.getService(); 1522 if (inm == null) { 1523 return; 1524 } 1525 try { 1526 inm.cancelNotificationWithTag("android", null, 1527 R.string.heavy_weight_notification, msg.arg1); 1528 } catch (RuntimeException e) { 1529 Slog.w(ActivityManagerService.TAG, 1530 "Error canceling notification for service", e); 1531 } catch (RemoteException e) { 1532 } 1533 } break; 1534 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1535 synchronized (ActivityManagerService.this) { 1536 checkExcessivePowerUsageLocked(true); 1537 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1538 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1539 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1540 } 1541 } break; 1542 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1543 synchronized (ActivityManagerService.this) { 1544 ActivityRecord ar = (ActivityRecord)msg.obj; 1545 if (mCompatModeDialog != null) { 1546 if (mCompatModeDialog.mAppInfo.packageName.equals( 1547 ar.info.applicationInfo.packageName)) { 1548 return; 1549 } 1550 mCompatModeDialog.dismiss(); 1551 mCompatModeDialog = null; 1552 } 1553 if (ar != null && false) { 1554 if (mCompatModePackages.getPackageAskCompatModeLocked( 1555 ar.packageName)) { 1556 int mode = mCompatModePackages.computeCompatModeLocked( 1557 ar.info.applicationInfo); 1558 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1559 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1560 mCompatModeDialog = new CompatModeDialog( 1561 ActivityManagerService.this, mContext, 1562 ar.info.applicationInfo); 1563 mCompatModeDialog.show(); 1564 } 1565 } 1566 } 1567 } 1568 break; 1569 } 1570 case DISPATCH_PROCESSES_CHANGED: { 1571 dispatchProcessesChanged(); 1572 break; 1573 } 1574 case DISPATCH_PROCESS_DIED: { 1575 final int pid = msg.arg1; 1576 final int uid = msg.arg2; 1577 dispatchProcessDied(pid, uid); 1578 break; 1579 } 1580 case REPORT_MEM_USAGE_MSG: { 1581 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1582 Thread thread = new Thread() { 1583 @Override public void run() { 1584 final SparseArray<ProcessMemInfo> infoMap 1585 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1586 for (int i=0, N=memInfos.size(); i<N; i++) { 1587 ProcessMemInfo mi = memInfos.get(i); 1588 infoMap.put(mi.pid, mi); 1589 } 1590 updateCpuStatsNow(); 1591 synchronized (mProcessCpuThread) { 1592 final int N = mProcessCpuTracker.countStats(); 1593 for (int i=0; i<N; i++) { 1594 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1595 if (st.vsize > 0) { 1596 long pss = Debug.getPss(st.pid, null); 1597 if (pss > 0) { 1598 if (infoMap.indexOfKey(st.pid) < 0) { 1599 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1600 ProcessList.NATIVE_ADJ, -1, "native", null); 1601 mi.pss = pss; 1602 memInfos.add(mi); 1603 } 1604 } 1605 } 1606 } 1607 } 1608 1609 long totalPss = 0; 1610 for (int i=0, N=memInfos.size(); i<N; i++) { 1611 ProcessMemInfo mi = memInfos.get(i); 1612 if (mi.pss == 0) { 1613 mi.pss = Debug.getPss(mi.pid, null); 1614 } 1615 totalPss += mi.pss; 1616 } 1617 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1618 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1619 if (lhs.oomAdj != rhs.oomAdj) { 1620 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1621 } 1622 if (lhs.pss != rhs.pss) { 1623 return lhs.pss < rhs.pss ? 1 : -1; 1624 } 1625 return 0; 1626 } 1627 }); 1628 1629 StringBuilder tag = new StringBuilder(128); 1630 StringBuilder stack = new StringBuilder(128); 1631 tag.append("Low on memory -- "); 1632 appendMemBucket(tag, totalPss, "total", false); 1633 appendMemBucket(stack, totalPss, "total", true); 1634 1635 StringBuilder logBuilder = new StringBuilder(1024); 1636 logBuilder.append("Low on memory:\n"); 1637 1638 boolean firstLine = true; 1639 int lastOomAdj = Integer.MIN_VALUE; 1640 for (int i=0, N=memInfos.size(); i<N; i++) { 1641 ProcessMemInfo mi = memInfos.get(i); 1642 1643 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1644 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1645 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1646 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1647 if (lastOomAdj != mi.oomAdj) { 1648 lastOomAdj = mi.oomAdj; 1649 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1650 tag.append(" / "); 1651 } 1652 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1653 if (firstLine) { 1654 stack.append(":"); 1655 firstLine = false; 1656 } 1657 stack.append("\n\t at "); 1658 } else { 1659 stack.append("$"); 1660 } 1661 } else { 1662 tag.append(" "); 1663 stack.append("$"); 1664 } 1665 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1666 appendMemBucket(tag, mi.pss, mi.name, false); 1667 } 1668 appendMemBucket(stack, mi.pss, mi.name, true); 1669 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1670 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1671 stack.append("("); 1672 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1673 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1674 stack.append(DUMP_MEM_OOM_LABEL[k]); 1675 stack.append(":"); 1676 stack.append(DUMP_MEM_OOM_ADJ[k]); 1677 } 1678 } 1679 stack.append(")"); 1680 } 1681 } 1682 1683 logBuilder.append(" "); 1684 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1685 logBuilder.append(' '); 1686 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1687 logBuilder.append(' '); 1688 ProcessList.appendRamKb(logBuilder, mi.pss); 1689 logBuilder.append(" kB: "); 1690 logBuilder.append(mi.name); 1691 logBuilder.append(" ("); 1692 logBuilder.append(mi.pid); 1693 logBuilder.append(") "); 1694 logBuilder.append(mi.adjType); 1695 logBuilder.append('\n'); 1696 if (mi.adjReason != null) { 1697 logBuilder.append(" "); 1698 logBuilder.append(mi.adjReason); 1699 logBuilder.append('\n'); 1700 } 1701 } 1702 1703 logBuilder.append(" "); 1704 ProcessList.appendRamKb(logBuilder, totalPss); 1705 logBuilder.append(" kB: TOTAL\n"); 1706 1707 long[] infos = new long[Debug.MEMINFO_COUNT]; 1708 Debug.getMemInfo(infos); 1709 logBuilder.append(" MemInfo: "); 1710 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1711 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1712 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1713 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1714 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1715 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1716 logBuilder.append(" ZRAM: "); 1717 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1718 logBuilder.append(" kB RAM, "); 1719 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1720 logBuilder.append(" kB swap total, "); 1721 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1722 logBuilder.append(" kB swap free\n"); 1723 } 1724 Slog.i(TAG, logBuilder.toString()); 1725 1726 StringBuilder dropBuilder = new StringBuilder(1024); 1727 /* 1728 StringWriter oomSw = new StringWriter(); 1729 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1730 StringWriter catSw = new StringWriter(); 1731 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1732 String[] emptyArgs = new String[] { }; 1733 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1734 oomPw.flush(); 1735 String oomString = oomSw.toString(); 1736 */ 1737 dropBuilder.append(stack); 1738 dropBuilder.append('\n'); 1739 dropBuilder.append('\n'); 1740 dropBuilder.append(logBuilder); 1741 dropBuilder.append('\n'); 1742 /* 1743 dropBuilder.append(oomString); 1744 dropBuilder.append('\n'); 1745 */ 1746 StringWriter catSw = new StringWriter(); 1747 synchronized (ActivityManagerService.this) { 1748 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1749 String[] emptyArgs = new String[] { }; 1750 catPw.println(); 1751 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1752 catPw.println(); 1753 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1754 false, false, null); 1755 catPw.println(); 1756 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1757 catPw.flush(); 1758 } 1759 dropBuilder.append(catSw.toString()); 1760 addErrorToDropBox("lowmem", null, "system_server", null, 1761 null, tag.toString(), dropBuilder.toString(), null, null); 1762 //Slog.i(TAG, "Sent to dropbox:"); 1763 //Slog.i(TAG, dropBuilder.toString()); 1764 synchronized (ActivityManagerService.this) { 1765 long now = SystemClock.uptimeMillis(); 1766 if (mLastMemUsageReportTime < now) { 1767 mLastMemUsageReportTime = now; 1768 } 1769 } 1770 } 1771 }; 1772 thread.start(); 1773 break; 1774 } 1775 case START_USER_SWITCH_MSG: { 1776 showUserSwitchDialog(msg.arg1, (String) msg.obj); 1777 break; 1778 } 1779 case REPORT_USER_SWITCH_MSG: { 1780 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1781 break; 1782 } 1783 case CONTINUE_USER_SWITCH_MSG: { 1784 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1785 break; 1786 } 1787 case USER_SWITCH_TIMEOUT_MSG: { 1788 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1789 break; 1790 } 1791 case IMMERSIVE_MODE_LOCK_MSG: { 1792 final boolean nextState = (msg.arg1 != 0); 1793 if (mUpdateLock.isHeld() != nextState) { 1794 if (DEBUG_IMMERSIVE) { 1795 final ActivityRecord r = (ActivityRecord) msg.obj; 1796 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1797 } 1798 if (nextState) { 1799 mUpdateLock.acquire(); 1800 } else { 1801 mUpdateLock.release(); 1802 } 1803 } 1804 break; 1805 } 1806 case PERSIST_URI_GRANTS_MSG: { 1807 writeGrantedUriPermissions(); 1808 break; 1809 } 1810 case REQUEST_ALL_PSS_MSG: { 1811 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1812 break; 1813 } 1814 case START_PROFILES_MSG: { 1815 synchronized (ActivityManagerService.this) { 1816 startProfilesLocked(); 1817 } 1818 break; 1819 } 1820 case UPDATE_TIME: { 1821 synchronized (ActivityManagerService.this) { 1822 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1823 ProcessRecord r = mLruProcesses.get(i); 1824 if (r.thread != null) { 1825 try { 1826 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1827 } catch (RemoteException ex) { 1828 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1829 } 1830 } 1831 } 1832 } 1833 break; 1834 } 1835 case SYSTEM_USER_START_MSG: { 1836 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1837 Integer.toString(msg.arg1), msg.arg1); 1838 mSystemServiceManager.startUser(msg.arg1); 1839 break; 1840 } 1841 case SYSTEM_USER_CURRENT_MSG: { 1842 mBatteryStatsService.noteEvent( 1843 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1844 Integer.toString(msg.arg2), msg.arg2); 1845 mBatteryStatsService.noteEvent( 1846 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1847 Integer.toString(msg.arg1), msg.arg1); 1848 mSystemServiceManager.switchUser(msg.arg1); 1849 mLockToAppRequest.clearPrompt(); 1850 break; 1851 } 1852 case ENTER_ANIMATION_COMPLETE_MSG: { 1853 synchronized (ActivityManagerService.this) { 1854 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj); 1855 if (r != null && r.app != null && r.app.thread != null) { 1856 try { 1857 r.app.thread.scheduleEnterAnimationComplete(r.appToken); 1858 } catch (RemoteException e) { 1859 } 1860 } 1861 } 1862 break; 1863 } 1864 case ENABLE_SCREEN_AFTER_BOOT_MSG: { 1865 enableScreenAfterBoot(); 1866 break; 1867 } 1868 } 1869 } 1870 }; 1871 1872 static final int COLLECT_PSS_BG_MSG = 1; 1873 1874 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1875 @Override 1876 public void handleMessage(Message msg) { 1877 switch (msg.what) { 1878 case COLLECT_PSS_BG_MSG: { 1879 long start = SystemClock.uptimeMillis(); 1880 MemInfoReader memInfo = null; 1881 synchronized (ActivityManagerService.this) { 1882 if (mFullPssPending) { 1883 mFullPssPending = false; 1884 memInfo = new MemInfoReader(); 1885 } 1886 } 1887 if (memInfo != null) { 1888 updateCpuStatsNow(); 1889 long nativeTotalPss = 0; 1890 synchronized (mProcessCpuThread) { 1891 final int N = mProcessCpuTracker.countStats(); 1892 for (int j=0; j<N; j++) { 1893 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1894 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1895 // This is definitely an application process; skip it. 1896 continue; 1897 } 1898 synchronized (mPidsSelfLocked) { 1899 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1900 // This is one of our own processes; skip it. 1901 continue; 1902 } 1903 } 1904 nativeTotalPss += Debug.getPss(st.pid, null); 1905 } 1906 } 1907 memInfo.readMemInfo(); 1908 synchronized (this) { 1909 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1910 + (SystemClock.uptimeMillis()-start) + "ms"); 1911 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1912 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1913 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1914 +memInfo.getSlabSizeKb(), 1915 nativeTotalPss); 1916 } 1917 } 1918 1919 int i=0, num=0; 1920 long[] tmp = new long[1]; 1921 do { 1922 ProcessRecord proc; 1923 int procState; 1924 int pid; 1925 synchronized (ActivityManagerService.this) { 1926 if (i >= mPendingPssProcesses.size()) { 1927 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1928 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1929 mPendingPssProcesses.clear(); 1930 return; 1931 } 1932 proc = mPendingPssProcesses.get(i); 1933 procState = proc.pssProcState; 1934 if (proc.thread != null && procState == proc.setProcState) { 1935 pid = proc.pid; 1936 } else { 1937 proc = null; 1938 pid = 0; 1939 } 1940 i++; 1941 } 1942 if (proc != null) { 1943 long pss = Debug.getPss(pid, tmp); 1944 synchronized (ActivityManagerService.this) { 1945 if (proc.thread != null && proc.setProcState == procState 1946 && proc.pid == pid) { 1947 num++; 1948 proc.lastPssTime = SystemClock.uptimeMillis(); 1949 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1950 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1951 + ": " + pss + " lastPss=" + proc.lastPss 1952 + " state=" + ProcessList.makeProcStateString(procState)); 1953 if (proc.initialIdlePss == 0) { 1954 proc.initialIdlePss = pss; 1955 } 1956 proc.lastPss = pss; 1957 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1958 proc.lastCachedPss = pss; 1959 } 1960 } 1961 } 1962 } 1963 } while (true); 1964 } 1965 } 1966 } 1967 }; 1968 1969 /** 1970 * Monitor for package changes and update our internal state. 1971 */ 1972 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1973 @Override 1974 public void onPackageRemoved(String packageName, int uid) { 1975 // Remove all tasks with activities in the specified package from the list of recent tasks 1976 synchronized (ActivityManagerService.this) { 1977 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1978 TaskRecord tr = mRecentTasks.get(i); 1979 ComponentName cn = tr.intent.getComponent(); 1980 if (cn != null && cn.getPackageName().equals(packageName)) { 1981 // If the package name matches, remove the task and kill the process 1982 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1983 } 1984 } 1985 } 1986 } 1987 1988 @Override 1989 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1990 onPackageModified(packageName); 1991 return true; 1992 } 1993 1994 @Override 1995 public void onPackageModified(String packageName) { 1996 final PackageManager pm = mContext.getPackageManager(); 1997 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1998 new ArrayList<Pair<Intent, Integer>>(); 1999 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 2000 // Copy the list of recent tasks so that we don't hold onto the lock on 2001 // ActivityManagerService for long periods while checking if components exist. 2002 synchronized (ActivityManagerService.this) { 2003 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 2004 TaskRecord tr = mRecentTasks.get(i); 2005 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 2006 } 2007 } 2008 // Check the recent tasks and filter out all tasks with components that no longer exist. 2009 Intent tmpI = new Intent(); 2010 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 2011 Pair<Intent, Integer> p = recentTaskIntents.get(i); 2012 ComponentName cn = p.first.getComponent(); 2013 if (cn != null && cn.getPackageName().equals(packageName)) { 2014 try { 2015 // Add the task to the list to remove if the component no longer exists 2016 tmpI.setComponent(cn); 2017 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 2018 tasksToRemove.add(p.second); 2019 } 2020 } catch (Exception e) {} 2021 } 2022 } 2023 // Prune all the tasks with removed components from the list of recent tasks 2024 synchronized (ActivityManagerService.this) { 2025 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 2026 // Remove the task but don't kill the process (since other components in that 2027 // package may still be running and in the background) 2028 removeTaskByIdLocked(tasksToRemove.get(i), 0); 2029 } 2030 } 2031 } 2032 2033 @Override 2034 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 2035 // Force stop the specified packages 2036 if (packages != null) { 2037 for (String pkg : packages) { 2038 synchronized (ActivityManagerService.this) { 2039 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 2040 "finished booting")) { 2041 return true; 2042 } 2043 } 2044 } 2045 } 2046 return false; 2047 } 2048 }; 2049 2050 public void setSystemProcess() { 2051 try { 2052 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 2053 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 2054 ServiceManager.addService("meminfo", new MemBinder(this)); 2055 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 2056 ServiceManager.addService("dbinfo", new DbBinder(this)); 2057 if (MONITOR_CPU_USAGE) { 2058 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2059 } 2060 ServiceManager.addService("permission", new PermissionController(this)); 2061 2062 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2063 "android", STOCK_PM_FLAGS); 2064 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader()); 2065 2066 synchronized (this) { 2067 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0); 2068 app.persistent = true; 2069 app.pid = MY_PID; 2070 app.maxAdj = ProcessList.SYSTEM_ADJ; 2071 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2072 mProcessNames.put(app.processName, app.uid, app); 2073 synchronized (mPidsSelfLocked) { 2074 mPidsSelfLocked.put(app.pid, app); 2075 } 2076 updateLruProcessLocked(app, false, null); 2077 updateOomAdjLocked(); 2078 } 2079 } catch (PackageManager.NameNotFoundException e) { 2080 throw new RuntimeException( 2081 "Unable to find android system package", e); 2082 } 2083 } 2084 2085 public void setWindowManager(WindowManagerService wm) { 2086 mWindowManager = wm; 2087 mStackSupervisor.setWindowManager(wm); 2088 } 2089 2090 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2091 mUsageStatsService = usageStatsManager; 2092 } 2093 2094 public void startObservingNativeCrashes() { 2095 final NativeCrashListener ncl = new NativeCrashListener(this); 2096 ncl.start(); 2097 } 2098 2099 public IAppOpsService getAppOpsService() { 2100 return mAppOpsService; 2101 } 2102 2103 static class MemBinder extends Binder { 2104 ActivityManagerService mActivityManagerService; 2105 MemBinder(ActivityManagerService activityManagerService) { 2106 mActivityManagerService = activityManagerService; 2107 } 2108 2109 @Override 2110 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2111 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2112 != PackageManager.PERMISSION_GRANTED) { 2113 pw.println("Permission Denial: can't dump meminfo from from pid=" 2114 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2115 + " without permission " + android.Manifest.permission.DUMP); 2116 return; 2117 } 2118 2119 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2120 } 2121 } 2122 2123 static class GraphicsBinder extends Binder { 2124 ActivityManagerService mActivityManagerService; 2125 GraphicsBinder(ActivityManagerService activityManagerService) { 2126 mActivityManagerService = activityManagerService; 2127 } 2128 2129 @Override 2130 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2131 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2132 != PackageManager.PERMISSION_GRANTED) { 2133 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2134 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2135 + " without permission " + android.Manifest.permission.DUMP); 2136 return; 2137 } 2138 2139 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2140 } 2141 } 2142 2143 static class DbBinder extends Binder { 2144 ActivityManagerService mActivityManagerService; 2145 DbBinder(ActivityManagerService activityManagerService) { 2146 mActivityManagerService = activityManagerService; 2147 } 2148 2149 @Override 2150 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2151 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2152 != PackageManager.PERMISSION_GRANTED) { 2153 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2154 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2155 + " without permission " + android.Manifest.permission.DUMP); 2156 return; 2157 } 2158 2159 mActivityManagerService.dumpDbInfo(fd, pw, args); 2160 } 2161 } 2162 2163 static class CpuBinder extends Binder { 2164 ActivityManagerService mActivityManagerService; 2165 CpuBinder(ActivityManagerService activityManagerService) { 2166 mActivityManagerService = activityManagerService; 2167 } 2168 2169 @Override 2170 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2171 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2172 != PackageManager.PERMISSION_GRANTED) { 2173 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2174 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2175 + " without permission " + android.Manifest.permission.DUMP); 2176 return; 2177 } 2178 2179 synchronized (mActivityManagerService.mProcessCpuThread) { 2180 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2181 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2182 SystemClock.uptimeMillis())); 2183 } 2184 } 2185 } 2186 2187 public static final class Lifecycle extends SystemService { 2188 private final ActivityManagerService mService; 2189 2190 public Lifecycle(Context context) { 2191 super(context); 2192 mService = new ActivityManagerService(context); 2193 } 2194 2195 @Override 2196 public void onStart() { 2197 mService.start(); 2198 } 2199 2200 public ActivityManagerService getService() { 2201 return mService; 2202 } 2203 } 2204 2205 // Note: This method is invoked on the main thread but may need to attach various 2206 // handlers to other threads. So take care to be explicit about the looper. 2207 public ActivityManagerService(Context systemContext) { 2208 mContext = systemContext; 2209 mFactoryTest = FactoryTest.getMode(); 2210 mSystemThread = ActivityThread.currentActivityThread(); 2211 2212 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2213 2214 mHandlerThread = new ServiceThread(TAG, 2215 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2216 mHandlerThread.start(); 2217 mHandler = new MainHandler(mHandlerThread.getLooper()); 2218 2219 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2220 "foreground", BROADCAST_FG_TIMEOUT, false); 2221 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2222 "background", BROADCAST_BG_TIMEOUT, true); 2223 mBroadcastQueues[0] = mFgBroadcastQueue; 2224 mBroadcastQueues[1] = mBgBroadcastQueue; 2225 2226 mServices = new ActiveServices(this); 2227 mProviderMap = new ProviderMap(this); 2228 2229 // TODO: Move creation of battery stats service outside of activity manager service. 2230 File dataDir = Environment.getDataDirectory(); 2231 File systemDir = new File(dataDir, "system"); 2232 systemDir.mkdirs(); 2233 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler); 2234 mBatteryStatsService.getActiveStatistics().readLocked(); 2235 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2236 mOnBattery = DEBUG_POWER ? true 2237 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2238 mBatteryStatsService.getActiveStatistics().setCallback(this); 2239 2240 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2241 2242 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2243 2244 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2245 2246 // User 0 is the first and only user that runs at boot. 2247 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2248 mUserLru.add(Integer.valueOf(0)); 2249 updateStartedUserArrayLocked(); 2250 2251 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2252 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2253 2254 mConfiguration.setToDefaults(); 2255 mConfiguration.setLocale(Locale.getDefault()); 2256 2257 mConfigurationSeq = mConfiguration.seq = 1; 2258 mProcessCpuTracker.init(); 2259 2260 final Resources res = mContext.getResources(); 2261 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents); 2262 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 2263 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 2264 2265 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2266 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2267 mStackSupervisor = new ActivityStackSupervisor(this); 2268 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2269 2270 mProcessCpuThread = new Thread("CpuTracker") { 2271 @Override 2272 public void run() { 2273 while (true) { 2274 try { 2275 try { 2276 synchronized(this) { 2277 final long now = SystemClock.uptimeMillis(); 2278 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2279 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2280 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2281 // + ", write delay=" + nextWriteDelay); 2282 if (nextWriteDelay < nextCpuDelay) { 2283 nextCpuDelay = nextWriteDelay; 2284 } 2285 if (nextCpuDelay > 0) { 2286 mProcessCpuMutexFree.set(true); 2287 this.wait(nextCpuDelay); 2288 } 2289 } 2290 } catch (InterruptedException e) { 2291 } 2292 updateCpuStatsNow(); 2293 } catch (Exception e) { 2294 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2295 } 2296 } 2297 } 2298 }; 2299 2300 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2301 2302 Watchdog.getInstance().addMonitor(this); 2303 Watchdog.getInstance().addThread(mHandler); 2304 } 2305 2306 public void setSystemServiceManager(SystemServiceManager mgr) { 2307 mSystemServiceManager = mgr; 2308 } 2309 2310 private void start() { 2311 Process.removeAllProcessGroups(); 2312 mProcessCpuThread.start(); 2313 2314 mBatteryStatsService.publish(mContext); 2315 mAppOpsService.publish(mContext); 2316 Slog.d("AppOps", "AppOpsService published"); 2317 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2318 } 2319 2320 public void initPowerManagement() { 2321 mStackSupervisor.initPowerManagement(); 2322 mBatteryStatsService.initPowerManagement(); 2323 } 2324 2325 @Override 2326 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2327 throws RemoteException { 2328 if (code == SYSPROPS_TRANSACTION) { 2329 // We need to tell all apps about the system property change. 2330 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2331 synchronized(this) { 2332 final int NP = mProcessNames.getMap().size(); 2333 for (int ip=0; ip<NP; ip++) { 2334 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2335 final int NA = apps.size(); 2336 for (int ia=0; ia<NA; ia++) { 2337 ProcessRecord app = apps.valueAt(ia); 2338 if (app.thread != null) { 2339 procs.add(app.thread.asBinder()); 2340 } 2341 } 2342 } 2343 } 2344 2345 int N = procs.size(); 2346 for (int i=0; i<N; i++) { 2347 Parcel data2 = Parcel.obtain(); 2348 try { 2349 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2350 } catch (RemoteException e) { 2351 } 2352 data2.recycle(); 2353 } 2354 } 2355 try { 2356 return super.onTransact(code, data, reply, flags); 2357 } catch (RuntimeException e) { 2358 // The activity manager only throws security exceptions, so let's 2359 // log all others. 2360 if (!(e instanceof SecurityException)) { 2361 Slog.wtf(TAG, "Activity Manager Crash", e); 2362 } 2363 throw e; 2364 } 2365 } 2366 2367 void updateCpuStats() { 2368 final long now = SystemClock.uptimeMillis(); 2369 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2370 return; 2371 } 2372 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2373 synchronized (mProcessCpuThread) { 2374 mProcessCpuThread.notify(); 2375 } 2376 } 2377 } 2378 2379 void updateCpuStatsNow() { 2380 synchronized (mProcessCpuThread) { 2381 mProcessCpuMutexFree.set(false); 2382 final long now = SystemClock.uptimeMillis(); 2383 boolean haveNewCpuStats = false; 2384 2385 if (MONITOR_CPU_USAGE && 2386 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2387 mLastCpuTime.set(now); 2388 haveNewCpuStats = true; 2389 mProcessCpuTracker.update(); 2390 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2391 //Slog.i(TAG, "Total CPU usage: " 2392 // + mProcessCpu.getTotalCpuPercent() + "%"); 2393 2394 // Slog the cpu usage if the property is set. 2395 if ("true".equals(SystemProperties.get("events.cpu"))) { 2396 int user = mProcessCpuTracker.getLastUserTime(); 2397 int system = mProcessCpuTracker.getLastSystemTime(); 2398 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2399 int irq = mProcessCpuTracker.getLastIrqTime(); 2400 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2401 int idle = mProcessCpuTracker.getLastIdleTime(); 2402 2403 int total = user + system + iowait + irq + softIrq + idle; 2404 if (total == 0) total = 1; 2405 2406 EventLog.writeEvent(EventLogTags.CPU, 2407 ((user+system+iowait+irq+softIrq) * 100) / total, 2408 (user * 100) / total, 2409 (system * 100) / total, 2410 (iowait * 100) / total, 2411 (irq * 100) / total, 2412 (softIrq * 100) / total); 2413 } 2414 } 2415 2416 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2417 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2418 synchronized(bstats) { 2419 synchronized(mPidsSelfLocked) { 2420 if (haveNewCpuStats) { 2421 if (mOnBattery) { 2422 int perc = bstats.startAddingCpuLocked(); 2423 int totalUTime = 0; 2424 int totalSTime = 0; 2425 final int N = mProcessCpuTracker.countStats(); 2426 for (int i=0; i<N; i++) { 2427 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2428 if (!st.working) { 2429 continue; 2430 } 2431 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2432 int otherUTime = (st.rel_utime*perc)/100; 2433 int otherSTime = (st.rel_stime*perc)/100; 2434 totalUTime += otherUTime; 2435 totalSTime += otherSTime; 2436 if (pr != null) { 2437 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2438 if (ps == null || !ps.isActive()) { 2439 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2440 pr.info.uid, pr.processName); 2441 } 2442 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2443 st.rel_stime-otherSTime); 2444 ps.addSpeedStepTimes(cpuSpeedTimes); 2445 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2446 } else { 2447 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2448 if (ps == null || !ps.isActive()) { 2449 st.batteryStats = ps = bstats.getProcessStatsLocked( 2450 bstats.mapUid(st.uid), st.name); 2451 } 2452 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2453 st.rel_stime-otherSTime); 2454 ps.addSpeedStepTimes(cpuSpeedTimes); 2455 } 2456 } 2457 bstats.finishAddingCpuLocked(perc, totalUTime, 2458 totalSTime, cpuSpeedTimes); 2459 } 2460 } 2461 } 2462 2463 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2464 mLastWriteTime = now; 2465 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2466 } 2467 } 2468 } 2469 } 2470 2471 @Override 2472 public void batteryNeedsCpuUpdate() { 2473 updateCpuStatsNow(); 2474 } 2475 2476 @Override 2477 public void batteryPowerChanged(boolean onBattery) { 2478 // When plugging in, update the CPU stats first before changing 2479 // the plug state. 2480 updateCpuStatsNow(); 2481 synchronized (this) { 2482 synchronized(mPidsSelfLocked) { 2483 mOnBattery = DEBUG_POWER ? true : onBattery; 2484 } 2485 } 2486 } 2487 2488 /** 2489 * Initialize the application bind args. These are passed to each 2490 * process when the bindApplication() IPC is sent to the process. They're 2491 * lazily setup to make sure the services are running when they're asked for. 2492 */ 2493 private HashMap<String, IBinder> getCommonServicesLocked() { 2494 if (mAppBindArgs == null) { 2495 mAppBindArgs = new HashMap<String, IBinder>(); 2496 2497 // Setup the application init args 2498 mAppBindArgs.put("package", ServiceManager.getService("package")); 2499 mAppBindArgs.put("window", ServiceManager.getService("window")); 2500 mAppBindArgs.put(Context.ALARM_SERVICE, 2501 ServiceManager.getService(Context.ALARM_SERVICE)); 2502 } 2503 return mAppBindArgs; 2504 } 2505 2506 final void setFocusedActivityLocked(ActivityRecord r) { 2507 if (mFocusedActivity != r) { 2508 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2509 mFocusedActivity = r; 2510 if (r.task != null && r.task.voiceInteractor != null) { 2511 startRunningVoiceLocked(); 2512 } else { 2513 finishRunningVoiceLocked(); 2514 } 2515 mStackSupervisor.setFocusedStack(r); 2516 if (r != null) { 2517 mWindowManager.setFocusedApp(r.appToken, true); 2518 } 2519 applyUpdateLockStateLocked(r); 2520 } 2521 } 2522 2523 final void clearFocusedActivity(ActivityRecord r) { 2524 if (mFocusedActivity == r) { 2525 mFocusedActivity = null; 2526 } 2527 } 2528 2529 @Override 2530 public void setFocusedStack(int stackId) { 2531 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2532 synchronized (ActivityManagerService.this) { 2533 ActivityStack stack = mStackSupervisor.getStack(stackId); 2534 if (stack != null) { 2535 ActivityRecord r = stack.topRunningActivityLocked(null); 2536 if (r != null) { 2537 setFocusedActivityLocked(r); 2538 } 2539 } 2540 } 2541 } 2542 2543 @Override 2544 public void notifyActivityDrawn(IBinder token) { 2545 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2546 synchronized (this) { 2547 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2548 if (r != null) { 2549 r.task.stack.notifyActivityDrawnLocked(r); 2550 } 2551 } 2552 } 2553 2554 final void applyUpdateLockStateLocked(ActivityRecord r) { 2555 // Modifications to the UpdateLock state are done on our handler, outside 2556 // the activity manager's locks. The new state is determined based on the 2557 // state *now* of the relevant activity record. The object is passed to 2558 // the handler solely for logging detail, not to be consulted/modified. 2559 final boolean nextState = r != null && r.immersive; 2560 mHandler.sendMessage( 2561 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2562 } 2563 2564 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2565 Message msg = Message.obtain(); 2566 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2567 msg.obj = r.task.askedCompatMode ? null : r; 2568 mHandler.sendMessage(msg); 2569 } 2570 2571 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2572 String what, Object obj, ProcessRecord srcApp) { 2573 app.lastActivityTime = now; 2574 2575 if (app.activities.size() > 0) { 2576 // Don't want to touch dependent processes that are hosting activities. 2577 return index; 2578 } 2579 2580 int lrui = mLruProcesses.lastIndexOf(app); 2581 if (lrui < 0) { 2582 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2583 + what + " " + obj + " from " + srcApp); 2584 return index; 2585 } 2586 2587 if (lrui >= index) { 2588 // Don't want to cause this to move dependent processes *back* in the 2589 // list as if they were less frequently used. 2590 return index; 2591 } 2592 2593 if (lrui >= mLruProcessActivityStart) { 2594 // Don't want to touch dependent processes that are hosting activities. 2595 return index; 2596 } 2597 2598 mLruProcesses.remove(lrui); 2599 if (index > 0) { 2600 index--; 2601 } 2602 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2603 + " in LRU list: " + app); 2604 mLruProcesses.add(index, app); 2605 return index; 2606 } 2607 2608 final void removeLruProcessLocked(ProcessRecord app) { 2609 int lrui = mLruProcesses.lastIndexOf(app); 2610 if (lrui >= 0) { 2611 if (lrui <= mLruProcessActivityStart) { 2612 mLruProcessActivityStart--; 2613 } 2614 if (lrui <= mLruProcessServiceStart) { 2615 mLruProcessServiceStart--; 2616 } 2617 mLruProcesses.remove(lrui); 2618 } 2619 } 2620 2621 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2622 ProcessRecord client) { 2623 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2624 || app.treatLikeActivity; 2625 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2626 if (!activityChange && hasActivity) { 2627 // The process has activities, so we are only allowing activity-based adjustments 2628 // to move it. It should be kept in the front of the list with other 2629 // processes that have activities, and we don't want those to change their 2630 // order except due to activity operations. 2631 return; 2632 } 2633 2634 mLruSeq++; 2635 final long now = SystemClock.uptimeMillis(); 2636 app.lastActivityTime = now; 2637 2638 // First a quick reject: if the app is already at the position we will 2639 // put it, then there is nothing to do. 2640 if (hasActivity) { 2641 final int N = mLruProcesses.size(); 2642 if (N > 0 && mLruProcesses.get(N-1) == app) { 2643 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2644 return; 2645 } 2646 } else { 2647 if (mLruProcessServiceStart > 0 2648 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2649 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2650 return; 2651 } 2652 } 2653 2654 int lrui = mLruProcesses.lastIndexOf(app); 2655 2656 if (app.persistent && lrui >= 0) { 2657 // We don't care about the position of persistent processes, as long as 2658 // they are in the list. 2659 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2660 return; 2661 } 2662 2663 /* In progress: compute new position first, so we can avoid doing work 2664 if the process is not actually going to move. Not yet working. 2665 int addIndex; 2666 int nextIndex; 2667 boolean inActivity = false, inService = false; 2668 if (hasActivity) { 2669 // Process has activities, put it at the very tipsy-top. 2670 addIndex = mLruProcesses.size(); 2671 nextIndex = mLruProcessServiceStart; 2672 inActivity = true; 2673 } else if (hasService) { 2674 // Process has services, put it at the top of the service list. 2675 addIndex = mLruProcessActivityStart; 2676 nextIndex = mLruProcessServiceStart; 2677 inActivity = true; 2678 inService = true; 2679 } else { 2680 // Process not otherwise of interest, it goes to the top of the non-service area. 2681 addIndex = mLruProcessServiceStart; 2682 if (client != null) { 2683 int clientIndex = mLruProcesses.lastIndexOf(client); 2684 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2685 + app); 2686 if (clientIndex >= 0 && addIndex > clientIndex) { 2687 addIndex = clientIndex; 2688 } 2689 } 2690 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2691 } 2692 2693 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2694 + mLruProcessActivityStart + "): " + app); 2695 */ 2696 2697 if (lrui >= 0) { 2698 if (lrui < mLruProcessActivityStart) { 2699 mLruProcessActivityStart--; 2700 } 2701 if (lrui < mLruProcessServiceStart) { 2702 mLruProcessServiceStart--; 2703 } 2704 /* 2705 if (addIndex > lrui) { 2706 addIndex--; 2707 } 2708 if (nextIndex > lrui) { 2709 nextIndex--; 2710 } 2711 */ 2712 mLruProcesses.remove(lrui); 2713 } 2714 2715 /* 2716 mLruProcesses.add(addIndex, app); 2717 if (inActivity) { 2718 mLruProcessActivityStart++; 2719 } 2720 if (inService) { 2721 mLruProcessActivityStart++; 2722 } 2723 */ 2724 2725 int nextIndex; 2726 if (hasActivity) { 2727 final int N = mLruProcesses.size(); 2728 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2729 // Process doesn't have activities, but has clients with 2730 // activities... move it up, but one below the top (the top 2731 // should always have a real activity). 2732 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2733 mLruProcesses.add(N-1, app); 2734 // To keep it from spamming the LRU list (by making a bunch of clients), 2735 // we will push down any other entries owned by the app. 2736 final int uid = app.info.uid; 2737 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2738 ProcessRecord subProc = mLruProcesses.get(i); 2739 if (subProc.info.uid == uid) { 2740 // We want to push this one down the list. If the process after 2741 // it is for the same uid, however, don't do so, because we don't 2742 // want them internally to be re-ordered. 2743 if (mLruProcesses.get(i-1).info.uid != uid) { 2744 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2745 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2746 ProcessRecord tmp = mLruProcesses.get(i); 2747 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2748 mLruProcesses.set(i-1, tmp); 2749 i--; 2750 } 2751 } else { 2752 // A gap, we can stop here. 2753 break; 2754 } 2755 } 2756 } else { 2757 // Process has activities, put it at the very tipsy-top. 2758 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2759 mLruProcesses.add(app); 2760 } 2761 nextIndex = mLruProcessServiceStart; 2762 } else if (hasService) { 2763 // Process has services, put it at the top of the service list. 2764 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2765 mLruProcesses.add(mLruProcessActivityStart, app); 2766 nextIndex = mLruProcessServiceStart; 2767 mLruProcessActivityStart++; 2768 } else { 2769 // Process not otherwise of interest, it goes to the top of the non-service area. 2770 int index = mLruProcessServiceStart; 2771 if (client != null) { 2772 // If there is a client, don't allow the process to be moved up higher 2773 // in the list than that client. 2774 int clientIndex = mLruProcesses.lastIndexOf(client); 2775 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2776 + " when updating " + app); 2777 if (clientIndex <= lrui) { 2778 // Don't allow the client index restriction to push it down farther in the 2779 // list than it already is. 2780 clientIndex = lrui; 2781 } 2782 if (clientIndex >= 0 && index > clientIndex) { 2783 index = clientIndex; 2784 } 2785 } 2786 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2787 mLruProcesses.add(index, app); 2788 nextIndex = index-1; 2789 mLruProcessActivityStart++; 2790 mLruProcessServiceStart++; 2791 } 2792 2793 // If the app is currently using a content provider or service, 2794 // bump those processes as well. 2795 for (int j=app.connections.size()-1; j>=0; j--) { 2796 ConnectionRecord cr = app.connections.valueAt(j); 2797 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2798 && cr.binding.service.app != null 2799 && cr.binding.service.app.lruSeq != mLruSeq 2800 && !cr.binding.service.app.persistent) { 2801 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2802 "service connection", cr, app); 2803 } 2804 } 2805 for (int j=app.conProviders.size()-1; j>=0; j--) { 2806 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2807 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2808 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2809 "provider reference", cpr, app); 2810 } 2811 } 2812 } 2813 2814 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2815 if (uid == Process.SYSTEM_UID) { 2816 // The system gets to run in any process. If there are multiple 2817 // processes with the same uid, just pick the first (this 2818 // should never happen). 2819 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2820 if (procs == null) return null; 2821 final int N = procs.size(); 2822 for (int i = 0; i < N; i++) { 2823 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2824 } 2825 } 2826 ProcessRecord proc = mProcessNames.get(processName, uid); 2827 if (false && proc != null && !keepIfLarge 2828 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2829 && proc.lastCachedPss >= 4000) { 2830 // Turn this condition on to cause killing to happen regularly, for testing. 2831 if (proc.baseProcessTracker != null) { 2832 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2833 } 2834 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2835 } else if (proc != null && !keepIfLarge 2836 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2837 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2838 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2839 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2840 if (proc.baseProcessTracker != null) { 2841 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2842 } 2843 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 2844 } 2845 } 2846 return proc; 2847 } 2848 2849 void ensurePackageDexOpt(String packageName) { 2850 IPackageManager pm = AppGlobals.getPackageManager(); 2851 try { 2852 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2853 mDidDexOpt = true; 2854 } 2855 } catch (RemoteException e) { 2856 } 2857 } 2858 2859 boolean isNextTransitionForward() { 2860 int transit = mWindowManager.getPendingAppTransition(); 2861 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2862 || transit == AppTransition.TRANSIT_TASK_OPEN 2863 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2864 } 2865 2866 int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 2867 String processName, String abiOverride, int uid, Runnable crashHandler) { 2868 synchronized(this) { 2869 ApplicationInfo info = new ApplicationInfo(); 2870 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid. 2871 // For isolated processes, the former contains the parent's uid and the latter the 2872 // actual uid of the isolated process. 2873 // In the special case introduced by this method (which is, starting an isolated 2874 // process directly from the SystemServer without an actual parent app process) the 2875 // closest thing to a parent's uid is SYSTEM_UID. 2876 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger 2877 // the |isolated| logic in the ProcessRecord constructor. 2878 info.uid = Process.SYSTEM_UID; 2879 info.processName = processName; 2880 info.className = entryPoint; 2881 info.packageName = "android"; 2882 ProcessRecord proc = startProcessLocked(processName, info /* info */, 2883 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */, 2884 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */, 2885 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs, 2886 crashHandler); 2887 return proc != null ? proc.pid : 0; 2888 } 2889 } 2890 2891 final ProcessRecord startProcessLocked(String processName, 2892 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2893 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2894 boolean isolated, boolean keepIfLarge) { 2895 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType, 2896 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge, 2897 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */, 2898 null /* crashHandler */); 2899 } 2900 2901 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 2902 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, 2903 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 2904 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 2905 ProcessRecord app; 2906 if (!isolated) { 2907 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2908 } else { 2909 // If this is an isolated process, it can't re-use an existing process. 2910 app = null; 2911 } 2912 // We don't have to do anything more if: 2913 // (1) There is an existing application record; and 2914 // (2) The caller doesn't think it is dead, OR there is no thread 2915 // object attached to it so we know it couldn't have crashed; and 2916 // (3) There is a pid assigned to it, so it is either starting or 2917 // already running. 2918 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2919 + " app=" + app + " knownToBeDead=" + knownToBeDead 2920 + " thread=" + (app != null ? app.thread : null) 2921 + " pid=" + (app != null ? app.pid : -1)); 2922 if (app != null && app.pid > 0) { 2923 if (!knownToBeDead || app.thread == null) { 2924 // We already have the app running, or are waiting for it to 2925 // come up (we have a pid but not yet its thread), so keep it. 2926 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2927 // If this is a new package in the process, add the package to the list 2928 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2929 return app; 2930 } 2931 2932 // An application record is attached to a previous process, 2933 // clean it up now. 2934 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2935 Process.killProcessGroup(app.info.uid, app.pid); 2936 handleAppDiedLocked(app, true, true); 2937 } 2938 2939 String hostingNameStr = hostingName != null 2940 ? hostingName.flattenToShortString() : null; 2941 2942 if (!isolated) { 2943 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2944 // If we are in the background, then check to see if this process 2945 // is bad. If so, we will just silently fail. 2946 if (mBadProcesses.get(info.processName, info.uid) != null) { 2947 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2948 + "/" + info.processName); 2949 return null; 2950 } 2951 } else { 2952 // When the user is explicitly starting a process, then clear its 2953 // crash count so that we won't make it bad until they see at 2954 // least one crash dialog again, and make the process good again 2955 // if it had been bad. 2956 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2957 + "/" + info.processName); 2958 mProcessCrashTimes.remove(info.processName, info.uid); 2959 if (mBadProcesses.get(info.processName, info.uid) != null) { 2960 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2961 UserHandle.getUserId(info.uid), info.uid, 2962 info.processName); 2963 mBadProcesses.remove(info.processName, info.uid); 2964 if (app != null) { 2965 app.bad = false; 2966 } 2967 } 2968 } 2969 } 2970 2971 if (app == null) { 2972 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); 2973 app.crashHandler = crashHandler; 2974 if (app == null) { 2975 Slog.w(TAG, "Failed making new process record for " 2976 + processName + "/" + info.uid + " isolated=" + isolated); 2977 return null; 2978 } 2979 mProcessNames.put(processName, app.uid, app); 2980 if (isolated) { 2981 mIsolatedProcesses.put(app.uid, app); 2982 } 2983 } else { 2984 // If this is a new package in the process, add the package to the list 2985 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2986 } 2987 2988 // If the system is not ready yet, then hold off on starting this 2989 // process until it is. 2990 if (!mProcessesReady 2991 && !isAllowedWhileBooting(info) 2992 && !allowWhileBooting) { 2993 if (!mProcessesOnHold.contains(app)) { 2994 mProcessesOnHold.add(app); 2995 } 2996 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2997 return app; 2998 } 2999 3000 startProcessLocked( 3001 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); 3002 return (app.pid != 0) ? app : null; 3003 } 3004 3005 boolean isAllowedWhileBooting(ApplicationInfo ai) { 3006 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 3007 } 3008 3009 private final void startProcessLocked(ProcessRecord app, 3010 String hostingType, String hostingNameStr) { 3011 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, 3012 null /* entryPoint */, null /* entryPointArgs */); 3013 } 3014 3015 private final void startProcessLocked(ProcessRecord app, String hostingType, 3016 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { 3017 if (app.pid > 0 && app.pid != MY_PID) { 3018 synchronized (mPidsSelfLocked) { 3019 mPidsSelfLocked.remove(app.pid); 3020 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 3021 } 3022 app.setPid(0); 3023 } 3024 3025 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 3026 "startProcessLocked removing on hold: " + app); 3027 mProcessesOnHold.remove(app); 3028 3029 updateCpuStats(); 3030 3031 try { 3032 int uid = app.uid; 3033 3034 int[] gids = null; 3035 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 3036 if (!app.isolated) { 3037 int[] permGids = null; 3038 try { 3039 final PackageManager pm = mContext.getPackageManager(); 3040 permGids = pm.getPackageGids(app.info.packageName); 3041 3042 if (Environment.isExternalStorageEmulated()) { 3043 if (pm.checkPermission( 3044 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 3045 app.info.packageName) == PERMISSION_GRANTED) { 3046 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 3047 } else { 3048 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 3049 } 3050 } 3051 } catch (PackageManager.NameNotFoundException e) { 3052 Slog.w(TAG, "Unable to retrieve gids", e); 3053 } 3054 3055 /* 3056 * Add shared application and profile GIDs so applications can share some 3057 * resources like shared libraries and access user-wide resources 3058 */ 3059 if (permGids == null) { 3060 gids = new int[2]; 3061 } else { 3062 gids = new int[permGids.length + 2]; 3063 System.arraycopy(permGids, 0, gids, 2, permGids.length); 3064 } 3065 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 3066 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 3067 } 3068 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 3069 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3070 && mTopComponent != null 3071 && app.processName.equals(mTopComponent.getPackageName())) { 3072 uid = 0; 3073 } 3074 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 3075 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 3076 uid = 0; 3077 } 3078 } 3079 int debugFlags = 0; 3080 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 3081 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 3082 // Also turn on CheckJNI for debuggable apps. It's quite 3083 // awkward to turn on otherwise. 3084 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3085 } 3086 // Run the app in safe mode if its manifest requests so or the 3087 // system is booted in safe mode. 3088 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 3089 mSafeMode == true) { 3090 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 3091 } 3092 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 3093 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 3094 } 3095 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 3096 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 3097 } 3098 if ("1".equals(SystemProperties.get("debug.assert"))) { 3099 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3100 } 3101 3102 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3103 if (requiredAbi == null) { 3104 requiredAbi = Build.SUPPORTED_ABIS[0]; 3105 } 3106 3107 // Start the process. It will either succeed and return a result containing 3108 // the PID of the new process, or else throw a RuntimeException. 3109 boolean isActivityProcess = (entryPoint == null); 3110 if (entryPoint == null) entryPoint = "android.app.ActivityThread"; 3111 Process.ProcessStartResult startResult = Process.start(entryPoint, 3112 app.processName, uid, uid, gids, debugFlags, mountExternal, 3113 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs); 3114 3115 if (app.isolated) { 3116 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3117 } 3118 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3119 3120 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3121 UserHandle.getUserId(uid), startResult.pid, uid, 3122 app.processName, hostingType, 3123 hostingNameStr != null ? hostingNameStr : ""); 3124 3125 if (app.persistent) { 3126 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3127 } 3128 3129 StringBuilder buf = mStringBuilder; 3130 buf.setLength(0); 3131 buf.append("Start proc "); 3132 buf.append(app.processName); 3133 if (!isActivityProcess) { 3134 buf.append(" ["); 3135 buf.append(entryPoint); 3136 buf.append("]"); 3137 } 3138 buf.append(" for "); 3139 buf.append(hostingType); 3140 if (hostingNameStr != null) { 3141 buf.append(" "); 3142 buf.append(hostingNameStr); 3143 } 3144 buf.append(": pid="); 3145 buf.append(startResult.pid); 3146 buf.append(" uid="); 3147 buf.append(uid); 3148 buf.append(" gids={"); 3149 if (gids != null) { 3150 for (int gi=0; gi<gids.length; gi++) { 3151 if (gi != 0) buf.append(", "); 3152 buf.append(gids[gi]); 3153 3154 } 3155 } 3156 buf.append("}"); 3157 if (requiredAbi != null) { 3158 buf.append(" abi="); 3159 buf.append(requiredAbi); 3160 } 3161 Slog.i(TAG, buf.toString()); 3162 app.setPid(startResult.pid); 3163 app.usingWrapper = startResult.usingWrapper; 3164 app.removed = false; 3165 app.killedByAm = false; 3166 synchronized (mPidsSelfLocked) { 3167 this.mPidsSelfLocked.put(startResult.pid, app); 3168 if (isActivityProcess) { 3169 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3170 msg.obj = app; 3171 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3172 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3173 } 3174 } 3175 } catch (RuntimeException e) { 3176 // XXX do better error recovery. 3177 app.setPid(0); 3178 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3179 if (app.isolated) { 3180 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3181 } 3182 Slog.e(TAG, "Failure starting process " + app.processName, e); 3183 } 3184 } 3185 3186 void updateUsageStats(ActivityRecord component, boolean resumed) { 3187 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3188 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3189 if (resumed) { 3190 if (mUsageStatsService != null) { 3191 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3192 System.currentTimeMillis(), 3193 UsageEvents.Event.MOVE_TO_FOREGROUND); 3194 } 3195 synchronized (stats) { 3196 stats.noteActivityResumedLocked(component.app.uid); 3197 } 3198 } else { 3199 if (mUsageStatsService != null) { 3200 mUsageStatsService.reportEvent(component.realActivity, component.userId, 3201 System.currentTimeMillis(), 3202 UsageEvents.Event.MOVE_TO_BACKGROUND); 3203 } 3204 synchronized (stats) { 3205 stats.noteActivityPausedLocked(component.app.uid); 3206 } 3207 } 3208 } 3209 3210 Intent getHomeIntent() { 3211 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3212 intent.setComponent(mTopComponent); 3213 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3214 intent.addCategory(Intent.CATEGORY_HOME); 3215 } 3216 return intent; 3217 } 3218 3219 boolean startHomeActivityLocked(int userId) { 3220 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3221 && mTopAction == null) { 3222 // We are running in factory test mode, but unable to find 3223 // the factory test app, so just sit around displaying the 3224 // error message and don't try to start anything. 3225 return false; 3226 } 3227 Intent intent = getHomeIntent(); 3228 ActivityInfo aInfo = 3229 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3230 if (aInfo != null) { 3231 intent.setComponent(new ComponentName( 3232 aInfo.applicationInfo.packageName, aInfo.name)); 3233 // Don't do this if the home app is currently being 3234 // instrumented. 3235 aInfo = new ActivityInfo(aInfo); 3236 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3237 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3238 aInfo.applicationInfo.uid, true); 3239 if (app == null || app.instrumentationClass == null) { 3240 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3241 mStackSupervisor.startHomeActivity(intent, aInfo); 3242 } 3243 } 3244 3245 return true; 3246 } 3247 3248 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3249 ActivityInfo ai = null; 3250 ComponentName comp = intent.getComponent(); 3251 try { 3252 if (comp != null) { 3253 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3254 } else { 3255 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3256 intent, 3257 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3258 flags, userId); 3259 3260 if (info != null) { 3261 ai = info.activityInfo; 3262 } 3263 } 3264 } catch (RemoteException e) { 3265 // ignore 3266 } 3267 3268 return ai; 3269 } 3270 3271 /** 3272 * Starts the "new version setup screen" if appropriate. 3273 */ 3274 void startSetupActivityLocked() { 3275 // Only do this once per boot. 3276 if (mCheckedForSetup) { 3277 return; 3278 } 3279 3280 // We will show this screen if the current one is a different 3281 // version than the last one shown, and we are not running in 3282 // low-level factory test mode. 3283 final ContentResolver resolver = mContext.getContentResolver(); 3284 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3285 Settings.Global.getInt(resolver, 3286 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3287 mCheckedForSetup = true; 3288 3289 // See if we should be showing the platform update setup UI. 3290 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3291 List<ResolveInfo> ris = mContext.getPackageManager() 3292 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3293 3294 // We don't allow third party apps to replace this. 3295 ResolveInfo ri = null; 3296 for (int i=0; ris != null && i<ris.size(); i++) { 3297 if ((ris.get(i).activityInfo.applicationInfo.flags 3298 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3299 ri = ris.get(i); 3300 break; 3301 } 3302 } 3303 3304 if (ri != null) { 3305 String vers = ri.activityInfo.metaData != null 3306 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3307 : null; 3308 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3309 vers = ri.activityInfo.applicationInfo.metaData.getString( 3310 Intent.METADATA_SETUP_VERSION); 3311 } 3312 String lastVers = Settings.Secure.getString( 3313 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3314 if (vers != null && !vers.equals(lastVers)) { 3315 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3316 intent.setComponent(new ComponentName( 3317 ri.activityInfo.packageName, ri.activityInfo.name)); 3318 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3319 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null, 3320 null); 3321 } 3322 } 3323 } 3324 } 3325 3326 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3327 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3328 } 3329 3330 void enforceNotIsolatedCaller(String caller) { 3331 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3332 throw new SecurityException("Isolated process not allowed to call " + caller); 3333 } 3334 } 3335 3336 @Override 3337 public int getFrontActivityScreenCompatMode() { 3338 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3339 synchronized (this) { 3340 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3341 } 3342 } 3343 3344 @Override 3345 public void setFrontActivityScreenCompatMode(int mode) { 3346 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3347 "setFrontActivityScreenCompatMode"); 3348 synchronized (this) { 3349 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3350 } 3351 } 3352 3353 @Override 3354 public int getPackageScreenCompatMode(String packageName) { 3355 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3356 synchronized (this) { 3357 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3358 } 3359 } 3360 3361 @Override 3362 public void setPackageScreenCompatMode(String packageName, int mode) { 3363 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3364 "setPackageScreenCompatMode"); 3365 synchronized (this) { 3366 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3367 } 3368 } 3369 3370 @Override 3371 public boolean getPackageAskScreenCompat(String packageName) { 3372 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3373 synchronized (this) { 3374 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3375 } 3376 } 3377 3378 @Override 3379 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3380 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3381 "setPackageAskScreenCompat"); 3382 synchronized (this) { 3383 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3384 } 3385 } 3386 3387 private void dispatchProcessesChanged() { 3388 int N; 3389 synchronized (this) { 3390 N = mPendingProcessChanges.size(); 3391 if (mActiveProcessChanges.length < N) { 3392 mActiveProcessChanges = new ProcessChangeItem[N]; 3393 } 3394 mPendingProcessChanges.toArray(mActiveProcessChanges); 3395 mAvailProcessChanges.addAll(mPendingProcessChanges); 3396 mPendingProcessChanges.clear(); 3397 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3398 } 3399 3400 int i = mProcessObservers.beginBroadcast(); 3401 while (i > 0) { 3402 i--; 3403 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3404 if (observer != null) { 3405 try { 3406 for (int j=0; j<N; j++) { 3407 ProcessChangeItem item = mActiveProcessChanges[j]; 3408 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3409 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3410 + item.pid + " uid=" + item.uid + ": " 3411 + item.foregroundActivities); 3412 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3413 item.foregroundActivities); 3414 } 3415 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3416 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3417 + item.pid + " uid=" + item.uid + ": " + item.processState); 3418 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3419 } 3420 } 3421 } catch (RemoteException e) { 3422 } 3423 } 3424 } 3425 mProcessObservers.finishBroadcast(); 3426 } 3427 3428 private void dispatchProcessDied(int pid, int uid) { 3429 int i = mProcessObservers.beginBroadcast(); 3430 while (i > 0) { 3431 i--; 3432 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3433 if (observer != null) { 3434 try { 3435 observer.onProcessDied(pid, uid); 3436 } catch (RemoteException e) { 3437 } 3438 } 3439 } 3440 mProcessObservers.finishBroadcast(); 3441 } 3442 3443 @Override 3444 public final int startActivity(IApplicationThread caller, String callingPackage, 3445 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3446 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3447 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3448 resultWho, requestCode, startFlags, profilerInfo, options, 3449 UserHandle.getCallingUserId()); 3450 } 3451 3452 @Override 3453 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3454 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3455 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3456 enforceNotIsolatedCaller("startActivity"); 3457 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3458 false, ALLOW_FULL_ONLY, "startActivity", null); 3459 // TODO: Switch to user app stacks here. 3460 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3461 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3462 profilerInfo, null, null, options, userId, null, null); 3463 } 3464 3465 @Override 3466 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage, 3467 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3468 int startFlags, ProfilerInfo profilerInfo, Bundle options) { 3469 3470 // This is very dangerous -- it allows you to perform a start activity (including 3471 // permission grants) as any app that may launch one of your own activities. So 3472 // we will only allow this to be done from activities that are part of the core framework, 3473 // and then only when they are running as the system. 3474 final ActivityRecord sourceRecord; 3475 final int targetUid; 3476 final String targetPackage; 3477 synchronized (this) { 3478 if (resultTo == null) { 3479 throw new SecurityException("Must be called from an activity"); 3480 } 3481 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo); 3482 if (sourceRecord == null) { 3483 throw new SecurityException("Called with bad activity token: " + resultTo); 3484 } 3485 if (!sourceRecord.info.packageName.equals("android")) { 3486 throw new SecurityException( 3487 "Must be called from an activity that is declared in the android package"); 3488 } 3489 if (sourceRecord.app == null) { 3490 throw new SecurityException("Called without a process attached to activity"); 3491 } 3492 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) { 3493 // This is still okay, as long as this activity is running under the 3494 // uid of the original calling activity. 3495 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) { 3496 throw new SecurityException( 3497 "Calling activity in uid " + sourceRecord.app.uid 3498 + " must be system uid or original calling uid " 3499 + sourceRecord.launchedFromUid); 3500 } 3501 } 3502 targetUid = sourceRecord.launchedFromUid; 3503 targetPackage = sourceRecord.launchedFromPackage; 3504 } 3505 3506 // TODO: Switch to user app stacks here. 3507 try { 3508 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent, 3509 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null, 3510 null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null); 3511 return ret; 3512 } catch (SecurityException e) { 3513 // XXX need to figure out how to propagate to original app. 3514 // A SecurityException here is generally actually a fault of the original 3515 // calling activity (such as a fairly granting permissions), so propagate it 3516 // back to them. 3517 /* 3518 StringBuilder msg = new StringBuilder(); 3519 msg.append("While launching"); 3520 msg.append(intent.toString()); 3521 msg.append(": "); 3522 msg.append(e.getMessage()); 3523 */ 3524 throw e; 3525 } 3526 } 3527 3528 @Override 3529 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3530 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3531 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) { 3532 enforceNotIsolatedCaller("startActivityAndWait"); 3533 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3534 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3535 WaitResult res = new WaitResult(); 3536 // TODO: Switch to user app stacks here. 3537 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3538 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null, 3539 options, userId, null, null); 3540 return res; 3541 } 3542 3543 @Override 3544 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3545 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, 3546 int startFlags, Configuration config, Bundle options, int userId) { 3547 enforceNotIsolatedCaller("startActivityWithConfig"); 3548 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3549 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3550 // TODO: Switch to user app stacks here. 3551 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3552 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3553 null, null, config, options, userId, null, null); 3554 return ret; 3555 } 3556 3557 @Override 3558 public int startActivityIntentSender(IApplicationThread caller, 3559 IntentSender intent, Intent fillInIntent, String resolvedType, 3560 IBinder resultTo, String resultWho, int requestCode, 3561 int flagsMask, int flagsValues, Bundle options) { 3562 enforceNotIsolatedCaller("startActivityIntentSender"); 3563 // Refuse possible leaked file descriptors 3564 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3565 throw new IllegalArgumentException("File descriptors passed in Intent"); 3566 } 3567 3568 IIntentSender sender = intent.getTarget(); 3569 if (!(sender instanceof PendingIntentRecord)) { 3570 throw new IllegalArgumentException("Bad PendingIntent object"); 3571 } 3572 3573 PendingIntentRecord pir = (PendingIntentRecord)sender; 3574 3575 synchronized (this) { 3576 // If this is coming from the currently resumed activity, it is 3577 // effectively saying that app switches are allowed at this point. 3578 final ActivityStack stack = getFocusedStack(); 3579 if (stack.mResumedActivity != null && 3580 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3581 mAppSwitchesAllowedTime = 0; 3582 } 3583 } 3584 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3585 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3586 return ret; 3587 } 3588 3589 @Override 3590 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3591 Intent intent, String resolvedType, IVoiceInteractionSession session, 3592 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, 3593 Bundle options, int userId) { 3594 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3595 != PackageManager.PERMISSION_GRANTED) { 3596 String msg = "Permission Denial: startVoiceActivity() from pid=" 3597 + Binder.getCallingPid() 3598 + ", uid=" + Binder.getCallingUid() 3599 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3600 Slog.w(TAG, msg); 3601 throw new SecurityException(msg); 3602 } 3603 if (session == null || interactor == null) { 3604 throw new NullPointerException("null session or interactor"); 3605 } 3606 userId = handleIncomingUser(callingPid, callingUid, userId, 3607 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3608 // TODO: Switch to user app stacks here. 3609 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3610 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null, 3611 null, options, userId, null, null); 3612 } 3613 3614 @Override 3615 public boolean startNextMatchingActivity(IBinder callingActivity, 3616 Intent intent, Bundle options) { 3617 // Refuse possible leaked file descriptors 3618 if (intent != null && intent.hasFileDescriptors() == true) { 3619 throw new IllegalArgumentException("File descriptors passed in Intent"); 3620 } 3621 3622 synchronized (this) { 3623 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3624 if (r == null) { 3625 ActivityOptions.abort(options); 3626 return false; 3627 } 3628 if (r.app == null || r.app.thread == null) { 3629 // The caller is not running... d'oh! 3630 ActivityOptions.abort(options); 3631 return false; 3632 } 3633 intent = new Intent(intent); 3634 // The caller is not allowed to change the data. 3635 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3636 // And we are resetting to find the next component... 3637 intent.setComponent(null); 3638 3639 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3640 3641 ActivityInfo aInfo = null; 3642 try { 3643 List<ResolveInfo> resolves = 3644 AppGlobals.getPackageManager().queryIntentActivities( 3645 intent, r.resolvedType, 3646 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3647 UserHandle.getCallingUserId()); 3648 3649 // Look for the original activity in the list... 3650 final int N = resolves != null ? resolves.size() : 0; 3651 for (int i=0; i<N; i++) { 3652 ResolveInfo rInfo = resolves.get(i); 3653 if (rInfo.activityInfo.packageName.equals(r.packageName) 3654 && rInfo.activityInfo.name.equals(r.info.name)) { 3655 // We found the current one... the next matching is 3656 // after it. 3657 i++; 3658 if (i<N) { 3659 aInfo = resolves.get(i).activityInfo; 3660 } 3661 if (debug) { 3662 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3663 + "/" + r.info.name); 3664 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3665 + "/" + aInfo.name); 3666 } 3667 break; 3668 } 3669 } 3670 } catch (RemoteException e) { 3671 } 3672 3673 if (aInfo == null) { 3674 // Nobody who is next! 3675 ActivityOptions.abort(options); 3676 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3677 return false; 3678 } 3679 3680 intent.setComponent(new ComponentName( 3681 aInfo.applicationInfo.packageName, aInfo.name)); 3682 intent.setFlags(intent.getFlags()&~( 3683 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3684 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3685 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3686 Intent.FLAG_ACTIVITY_NEW_TASK)); 3687 3688 // Okay now we need to start the new activity, replacing the 3689 // currently running activity. This is a little tricky because 3690 // we want to start the new one as if the current one is finished, 3691 // but not finish the current one first so that there is no flicker. 3692 // And thus... 3693 final boolean wasFinishing = r.finishing; 3694 r.finishing = true; 3695 3696 // Propagate reply information over to the new activity. 3697 final ActivityRecord resultTo = r.resultTo; 3698 final String resultWho = r.resultWho; 3699 final int requestCode = r.requestCode; 3700 r.resultTo = null; 3701 if (resultTo != null) { 3702 resultTo.removeResultsLocked(r, resultWho, requestCode); 3703 } 3704 3705 final long origId = Binder.clearCallingIdentity(); 3706 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3707 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3708 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3709 options, false, null, null, null); 3710 Binder.restoreCallingIdentity(origId); 3711 3712 r.finishing = wasFinishing; 3713 if (res != ActivityManager.START_SUCCESS) { 3714 return false; 3715 } 3716 return true; 3717 } 3718 } 3719 3720 @Override 3721 public final int startActivityFromRecents(int taskId, Bundle options) { 3722 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3723 String msg = "Permission Denial: startActivityFromRecents called without " + 3724 START_TASKS_FROM_RECENTS; 3725 Slog.w(TAG, msg); 3726 throw new SecurityException(msg); 3727 } 3728 return startActivityFromRecentsInner(taskId, options); 3729 } 3730 3731 final int startActivityFromRecentsInner(int taskId, Bundle options) { 3732 final TaskRecord task; 3733 final int callingUid; 3734 final String callingPackage; 3735 final Intent intent; 3736 final int userId; 3737 synchronized (this) { 3738 task = recentTaskForIdLocked(taskId); 3739 if (task == null) { 3740 throw new IllegalArgumentException("Task " + taskId + " not found."); 3741 } 3742 callingUid = task.mCallingUid; 3743 callingPackage = task.mCallingPackage; 3744 intent = task.intent; 3745 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); 3746 userId = task.userId; 3747 } 3748 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3749 options, userId, null, task); 3750 } 3751 3752 final int startActivityInPackage(int uid, String callingPackage, 3753 Intent intent, String resolvedType, IBinder resultTo, 3754 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3755 IActivityContainer container, TaskRecord inTask) { 3756 3757 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3758 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3759 3760 // TODO: Switch to user app stacks here. 3761 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, 3762 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3763 null, null, null, options, userId, container, inTask); 3764 return ret; 3765 } 3766 3767 @Override 3768 public final int startActivities(IApplicationThread caller, String callingPackage, 3769 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3770 int userId) { 3771 enforceNotIsolatedCaller("startActivities"); 3772 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3773 false, ALLOW_FULL_ONLY, "startActivity", null); 3774 // TODO: Switch to user app stacks here. 3775 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3776 resolvedTypes, resultTo, options, userId); 3777 return ret; 3778 } 3779 3780 final int startActivitiesInPackage(int uid, String callingPackage, 3781 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3782 Bundle options, int userId) { 3783 3784 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3785 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3786 // TODO: Switch to user app stacks here. 3787 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3788 resultTo, options, userId); 3789 return ret; 3790 } 3791 3792 //explicitly remove thd old information in mRecentTasks when removing existing user. 3793 private void removeRecentTasksForUserLocked(int userId) { 3794 if(userId <= 0) { 3795 Slog.i(TAG, "Can't remove recent task on user " + userId); 3796 return; 3797 } 3798 3799 for (int i = mRecentTasks.size() - 1; i >= 0; --i) { 3800 TaskRecord tr = mRecentTasks.get(i); 3801 if (tr.userId == userId) { 3802 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr 3803 + " when finishing user" + userId); 3804 mRecentTasks.remove(i); 3805 tr.removedFromRecents(mTaskPersister); 3806 } 3807 } 3808 3809 // Remove tasks from persistent storage. 3810 mTaskPersister.wakeup(null, true); 3811 } 3812 3813 /** 3814 * Update the recent tasks lists: make sure tasks should still be here (their 3815 * applications / activities still exist), update their availability, fixup ordering 3816 * of affiliations. 3817 */ 3818 void cleanupRecentTasksLocked(int userId) { 3819 if (mRecentTasks == null) { 3820 // Happens when called from the packagemanager broadcast before boot. 3821 return; 3822 } 3823 3824 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>(); 3825 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>(); 3826 final IPackageManager pm = AppGlobals.getPackageManager(); 3827 final ActivityInfo dummyAct = new ActivityInfo(); 3828 final ApplicationInfo dummyApp = new ApplicationInfo(); 3829 3830 int N = mRecentTasks.size(); 3831 3832 int[] users = userId == UserHandle.USER_ALL 3833 ? getUsersLocked() : new int[] { userId }; 3834 for (int user : users) { 3835 for (int i = 0; i < N; i++) { 3836 TaskRecord task = mRecentTasks.get(i); 3837 if (task.userId != user) { 3838 // Only look at tasks for the user ID of interest. 3839 continue; 3840 } 3841 if (task.autoRemoveRecents && task.getTopActivity() == null) { 3842 // This situation is broken, and we should just get rid of it now. 3843 mRecentTasks.remove(i); 3844 task.removedFromRecents(mTaskPersister); 3845 i--; 3846 N--; 3847 Slog.w(TAG, "Removing auto-remove without activity: " + task); 3848 continue; 3849 } 3850 // Check whether this activity is currently available. 3851 if (task.realActivity != null) { 3852 ActivityInfo ai = availActCache.get(task.realActivity); 3853 if (ai == null) { 3854 try { 3855 ai = pm.getActivityInfo(task.realActivity, 3856 PackageManager.GET_UNINSTALLED_PACKAGES 3857 | PackageManager.GET_DISABLED_COMPONENTS, user); 3858 } catch (RemoteException e) { 3859 // Will never happen. 3860 continue; 3861 } 3862 if (ai == null) { 3863 ai = dummyAct; 3864 } 3865 availActCache.put(task.realActivity, ai); 3866 } 3867 if (ai == dummyAct) { 3868 // This could be either because the activity no longer exists, or the 3869 // app is temporarily gone. For the former we want to remove the recents 3870 // entry; for the latter we want to mark it as unavailable. 3871 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName()); 3872 if (app == null) { 3873 try { 3874 app = pm.getApplicationInfo(task.realActivity.getPackageName(), 3875 PackageManager.GET_UNINSTALLED_PACKAGES 3876 | PackageManager.GET_DISABLED_COMPONENTS, user); 3877 } catch (RemoteException e) { 3878 // Will never happen. 3879 continue; 3880 } 3881 if (app == null) { 3882 app = dummyApp; 3883 } 3884 availAppCache.put(task.realActivity.getPackageName(), app); 3885 } 3886 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3887 // Doesn't exist any more! Good-bye. 3888 mRecentTasks.remove(i); 3889 task.removedFromRecents(mTaskPersister); 3890 i--; 3891 N--; 3892 Slog.w(TAG, "Removing no longer valid recent: " + task); 3893 continue; 3894 } else { 3895 // Otherwise just not available for now. 3896 if (task.isAvailable) { 3897 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3898 + task); 3899 } 3900 task.isAvailable = false; 3901 } 3902 } else { 3903 if (!ai.enabled || !ai.applicationInfo.enabled 3904 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) { 3905 if (task.isAvailable) { 3906 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: " 3907 + task + " (enabled=" + ai.enabled + "/" 3908 + ai.applicationInfo.enabled + " flags=" 3909 + Integer.toHexString(ai.applicationInfo.flags) + ")"); 3910 } 3911 task.isAvailable = false; 3912 } else { 3913 if (!task.isAvailable) { 3914 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: " 3915 + task); 3916 } 3917 task.isAvailable = true; 3918 } 3919 } 3920 } 3921 } 3922 } 3923 3924 // Verify the affiliate chain for each task. 3925 for (int i = 0; i < N; ) { 3926 TaskRecord task = mRecentTasks.remove(i); 3927 if (mTmpRecents.contains(task)) { 3928 continue; 3929 } 3930 int affiliatedTaskId = task.mAffiliatedTaskId; 3931 while (true) { 3932 TaskRecord next = task.mNextAffiliate; 3933 if (next == null) { 3934 break; 3935 } 3936 if (next.mAffiliatedTaskId != affiliatedTaskId) { 3937 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 3938 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 3939 task.setNextAffiliate(null); 3940 if (next.mPrevAffiliate == task) { 3941 next.setPrevAffiliate(null); 3942 } 3943 break; 3944 } 3945 if (next.mPrevAffiliate != task) { 3946 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 3947 next.mPrevAffiliate + " task=" + task); 3948 next.setPrevAffiliate(null); 3949 task.setNextAffiliate(null); 3950 break; 3951 } 3952 if (!mRecentTasks.contains(next)) { 3953 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 3954 task.setNextAffiliate(null); 3955 // We know that next.mPrevAffiliate is always task, from above, so clear 3956 // its previous affiliate. 3957 next.setPrevAffiliate(null); 3958 break; 3959 } 3960 task = next; 3961 } 3962 // task is now the end of the list 3963 do { 3964 mRecentTasks.remove(task); 3965 mRecentTasks.add(i++, task); 3966 mTmpRecents.add(task); 3967 task.inRecents = true; 3968 } while ((task = task.mPrevAffiliate) != null); 3969 } 3970 mTmpRecents.clear(); 3971 // mRecentTasks is now in sorted, affiliated order. 3972 } 3973 3974 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) { 3975 int N = mRecentTasks.size(); 3976 TaskRecord top = task; 3977 int topIndex = taskIndex; 3978 while (top.mNextAffiliate != null && topIndex > 0) { 3979 top = top.mNextAffiliate; 3980 topIndex--; 3981 } 3982 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at " 3983 + topIndex + " from intial " + taskIndex); 3984 // Find the end of the chain, doing a sanity check along the way. 3985 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId; 3986 int endIndex = topIndex; 3987 TaskRecord prev = top; 3988 while (endIndex < N) { 3989 TaskRecord cur = mRecentTasks.get(endIndex); 3990 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @" 3991 + endIndex + " " + cur); 3992 if (cur == top) { 3993 // Verify start of the chain. 3994 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) { 3995 Slog.wtf(TAG, "Bad chain @" + endIndex 3996 + ": first task has next affiliate: " + prev); 3997 sane = false; 3998 break; 3999 } 4000 } else { 4001 // Verify middle of the chain's next points back to the one before. 4002 if (cur.mNextAffiliate != prev 4003 || cur.mNextAffiliateTaskId != prev.taskId) { 4004 Slog.wtf(TAG, "Bad chain @" + endIndex 4005 + ": middle task " + cur + " @" + endIndex 4006 + " has bad next affiliate " 4007 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId 4008 + ", expected " + prev); 4009 sane = false; 4010 break; 4011 } 4012 } 4013 if (cur.mPrevAffiliateTaskId == -1) { 4014 // Chain ends here. 4015 if (cur.mPrevAffiliate != null) { 4016 Slog.wtf(TAG, "Bad chain @" + endIndex 4017 + ": last task " + cur + " has previous affiliate " 4018 + cur.mPrevAffiliate); 4019 sane = false; 4020 } 4021 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex); 4022 break; 4023 } else { 4024 // Verify middle of the chain's prev points to a valid item. 4025 if (cur.mPrevAffiliate == null) { 4026 Slog.wtf(TAG, "Bad chain @" + endIndex 4027 + ": task " + cur + " has previous affiliate " 4028 + cur.mPrevAffiliate + " but should be id " 4029 + cur.mPrevAffiliate); 4030 sane = false; 4031 break; 4032 } 4033 } 4034 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) { 4035 Slog.wtf(TAG, "Bad chain @" + endIndex 4036 + ": task " + cur + " has affiliated id " 4037 + cur.mAffiliatedTaskId + " but should be " 4038 + task.mAffiliatedTaskId); 4039 sane = false; 4040 break; 4041 } 4042 prev = cur; 4043 endIndex++; 4044 if (endIndex >= N) { 4045 Slog.wtf(TAG, "Bad chain ran off index " + endIndex 4046 + ": last task " + prev); 4047 sane = false; 4048 break; 4049 } 4050 } 4051 if (sane) { 4052 if (endIndex < taskIndex) { 4053 Slog.wtf(TAG, "Bad chain @" + endIndex 4054 + ": did not extend to task " + task + " @" + taskIndex); 4055 sane = false; 4056 } 4057 } 4058 if (sane) { 4059 // All looks good, we can just move all of the affiliated tasks 4060 // to the top. 4061 for (int i=topIndex; i<=endIndex; i++) { 4062 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task 4063 + " from " + i + " to " + (i-topIndex)); 4064 TaskRecord cur = mRecentTasks.remove(i); 4065 mRecentTasks.add(i-topIndex, cur); 4066 } 4067 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex 4068 + " to " + endIndex); 4069 return true; 4070 } 4071 4072 // Whoops, couldn't do it. 4073 return false; 4074 } 4075 4076 final void addRecentTaskLocked(TaskRecord task) { 4077 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId 4078 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1; 4079 4080 int N = mRecentTasks.size(); 4081 // Quick case: check if the top-most recent task is the same. 4082 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) { 4083 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task); 4084 return; 4085 } 4086 // Another quick case: check if this is part of a set of affiliated 4087 // tasks that are at the top. 4088 if (isAffiliated && N > 0 && task.inRecents 4089 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) { 4090 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0) 4091 + " at top when adding " + task); 4092 return; 4093 } 4094 // Another quick case: never add voice sessions. 4095 if (task.voiceSession != null) { 4096 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task); 4097 return; 4098 } 4099 4100 boolean needAffiliationFix = false; 4101 4102 // Slightly less quick case: the task is already in recents, so all we need 4103 // to do is move it. 4104 if (task.inRecents) { 4105 int taskIndex = mRecentTasks.indexOf(task); 4106 if (taskIndex >= 0) { 4107 if (!isAffiliated) { 4108 // Simple case: this is not an affiliated task, so we just move it to the front. 4109 mRecentTasks.remove(taskIndex); 4110 mRecentTasks.add(0, task); 4111 notifyTaskPersisterLocked(task, false); 4112 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task 4113 + " from " + taskIndex); 4114 return; 4115 } else { 4116 // More complicated: need to keep all affiliated tasks together. 4117 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4118 // All went well. 4119 return; 4120 } 4121 4122 // Uh oh... something bad in the affiliation chain, try to rebuild 4123 // everything and then go through our general path of adding a new task. 4124 needAffiliationFix = true; 4125 } 4126 } else { 4127 Slog.wtf(TAG, "Task with inRecent not in recents: " + task); 4128 needAffiliationFix = true; 4129 } 4130 } 4131 4132 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task); 4133 trimRecentsForTask(task, true); 4134 4135 N = mRecentTasks.size(); 4136 while (N >= ActivityManager.getMaxRecentTasksStatic()) { 4137 final TaskRecord tr = mRecentTasks.remove(N - 1); 4138 tr.removedFromRecents(mTaskPersister); 4139 N--; 4140 } 4141 task.inRecents = true; 4142 if (!isAffiliated || needAffiliationFix) { 4143 // If this is a simple non-affiliated task, or we had some failure trying to 4144 // handle it as part of an affilated task, then just place it at the top. 4145 mRecentTasks.add(0, task); 4146 } else if (isAffiliated) { 4147 // If this is a new affiliated task, then move all of the affiliated tasks 4148 // to the front and insert this new one. 4149 TaskRecord other = task.mNextAffiliate; 4150 if (other == null) { 4151 other = task.mPrevAffiliate; 4152 } 4153 if (other != null) { 4154 int otherIndex = mRecentTasks.indexOf(other); 4155 if (otherIndex >= 0) { 4156 // Insert new task at appropriate location. 4157 int taskIndex; 4158 if (other == task.mNextAffiliate) { 4159 // We found the index of our next affiliation, which is who is 4160 // before us in the list, so add after that point. 4161 taskIndex = otherIndex+1; 4162 } else { 4163 // We found the index of our previous affiliation, which is who is 4164 // after us in the list, so add at their position. 4165 taskIndex = otherIndex; 4166 } 4167 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at " 4168 + taskIndex + ": " + task); 4169 mRecentTasks.add(taskIndex, task); 4170 4171 // Now move everything to the front. 4172 if (moveAffiliatedTasksToFront(task, taskIndex)) { 4173 // All went well. 4174 return; 4175 } 4176 4177 // Uh oh... something bad in the affiliation chain, try to rebuild 4178 // everything and then go through our general path of adding a new task. 4179 needAffiliationFix = true; 4180 } else { 4181 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation " 4182 + other); 4183 needAffiliationFix = true; 4184 } 4185 } else { 4186 if (DEBUG_RECENTS) Slog.d(TAG, 4187 "addRecent: adding affiliated task without next/prev:" + task); 4188 needAffiliationFix = true; 4189 } 4190 } 4191 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task); 4192 4193 if (needAffiliationFix) { 4194 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations"); 4195 cleanupRecentTasksLocked(task.userId); 4196 } 4197 } 4198 4199 /** 4200 * If needed, remove oldest existing entries in recents that are for the same kind 4201 * of task as the given one. 4202 */ 4203 int trimRecentsForTask(TaskRecord task, boolean doTrim) { 4204 int N = mRecentTasks.size(); 4205 final Intent intent = task.intent; 4206 final boolean document = intent != null && intent.isDocument(); 4207 4208 int maxRecents = task.maxRecents - 1; 4209 for (int i=0; i<N; i++) { 4210 final TaskRecord tr = mRecentTasks.get(i); 4211 if (task != tr) { 4212 if (task.userId != tr.userId) { 4213 continue; 4214 } 4215 if (i > MAX_RECENT_BITMAPS) { 4216 tr.freeLastThumbnail(); 4217 } 4218 final Intent trIntent = tr.intent; 4219 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 4220 (intent == null || !intent.filterEquals(trIntent))) { 4221 continue; 4222 } 4223 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 4224 if (document && trIsDocument) { 4225 // These are the same document activity (not necessarily the same doc). 4226 if (maxRecents > 0) { 4227 --maxRecents; 4228 continue; 4229 } 4230 // Hit the maximum number of documents for this task. Fall through 4231 // and remove this document from recents. 4232 } else if (document || trIsDocument) { 4233 // Only one of these is a document. Not the droid we're looking for. 4234 continue; 4235 } 4236 } 4237 4238 if (!doTrim) { 4239 // If the caller is not actually asking for a trim, just tell them we reached 4240 // a point where the trim would happen. 4241 return i; 4242 } 4243 4244 // Either task and tr are the same or, their affinities match or their intents match 4245 // and neither of them is a document, or they are documents using the same activity 4246 // and their maxRecents has been reached. 4247 tr.disposeThumbnail(); 4248 mRecentTasks.remove(i); 4249 if (task != tr) { 4250 tr.removedFromRecents(mTaskPersister); 4251 } 4252 i--; 4253 N--; 4254 if (task.intent == null) { 4255 // If the new recent task we are adding is not fully 4256 // specified, then replace it with the existing recent task. 4257 task = tr; 4258 } 4259 notifyTaskPersisterLocked(tr, false); 4260 } 4261 4262 return -1; 4263 } 4264 4265 @Override 4266 public void reportActivityFullyDrawn(IBinder token) { 4267 synchronized (this) { 4268 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4269 if (r == null) { 4270 return; 4271 } 4272 r.reportFullyDrawnLocked(); 4273 } 4274 } 4275 4276 @Override 4277 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 4278 synchronized (this) { 4279 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4280 if (r == null) { 4281 return; 4282 } 4283 final long origId = Binder.clearCallingIdentity(); 4284 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 4285 Configuration config = mWindowManager.updateOrientationFromAppTokens( 4286 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 4287 if (config != null) { 4288 r.frozenBeforeDestroy = true; 4289 if (!updateConfigurationLocked(config, r, false, false)) { 4290 mStackSupervisor.resumeTopActivitiesLocked(); 4291 } 4292 } 4293 Binder.restoreCallingIdentity(origId); 4294 } 4295 } 4296 4297 @Override 4298 public int getRequestedOrientation(IBinder token) { 4299 synchronized (this) { 4300 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4301 if (r == null) { 4302 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 4303 } 4304 return mWindowManager.getAppOrientation(r.appToken); 4305 } 4306 } 4307 4308 /** 4309 * This is the internal entry point for handling Activity.finish(). 4310 * 4311 * @param token The Binder token referencing the Activity we want to finish. 4312 * @param resultCode Result code, if any, from this Activity. 4313 * @param resultData Result data (Intent), if any, from this Activity. 4314 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 4315 * the root Activity in the task. 4316 * 4317 * @return Returns true if the activity successfully finished, or false if it is still running. 4318 */ 4319 @Override 4320 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 4321 boolean finishTask) { 4322 // Refuse possible leaked file descriptors 4323 if (resultData != null && resultData.hasFileDescriptors() == true) { 4324 throw new IllegalArgumentException("File descriptors passed in Intent"); 4325 } 4326 4327 synchronized(this) { 4328 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4329 if (r == null) { 4330 return true; 4331 } 4332 // Keep track of the root activity of the task before we finish it 4333 TaskRecord tr = r.task; 4334 ActivityRecord rootR = tr.getRootActivity(); 4335 // Do not allow task to finish in Lock Task mode. 4336 if (tr == mStackSupervisor.mLockTaskModeTask) { 4337 if (rootR == r) { 4338 mStackSupervisor.showLockTaskToast(); 4339 return false; 4340 } 4341 } 4342 if (mController != null) { 4343 // Find the first activity that is not finishing. 4344 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 4345 if (next != null) { 4346 // ask watcher if this is allowed 4347 boolean resumeOK = true; 4348 try { 4349 resumeOK = mController.activityResuming(next.packageName); 4350 } catch (RemoteException e) { 4351 mController = null; 4352 Watchdog.getInstance().setActivityController(null); 4353 } 4354 4355 if (!resumeOK) { 4356 return false; 4357 } 4358 } 4359 } 4360 final long origId = Binder.clearCallingIdentity(); 4361 try { 4362 boolean res; 4363 if (finishTask && r == rootR) { 4364 // If requested, remove the task that is associated to this activity only if it 4365 // was the root activity in the task. The result code and data is ignored because 4366 // we don't support returning them across task boundaries. 4367 res = removeTaskByIdLocked(tr.taskId, 0); 4368 } else { 4369 res = tr.stack.requestFinishActivityLocked(token, resultCode, 4370 resultData, "app-request", true); 4371 } 4372 return res; 4373 } finally { 4374 Binder.restoreCallingIdentity(origId); 4375 } 4376 } 4377 } 4378 4379 @Override 4380 public final void finishHeavyWeightApp() { 4381 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4382 != PackageManager.PERMISSION_GRANTED) { 4383 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 4384 + Binder.getCallingPid() 4385 + ", uid=" + Binder.getCallingUid() 4386 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4387 Slog.w(TAG, msg); 4388 throw new SecurityException(msg); 4389 } 4390 4391 synchronized(this) { 4392 if (mHeavyWeightProcess == null) { 4393 return; 4394 } 4395 4396 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 4397 mHeavyWeightProcess.activities); 4398 for (int i=0; i<activities.size(); i++) { 4399 ActivityRecord r = activities.get(i); 4400 if (!r.finishing) { 4401 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 4402 null, "finish-heavy", true); 4403 } 4404 } 4405 4406 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4407 mHeavyWeightProcess.userId, 0)); 4408 mHeavyWeightProcess = null; 4409 } 4410 } 4411 4412 @Override 4413 public void crashApplication(int uid, int initialPid, String packageName, 4414 String message) { 4415 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4416 != PackageManager.PERMISSION_GRANTED) { 4417 String msg = "Permission Denial: crashApplication() from pid=" 4418 + Binder.getCallingPid() 4419 + ", uid=" + Binder.getCallingUid() 4420 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4421 Slog.w(TAG, msg); 4422 throw new SecurityException(msg); 4423 } 4424 4425 synchronized(this) { 4426 ProcessRecord proc = null; 4427 4428 // Figure out which process to kill. We don't trust that initialPid 4429 // still has any relation to current pids, so must scan through the 4430 // list. 4431 synchronized (mPidsSelfLocked) { 4432 for (int i=0; i<mPidsSelfLocked.size(); i++) { 4433 ProcessRecord p = mPidsSelfLocked.valueAt(i); 4434 if (p.uid != uid) { 4435 continue; 4436 } 4437 if (p.pid == initialPid) { 4438 proc = p; 4439 break; 4440 } 4441 if (p.pkgList.containsKey(packageName)) { 4442 proc = p; 4443 } 4444 } 4445 } 4446 4447 if (proc == null) { 4448 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 4449 + " initialPid=" + initialPid 4450 + " packageName=" + packageName); 4451 return; 4452 } 4453 4454 if (proc.thread != null) { 4455 if (proc.pid == Process.myPid()) { 4456 Log.w(TAG, "crashApplication: trying to crash self!"); 4457 return; 4458 } 4459 long ident = Binder.clearCallingIdentity(); 4460 try { 4461 proc.thread.scheduleCrash(message); 4462 } catch (RemoteException e) { 4463 } 4464 Binder.restoreCallingIdentity(ident); 4465 } 4466 } 4467 } 4468 4469 @Override 4470 public final void finishSubActivity(IBinder token, String resultWho, 4471 int requestCode) { 4472 synchronized(this) { 4473 final long origId = Binder.clearCallingIdentity(); 4474 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4475 if (r != null) { 4476 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 4477 } 4478 Binder.restoreCallingIdentity(origId); 4479 } 4480 } 4481 4482 @Override 4483 public boolean finishActivityAffinity(IBinder token) { 4484 synchronized(this) { 4485 final long origId = Binder.clearCallingIdentity(); 4486 try { 4487 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4488 4489 ActivityRecord rootR = r.task.getRootActivity(); 4490 // Do not allow task to finish in Lock Task mode. 4491 if (r.task == mStackSupervisor.mLockTaskModeTask) { 4492 if (rootR == r) { 4493 mStackSupervisor.showLockTaskToast(); 4494 return false; 4495 } 4496 } 4497 boolean res = false; 4498 if (r != null) { 4499 res = r.task.stack.finishActivityAffinityLocked(r); 4500 } 4501 return res; 4502 } finally { 4503 Binder.restoreCallingIdentity(origId); 4504 } 4505 } 4506 } 4507 4508 @Override 4509 public void finishVoiceTask(IVoiceInteractionSession session) { 4510 synchronized(this) { 4511 final long origId = Binder.clearCallingIdentity(); 4512 try { 4513 mStackSupervisor.finishVoiceTask(session); 4514 } finally { 4515 Binder.restoreCallingIdentity(origId); 4516 } 4517 } 4518 4519 } 4520 4521 @Override 4522 public boolean releaseActivityInstance(IBinder token) { 4523 synchronized(this) { 4524 final long origId = Binder.clearCallingIdentity(); 4525 try { 4526 ActivityRecord r = ActivityRecord.isInStackLocked(token); 4527 if (r.task == null || r.task.stack == null) { 4528 return false; 4529 } 4530 return r.task.stack.safelyDestroyActivityLocked(r, "app-req"); 4531 } finally { 4532 Binder.restoreCallingIdentity(origId); 4533 } 4534 } 4535 } 4536 4537 @Override 4538 public void releaseSomeActivities(IApplicationThread appInt) { 4539 synchronized(this) { 4540 final long origId = Binder.clearCallingIdentity(); 4541 try { 4542 ProcessRecord app = getRecordForAppLocked(appInt); 4543 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem"); 4544 } finally { 4545 Binder.restoreCallingIdentity(origId); 4546 } 4547 } 4548 } 4549 4550 @Override 4551 public boolean willActivityBeVisible(IBinder token) { 4552 synchronized(this) { 4553 ActivityStack stack = ActivityRecord.getStackLocked(token); 4554 if (stack != null) { 4555 return stack.willActivityBeVisibleLocked(token); 4556 } 4557 return false; 4558 } 4559 } 4560 4561 @Override 4562 public void overridePendingTransition(IBinder token, String packageName, 4563 int enterAnim, int exitAnim) { 4564 synchronized(this) { 4565 ActivityRecord self = ActivityRecord.isInStackLocked(token); 4566 if (self == null) { 4567 return; 4568 } 4569 4570 final long origId = Binder.clearCallingIdentity(); 4571 4572 if (self.state == ActivityState.RESUMED 4573 || self.state == ActivityState.PAUSING) { 4574 mWindowManager.overridePendingAppTransition(packageName, 4575 enterAnim, exitAnim, null); 4576 } 4577 4578 Binder.restoreCallingIdentity(origId); 4579 } 4580 } 4581 4582 /** 4583 * Main function for removing an existing process from the activity manager 4584 * as a result of that process going away. Clears out all connections 4585 * to the process. 4586 */ 4587 private final void handleAppDiedLocked(ProcessRecord app, 4588 boolean restarting, boolean allowRestart) { 4589 int pid = app.pid; 4590 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 4591 if (!restarting) { 4592 removeLruProcessLocked(app); 4593 if (pid > 0) { 4594 ProcessList.remove(pid); 4595 } 4596 } 4597 4598 if (mProfileProc == app) { 4599 clearProfilerLocked(); 4600 } 4601 4602 // Remove this application's activities from active lists. 4603 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 4604 4605 app.activities.clear(); 4606 4607 if (app.instrumentationClass != null) { 4608 Slog.w(TAG, "Crash of app " + app.processName 4609 + " running instrumentation " + app.instrumentationClass); 4610 Bundle info = new Bundle(); 4611 info.putString("shortMsg", "Process crashed."); 4612 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4613 } 4614 4615 if (!restarting) { 4616 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4617 // If there was nothing to resume, and we are not already 4618 // restarting this process, but there is a visible activity that 4619 // is hosted by the process... then make sure all visible 4620 // activities are running, taking care of restarting this 4621 // process. 4622 if (hasVisibleActivities) { 4623 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4624 } 4625 } 4626 } 4627 } 4628 4629 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4630 IBinder threadBinder = thread.asBinder(); 4631 // Find the application record. 4632 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4633 ProcessRecord rec = mLruProcesses.get(i); 4634 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4635 return i; 4636 } 4637 } 4638 return -1; 4639 } 4640 4641 final ProcessRecord getRecordForAppLocked( 4642 IApplicationThread thread) { 4643 if (thread == null) { 4644 return null; 4645 } 4646 4647 int appIndex = getLRURecordIndexForAppLocked(thread); 4648 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4649 } 4650 4651 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4652 // If there are no longer any background processes running, 4653 // and the app that died was not running instrumentation, 4654 // then tell everyone we are now low on memory. 4655 boolean haveBg = false; 4656 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4657 ProcessRecord rec = mLruProcesses.get(i); 4658 if (rec.thread != null 4659 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4660 haveBg = true; 4661 break; 4662 } 4663 } 4664 4665 if (!haveBg) { 4666 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4667 if (doReport) { 4668 long now = SystemClock.uptimeMillis(); 4669 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4670 doReport = false; 4671 } else { 4672 mLastMemUsageReportTime = now; 4673 } 4674 } 4675 final ArrayList<ProcessMemInfo> memInfos 4676 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4677 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4678 long now = SystemClock.uptimeMillis(); 4679 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4680 ProcessRecord rec = mLruProcesses.get(i); 4681 if (rec == dyingProc || rec.thread == null) { 4682 continue; 4683 } 4684 if (doReport) { 4685 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4686 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4687 } 4688 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4689 // The low memory report is overriding any current 4690 // state for a GC request. Make sure to do 4691 // heavy/important/visible/foreground processes first. 4692 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4693 rec.lastRequestedGc = 0; 4694 } else { 4695 rec.lastRequestedGc = rec.lastLowMemory; 4696 } 4697 rec.reportLowMemory = true; 4698 rec.lastLowMemory = now; 4699 mProcessesToGc.remove(rec); 4700 addProcessToGcListLocked(rec); 4701 } 4702 } 4703 if (doReport) { 4704 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4705 mHandler.sendMessage(msg); 4706 } 4707 scheduleAppGcsLocked(); 4708 } 4709 } 4710 4711 final void appDiedLocked(ProcessRecord app) { 4712 appDiedLocked(app, app.pid, app.thread); 4713 } 4714 4715 final void appDiedLocked(ProcessRecord app, int pid, 4716 IApplicationThread thread) { 4717 4718 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4719 synchronized (stats) { 4720 stats.noteProcessDiedLocked(app.info.uid, pid); 4721 } 4722 4723 Process.killProcessGroup(app.info.uid, pid); 4724 4725 // Clean up already done if the process has been re-started. 4726 if (app.pid == pid && app.thread != null && 4727 app.thread.asBinder() == thread.asBinder()) { 4728 boolean doLowMem = app.instrumentationClass == null; 4729 boolean doOomAdj = doLowMem; 4730 if (!app.killedByAm) { 4731 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4732 + ") has died."); 4733 mAllowLowerMemLevel = true; 4734 } else { 4735 // Note that we always want to do oom adj to update our state with the 4736 // new number of procs. 4737 mAllowLowerMemLevel = false; 4738 doLowMem = false; 4739 } 4740 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4741 if (DEBUG_CLEANUP) Slog.v( 4742 TAG, "Dying app: " + app + ", pid: " + pid 4743 + ", thread: " + thread.asBinder()); 4744 handleAppDiedLocked(app, false, true); 4745 4746 if (doOomAdj) { 4747 updateOomAdjLocked(); 4748 } 4749 if (doLowMem) { 4750 doLowMemReportIfNeededLocked(app); 4751 } 4752 } else if (app.pid != pid) { 4753 // A new process has already been started. 4754 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4755 + ") has died and restarted (pid " + app.pid + ")."); 4756 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4757 } else if (DEBUG_PROCESSES) { 4758 Slog.d(TAG, "Received spurious death notification for thread " 4759 + thread.asBinder()); 4760 } 4761 } 4762 4763 /** 4764 * If a stack trace dump file is configured, dump process stack traces. 4765 * @param clearTraces causes the dump file to be erased prior to the new 4766 * traces being written, if true; when false, the new traces will be 4767 * appended to any existing file content. 4768 * @param firstPids of dalvik VM processes to dump stack traces for first 4769 * @param lastPids of dalvik VM processes to dump stack traces for last 4770 * @param nativeProcs optional list of native process names to dump stack crawls 4771 * @return file containing stack traces, or null if no dump file is configured 4772 */ 4773 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4774 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4775 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4776 if (tracesPath == null || tracesPath.length() == 0) { 4777 return null; 4778 } 4779 4780 File tracesFile = new File(tracesPath); 4781 try { 4782 File tracesDir = tracesFile.getParentFile(); 4783 if (!tracesDir.exists()) { 4784 tracesFile.mkdirs(); 4785 if (!SELinux.restorecon(tracesDir)) { 4786 return null; 4787 } 4788 } 4789 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4790 4791 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4792 tracesFile.createNewFile(); 4793 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4794 } catch (IOException e) { 4795 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4796 return null; 4797 } 4798 4799 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4800 return tracesFile; 4801 } 4802 4803 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4804 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4805 // Use a FileObserver to detect when traces finish writing. 4806 // The order of traces is considered important to maintain for legibility. 4807 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4808 @Override 4809 public synchronized void onEvent(int event, String path) { notify(); } 4810 }; 4811 4812 try { 4813 observer.startWatching(); 4814 4815 // First collect all of the stacks of the most important pids. 4816 if (firstPids != null) { 4817 try { 4818 int num = firstPids.size(); 4819 for (int i = 0; i < num; i++) { 4820 synchronized (observer) { 4821 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4822 observer.wait(200); // Wait for write-close, give up after 200msec 4823 } 4824 } 4825 } catch (InterruptedException e) { 4826 Log.wtf(TAG, e); 4827 } 4828 } 4829 4830 // Next collect the stacks of the native pids 4831 if (nativeProcs != null) { 4832 int[] pids = Process.getPidsForCommands(nativeProcs); 4833 if (pids != null) { 4834 for (int pid : pids) { 4835 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4836 } 4837 } 4838 } 4839 4840 // Lastly, measure CPU usage. 4841 if (processCpuTracker != null) { 4842 processCpuTracker.init(); 4843 System.gc(); 4844 processCpuTracker.update(); 4845 try { 4846 synchronized (processCpuTracker) { 4847 processCpuTracker.wait(500); // measure over 1/2 second. 4848 } 4849 } catch (InterruptedException e) { 4850 } 4851 processCpuTracker.update(); 4852 4853 // We'll take the stack crawls of just the top apps using CPU. 4854 final int N = processCpuTracker.countWorkingStats(); 4855 int numProcs = 0; 4856 for (int i=0; i<N && numProcs<5; i++) { 4857 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4858 if (lastPids.indexOfKey(stats.pid) >= 0) { 4859 numProcs++; 4860 try { 4861 synchronized (observer) { 4862 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4863 observer.wait(200); // Wait for write-close, give up after 200msec 4864 } 4865 } catch (InterruptedException e) { 4866 Log.wtf(TAG, e); 4867 } 4868 4869 } 4870 } 4871 } 4872 } finally { 4873 observer.stopWatching(); 4874 } 4875 } 4876 4877 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4878 if (true || IS_USER_BUILD) { 4879 return; 4880 } 4881 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4882 if (tracesPath == null || tracesPath.length() == 0) { 4883 return; 4884 } 4885 4886 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4887 StrictMode.allowThreadDiskWrites(); 4888 try { 4889 final File tracesFile = new File(tracesPath); 4890 final File tracesDir = tracesFile.getParentFile(); 4891 final File tracesTmp = new File(tracesDir, "__tmp__"); 4892 try { 4893 if (!tracesDir.exists()) { 4894 tracesFile.mkdirs(); 4895 if (!SELinux.restorecon(tracesDir.getPath())) { 4896 return; 4897 } 4898 } 4899 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4900 4901 if (tracesFile.exists()) { 4902 tracesTmp.delete(); 4903 tracesFile.renameTo(tracesTmp); 4904 } 4905 StringBuilder sb = new StringBuilder(); 4906 Time tobj = new Time(); 4907 tobj.set(System.currentTimeMillis()); 4908 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4909 sb.append(": "); 4910 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4911 sb.append(" since "); 4912 sb.append(msg); 4913 FileOutputStream fos = new FileOutputStream(tracesFile); 4914 fos.write(sb.toString().getBytes()); 4915 if (app == null) { 4916 fos.write("\n*** No application process!".getBytes()); 4917 } 4918 fos.close(); 4919 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4920 } catch (IOException e) { 4921 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4922 return; 4923 } 4924 4925 if (app != null) { 4926 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4927 firstPids.add(app.pid); 4928 dumpStackTraces(tracesPath, firstPids, null, null, null); 4929 } 4930 4931 File lastTracesFile = null; 4932 File curTracesFile = null; 4933 for (int i=9; i>=0; i--) { 4934 String name = String.format(Locale.US, "slow%02d.txt", i); 4935 curTracesFile = new File(tracesDir, name); 4936 if (curTracesFile.exists()) { 4937 if (lastTracesFile != null) { 4938 curTracesFile.renameTo(lastTracesFile); 4939 } else { 4940 curTracesFile.delete(); 4941 } 4942 } 4943 lastTracesFile = curTracesFile; 4944 } 4945 tracesFile.renameTo(curTracesFile); 4946 if (tracesTmp.exists()) { 4947 tracesTmp.renameTo(tracesFile); 4948 } 4949 } finally { 4950 StrictMode.setThreadPolicy(oldPolicy); 4951 } 4952 } 4953 4954 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4955 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4956 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4957 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4958 4959 if (mController != null) { 4960 try { 4961 // 0 == continue, -1 = kill process immediately 4962 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4963 if (res < 0 && app.pid != MY_PID) { 4964 app.kill("anr", true); 4965 } 4966 } catch (RemoteException e) { 4967 mController = null; 4968 Watchdog.getInstance().setActivityController(null); 4969 } 4970 } 4971 4972 long anrTime = SystemClock.uptimeMillis(); 4973 if (MONITOR_CPU_USAGE) { 4974 updateCpuStatsNow(); 4975 } 4976 4977 synchronized (this) { 4978 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4979 if (mShuttingDown) { 4980 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4981 return; 4982 } else if (app.notResponding) { 4983 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4984 return; 4985 } else if (app.crashing) { 4986 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4987 return; 4988 } 4989 4990 // In case we come through here for the same app before completing 4991 // this one, mark as anring now so we will bail out. 4992 app.notResponding = true; 4993 4994 // Log the ANR to the event log. 4995 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4996 app.processName, app.info.flags, annotation); 4997 4998 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4999 firstPids.add(app.pid); 5000 5001 int parentPid = app.pid; 5002 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 5003 if (parentPid != app.pid) firstPids.add(parentPid); 5004 5005 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 5006 5007 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 5008 ProcessRecord r = mLruProcesses.get(i); 5009 if (r != null && r.thread != null) { 5010 int pid = r.pid; 5011 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 5012 if (r.persistent) { 5013 firstPids.add(pid); 5014 } else { 5015 lastPids.put(pid, Boolean.TRUE); 5016 } 5017 } 5018 } 5019 } 5020 } 5021 5022 // Log the ANR to the main log. 5023 StringBuilder info = new StringBuilder(); 5024 info.setLength(0); 5025 info.append("ANR in ").append(app.processName); 5026 if (activity != null && activity.shortComponentName != null) { 5027 info.append(" (").append(activity.shortComponentName).append(")"); 5028 } 5029 info.append("\n"); 5030 info.append("PID: ").append(app.pid).append("\n"); 5031 if (annotation != null) { 5032 info.append("Reason: ").append(annotation).append("\n"); 5033 } 5034 if (parent != null && parent != activity) { 5035 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 5036 } 5037 5038 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 5039 5040 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 5041 NATIVE_STACKS_OF_INTEREST); 5042 5043 String cpuInfo = null; 5044 if (MONITOR_CPU_USAGE) { 5045 updateCpuStatsNow(); 5046 synchronized (mProcessCpuThread) { 5047 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 5048 } 5049 info.append(processCpuTracker.printCurrentLoad()); 5050 info.append(cpuInfo); 5051 } 5052 5053 info.append(processCpuTracker.printCurrentState(anrTime)); 5054 5055 Slog.e(TAG, info.toString()); 5056 if (tracesFile == null) { 5057 // There is no trace file, so dump (only) the alleged culprit's threads to the log 5058 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 5059 } 5060 5061 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 5062 cpuInfo, tracesFile, null); 5063 5064 if (mController != null) { 5065 try { 5066 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 5067 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 5068 if (res != 0) { 5069 if (res < 0 && app.pid != MY_PID) { 5070 app.kill("anr", true); 5071 } else { 5072 synchronized (this) { 5073 mServices.scheduleServiceTimeoutLocked(app); 5074 } 5075 } 5076 return; 5077 } 5078 } catch (RemoteException e) { 5079 mController = null; 5080 Watchdog.getInstance().setActivityController(null); 5081 } 5082 } 5083 5084 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 5085 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 5086 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 5087 5088 synchronized (this) { 5089 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 5090 app.kill("bg anr", true); 5091 return; 5092 } 5093 5094 // Set the app's notResponding state, and look up the errorReportReceiver 5095 makeAppNotRespondingLocked(app, 5096 activity != null ? activity.shortComponentName : null, 5097 annotation != null ? "ANR " + annotation : "ANR", 5098 info.toString()); 5099 5100 // Bring up the infamous App Not Responding dialog 5101 Message msg = Message.obtain(); 5102 HashMap<String, Object> map = new HashMap<String, Object>(); 5103 msg.what = SHOW_NOT_RESPONDING_MSG; 5104 msg.obj = map; 5105 msg.arg1 = aboveSystem ? 1 : 0; 5106 map.put("app", app); 5107 if (activity != null) { 5108 map.put("activity", activity); 5109 } 5110 5111 mHandler.sendMessage(msg); 5112 } 5113 } 5114 5115 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 5116 if (!mLaunchWarningShown) { 5117 mLaunchWarningShown = true; 5118 mHandler.post(new Runnable() { 5119 @Override 5120 public void run() { 5121 synchronized (ActivityManagerService.this) { 5122 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 5123 d.show(); 5124 mHandler.postDelayed(new Runnable() { 5125 @Override 5126 public void run() { 5127 synchronized (ActivityManagerService.this) { 5128 d.dismiss(); 5129 mLaunchWarningShown = false; 5130 } 5131 } 5132 }, 4000); 5133 } 5134 } 5135 }); 5136 } 5137 } 5138 5139 @Override 5140 public boolean clearApplicationUserData(final String packageName, 5141 final IPackageDataObserver observer, int userId) { 5142 enforceNotIsolatedCaller("clearApplicationUserData"); 5143 int uid = Binder.getCallingUid(); 5144 int pid = Binder.getCallingPid(); 5145 userId = handleIncomingUser(pid, uid, 5146 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 5147 long callingId = Binder.clearCallingIdentity(); 5148 try { 5149 IPackageManager pm = AppGlobals.getPackageManager(); 5150 int pkgUid = -1; 5151 synchronized(this) { 5152 try { 5153 pkgUid = pm.getPackageUid(packageName, userId); 5154 } catch (RemoteException e) { 5155 } 5156 if (pkgUid == -1) { 5157 Slog.w(TAG, "Invalid packageName: " + packageName); 5158 if (observer != null) { 5159 try { 5160 observer.onRemoveCompleted(packageName, false); 5161 } catch (RemoteException e) { 5162 Slog.i(TAG, "Observer no longer exists."); 5163 } 5164 } 5165 return false; 5166 } 5167 if (uid == pkgUid || checkComponentPermission( 5168 android.Manifest.permission.CLEAR_APP_USER_DATA, 5169 pid, uid, -1, true) 5170 == PackageManager.PERMISSION_GRANTED) { 5171 forceStopPackageLocked(packageName, pkgUid, "clear data"); 5172 } else { 5173 throw new SecurityException("PID " + pid + " does not have permission " 5174 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 5175 + " of package " + packageName); 5176 } 5177 5178 // Remove all tasks match the cleared application package and user 5179 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 5180 final TaskRecord tr = mRecentTasks.get(i); 5181 final String taskPackageName = 5182 tr.getBaseIntent().getComponent().getPackageName(); 5183 if (tr.userId != userId) continue; 5184 if (!taskPackageName.equals(packageName)) continue; 5185 removeTaskByIdLocked(tr.taskId, 0); 5186 } 5187 } 5188 5189 try { 5190 // Clear application user data 5191 pm.clearApplicationUserData(packageName, observer, userId); 5192 5193 synchronized(this) { 5194 // Remove all permissions granted from/to this package 5195 removeUriPermissionsForPackageLocked(packageName, userId, true); 5196 } 5197 5198 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 5199 Uri.fromParts("package", packageName, null)); 5200 intent.putExtra(Intent.EXTRA_UID, pkgUid); 5201 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 5202 null, null, 0, null, null, null, false, false, userId); 5203 } catch (RemoteException e) { 5204 } 5205 } finally { 5206 Binder.restoreCallingIdentity(callingId); 5207 } 5208 return true; 5209 } 5210 5211 @Override 5212 public void killBackgroundProcesses(final String packageName, int userId) { 5213 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5214 != PackageManager.PERMISSION_GRANTED && 5215 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 5216 != PackageManager.PERMISSION_GRANTED) { 5217 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 5218 + Binder.getCallingPid() 5219 + ", uid=" + Binder.getCallingUid() 5220 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5221 Slog.w(TAG, msg); 5222 throw new SecurityException(msg); 5223 } 5224 5225 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 5226 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 5227 long callingId = Binder.clearCallingIdentity(); 5228 try { 5229 IPackageManager pm = AppGlobals.getPackageManager(); 5230 synchronized(this) { 5231 int appId = -1; 5232 try { 5233 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 5234 } catch (RemoteException e) { 5235 } 5236 if (appId == -1) { 5237 Slog.w(TAG, "Invalid packageName: " + packageName); 5238 return; 5239 } 5240 killPackageProcessesLocked(packageName, appId, userId, 5241 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 5242 } 5243 } finally { 5244 Binder.restoreCallingIdentity(callingId); 5245 } 5246 } 5247 5248 @Override 5249 public void killAllBackgroundProcesses() { 5250 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 5251 != PackageManager.PERMISSION_GRANTED) { 5252 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 5253 + Binder.getCallingPid() 5254 + ", uid=" + Binder.getCallingUid() 5255 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 5256 Slog.w(TAG, msg); 5257 throw new SecurityException(msg); 5258 } 5259 5260 long callingId = Binder.clearCallingIdentity(); 5261 try { 5262 synchronized(this) { 5263 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5264 final int NP = mProcessNames.getMap().size(); 5265 for (int ip=0; ip<NP; ip++) { 5266 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5267 final int NA = apps.size(); 5268 for (int ia=0; ia<NA; ia++) { 5269 ProcessRecord app = apps.valueAt(ia); 5270 if (app.persistent) { 5271 // we don't kill persistent processes 5272 continue; 5273 } 5274 if (app.removed) { 5275 procs.add(app); 5276 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 5277 app.removed = true; 5278 procs.add(app); 5279 } 5280 } 5281 } 5282 5283 int N = procs.size(); 5284 for (int i=0; i<N; i++) { 5285 removeProcessLocked(procs.get(i), false, true, "kill all background"); 5286 } 5287 mAllowLowerMemLevel = true; 5288 updateOomAdjLocked(); 5289 doLowMemReportIfNeededLocked(null); 5290 } 5291 } finally { 5292 Binder.restoreCallingIdentity(callingId); 5293 } 5294 } 5295 5296 @Override 5297 public void forceStopPackage(final String packageName, int userId) { 5298 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 5299 != PackageManager.PERMISSION_GRANTED) { 5300 String msg = "Permission Denial: forceStopPackage() from pid=" 5301 + Binder.getCallingPid() 5302 + ", uid=" + Binder.getCallingUid() 5303 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 5304 Slog.w(TAG, msg); 5305 throw new SecurityException(msg); 5306 } 5307 final int callingPid = Binder.getCallingPid(); 5308 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 5309 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 5310 long callingId = Binder.clearCallingIdentity(); 5311 try { 5312 IPackageManager pm = AppGlobals.getPackageManager(); 5313 synchronized(this) { 5314 int[] users = userId == UserHandle.USER_ALL 5315 ? getUsersLocked() : new int[] { userId }; 5316 for (int user : users) { 5317 int pkgUid = -1; 5318 try { 5319 pkgUid = pm.getPackageUid(packageName, user); 5320 } catch (RemoteException e) { 5321 } 5322 if (pkgUid == -1) { 5323 Slog.w(TAG, "Invalid packageName: " + packageName); 5324 continue; 5325 } 5326 try { 5327 pm.setPackageStoppedState(packageName, true, user); 5328 } catch (RemoteException e) { 5329 } catch (IllegalArgumentException e) { 5330 Slog.w(TAG, "Failed trying to unstop package " 5331 + packageName + ": " + e); 5332 } 5333 if (isUserRunningLocked(user, false)) { 5334 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 5335 } 5336 } 5337 } 5338 } finally { 5339 Binder.restoreCallingIdentity(callingId); 5340 } 5341 } 5342 5343 @Override 5344 public void addPackageDependency(String packageName) { 5345 synchronized (this) { 5346 int callingPid = Binder.getCallingPid(); 5347 if (callingPid == Process.myPid()) { 5348 // Yeah, um, no. 5349 Slog.w(TAG, "Can't addPackageDependency on system process"); 5350 return; 5351 } 5352 ProcessRecord proc; 5353 synchronized (mPidsSelfLocked) { 5354 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 5355 } 5356 if (proc != null) { 5357 if (proc.pkgDeps == null) { 5358 proc.pkgDeps = new ArraySet<String>(1); 5359 } 5360 proc.pkgDeps.add(packageName); 5361 } 5362 } 5363 } 5364 5365 /* 5366 * The pkg name and app id have to be specified. 5367 */ 5368 @Override 5369 public void killApplicationWithAppId(String pkg, int appid, String reason) { 5370 if (pkg == null) { 5371 return; 5372 } 5373 // Make sure the uid is valid. 5374 if (appid < 0) { 5375 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 5376 return; 5377 } 5378 int callerUid = Binder.getCallingUid(); 5379 // Only the system server can kill an application 5380 if (callerUid == Process.SYSTEM_UID) { 5381 // Post an aysnc message to kill the application 5382 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 5383 msg.arg1 = appid; 5384 msg.arg2 = 0; 5385 Bundle bundle = new Bundle(); 5386 bundle.putString("pkg", pkg); 5387 bundle.putString("reason", reason); 5388 msg.obj = bundle; 5389 mHandler.sendMessage(msg); 5390 } else { 5391 throw new SecurityException(callerUid + " cannot kill pkg: " + 5392 pkg); 5393 } 5394 } 5395 5396 @Override 5397 public void closeSystemDialogs(String reason) { 5398 enforceNotIsolatedCaller("closeSystemDialogs"); 5399 5400 final int pid = Binder.getCallingPid(); 5401 final int uid = Binder.getCallingUid(); 5402 final long origId = Binder.clearCallingIdentity(); 5403 try { 5404 synchronized (this) { 5405 // Only allow this from foreground processes, so that background 5406 // applications can't abuse it to prevent system UI from being shown. 5407 if (uid >= Process.FIRST_APPLICATION_UID) { 5408 ProcessRecord proc; 5409 synchronized (mPidsSelfLocked) { 5410 proc = mPidsSelfLocked.get(pid); 5411 } 5412 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 5413 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 5414 + " from background process " + proc); 5415 return; 5416 } 5417 } 5418 closeSystemDialogsLocked(reason); 5419 } 5420 } finally { 5421 Binder.restoreCallingIdentity(origId); 5422 } 5423 } 5424 5425 void closeSystemDialogsLocked(String reason) { 5426 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 5427 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5428 | Intent.FLAG_RECEIVER_FOREGROUND); 5429 if (reason != null) { 5430 intent.putExtra("reason", reason); 5431 } 5432 mWindowManager.closeSystemDialogs(reason); 5433 5434 mStackSupervisor.closeSystemDialogsLocked(); 5435 5436 broadcastIntentLocked(null, null, intent, null, 5437 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 5438 Process.SYSTEM_UID, UserHandle.USER_ALL); 5439 } 5440 5441 @Override 5442 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 5443 enforceNotIsolatedCaller("getProcessMemoryInfo"); 5444 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 5445 for (int i=pids.length-1; i>=0; i--) { 5446 ProcessRecord proc; 5447 int oomAdj; 5448 synchronized (this) { 5449 synchronized (mPidsSelfLocked) { 5450 proc = mPidsSelfLocked.get(pids[i]); 5451 oomAdj = proc != null ? proc.setAdj : 0; 5452 } 5453 } 5454 infos[i] = new Debug.MemoryInfo(); 5455 Debug.getMemoryInfo(pids[i], infos[i]); 5456 if (proc != null) { 5457 synchronized (this) { 5458 if (proc.thread != null && proc.setAdj == oomAdj) { 5459 // Record this for posterity if the process has been stable. 5460 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 5461 infos[i].getTotalUss(), false, proc.pkgList); 5462 } 5463 } 5464 } 5465 } 5466 return infos; 5467 } 5468 5469 @Override 5470 public long[] getProcessPss(int[] pids) { 5471 enforceNotIsolatedCaller("getProcessPss"); 5472 long[] pss = new long[pids.length]; 5473 for (int i=pids.length-1; i>=0; i--) { 5474 ProcessRecord proc; 5475 int oomAdj; 5476 synchronized (this) { 5477 synchronized (mPidsSelfLocked) { 5478 proc = mPidsSelfLocked.get(pids[i]); 5479 oomAdj = proc != null ? proc.setAdj : 0; 5480 } 5481 } 5482 long[] tmpUss = new long[1]; 5483 pss[i] = Debug.getPss(pids[i], tmpUss); 5484 if (proc != null) { 5485 synchronized (this) { 5486 if (proc.thread != null && proc.setAdj == oomAdj) { 5487 // Record this for posterity if the process has been stable. 5488 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 5489 } 5490 } 5491 } 5492 } 5493 return pss; 5494 } 5495 5496 @Override 5497 public void killApplicationProcess(String processName, int uid) { 5498 if (processName == null) { 5499 return; 5500 } 5501 5502 int callerUid = Binder.getCallingUid(); 5503 // Only the system server can kill an application 5504 if (callerUid == Process.SYSTEM_UID) { 5505 synchronized (this) { 5506 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 5507 if (app != null && app.thread != null) { 5508 try { 5509 app.thread.scheduleSuicide(); 5510 } catch (RemoteException e) { 5511 // If the other end already died, then our work here is done. 5512 } 5513 } else { 5514 Slog.w(TAG, "Process/uid not found attempting kill of " 5515 + processName + " / " + uid); 5516 } 5517 } 5518 } else { 5519 throw new SecurityException(callerUid + " cannot kill app process: " + 5520 processName); 5521 } 5522 } 5523 5524 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 5525 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 5526 false, true, false, false, UserHandle.getUserId(uid), reason); 5527 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 5528 Uri.fromParts("package", packageName, null)); 5529 if (!mProcessesReady) { 5530 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5531 | Intent.FLAG_RECEIVER_FOREGROUND); 5532 } 5533 intent.putExtra(Intent.EXTRA_UID, uid); 5534 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 5535 broadcastIntentLocked(null, null, intent, 5536 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5537 false, false, 5538 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 5539 } 5540 5541 private void forceStopUserLocked(int userId, String reason) { 5542 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 5543 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 5544 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 5545 | Intent.FLAG_RECEIVER_FOREGROUND); 5546 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5547 broadcastIntentLocked(null, null, intent, 5548 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 5549 false, false, 5550 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 5551 } 5552 5553 private final boolean killPackageProcessesLocked(String packageName, int appId, 5554 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 5555 boolean doit, boolean evenPersistent, String reason) { 5556 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 5557 5558 // Remove all processes this package may have touched: all with the 5559 // same UID (except for the system or root user), and all whose name 5560 // matches the package name. 5561 final int NP = mProcessNames.getMap().size(); 5562 for (int ip=0; ip<NP; ip++) { 5563 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 5564 final int NA = apps.size(); 5565 for (int ia=0; ia<NA; ia++) { 5566 ProcessRecord app = apps.valueAt(ia); 5567 if (app.persistent && !evenPersistent) { 5568 // we don't kill persistent processes 5569 continue; 5570 } 5571 if (app.removed) { 5572 if (doit) { 5573 procs.add(app); 5574 } 5575 continue; 5576 } 5577 5578 // Skip process if it doesn't meet our oom adj requirement. 5579 if (app.setAdj < minOomAdj) { 5580 continue; 5581 } 5582 5583 // If no package is specified, we call all processes under the 5584 // give user id. 5585 if (packageName == null) { 5586 if (app.userId != userId) { 5587 continue; 5588 } 5589 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 5590 continue; 5591 } 5592 // Package has been specified, we want to hit all processes 5593 // that match it. We need to qualify this by the processes 5594 // that are running under the specified app and user ID. 5595 } else { 5596 final boolean isDep = app.pkgDeps != null 5597 && app.pkgDeps.contains(packageName); 5598 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 5599 continue; 5600 } 5601 if (userId != UserHandle.USER_ALL && app.userId != userId) { 5602 continue; 5603 } 5604 if (!app.pkgList.containsKey(packageName) && !isDep) { 5605 continue; 5606 } 5607 } 5608 5609 // Process has passed all conditions, kill it! 5610 if (!doit) { 5611 return true; 5612 } 5613 app.removed = true; 5614 procs.add(app); 5615 } 5616 } 5617 5618 int N = procs.size(); 5619 for (int i=0; i<N; i++) { 5620 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 5621 } 5622 updateOomAdjLocked(); 5623 return N > 0; 5624 } 5625 5626 private final boolean forceStopPackageLocked(String name, int appId, 5627 boolean callerWillRestart, boolean purgeCache, boolean doit, 5628 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5629 int i; 5630 int N; 5631 5632 if (userId == UserHandle.USER_ALL && name == null) { 5633 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5634 } 5635 5636 if (appId < 0 && name != null) { 5637 try { 5638 appId = UserHandle.getAppId( 5639 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5640 } catch (RemoteException e) { 5641 } 5642 } 5643 5644 if (doit) { 5645 if (name != null) { 5646 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5647 + " user=" + userId + ": " + reason); 5648 } else { 5649 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5650 } 5651 5652 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5653 for (int ip=pmap.size()-1; ip>=0; ip--) { 5654 SparseArray<Long> ba = pmap.valueAt(ip); 5655 for (i=ba.size()-1; i>=0; i--) { 5656 boolean remove = false; 5657 final int entUid = ba.keyAt(i); 5658 if (name != null) { 5659 if (userId == UserHandle.USER_ALL) { 5660 if (UserHandle.getAppId(entUid) == appId) { 5661 remove = true; 5662 } 5663 } else { 5664 if (entUid == UserHandle.getUid(userId, appId)) { 5665 remove = true; 5666 } 5667 } 5668 } else if (UserHandle.getUserId(entUid) == userId) { 5669 remove = true; 5670 } 5671 if (remove) { 5672 ba.removeAt(i); 5673 } 5674 } 5675 if (ba.size() == 0) { 5676 pmap.removeAt(ip); 5677 } 5678 } 5679 } 5680 5681 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5682 -100, callerWillRestart, true, doit, evenPersistent, 5683 name == null ? ("stop user " + userId) : ("stop " + name)); 5684 5685 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5686 if (!doit) { 5687 return true; 5688 } 5689 didSomething = true; 5690 } 5691 5692 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5693 if (!doit) { 5694 return true; 5695 } 5696 didSomething = true; 5697 } 5698 5699 if (name == null) { 5700 // Remove all sticky broadcasts from this user. 5701 mStickyBroadcasts.remove(userId); 5702 } 5703 5704 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5705 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5706 userId, providers)) { 5707 if (!doit) { 5708 return true; 5709 } 5710 didSomething = true; 5711 } 5712 N = providers.size(); 5713 for (i=0; i<N; i++) { 5714 removeDyingProviderLocked(null, providers.get(i), true); 5715 } 5716 5717 // Remove transient permissions granted from/to this package/user 5718 removeUriPermissionsForPackageLocked(name, userId, false); 5719 5720 if (name == null || uninstalling) { 5721 // Remove pending intents. For now we only do this when force 5722 // stopping users, because we have some problems when doing this 5723 // for packages -- app widgets are not currently cleaned up for 5724 // such packages, so they can be left with bad pending intents. 5725 if (mIntentSenderRecords.size() > 0) { 5726 Iterator<WeakReference<PendingIntentRecord>> it 5727 = mIntentSenderRecords.values().iterator(); 5728 while (it.hasNext()) { 5729 WeakReference<PendingIntentRecord> wpir = it.next(); 5730 if (wpir == null) { 5731 it.remove(); 5732 continue; 5733 } 5734 PendingIntentRecord pir = wpir.get(); 5735 if (pir == null) { 5736 it.remove(); 5737 continue; 5738 } 5739 if (name == null) { 5740 // Stopping user, remove all objects for the user. 5741 if (pir.key.userId != userId) { 5742 // Not the same user, skip it. 5743 continue; 5744 } 5745 } else { 5746 if (UserHandle.getAppId(pir.uid) != appId) { 5747 // Different app id, skip it. 5748 continue; 5749 } 5750 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5751 // Different user, skip it. 5752 continue; 5753 } 5754 if (!pir.key.packageName.equals(name)) { 5755 // Different package, skip it. 5756 continue; 5757 } 5758 } 5759 if (!doit) { 5760 return true; 5761 } 5762 didSomething = true; 5763 it.remove(); 5764 pir.canceled = true; 5765 if (pir.key.activity != null) { 5766 pir.key.activity.pendingResults.remove(pir.ref); 5767 } 5768 } 5769 } 5770 } 5771 5772 if (doit) { 5773 if (purgeCache && name != null) { 5774 AttributeCache ac = AttributeCache.instance(); 5775 if (ac != null) { 5776 ac.removePackage(name); 5777 } 5778 } 5779 if (mBooted) { 5780 mStackSupervisor.resumeTopActivitiesLocked(); 5781 mStackSupervisor.scheduleIdleLocked(); 5782 } 5783 } 5784 5785 return didSomething; 5786 } 5787 5788 private final boolean removeProcessLocked(ProcessRecord app, 5789 boolean callerWillRestart, boolean allowRestart, String reason) { 5790 final String name = app.processName; 5791 final int uid = app.uid; 5792 if (DEBUG_PROCESSES) Slog.d( 5793 TAG, "Force removing proc " + app.toShortString() + " (" + name 5794 + "/" + uid + ")"); 5795 5796 mProcessNames.remove(name, uid); 5797 mIsolatedProcesses.remove(app.uid); 5798 if (mHeavyWeightProcess == app) { 5799 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5800 mHeavyWeightProcess.userId, 0)); 5801 mHeavyWeightProcess = null; 5802 } 5803 boolean needRestart = false; 5804 if (app.pid > 0 && app.pid != MY_PID) { 5805 int pid = app.pid; 5806 synchronized (mPidsSelfLocked) { 5807 mPidsSelfLocked.remove(pid); 5808 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5809 } 5810 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5811 if (app.isolated) { 5812 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5813 } 5814 app.kill(reason, true); 5815 handleAppDiedLocked(app, true, allowRestart); 5816 removeLruProcessLocked(app); 5817 5818 if (app.persistent && !app.isolated) { 5819 if (!callerWillRestart) { 5820 addAppLocked(app.info, false, null /* ABI override */); 5821 } else { 5822 needRestart = true; 5823 } 5824 } 5825 } else { 5826 mRemovedProcesses.add(app); 5827 } 5828 5829 return needRestart; 5830 } 5831 5832 private final void processStartTimedOutLocked(ProcessRecord app) { 5833 final int pid = app.pid; 5834 boolean gone = false; 5835 synchronized (mPidsSelfLocked) { 5836 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5837 if (knownApp != null && knownApp.thread == null) { 5838 mPidsSelfLocked.remove(pid); 5839 gone = true; 5840 } 5841 } 5842 5843 if (gone) { 5844 Slog.w(TAG, "Process " + app + " failed to attach"); 5845 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5846 pid, app.uid, app.processName); 5847 mProcessNames.remove(app.processName, app.uid); 5848 mIsolatedProcesses.remove(app.uid); 5849 if (mHeavyWeightProcess == app) { 5850 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5851 mHeavyWeightProcess.userId, 0)); 5852 mHeavyWeightProcess = null; 5853 } 5854 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5855 if (app.isolated) { 5856 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5857 } 5858 // Take care of any launching providers waiting for this process. 5859 checkAppInLaunchingProvidersLocked(app, true); 5860 // Take care of any services that are waiting for the process. 5861 mServices.processStartTimedOutLocked(app); 5862 app.kill("start timeout", true); 5863 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5864 Slog.w(TAG, "Unattached app died before backup, skipping"); 5865 try { 5866 IBackupManager bm = IBackupManager.Stub.asInterface( 5867 ServiceManager.getService(Context.BACKUP_SERVICE)); 5868 bm.agentDisconnected(app.info.packageName); 5869 } catch (RemoteException e) { 5870 // Can't happen; the backup manager is local 5871 } 5872 } 5873 if (isPendingBroadcastProcessLocked(pid)) { 5874 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5875 skipPendingBroadcastLocked(pid); 5876 } 5877 } else { 5878 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5879 } 5880 } 5881 5882 private final boolean attachApplicationLocked(IApplicationThread thread, 5883 int pid) { 5884 5885 // Find the application record that is being attached... either via 5886 // the pid if we are running in multiple processes, or just pull the 5887 // next app record if we are emulating process with anonymous threads. 5888 ProcessRecord app; 5889 if (pid != MY_PID && pid >= 0) { 5890 synchronized (mPidsSelfLocked) { 5891 app = mPidsSelfLocked.get(pid); 5892 } 5893 } else { 5894 app = null; 5895 } 5896 5897 if (app == null) { 5898 Slog.w(TAG, "No pending application record for pid " + pid 5899 + " (IApplicationThread " + thread + "); dropping process"); 5900 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5901 if (pid > 0 && pid != MY_PID) { 5902 Process.killProcessQuiet(pid); 5903 //TODO: Process.killProcessGroup(app.info.uid, pid); 5904 } else { 5905 try { 5906 thread.scheduleExit(); 5907 } catch (Exception e) { 5908 // Ignore exceptions. 5909 } 5910 } 5911 return false; 5912 } 5913 5914 // If this application record is still attached to a previous 5915 // process, clean it up now. 5916 if (app.thread != null) { 5917 handleAppDiedLocked(app, true, true); 5918 } 5919 5920 // Tell the process all about itself. 5921 5922 if (localLOGV) Slog.v( 5923 TAG, "Binding process pid " + pid + " to record " + app); 5924 5925 final String processName = app.processName; 5926 try { 5927 AppDeathRecipient adr = new AppDeathRecipient( 5928 app, pid, thread); 5929 thread.asBinder().linkToDeath(adr, 0); 5930 app.deathRecipient = adr; 5931 } catch (RemoteException e) { 5932 app.resetPackageList(mProcessStats); 5933 startProcessLocked(app, "link fail", processName); 5934 return false; 5935 } 5936 5937 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5938 5939 app.makeActive(thread, mProcessStats); 5940 app.curAdj = app.setAdj = -100; 5941 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5942 app.forcingToForeground = null; 5943 updateProcessForegroundLocked(app, false, false); 5944 app.hasShownUi = false; 5945 app.debugging = false; 5946 app.cached = false; 5947 5948 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5949 5950 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5951 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5952 5953 if (!normalMode) { 5954 Slog.i(TAG, "Launching preboot mode app: " + app); 5955 } 5956 5957 if (localLOGV) Slog.v( 5958 TAG, "New app record " + app 5959 + " thread=" + thread.asBinder() + " pid=" + pid); 5960 try { 5961 int testMode = IApplicationThread.DEBUG_OFF; 5962 if (mDebugApp != null && mDebugApp.equals(processName)) { 5963 testMode = mWaitForDebugger 5964 ? IApplicationThread.DEBUG_WAIT 5965 : IApplicationThread.DEBUG_ON; 5966 app.debugging = true; 5967 if (mDebugTransient) { 5968 mDebugApp = mOrigDebugApp; 5969 mWaitForDebugger = mOrigWaitForDebugger; 5970 } 5971 } 5972 String profileFile = app.instrumentationProfileFile; 5973 ParcelFileDescriptor profileFd = null; 5974 int samplingInterval = 0; 5975 boolean profileAutoStop = false; 5976 if (mProfileApp != null && mProfileApp.equals(processName)) { 5977 mProfileProc = app; 5978 profileFile = mProfileFile; 5979 profileFd = mProfileFd; 5980 samplingInterval = mSamplingInterval; 5981 profileAutoStop = mAutoStopProfiler; 5982 } 5983 boolean enableOpenGlTrace = false; 5984 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5985 enableOpenGlTrace = true; 5986 mOpenGlTraceApp = null; 5987 } 5988 5989 // If the app is being launched for restore or full backup, set it up specially 5990 boolean isRestrictedBackupMode = false; 5991 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5992 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5993 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5994 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5995 } 5996 5997 ensurePackageDexOpt(app.instrumentationInfo != null 5998 ? app.instrumentationInfo.packageName 5999 : app.info.packageName); 6000 if (app.instrumentationClass != null) { 6001 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 6002 } 6003 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 6004 + processName + " with config " + mConfiguration); 6005 ApplicationInfo appInfo = app.instrumentationInfo != null 6006 ? app.instrumentationInfo : app.info; 6007 app.compat = compatibilityInfoForPackageLocked(appInfo); 6008 if (profileFd != null) { 6009 profileFd = profileFd.dup(); 6010 } 6011 ProfilerInfo profilerInfo = profileFile == null ? null 6012 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); 6013 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, 6014 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, 6015 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 6016 isRestrictedBackupMode || !normalMode, app.persistent, 6017 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 6018 mCoreSettingsObserver.getCoreSettingsLocked()); 6019 updateLruProcessLocked(app, false, null); 6020 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 6021 } catch (Exception e) { 6022 // todo: Yikes! What should we do? For now we will try to 6023 // start another process, but that could easily get us in 6024 // an infinite loop of restarting processes... 6025 Slog.w(TAG, "Exception thrown during bind!", e); 6026 6027 app.resetPackageList(mProcessStats); 6028 app.unlinkDeathRecipient(); 6029 startProcessLocked(app, "bind fail", processName); 6030 return false; 6031 } 6032 6033 // Remove this record from the list of starting applications. 6034 mPersistentStartingProcesses.remove(app); 6035 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 6036 "Attach application locked removing on hold: " + app); 6037 mProcessesOnHold.remove(app); 6038 6039 boolean badApp = false; 6040 boolean didSomething = false; 6041 6042 // See if the top visible activity is waiting to run in this process... 6043 if (normalMode) { 6044 try { 6045 if (mStackSupervisor.attachApplicationLocked(app)) { 6046 didSomething = true; 6047 } 6048 } catch (Exception e) { 6049 badApp = true; 6050 } 6051 } 6052 6053 // Find any services that should be running in this process... 6054 if (!badApp) { 6055 try { 6056 didSomething |= mServices.attachApplicationLocked(app, processName); 6057 } catch (Exception e) { 6058 badApp = true; 6059 } 6060 } 6061 6062 // Check if a next-broadcast receiver is in this process... 6063 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 6064 try { 6065 didSomething |= sendPendingBroadcastsLocked(app); 6066 } catch (Exception e) { 6067 // If the app died trying to launch the receiver we declare it 'bad' 6068 badApp = true; 6069 } 6070 } 6071 6072 // Check whether the next backup agent is in this process... 6073 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 6074 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 6075 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 6076 try { 6077 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 6078 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 6079 mBackupTarget.backupMode); 6080 } catch (Exception e) { 6081 Slog.w(TAG, "Exception scheduling backup agent creation: "); 6082 e.printStackTrace(); 6083 } 6084 } 6085 6086 if (badApp) { 6087 // todo: Also need to kill application to deal with all 6088 // kinds of exceptions. 6089 handleAppDiedLocked(app, false, true); 6090 return false; 6091 } 6092 6093 if (!didSomething) { 6094 updateOomAdjLocked(); 6095 } 6096 6097 return true; 6098 } 6099 6100 @Override 6101 public final void attachApplication(IApplicationThread thread) { 6102 synchronized (this) { 6103 int callingPid = Binder.getCallingPid(); 6104 final long origId = Binder.clearCallingIdentity(); 6105 attachApplicationLocked(thread, callingPid); 6106 Binder.restoreCallingIdentity(origId); 6107 } 6108 } 6109 6110 @Override 6111 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 6112 final long origId = Binder.clearCallingIdentity(); 6113 synchronized (this) { 6114 ActivityStack stack = ActivityRecord.getStackLocked(token); 6115 if (stack != null) { 6116 ActivityRecord r = 6117 mStackSupervisor.activityIdleInternalLocked(token, false, config); 6118 if (stopProfiling) { 6119 if ((mProfileProc == r.app) && (mProfileFd != null)) { 6120 try { 6121 mProfileFd.close(); 6122 } catch (IOException e) { 6123 } 6124 clearProfilerLocked(); 6125 } 6126 } 6127 } 6128 } 6129 Binder.restoreCallingIdentity(origId); 6130 } 6131 6132 void postEnableScreenAfterBootLocked() { 6133 mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG); 6134 } 6135 6136 void enableScreenAfterBoot() { 6137 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 6138 SystemClock.uptimeMillis()); 6139 mWindowManager.enableScreenAfterBoot(); 6140 6141 synchronized (this) { 6142 updateEventDispatchingLocked(); 6143 } 6144 } 6145 6146 @Override 6147 public void showBootMessage(final CharSequence msg, final boolean always) { 6148 enforceNotIsolatedCaller("showBootMessage"); 6149 mWindowManager.showBootMessage(msg, always); 6150 } 6151 6152 @Override 6153 public void keyguardWaitingForActivityDrawn() { 6154 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn"); 6155 final long token = Binder.clearCallingIdentity(); 6156 try { 6157 synchronized (this) { 6158 if (DEBUG_LOCKSCREEN) logLockScreen(""); 6159 mWindowManager.keyguardWaitingForActivityDrawn(); 6160 } 6161 } finally { 6162 Binder.restoreCallingIdentity(token); 6163 } 6164 } 6165 6166 final void finishBooting() { 6167 // Register receivers to handle package update events 6168 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 6169 6170 // Let system services know. 6171 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED); 6172 6173 synchronized (this) { 6174 // Ensure that any processes we had put on hold are now started 6175 // up. 6176 final int NP = mProcessesOnHold.size(); 6177 if (NP > 0) { 6178 ArrayList<ProcessRecord> procs = 6179 new ArrayList<ProcessRecord>(mProcessesOnHold); 6180 for (int ip=0; ip<NP; ip++) { 6181 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 6182 + procs.get(ip)); 6183 startProcessLocked(procs.get(ip), "on-hold", null); 6184 } 6185 } 6186 6187 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 6188 // Start looking for apps that are abusing wake locks. 6189 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 6190 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 6191 // Tell anyone interested that we are done booting! 6192 SystemProperties.set("sys.boot_completed", "1"); 6193 SystemProperties.set("dev.bootcomplete", "1"); 6194 for (int i=0; i<mStartedUsers.size(); i++) { 6195 UserStartedState uss = mStartedUsers.valueAt(i); 6196 if (uss.mState == UserStartedState.STATE_BOOTING) { 6197 uss.mState = UserStartedState.STATE_RUNNING; 6198 final int userId = mStartedUsers.keyAt(i); 6199 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 6200 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 6201 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 6202 broadcastIntentLocked(null, null, intent, null, 6203 new IIntentReceiver.Stub() { 6204 @Override 6205 public void performReceive(Intent intent, int resultCode, 6206 String data, Bundle extras, boolean ordered, 6207 boolean sticky, int sendingUser) { 6208 synchronized (ActivityManagerService.this) { 6209 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 6210 true, false); 6211 } 6212 } 6213 }, 6214 0, null, null, 6215 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 6216 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 6217 userId); 6218 } 6219 } 6220 scheduleStartProfilesLocked(); 6221 } 6222 } 6223 } 6224 6225 final void ensureBootCompleted() { 6226 boolean booting; 6227 boolean enableScreen; 6228 synchronized (this) { 6229 booting = mBooting; 6230 mBooting = false; 6231 enableScreen = !mBooted; 6232 mBooted = true; 6233 } 6234 6235 if (booting) { 6236 finishBooting(); 6237 } 6238 6239 if (enableScreen) { 6240 enableScreenAfterBoot(); 6241 } 6242 } 6243 6244 @Override 6245 public final void activityResumed(IBinder token) { 6246 final long origId = Binder.clearCallingIdentity(); 6247 synchronized(this) { 6248 ActivityStack stack = ActivityRecord.getStackLocked(token); 6249 if (stack != null) { 6250 ActivityRecord.activityResumedLocked(token); 6251 } 6252 } 6253 Binder.restoreCallingIdentity(origId); 6254 } 6255 6256 @Override 6257 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 6258 final long origId = Binder.clearCallingIdentity(); 6259 synchronized(this) { 6260 ActivityStack stack = ActivityRecord.getStackLocked(token); 6261 if (stack != null) { 6262 stack.activityPausedLocked(token, false, persistentState); 6263 } 6264 } 6265 Binder.restoreCallingIdentity(origId); 6266 } 6267 6268 @Override 6269 public final void activityStopped(IBinder token, Bundle icicle, 6270 PersistableBundle persistentState, CharSequence description) { 6271 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 6272 6273 // Refuse possible leaked file descriptors 6274 if (icicle != null && icicle.hasFileDescriptors()) { 6275 throw new IllegalArgumentException("File descriptors passed in Bundle"); 6276 } 6277 6278 final long origId = Binder.clearCallingIdentity(); 6279 6280 synchronized (this) { 6281 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6282 if (r != null) { 6283 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 6284 } 6285 } 6286 6287 trimApplications(); 6288 6289 Binder.restoreCallingIdentity(origId); 6290 } 6291 6292 @Override 6293 public final void activityDestroyed(IBinder token) { 6294 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 6295 synchronized (this) { 6296 ActivityStack stack = ActivityRecord.getStackLocked(token); 6297 if (stack != null) { 6298 stack.activityDestroyedLocked(token); 6299 } 6300 } 6301 } 6302 6303 @Override 6304 public final void backgroundResourcesReleased(IBinder token) { 6305 final long origId = Binder.clearCallingIdentity(); 6306 try { 6307 synchronized (this) { 6308 ActivityStack stack = ActivityRecord.getStackLocked(token); 6309 if (stack != null) { 6310 stack.backgroundResourcesReleased(token); 6311 } 6312 } 6313 } finally { 6314 Binder.restoreCallingIdentity(origId); 6315 } 6316 } 6317 6318 @Override 6319 public final void notifyLaunchTaskBehindComplete(IBinder token) { 6320 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 6321 } 6322 6323 @Override 6324 public final void notifyEnterAnimationComplete(IBinder token) { 6325 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token)); 6326 } 6327 6328 @Override 6329 public String getCallingPackage(IBinder token) { 6330 synchronized (this) { 6331 ActivityRecord r = getCallingRecordLocked(token); 6332 return r != null ? r.info.packageName : null; 6333 } 6334 } 6335 6336 @Override 6337 public ComponentName getCallingActivity(IBinder token) { 6338 synchronized (this) { 6339 ActivityRecord r = getCallingRecordLocked(token); 6340 return r != null ? r.intent.getComponent() : null; 6341 } 6342 } 6343 6344 private ActivityRecord getCallingRecordLocked(IBinder token) { 6345 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6346 if (r == null) { 6347 return null; 6348 } 6349 return r.resultTo; 6350 } 6351 6352 @Override 6353 public ComponentName getActivityClassForToken(IBinder token) { 6354 synchronized(this) { 6355 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6356 if (r == null) { 6357 return null; 6358 } 6359 return r.intent.getComponent(); 6360 } 6361 } 6362 6363 @Override 6364 public String getPackageForToken(IBinder token) { 6365 synchronized(this) { 6366 ActivityRecord r = ActivityRecord.isInStackLocked(token); 6367 if (r == null) { 6368 return null; 6369 } 6370 return r.packageName; 6371 } 6372 } 6373 6374 @Override 6375 public IIntentSender getIntentSender(int type, 6376 String packageName, IBinder token, String resultWho, 6377 int requestCode, Intent[] intents, String[] resolvedTypes, 6378 int flags, Bundle options, int userId) { 6379 enforceNotIsolatedCaller("getIntentSender"); 6380 // Refuse possible leaked file descriptors 6381 if (intents != null) { 6382 if (intents.length < 1) { 6383 throw new IllegalArgumentException("Intents array length must be >= 1"); 6384 } 6385 for (int i=0; i<intents.length; i++) { 6386 Intent intent = intents[i]; 6387 if (intent != null) { 6388 if (intent.hasFileDescriptors()) { 6389 throw new IllegalArgumentException("File descriptors passed in Intent"); 6390 } 6391 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 6392 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 6393 throw new IllegalArgumentException( 6394 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 6395 } 6396 intents[i] = new Intent(intent); 6397 } 6398 } 6399 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 6400 throw new IllegalArgumentException( 6401 "Intent array length does not match resolvedTypes length"); 6402 } 6403 } 6404 if (options != null) { 6405 if (options.hasFileDescriptors()) { 6406 throw new IllegalArgumentException("File descriptors passed in options"); 6407 } 6408 } 6409 6410 synchronized(this) { 6411 int callingUid = Binder.getCallingUid(); 6412 int origUserId = userId; 6413 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 6414 type == ActivityManager.INTENT_SENDER_BROADCAST, 6415 ALLOW_NON_FULL, "getIntentSender", null); 6416 if (origUserId == UserHandle.USER_CURRENT) { 6417 // We don't want to evaluate this until the pending intent is 6418 // actually executed. However, we do want to always do the 6419 // security checking for it above. 6420 userId = UserHandle.USER_CURRENT; 6421 } 6422 try { 6423 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 6424 int uid = AppGlobals.getPackageManager() 6425 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6426 if (!UserHandle.isSameApp(callingUid, uid)) { 6427 String msg = "Permission Denial: getIntentSender() from pid=" 6428 + Binder.getCallingPid() 6429 + ", uid=" + Binder.getCallingUid() 6430 + ", (need uid=" + uid + ")" 6431 + " is not allowed to send as package " + packageName; 6432 Slog.w(TAG, msg); 6433 throw new SecurityException(msg); 6434 } 6435 } 6436 6437 return getIntentSenderLocked(type, packageName, callingUid, userId, 6438 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 6439 6440 } catch (RemoteException e) { 6441 throw new SecurityException(e); 6442 } 6443 } 6444 } 6445 6446 IIntentSender getIntentSenderLocked(int type, String packageName, 6447 int callingUid, int userId, IBinder token, String resultWho, 6448 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 6449 Bundle options) { 6450 if (DEBUG_MU) 6451 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 6452 ActivityRecord activity = null; 6453 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6454 activity = ActivityRecord.isInStackLocked(token); 6455 if (activity == null) { 6456 return null; 6457 } 6458 if (activity.finishing) { 6459 return null; 6460 } 6461 } 6462 6463 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 6464 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 6465 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 6466 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 6467 |PendingIntent.FLAG_UPDATE_CURRENT); 6468 6469 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 6470 type, packageName, activity, resultWho, 6471 requestCode, intents, resolvedTypes, flags, options, userId); 6472 WeakReference<PendingIntentRecord> ref; 6473 ref = mIntentSenderRecords.get(key); 6474 PendingIntentRecord rec = ref != null ? ref.get() : null; 6475 if (rec != null) { 6476 if (!cancelCurrent) { 6477 if (updateCurrent) { 6478 if (rec.key.requestIntent != null) { 6479 rec.key.requestIntent.replaceExtras(intents != null ? 6480 intents[intents.length - 1] : null); 6481 } 6482 if (intents != null) { 6483 intents[intents.length-1] = rec.key.requestIntent; 6484 rec.key.allIntents = intents; 6485 rec.key.allResolvedTypes = resolvedTypes; 6486 } else { 6487 rec.key.allIntents = null; 6488 rec.key.allResolvedTypes = null; 6489 } 6490 } 6491 return rec; 6492 } 6493 rec.canceled = true; 6494 mIntentSenderRecords.remove(key); 6495 } 6496 if (noCreate) { 6497 return rec; 6498 } 6499 rec = new PendingIntentRecord(this, key, callingUid); 6500 mIntentSenderRecords.put(key, rec.ref); 6501 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 6502 if (activity.pendingResults == null) { 6503 activity.pendingResults 6504 = new HashSet<WeakReference<PendingIntentRecord>>(); 6505 } 6506 activity.pendingResults.add(rec.ref); 6507 } 6508 return rec; 6509 } 6510 6511 @Override 6512 public void cancelIntentSender(IIntentSender sender) { 6513 if (!(sender instanceof PendingIntentRecord)) { 6514 return; 6515 } 6516 synchronized(this) { 6517 PendingIntentRecord rec = (PendingIntentRecord)sender; 6518 try { 6519 int uid = AppGlobals.getPackageManager() 6520 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 6521 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 6522 String msg = "Permission Denial: cancelIntentSender() from pid=" 6523 + Binder.getCallingPid() 6524 + ", uid=" + Binder.getCallingUid() 6525 + " is not allowed to cancel packges " 6526 + rec.key.packageName; 6527 Slog.w(TAG, msg); 6528 throw new SecurityException(msg); 6529 } 6530 } catch (RemoteException e) { 6531 throw new SecurityException(e); 6532 } 6533 cancelIntentSenderLocked(rec, true); 6534 } 6535 } 6536 6537 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 6538 rec.canceled = true; 6539 mIntentSenderRecords.remove(rec.key); 6540 if (cleanActivity && rec.key.activity != null) { 6541 rec.key.activity.pendingResults.remove(rec.ref); 6542 } 6543 } 6544 6545 @Override 6546 public String getPackageForIntentSender(IIntentSender pendingResult) { 6547 if (!(pendingResult instanceof PendingIntentRecord)) { 6548 return null; 6549 } 6550 try { 6551 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6552 return res.key.packageName; 6553 } catch (ClassCastException e) { 6554 } 6555 return null; 6556 } 6557 6558 @Override 6559 public int getUidForIntentSender(IIntentSender sender) { 6560 if (sender instanceof PendingIntentRecord) { 6561 try { 6562 PendingIntentRecord res = (PendingIntentRecord)sender; 6563 return res.uid; 6564 } catch (ClassCastException e) { 6565 } 6566 } 6567 return -1; 6568 } 6569 6570 @Override 6571 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 6572 if (!(pendingResult instanceof PendingIntentRecord)) { 6573 return false; 6574 } 6575 try { 6576 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6577 if (res.key.allIntents == null) { 6578 return false; 6579 } 6580 for (int i=0; i<res.key.allIntents.length; i++) { 6581 Intent intent = res.key.allIntents[i]; 6582 if (intent.getPackage() != null && intent.getComponent() != null) { 6583 return false; 6584 } 6585 } 6586 return true; 6587 } catch (ClassCastException e) { 6588 } 6589 return false; 6590 } 6591 6592 @Override 6593 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 6594 if (!(pendingResult instanceof PendingIntentRecord)) { 6595 return false; 6596 } 6597 try { 6598 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6599 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 6600 return true; 6601 } 6602 return false; 6603 } catch (ClassCastException e) { 6604 } 6605 return false; 6606 } 6607 6608 @Override 6609 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 6610 if (!(pendingResult instanceof PendingIntentRecord)) { 6611 return null; 6612 } 6613 try { 6614 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6615 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 6616 } catch (ClassCastException e) { 6617 } 6618 return null; 6619 } 6620 6621 @Override 6622 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 6623 if (!(pendingResult instanceof PendingIntentRecord)) { 6624 return null; 6625 } 6626 try { 6627 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 6628 Intent intent = res.key.requestIntent; 6629 if (intent != null) { 6630 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 6631 || res.lastTagPrefix.equals(prefix))) { 6632 return res.lastTag; 6633 } 6634 res.lastTagPrefix = prefix; 6635 StringBuilder sb = new StringBuilder(128); 6636 if (prefix != null) { 6637 sb.append(prefix); 6638 } 6639 if (intent.getAction() != null) { 6640 sb.append(intent.getAction()); 6641 } else if (intent.getComponent() != null) { 6642 intent.getComponent().appendShortString(sb); 6643 } else { 6644 sb.append("?"); 6645 } 6646 return res.lastTag = sb.toString(); 6647 } 6648 } catch (ClassCastException e) { 6649 } 6650 return null; 6651 } 6652 6653 @Override 6654 public void setProcessLimit(int max) { 6655 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6656 "setProcessLimit()"); 6657 synchronized (this) { 6658 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6659 mProcessLimitOverride = max; 6660 } 6661 trimApplications(); 6662 } 6663 6664 @Override 6665 public int getProcessLimit() { 6666 synchronized (this) { 6667 return mProcessLimitOverride; 6668 } 6669 } 6670 6671 void foregroundTokenDied(ForegroundToken token) { 6672 synchronized (ActivityManagerService.this) { 6673 synchronized (mPidsSelfLocked) { 6674 ForegroundToken cur 6675 = mForegroundProcesses.get(token.pid); 6676 if (cur != token) { 6677 return; 6678 } 6679 mForegroundProcesses.remove(token.pid); 6680 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6681 if (pr == null) { 6682 return; 6683 } 6684 pr.forcingToForeground = null; 6685 updateProcessForegroundLocked(pr, false, false); 6686 } 6687 updateOomAdjLocked(); 6688 } 6689 } 6690 6691 @Override 6692 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6693 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6694 "setProcessForeground()"); 6695 synchronized(this) { 6696 boolean changed = false; 6697 6698 synchronized (mPidsSelfLocked) { 6699 ProcessRecord pr = mPidsSelfLocked.get(pid); 6700 if (pr == null && isForeground) { 6701 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6702 return; 6703 } 6704 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6705 if (oldToken != null) { 6706 oldToken.token.unlinkToDeath(oldToken, 0); 6707 mForegroundProcesses.remove(pid); 6708 if (pr != null) { 6709 pr.forcingToForeground = null; 6710 } 6711 changed = true; 6712 } 6713 if (isForeground && token != null) { 6714 ForegroundToken newToken = new ForegroundToken() { 6715 @Override 6716 public void binderDied() { 6717 foregroundTokenDied(this); 6718 } 6719 }; 6720 newToken.pid = pid; 6721 newToken.token = token; 6722 try { 6723 token.linkToDeath(newToken, 0); 6724 mForegroundProcesses.put(pid, newToken); 6725 pr.forcingToForeground = token; 6726 changed = true; 6727 } catch (RemoteException e) { 6728 // If the process died while doing this, we will later 6729 // do the cleanup with the process death link. 6730 } 6731 } 6732 } 6733 6734 if (changed) { 6735 updateOomAdjLocked(); 6736 } 6737 } 6738 } 6739 6740 // ========================================================= 6741 // PERMISSIONS 6742 // ========================================================= 6743 6744 static class PermissionController extends IPermissionController.Stub { 6745 ActivityManagerService mActivityManagerService; 6746 PermissionController(ActivityManagerService activityManagerService) { 6747 mActivityManagerService = activityManagerService; 6748 } 6749 6750 @Override 6751 public boolean checkPermission(String permission, int pid, int uid) { 6752 return mActivityManagerService.checkPermission(permission, pid, 6753 uid) == PackageManager.PERMISSION_GRANTED; 6754 } 6755 } 6756 6757 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6758 @Override 6759 public int checkComponentPermission(String permission, int pid, int uid, 6760 int owningUid, boolean exported) { 6761 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6762 owningUid, exported); 6763 } 6764 6765 @Override 6766 public Object getAMSLock() { 6767 return ActivityManagerService.this; 6768 } 6769 } 6770 6771 /** 6772 * This can be called with or without the global lock held. 6773 */ 6774 int checkComponentPermission(String permission, int pid, int uid, 6775 int owningUid, boolean exported) { 6776 // We might be performing an operation on behalf of an indirect binder 6777 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6778 // client identity accordingly before proceeding. 6779 Identity tlsIdentity = sCallerIdentity.get(); 6780 if (tlsIdentity != null) { 6781 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6782 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6783 uid = tlsIdentity.uid; 6784 pid = tlsIdentity.pid; 6785 } 6786 6787 if (pid == MY_PID) { 6788 return PackageManager.PERMISSION_GRANTED; 6789 } 6790 6791 return ActivityManager.checkComponentPermission(permission, uid, 6792 owningUid, exported); 6793 } 6794 6795 /** 6796 * As the only public entry point for permissions checking, this method 6797 * can enforce the semantic that requesting a check on a null global 6798 * permission is automatically denied. (Internally a null permission 6799 * string is used when calling {@link #checkComponentPermission} in cases 6800 * when only uid-based security is needed.) 6801 * 6802 * This can be called with or without the global lock held. 6803 */ 6804 @Override 6805 public int checkPermission(String permission, int pid, int uid) { 6806 if (permission == null) { 6807 return PackageManager.PERMISSION_DENIED; 6808 } 6809 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6810 } 6811 6812 /** 6813 * Binder IPC calls go through the public entry point. 6814 * This can be called with or without the global lock held. 6815 */ 6816 int checkCallingPermission(String permission) { 6817 return checkPermission(permission, 6818 Binder.getCallingPid(), 6819 UserHandle.getAppId(Binder.getCallingUid())); 6820 } 6821 6822 /** 6823 * This can be called with or without the global lock held. 6824 */ 6825 void enforceCallingPermission(String permission, String func) { 6826 if (checkCallingPermission(permission) 6827 == PackageManager.PERMISSION_GRANTED) { 6828 return; 6829 } 6830 6831 String msg = "Permission Denial: " + func + " from pid=" 6832 + Binder.getCallingPid() 6833 + ", uid=" + Binder.getCallingUid() 6834 + " requires " + permission; 6835 Slog.w(TAG, msg); 6836 throw new SecurityException(msg); 6837 } 6838 6839 /** 6840 * Determine if UID is holding permissions required to access {@link Uri} in 6841 * the given {@link ProviderInfo}. Final permission checking is always done 6842 * in {@link ContentProvider}. 6843 */ 6844 private final boolean checkHoldingPermissionsLocked( 6845 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6846 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6847 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6848 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6849 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true) 6850 != PERMISSION_GRANTED) { 6851 return false; 6852 } 6853 } 6854 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6855 } 6856 6857 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6858 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6859 if (pi.applicationInfo.uid == uid) { 6860 return true; 6861 } else if (!pi.exported) { 6862 return false; 6863 } 6864 6865 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6866 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6867 try { 6868 // check if target holds top-level <provider> permissions 6869 if (!readMet && pi.readPermission != null && considerUidPermissions 6870 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6871 readMet = true; 6872 } 6873 if (!writeMet && pi.writePermission != null && considerUidPermissions 6874 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6875 writeMet = true; 6876 } 6877 6878 // track if unprotected read/write is allowed; any denied 6879 // <path-permission> below removes this ability 6880 boolean allowDefaultRead = pi.readPermission == null; 6881 boolean allowDefaultWrite = pi.writePermission == null; 6882 6883 // check if target holds any <path-permission> that match uri 6884 final PathPermission[] pps = pi.pathPermissions; 6885 if (pps != null) { 6886 final String path = grantUri.uri.getPath(); 6887 int i = pps.length; 6888 while (i > 0 && (!readMet || !writeMet)) { 6889 i--; 6890 PathPermission pp = pps[i]; 6891 if (pp.match(path)) { 6892 if (!readMet) { 6893 final String pprperm = pp.getReadPermission(); 6894 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6895 + pprperm + " for " + pp.getPath() 6896 + ": match=" + pp.match(path) 6897 + " check=" + pm.checkUidPermission(pprperm, uid)); 6898 if (pprperm != null) { 6899 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6900 == PERMISSION_GRANTED) { 6901 readMet = true; 6902 } else { 6903 allowDefaultRead = false; 6904 } 6905 } 6906 } 6907 if (!writeMet) { 6908 final String ppwperm = pp.getWritePermission(); 6909 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6910 + ppwperm + " for " + pp.getPath() 6911 + ": match=" + pp.match(path) 6912 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6913 if (ppwperm != null) { 6914 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6915 == PERMISSION_GRANTED) { 6916 writeMet = true; 6917 } else { 6918 allowDefaultWrite = false; 6919 } 6920 } 6921 } 6922 } 6923 } 6924 } 6925 6926 // grant unprotected <provider> read/write, if not blocked by 6927 // <path-permission> above 6928 if (allowDefaultRead) readMet = true; 6929 if (allowDefaultWrite) writeMet = true; 6930 6931 } catch (RemoteException e) { 6932 return false; 6933 } 6934 6935 return readMet && writeMet; 6936 } 6937 6938 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6939 ProviderInfo pi = null; 6940 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6941 if (cpr != null) { 6942 pi = cpr.info; 6943 } else { 6944 try { 6945 pi = AppGlobals.getPackageManager().resolveContentProvider( 6946 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6947 } catch (RemoteException ex) { 6948 } 6949 } 6950 return pi; 6951 } 6952 6953 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6954 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6955 if (targetUris != null) { 6956 return targetUris.get(grantUri); 6957 } 6958 return null; 6959 } 6960 6961 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6962 String targetPkg, int targetUid, GrantUri grantUri) { 6963 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6964 if (targetUris == null) { 6965 targetUris = Maps.newArrayMap(); 6966 mGrantedUriPermissions.put(targetUid, targetUris); 6967 } 6968 6969 UriPermission perm = targetUris.get(grantUri); 6970 if (perm == null) { 6971 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6972 targetUris.put(grantUri, perm); 6973 } 6974 6975 return perm; 6976 } 6977 6978 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6979 final int modeFlags) { 6980 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6981 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6982 : UriPermission.STRENGTH_OWNED; 6983 6984 // Root gets to do everything. 6985 if (uid == 0) { 6986 return true; 6987 } 6988 6989 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6990 if (perms == null) return false; 6991 6992 // First look for exact match 6993 final UriPermission exactPerm = perms.get(grantUri); 6994 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6995 return true; 6996 } 6997 6998 // No exact match, look for prefixes 6999 final int N = perms.size(); 7000 for (int i = 0; i < N; i++) { 7001 final UriPermission perm = perms.valueAt(i); 7002 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 7003 && perm.getStrength(modeFlags) >= minStrength) { 7004 return true; 7005 } 7006 } 7007 7008 return false; 7009 } 7010 7011 /** 7012 * @param uri This uri must NOT contain an embedded userId. 7013 * @param userId The userId in which the uri is to be resolved. 7014 */ 7015 @Override 7016 public int checkUriPermission(Uri uri, int pid, int uid, 7017 final int modeFlags, int userId) { 7018 enforceNotIsolatedCaller("checkUriPermission"); 7019 7020 // Another redirected-binder-call permissions check as in 7021 // {@link checkComponentPermission}. 7022 Identity tlsIdentity = sCallerIdentity.get(); 7023 if (tlsIdentity != null) { 7024 uid = tlsIdentity.uid; 7025 pid = tlsIdentity.pid; 7026 } 7027 7028 // Our own process gets to do everything. 7029 if (pid == MY_PID) { 7030 return PackageManager.PERMISSION_GRANTED; 7031 } 7032 synchronized (this) { 7033 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 7034 ? PackageManager.PERMISSION_GRANTED 7035 : PackageManager.PERMISSION_DENIED; 7036 } 7037 } 7038 7039 /** 7040 * Check if the targetPkg can be granted permission to access uri by 7041 * the callingUid using the given modeFlags. Throws a security exception 7042 * if callingUid is not allowed to do this. Returns the uid of the target 7043 * if the URI permission grant should be performed; returns -1 if it is not 7044 * needed (for example targetPkg already has permission to access the URI). 7045 * If you already know the uid of the target, you can supply it in 7046 * lastTargetUid else set that to -1. 7047 */ 7048 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7049 final int modeFlags, int lastTargetUid) { 7050 if (!Intent.isAccessUriMode(modeFlags)) { 7051 return -1; 7052 } 7053 7054 if (targetPkg != null) { 7055 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7056 "Checking grant " + targetPkg + " permission to " + grantUri); 7057 } 7058 7059 final IPackageManager pm = AppGlobals.getPackageManager(); 7060 7061 // If this is not a content: uri, we can't do anything with it. 7062 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 7063 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7064 "Can't grant URI permission for non-content URI: " + grantUri); 7065 return -1; 7066 } 7067 7068 final String authority = grantUri.uri.getAuthority(); 7069 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7070 if (pi == null) { 7071 Slog.w(TAG, "No content provider found for permission check: " + 7072 grantUri.uri.toSafeString()); 7073 return -1; 7074 } 7075 7076 int targetUid = lastTargetUid; 7077 if (targetUid < 0 && targetPkg != null) { 7078 try { 7079 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 7080 if (targetUid < 0) { 7081 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7082 "Can't grant URI permission no uid for: " + targetPkg); 7083 return -1; 7084 } 7085 } catch (RemoteException ex) { 7086 return -1; 7087 } 7088 } 7089 7090 if (targetUid >= 0) { 7091 // First... does the target actually need this permission? 7092 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 7093 // No need to grant the target this permission. 7094 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7095 "Target " + targetPkg + " already has full permission to " + grantUri); 7096 return -1; 7097 } 7098 } else { 7099 // First... there is no target package, so can anyone access it? 7100 boolean allowed = pi.exported; 7101 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 7102 if (pi.readPermission != null) { 7103 allowed = false; 7104 } 7105 } 7106 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 7107 if (pi.writePermission != null) { 7108 allowed = false; 7109 } 7110 } 7111 if (allowed) { 7112 return -1; 7113 } 7114 } 7115 7116 /* There is a special cross user grant if: 7117 * - The target is on another user. 7118 * - Apps on the current user can access the uri without any uid permissions. 7119 * In this case, we grant a uri permission, even if the ContentProvider does not normally 7120 * grant uri permissions. 7121 */ 7122 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 7123 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 7124 modeFlags, false /*without considering the uid permissions*/); 7125 7126 // Second... is the provider allowing granting of URI permissions? 7127 if (!specialCrossUserGrant) { 7128 if (!pi.grantUriPermissions) { 7129 throw new SecurityException("Provider " + pi.packageName 7130 + "/" + pi.name 7131 + " does not allow granting of Uri permissions (uri " 7132 + grantUri + ")"); 7133 } 7134 if (pi.uriPermissionPatterns != null) { 7135 final int N = pi.uriPermissionPatterns.length; 7136 boolean allowed = false; 7137 for (int i=0; i<N; i++) { 7138 if (pi.uriPermissionPatterns[i] != null 7139 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 7140 allowed = true; 7141 break; 7142 } 7143 } 7144 if (!allowed) { 7145 throw new SecurityException("Provider " + pi.packageName 7146 + "/" + pi.name 7147 + " does not allow granting of permission to path of Uri " 7148 + grantUri); 7149 } 7150 } 7151 } 7152 7153 // Third... does the caller itself have permission to access 7154 // this uri? 7155 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 7156 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7157 // Require they hold a strong enough Uri permission 7158 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 7159 throw new SecurityException("Uid " + callingUid 7160 + " does not have permission to uri " + grantUri); 7161 } 7162 } 7163 } 7164 return targetUid; 7165 } 7166 7167 /** 7168 * @param uri This uri must NOT contain an embedded userId. 7169 * @param userId The userId in which the uri is to be resolved. 7170 */ 7171 @Override 7172 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 7173 final int modeFlags, int userId) { 7174 enforceNotIsolatedCaller("checkGrantUriPermission"); 7175 synchronized(this) { 7176 return checkGrantUriPermissionLocked(callingUid, targetPkg, 7177 new GrantUri(userId, uri, false), modeFlags, -1); 7178 } 7179 } 7180 7181 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 7182 final int modeFlags, UriPermissionOwner owner) { 7183 if (!Intent.isAccessUriMode(modeFlags)) { 7184 return; 7185 } 7186 7187 // So here we are: the caller has the assumed permission 7188 // to the uri, and the target doesn't. Let's now give this to 7189 // the target. 7190 7191 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7192 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 7193 7194 final String authority = grantUri.uri.getAuthority(); 7195 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7196 if (pi == null) { 7197 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 7198 return; 7199 } 7200 7201 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 7202 grantUri.prefix = true; 7203 } 7204 final UriPermission perm = findOrCreateUriPermissionLocked( 7205 pi.packageName, targetPkg, targetUid, grantUri); 7206 perm.grantModes(modeFlags, owner); 7207 } 7208 7209 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 7210 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 7211 if (targetPkg == null) { 7212 throw new NullPointerException("targetPkg"); 7213 } 7214 int targetUid; 7215 final IPackageManager pm = AppGlobals.getPackageManager(); 7216 try { 7217 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7218 } catch (RemoteException ex) { 7219 return; 7220 } 7221 7222 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 7223 targetUid); 7224 if (targetUid < 0) { 7225 return; 7226 } 7227 7228 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 7229 owner); 7230 } 7231 7232 static class NeededUriGrants extends ArrayList<GrantUri> { 7233 final String targetPkg; 7234 final int targetUid; 7235 final int flags; 7236 7237 NeededUriGrants(String targetPkg, int targetUid, int flags) { 7238 this.targetPkg = targetPkg; 7239 this.targetUid = targetUid; 7240 this.flags = flags; 7241 } 7242 } 7243 7244 /** 7245 * Like checkGrantUriPermissionLocked, but takes an Intent. 7246 */ 7247 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 7248 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 7249 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7250 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 7251 + " clip=" + (intent != null ? intent.getClipData() : null) 7252 + " from " + intent + "; flags=0x" 7253 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 7254 7255 if (targetPkg == null) { 7256 throw new NullPointerException("targetPkg"); 7257 } 7258 7259 if (intent == null) { 7260 return null; 7261 } 7262 Uri data = intent.getData(); 7263 ClipData clip = intent.getClipData(); 7264 if (data == null && clip == null) { 7265 return null; 7266 } 7267 // Default userId for uris in the intent (if they don't specify it themselves) 7268 int contentUserHint = intent.getContentUserHint(); 7269 if (contentUserHint == UserHandle.USER_CURRENT) { 7270 contentUserHint = UserHandle.getUserId(callingUid); 7271 } 7272 final IPackageManager pm = AppGlobals.getPackageManager(); 7273 int targetUid; 7274 if (needed != null) { 7275 targetUid = needed.targetUid; 7276 } else { 7277 try { 7278 targetUid = pm.getPackageUid(targetPkg, targetUserId); 7279 } catch (RemoteException ex) { 7280 return null; 7281 } 7282 if (targetUid < 0) { 7283 if (DEBUG_URI_PERMISSION) { 7284 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 7285 + " on user " + targetUserId); 7286 } 7287 return null; 7288 } 7289 } 7290 if (data != null) { 7291 GrantUri grantUri = GrantUri.resolve(contentUserHint, data); 7292 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7293 targetUid); 7294 if (targetUid > 0) { 7295 if (needed == null) { 7296 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7297 } 7298 needed.add(grantUri); 7299 } 7300 } 7301 if (clip != null) { 7302 for (int i=0; i<clip.getItemCount(); i++) { 7303 Uri uri = clip.getItemAt(i).getUri(); 7304 if (uri != null) { 7305 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri); 7306 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 7307 targetUid); 7308 if (targetUid > 0) { 7309 if (needed == null) { 7310 needed = new NeededUriGrants(targetPkg, targetUid, mode); 7311 } 7312 needed.add(grantUri); 7313 } 7314 } else { 7315 Intent clipIntent = clip.getItemAt(i).getIntent(); 7316 if (clipIntent != null) { 7317 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 7318 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 7319 if (newNeeded != null) { 7320 needed = newNeeded; 7321 } 7322 } 7323 } 7324 } 7325 } 7326 7327 return needed; 7328 } 7329 7330 /** 7331 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 7332 */ 7333 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 7334 UriPermissionOwner owner) { 7335 if (needed != null) { 7336 for (int i=0; i<needed.size(); i++) { 7337 GrantUri grantUri = needed.get(i); 7338 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 7339 grantUri, needed.flags, owner); 7340 } 7341 } 7342 } 7343 7344 void grantUriPermissionFromIntentLocked(int callingUid, 7345 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 7346 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 7347 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 7348 if (needed == null) { 7349 return; 7350 } 7351 7352 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 7353 } 7354 7355 /** 7356 * @param uri This uri must NOT contain an embedded userId. 7357 * @param userId The userId in which the uri is to be resolved. 7358 */ 7359 @Override 7360 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 7361 final int modeFlags, int userId) { 7362 enforceNotIsolatedCaller("grantUriPermission"); 7363 GrantUri grantUri = new GrantUri(userId, uri, false); 7364 synchronized(this) { 7365 final ProcessRecord r = getRecordForAppLocked(caller); 7366 if (r == null) { 7367 throw new SecurityException("Unable to find app for caller " 7368 + caller 7369 + " when granting permission to uri " + grantUri); 7370 } 7371 if (targetPkg == null) { 7372 throw new IllegalArgumentException("null target"); 7373 } 7374 if (grantUri == null) { 7375 throw new IllegalArgumentException("null uri"); 7376 } 7377 7378 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 7379 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 7380 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 7381 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 7382 7383 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 7384 UserHandle.getUserId(r.uid)); 7385 } 7386 } 7387 7388 void removeUriPermissionIfNeededLocked(UriPermission perm) { 7389 if (perm.modeFlags == 0) { 7390 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7391 perm.targetUid); 7392 if (perms != null) { 7393 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 7394 "Removing " + perm.targetUid + " permission to " + perm.uri); 7395 7396 perms.remove(perm.uri); 7397 if (perms.isEmpty()) { 7398 mGrantedUriPermissions.remove(perm.targetUid); 7399 } 7400 } 7401 } 7402 } 7403 7404 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 7405 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 7406 7407 final IPackageManager pm = AppGlobals.getPackageManager(); 7408 final String authority = grantUri.uri.getAuthority(); 7409 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 7410 if (pi == null) { 7411 Slog.w(TAG, "No content provider found for permission revoke: " 7412 + grantUri.toSafeString()); 7413 return; 7414 } 7415 7416 // Does the caller have this permission on the URI? 7417 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 7418 // Right now, if you are not the original owner of the permission, 7419 // you are not allowed to revoke it. 7420 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 7421 throw new SecurityException("Uid " + callingUid 7422 + " does not have permission to uri " + grantUri); 7423 //} 7424 } 7425 7426 boolean persistChanged = false; 7427 7428 // Go through all of the permissions and remove any that match. 7429 int N = mGrantedUriPermissions.size(); 7430 for (int i = 0; i < N; i++) { 7431 final int targetUid = mGrantedUriPermissions.keyAt(i); 7432 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7433 7434 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7435 final UriPermission perm = it.next(); 7436 if (perm.uri.sourceUserId == grantUri.sourceUserId 7437 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 7438 if (DEBUG_URI_PERMISSION) 7439 Slog.v(TAG, 7440 "Revoking " + perm.targetUid + " permission to " + perm.uri); 7441 persistChanged |= perm.revokeModes( 7442 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7443 if (perm.modeFlags == 0) { 7444 it.remove(); 7445 } 7446 } 7447 } 7448 7449 if (perms.isEmpty()) { 7450 mGrantedUriPermissions.remove(targetUid); 7451 N--; 7452 i--; 7453 } 7454 } 7455 7456 if (persistChanged) { 7457 schedulePersistUriGrants(); 7458 } 7459 } 7460 7461 /** 7462 * @param uri This uri must NOT contain an embedded userId. 7463 * @param userId The userId in which the uri is to be resolved. 7464 */ 7465 @Override 7466 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 7467 int userId) { 7468 enforceNotIsolatedCaller("revokeUriPermission"); 7469 synchronized(this) { 7470 final ProcessRecord r = getRecordForAppLocked(caller); 7471 if (r == null) { 7472 throw new SecurityException("Unable to find app for caller " 7473 + caller 7474 + " when revoking permission to uri " + uri); 7475 } 7476 if (uri == null) { 7477 Slog.w(TAG, "revokeUriPermission: null uri"); 7478 return; 7479 } 7480 7481 if (!Intent.isAccessUriMode(modeFlags)) { 7482 return; 7483 } 7484 7485 final IPackageManager pm = AppGlobals.getPackageManager(); 7486 final String authority = uri.getAuthority(); 7487 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 7488 if (pi == null) { 7489 Slog.w(TAG, "No content provider found for permission revoke: " 7490 + uri.toSafeString()); 7491 return; 7492 } 7493 7494 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 7495 } 7496 } 7497 7498 /** 7499 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 7500 * given package. 7501 * 7502 * @param packageName Package name to match, or {@code null} to apply to all 7503 * packages. 7504 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 7505 * to all users. 7506 * @param persistable If persistable grants should be removed. 7507 */ 7508 private void removeUriPermissionsForPackageLocked( 7509 String packageName, int userHandle, boolean persistable) { 7510 if (userHandle == UserHandle.USER_ALL && packageName == null) { 7511 throw new IllegalArgumentException("Must narrow by either package or user"); 7512 } 7513 7514 boolean persistChanged = false; 7515 7516 int N = mGrantedUriPermissions.size(); 7517 for (int i = 0; i < N; i++) { 7518 final int targetUid = mGrantedUriPermissions.keyAt(i); 7519 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7520 7521 // Only inspect grants matching user 7522 if (userHandle == UserHandle.USER_ALL 7523 || userHandle == UserHandle.getUserId(targetUid)) { 7524 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 7525 final UriPermission perm = it.next(); 7526 7527 // Only inspect grants matching package 7528 if (packageName == null || perm.sourcePkg.equals(packageName) 7529 || perm.targetPkg.equals(packageName)) { 7530 persistChanged |= perm.revokeModes( 7531 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 7532 7533 // Only remove when no modes remain; any persisted grants 7534 // will keep this alive. 7535 if (perm.modeFlags == 0) { 7536 it.remove(); 7537 } 7538 } 7539 } 7540 7541 if (perms.isEmpty()) { 7542 mGrantedUriPermissions.remove(targetUid); 7543 N--; 7544 i--; 7545 } 7546 } 7547 } 7548 7549 if (persistChanged) { 7550 schedulePersistUriGrants(); 7551 } 7552 } 7553 7554 @Override 7555 public IBinder newUriPermissionOwner(String name) { 7556 enforceNotIsolatedCaller("newUriPermissionOwner"); 7557 synchronized(this) { 7558 UriPermissionOwner owner = new UriPermissionOwner(this, name); 7559 return owner.getExternalTokenLocked(); 7560 } 7561 } 7562 7563 /** 7564 * @param uri This uri must NOT contain an embedded userId. 7565 * @param sourceUserId The userId in which the uri is to be resolved. 7566 * @param targetUserId The userId of the app that receives the grant. 7567 */ 7568 @Override 7569 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 7570 final int modeFlags, int sourceUserId, int targetUserId) { 7571 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 7572 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null); 7573 synchronized(this) { 7574 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7575 if (owner == null) { 7576 throw new IllegalArgumentException("Unknown owner: " + token); 7577 } 7578 if (fromUid != Binder.getCallingUid()) { 7579 if (Binder.getCallingUid() != Process.myUid()) { 7580 // Only system code can grant URI permissions on behalf 7581 // of other users. 7582 throw new SecurityException("nice try"); 7583 } 7584 } 7585 if (targetPkg == null) { 7586 throw new IllegalArgumentException("null target"); 7587 } 7588 if (uri == null) { 7589 throw new IllegalArgumentException("null uri"); 7590 } 7591 7592 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 7593 modeFlags, owner, targetUserId); 7594 } 7595 } 7596 7597 /** 7598 * @param uri This uri must NOT contain an embedded userId. 7599 * @param userId The userId in which the uri is to be resolved. 7600 */ 7601 @Override 7602 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 7603 synchronized(this) { 7604 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 7605 if (owner == null) { 7606 throw new IllegalArgumentException("Unknown owner: " + token); 7607 } 7608 7609 if (uri == null) { 7610 owner.removeUriPermissionsLocked(mode); 7611 } else { 7612 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 7613 } 7614 } 7615 } 7616 7617 private void schedulePersistUriGrants() { 7618 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 7619 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 7620 10 * DateUtils.SECOND_IN_MILLIS); 7621 } 7622 } 7623 7624 private void writeGrantedUriPermissions() { 7625 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 7626 7627 // Snapshot permissions so we can persist without lock 7628 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 7629 synchronized (this) { 7630 final int size = mGrantedUriPermissions.size(); 7631 for (int i = 0; i < size; i++) { 7632 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 7633 for (UriPermission perm : perms.values()) { 7634 if (perm.persistedModeFlags != 0) { 7635 persist.add(perm.snapshot()); 7636 } 7637 } 7638 } 7639 } 7640 7641 FileOutputStream fos = null; 7642 try { 7643 fos = mGrantFile.startWrite(); 7644 7645 XmlSerializer out = new FastXmlSerializer(); 7646 out.setOutput(fos, "utf-8"); 7647 out.startDocument(null, true); 7648 out.startTag(null, TAG_URI_GRANTS); 7649 for (UriPermission.Snapshot perm : persist) { 7650 out.startTag(null, TAG_URI_GRANT); 7651 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 7652 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 7653 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 7654 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 7655 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 7656 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 7657 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 7658 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 7659 out.endTag(null, TAG_URI_GRANT); 7660 } 7661 out.endTag(null, TAG_URI_GRANTS); 7662 out.endDocument(); 7663 7664 mGrantFile.finishWrite(fos); 7665 } catch (IOException e) { 7666 if (fos != null) { 7667 mGrantFile.failWrite(fos); 7668 } 7669 } 7670 } 7671 7672 private void readGrantedUriPermissionsLocked() { 7673 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7674 7675 final long now = System.currentTimeMillis(); 7676 7677 FileInputStream fis = null; 7678 try { 7679 fis = mGrantFile.openRead(); 7680 final XmlPullParser in = Xml.newPullParser(); 7681 in.setInput(fis, null); 7682 7683 int type; 7684 while ((type = in.next()) != END_DOCUMENT) { 7685 final String tag = in.getName(); 7686 if (type == START_TAG) { 7687 if (TAG_URI_GRANT.equals(tag)) { 7688 final int sourceUserId; 7689 final int targetUserId; 7690 final int userHandle = readIntAttribute(in, 7691 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7692 if (userHandle != UserHandle.USER_NULL) { 7693 // For backwards compatibility. 7694 sourceUserId = userHandle; 7695 targetUserId = userHandle; 7696 } else { 7697 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7698 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7699 } 7700 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7701 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7702 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7703 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7704 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7705 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7706 7707 // Sanity check that provider still belongs to source package 7708 final ProviderInfo pi = getProviderInfoLocked( 7709 uri.getAuthority(), sourceUserId); 7710 if (pi != null && sourcePkg.equals(pi.packageName)) { 7711 int targetUid = -1; 7712 try { 7713 targetUid = AppGlobals.getPackageManager() 7714 .getPackageUid(targetPkg, targetUserId); 7715 } catch (RemoteException e) { 7716 } 7717 if (targetUid != -1) { 7718 final UriPermission perm = findOrCreateUriPermissionLocked( 7719 sourcePkg, targetPkg, targetUid, 7720 new GrantUri(sourceUserId, uri, prefix)); 7721 perm.initPersistedModes(modeFlags, createdTime); 7722 } 7723 } else { 7724 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7725 + " but instead found " + pi); 7726 } 7727 } 7728 } 7729 } 7730 } catch (FileNotFoundException e) { 7731 // Missing grants is okay 7732 } catch (IOException e) { 7733 Log.wtf(TAG, "Failed reading Uri grants", e); 7734 } catch (XmlPullParserException e) { 7735 Log.wtf(TAG, "Failed reading Uri grants", e); 7736 } finally { 7737 IoUtils.closeQuietly(fis); 7738 } 7739 } 7740 7741 /** 7742 * @param uri This uri must NOT contain an embedded userId. 7743 * @param userId The userId in which the uri is to be resolved. 7744 */ 7745 @Override 7746 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7747 enforceNotIsolatedCaller("takePersistableUriPermission"); 7748 7749 Preconditions.checkFlagsArgument(modeFlags, 7750 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7751 7752 synchronized (this) { 7753 final int callingUid = Binder.getCallingUid(); 7754 boolean persistChanged = false; 7755 GrantUri grantUri = new GrantUri(userId, uri, false); 7756 7757 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7758 new GrantUri(userId, uri, false)); 7759 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7760 new GrantUri(userId, uri, true)); 7761 7762 final boolean exactValid = (exactPerm != null) 7763 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7764 final boolean prefixValid = (prefixPerm != null) 7765 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7766 7767 if (!(exactValid || prefixValid)) { 7768 throw new SecurityException("No persistable permission grants found for UID " 7769 + callingUid + " and Uri " + grantUri.toSafeString()); 7770 } 7771 7772 if (exactValid) { 7773 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7774 } 7775 if (prefixValid) { 7776 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7777 } 7778 7779 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7780 7781 if (persistChanged) { 7782 schedulePersistUriGrants(); 7783 } 7784 } 7785 } 7786 7787 /** 7788 * @param uri This uri must NOT contain an embedded userId. 7789 * @param userId The userId in which the uri is to be resolved. 7790 */ 7791 @Override 7792 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7793 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7794 7795 Preconditions.checkFlagsArgument(modeFlags, 7796 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7797 7798 synchronized (this) { 7799 final int callingUid = Binder.getCallingUid(); 7800 boolean persistChanged = false; 7801 7802 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7803 new GrantUri(userId, uri, false)); 7804 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7805 new GrantUri(userId, uri, true)); 7806 if (exactPerm == null && prefixPerm == null) { 7807 throw new SecurityException("No permission grants found for UID " + callingUid 7808 + " and Uri " + uri.toSafeString()); 7809 } 7810 7811 if (exactPerm != null) { 7812 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7813 removeUriPermissionIfNeededLocked(exactPerm); 7814 } 7815 if (prefixPerm != null) { 7816 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7817 removeUriPermissionIfNeededLocked(prefixPerm); 7818 } 7819 7820 if (persistChanged) { 7821 schedulePersistUriGrants(); 7822 } 7823 } 7824 } 7825 7826 /** 7827 * Prune any older {@link UriPermission} for the given UID until outstanding 7828 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7829 * 7830 * @return if any mutations occured that require persisting. 7831 */ 7832 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7833 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7834 if (perms == null) return false; 7835 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7836 7837 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7838 for (UriPermission perm : perms.values()) { 7839 if (perm.persistedModeFlags != 0) { 7840 persisted.add(perm); 7841 } 7842 } 7843 7844 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7845 if (trimCount <= 0) return false; 7846 7847 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7848 for (int i = 0; i < trimCount; i++) { 7849 final UriPermission perm = persisted.get(i); 7850 7851 if (DEBUG_URI_PERMISSION) { 7852 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7853 } 7854 7855 perm.releasePersistableModes(~0); 7856 removeUriPermissionIfNeededLocked(perm); 7857 } 7858 7859 return true; 7860 } 7861 7862 @Override 7863 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7864 String packageName, boolean incoming) { 7865 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7866 Preconditions.checkNotNull(packageName, "packageName"); 7867 7868 final int callingUid = Binder.getCallingUid(); 7869 final IPackageManager pm = AppGlobals.getPackageManager(); 7870 try { 7871 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7872 if (packageUid != callingUid) { 7873 throw new SecurityException( 7874 "Package " + packageName + " does not belong to calling UID " + callingUid); 7875 } 7876 } catch (RemoteException e) { 7877 throw new SecurityException("Failed to verify package name ownership"); 7878 } 7879 7880 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7881 synchronized (this) { 7882 if (incoming) { 7883 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7884 callingUid); 7885 if (perms == null) { 7886 Slog.w(TAG, "No permission grants found for " + packageName); 7887 } else { 7888 for (UriPermission perm : perms.values()) { 7889 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7890 result.add(perm.buildPersistedPublicApiObject()); 7891 } 7892 } 7893 } 7894 } else { 7895 final int size = mGrantedUriPermissions.size(); 7896 for (int i = 0; i < size; i++) { 7897 final ArrayMap<GrantUri, UriPermission> perms = 7898 mGrantedUriPermissions.valueAt(i); 7899 for (UriPermission perm : perms.values()) { 7900 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7901 result.add(perm.buildPersistedPublicApiObject()); 7902 } 7903 } 7904 } 7905 } 7906 } 7907 return new ParceledListSlice<android.content.UriPermission>(result); 7908 } 7909 7910 @Override 7911 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7912 synchronized (this) { 7913 ProcessRecord app = 7914 who != null ? getRecordForAppLocked(who) : null; 7915 if (app == null) return; 7916 7917 Message msg = Message.obtain(); 7918 msg.what = WAIT_FOR_DEBUGGER_MSG; 7919 msg.obj = app; 7920 msg.arg1 = waiting ? 1 : 0; 7921 mHandler.sendMessage(msg); 7922 } 7923 } 7924 7925 @Override 7926 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7927 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7928 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7929 outInfo.availMem = Process.getFreeMemory(); 7930 outInfo.totalMem = Process.getTotalMemory(); 7931 outInfo.threshold = homeAppMem; 7932 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7933 outInfo.hiddenAppThreshold = cachedAppMem; 7934 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7935 ProcessList.SERVICE_ADJ); 7936 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7937 ProcessList.VISIBLE_APP_ADJ); 7938 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7939 ProcessList.FOREGROUND_APP_ADJ); 7940 } 7941 7942 // ========================================================= 7943 // TASK MANAGEMENT 7944 // ========================================================= 7945 7946 @Override 7947 public List<IAppTask> getAppTasks(String callingPackage) { 7948 int callingUid = Binder.getCallingUid(); 7949 long ident = Binder.clearCallingIdentity(); 7950 7951 synchronized(this) { 7952 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7953 try { 7954 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7955 7956 final int N = mRecentTasks.size(); 7957 for (int i = 0; i < N; i++) { 7958 TaskRecord tr = mRecentTasks.get(i); 7959 // Skip tasks that do not match the caller. We don't need to verify 7960 // callingPackage, because we are also limiting to callingUid and know 7961 // that will limit to the correct security sandbox. 7962 if (tr.effectiveUid != callingUid) { 7963 continue; 7964 } 7965 Intent intent = tr.getBaseIntent(); 7966 if (intent == null || 7967 !callingPackage.equals(intent.getComponent().getPackageName())) { 7968 continue; 7969 } 7970 ActivityManager.RecentTaskInfo taskInfo = 7971 createRecentTaskInfoFromTaskRecord(tr); 7972 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7973 list.add(taskImpl); 7974 } 7975 } finally { 7976 Binder.restoreCallingIdentity(ident); 7977 } 7978 return list; 7979 } 7980 } 7981 7982 @Override 7983 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7984 final int callingUid = Binder.getCallingUid(); 7985 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7986 7987 synchronized(this) { 7988 if (localLOGV) Slog.v( 7989 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7990 7991 final boolean allowed = checkCallingPermission( 7992 android.Manifest.permission.GET_TASKS) 7993 == PackageManager.PERMISSION_GRANTED; 7994 if (!allowed) { 7995 Slog.w(TAG, "getTasks: caller " + callingUid 7996 + " does not hold GET_TASKS; limiting output"); 7997 } 7998 7999 // TODO: Improve with MRU list from all ActivityStacks. 8000 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 8001 } 8002 8003 return list; 8004 } 8005 8006 TaskRecord getMostRecentTask() { 8007 return mRecentTasks.get(0); 8008 } 8009 8010 /** 8011 * Creates a new RecentTaskInfo from a TaskRecord. 8012 */ 8013 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 8014 // Update the task description to reflect any changes in the task stack 8015 tr.updateTaskDescription(); 8016 8017 // Compose the recent task info 8018 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 8019 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 8020 rti.persistentId = tr.taskId; 8021 rti.baseIntent = new Intent(tr.getBaseIntent()); 8022 rti.origActivity = tr.origActivity; 8023 rti.description = tr.lastDescription; 8024 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 8025 rti.userId = tr.userId; 8026 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 8027 rti.firstActiveTime = tr.firstActiveTime; 8028 rti.lastActiveTime = tr.lastActiveTime; 8029 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 8030 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor; 8031 return rti; 8032 } 8033 8034 @Override 8035 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 8036 final int callingUid = Binder.getCallingUid(); 8037 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 8038 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 8039 8040 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 8041 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 8042 synchronized (this) { 8043 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 8044 == PackageManager.PERMISSION_GRANTED; 8045 if (!allowed) { 8046 Slog.w(TAG, "getRecentTasks: caller " + callingUid 8047 + " does not hold GET_TASKS; limiting output"); 8048 } 8049 final boolean detailed = checkCallingPermission( 8050 android.Manifest.permission.GET_DETAILED_TASKS) 8051 == PackageManager.PERMISSION_GRANTED; 8052 8053 final int N = mRecentTasks.size(); 8054 ArrayList<ActivityManager.RecentTaskInfo> res 8055 = new ArrayList<ActivityManager.RecentTaskInfo>( 8056 maxNum < N ? maxNum : N); 8057 8058 final Set<Integer> includedUsers; 8059 if (includeProfiles) { 8060 includedUsers = getProfileIdsLocked(userId); 8061 } else { 8062 includedUsers = new HashSet<Integer>(); 8063 } 8064 includedUsers.add(Integer.valueOf(userId)); 8065 8066 for (int i=0; i<N && maxNum > 0; i++) { 8067 TaskRecord tr = mRecentTasks.get(i); 8068 // Only add calling user or related users recent tasks 8069 if (!includedUsers.contains(Integer.valueOf(tr.userId))) { 8070 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr); 8071 continue; 8072 } 8073 8074 // Return the entry if desired by the caller. We always return 8075 // the first entry, because callers always expect this to be the 8076 // foreground app. We may filter others if the caller has 8077 // not supplied RECENT_WITH_EXCLUDED and there is some reason 8078 // we should exclude the entry. 8079 8080 if (i == 0 8081 || withExcluded 8082 || (tr.intent == null) 8083 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 8084 == 0)) { 8085 if (!allowed) { 8086 // If the caller doesn't have the GET_TASKS permission, then only 8087 // allow them to see a small subset of tasks -- their own and home. 8088 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) { 8089 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr); 8090 continue; 8091 } 8092 } 8093 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) { 8094 if (tr.stack != null && tr.stack.isHomeStack()) { 8095 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr); 8096 continue; 8097 } 8098 } 8099 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 8100 // Don't include auto remove tasks that are finished or finishing. 8101 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: " 8102 + tr); 8103 continue; 8104 } 8105 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0 8106 && !tr.isAvailable) { 8107 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr); 8108 continue; 8109 } 8110 8111 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 8112 if (!detailed) { 8113 rti.baseIntent.replaceExtras((Bundle)null); 8114 } 8115 8116 res.add(rti); 8117 maxNum--; 8118 } 8119 } 8120 return res; 8121 } 8122 } 8123 8124 private TaskRecord recentTaskForIdLocked(int id) { 8125 final int N = mRecentTasks.size(); 8126 for (int i=0; i<N; i++) { 8127 TaskRecord tr = mRecentTasks.get(i); 8128 if (tr.taskId == id) { 8129 return tr; 8130 } 8131 } 8132 return null; 8133 } 8134 8135 @Override 8136 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 8137 synchronized (this) { 8138 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 8139 "getTaskThumbnail()"); 8140 TaskRecord tr = recentTaskForIdLocked(id); 8141 if (tr != null) { 8142 return tr.getTaskThumbnailLocked(); 8143 } 8144 } 8145 return null; 8146 } 8147 8148 @Override 8149 public int addAppTask(IBinder activityToken, Intent intent, 8150 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException { 8151 final int callingUid = Binder.getCallingUid(); 8152 final long callingIdent = Binder.clearCallingIdentity(); 8153 8154 try { 8155 synchronized (this) { 8156 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken); 8157 if (r == null) { 8158 throw new IllegalArgumentException("Activity does not exist; token=" 8159 + activityToken); 8160 } 8161 ComponentName comp = intent.getComponent(); 8162 if (comp == null) { 8163 throw new IllegalArgumentException("Intent " + intent 8164 + " must specify explicit component"); 8165 } 8166 if (thumbnail.getWidth() != mThumbnailWidth 8167 || thumbnail.getHeight() != mThumbnailHeight) { 8168 throw new IllegalArgumentException("Bad thumbnail size: got " 8169 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require " 8170 + mThumbnailWidth + "x" + mThumbnailHeight); 8171 } 8172 if (intent.getSelector() != null) { 8173 intent.setSelector(null); 8174 } 8175 if (intent.getSourceBounds() != null) { 8176 intent.setSourceBounds(null); 8177 } 8178 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) { 8179 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) { 8180 // The caller has added this as an auto-remove task... that makes no 8181 // sense, so turn off auto-remove. 8182 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS); 8183 } 8184 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) { 8185 // Must be a new task. 8186 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 8187 } 8188 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) { 8189 mLastAddedTaskActivity = null; 8190 } 8191 ActivityInfo ainfo = mLastAddedTaskActivity; 8192 if (ainfo == null) { 8193 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo( 8194 comp, 0, UserHandle.getUserId(callingUid)); 8195 if (ainfo.applicationInfo.uid != callingUid) { 8196 throw new SecurityException( 8197 "Can't add task for another application: target uid=" 8198 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid); 8199 } 8200 } 8201 8202 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo, 8203 intent, description); 8204 8205 int trimIdx = trimRecentsForTask(task, false); 8206 if (trimIdx >= 0) { 8207 // If this would have caused a trim, then we'll abort because that 8208 // means it would be added at the end of the list but then just removed. 8209 return -1; 8210 } 8211 8212 final int N = mRecentTasks.size(); 8213 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) { 8214 final TaskRecord tr = mRecentTasks.remove(N - 1); 8215 tr.removedFromRecents(mTaskPersister); 8216 } 8217 8218 task.inRecents = true; 8219 mRecentTasks.add(task); 8220 r.task.stack.addTask(task, false, false); 8221 8222 task.setLastThumbnail(thumbnail); 8223 task.freeLastThumbnail(); 8224 8225 return task.taskId; 8226 } 8227 } finally { 8228 Binder.restoreCallingIdentity(callingIdent); 8229 } 8230 } 8231 8232 @Override 8233 public Point getAppTaskThumbnailSize() { 8234 synchronized (this) { 8235 return new Point(mThumbnailWidth, mThumbnailHeight); 8236 } 8237 } 8238 8239 @Override 8240 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 8241 synchronized (this) { 8242 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8243 if (r != null) { 8244 r.taskDescription = td; 8245 r.task.updateTaskDescription(); 8246 } 8247 } 8248 } 8249 8250 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 8251 mRecentTasks.remove(tr); 8252 tr.removedFromRecents(mTaskPersister); 8253 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 8254 Intent baseIntent = new Intent( 8255 tr.intent != null ? tr.intent : tr.affinityIntent); 8256 ComponentName component = baseIntent.getComponent(); 8257 if (component == null) { 8258 Slog.w(TAG, "Now component for base intent of task: " + tr); 8259 return; 8260 } 8261 8262 // Find any running services associated with this app. 8263 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 8264 8265 if (killProcesses) { 8266 // Find any running processes associated with this app. 8267 final String pkg = component.getPackageName(); 8268 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 8269 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 8270 for (int i=0; i<pmap.size(); i++) { 8271 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 8272 for (int j=0; j<uids.size(); j++) { 8273 ProcessRecord proc = uids.valueAt(j); 8274 if (proc.userId != tr.userId) { 8275 continue; 8276 } 8277 if (!proc.pkgList.containsKey(pkg)) { 8278 continue; 8279 } 8280 procs.add(proc); 8281 } 8282 } 8283 8284 // Kill the running processes. 8285 for (int i=0; i<procs.size(); i++) { 8286 ProcessRecord pr = procs.get(i); 8287 if (pr == mHomeProcess) { 8288 // Don't kill the home process along with tasks from the same package. 8289 continue; 8290 } 8291 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 8292 pr.kill("remove task", true); 8293 } else { 8294 pr.waitingToKill = "remove task"; 8295 } 8296 } 8297 } 8298 } 8299 8300 /** 8301 * Removes the task with the specified task id. 8302 * 8303 * @param taskId Identifier of the task to be removed. 8304 * @param flags Additional operational flags. May be 0 or 8305 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 8306 * @return Returns true if the given task was found and removed. 8307 */ 8308 private boolean removeTaskByIdLocked(int taskId, int flags) { 8309 TaskRecord tr = recentTaskForIdLocked(taskId); 8310 if (tr != null) { 8311 tr.removeTaskActivitiesLocked(); 8312 cleanUpRemovedTaskLocked(tr, flags); 8313 if (tr.isPersistable) { 8314 notifyTaskPersisterLocked(null, true); 8315 } 8316 return true; 8317 } 8318 return false; 8319 } 8320 8321 @Override 8322 public boolean removeTask(int taskId, int flags) { 8323 synchronized (this) { 8324 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 8325 "removeTask()"); 8326 long ident = Binder.clearCallingIdentity(); 8327 try { 8328 return removeTaskByIdLocked(taskId, flags); 8329 } finally { 8330 Binder.restoreCallingIdentity(ident); 8331 } 8332 } 8333 } 8334 8335 /** 8336 * TODO: Add mController hook 8337 */ 8338 @Override 8339 public void moveTaskToFront(int taskId, int flags, Bundle options) { 8340 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8341 "moveTaskToFront()"); 8342 8343 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 8344 synchronized(this) { 8345 moveTaskToFrontLocked(taskId, flags, options); 8346 } 8347 } 8348 8349 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) { 8350 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8351 Binder.getCallingUid(), "Task to front")) { 8352 ActivityOptions.abort(options); 8353 return; 8354 } 8355 final long origId = Binder.clearCallingIdentity(); 8356 try { 8357 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 8358 if (task == null) { 8359 return; 8360 } 8361 if (mStackSupervisor.isLockTaskModeViolation(task)) { 8362 mStackSupervisor.showLockTaskToast(); 8363 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 8364 return; 8365 } 8366 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 8367 if (prev != null && prev.isRecentsActivity()) { 8368 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 8369 } 8370 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 8371 } finally { 8372 Binder.restoreCallingIdentity(origId); 8373 } 8374 ActivityOptions.abort(options); 8375 } 8376 8377 @Override 8378 public void moveTaskToBack(int taskId) { 8379 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8380 "moveTaskToBack()"); 8381 8382 synchronized(this) { 8383 TaskRecord tr = recentTaskForIdLocked(taskId); 8384 if (tr != null) { 8385 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 8386 ActivityStack stack = tr.stack; 8387 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 8388 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8389 Binder.getCallingUid(), "Task to back")) { 8390 return; 8391 } 8392 } 8393 final long origId = Binder.clearCallingIdentity(); 8394 try { 8395 stack.moveTaskToBackLocked(taskId, null); 8396 } finally { 8397 Binder.restoreCallingIdentity(origId); 8398 } 8399 } 8400 } 8401 } 8402 8403 /** 8404 * Moves an activity, and all of the other activities within the same task, to the bottom 8405 * of the history stack. The activity's order within the task is unchanged. 8406 * 8407 * @param token A reference to the activity we wish to move 8408 * @param nonRoot If false then this only works if the activity is the root 8409 * of a task; if true it will work for any activity in a task. 8410 * @return Returns true if the move completed, false if not. 8411 */ 8412 @Override 8413 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 8414 enforceNotIsolatedCaller("moveActivityTaskToBack"); 8415 synchronized(this) { 8416 final long origId = Binder.clearCallingIdentity(); 8417 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 8418 if (taskId >= 0) { 8419 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 8420 } 8421 Binder.restoreCallingIdentity(origId); 8422 } 8423 return false; 8424 } 8425 8426 @Override 8427 public void moveTaskBackwards(int task) { 8428 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 8429 "moveTaskBackwards()"); 8430 8431 synchronized(this) { 8432 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 8433 Binder.getCallingUid(), "Task backwards")) { 8434 return; 8435 } 8436 final long origId = Binder.clearCallingIdentity(); 8437 moveTaskBackwardsLocked(task); 8438 Binder.restoreCallingIdentity(origId); 8439 } 8440 } 8441 8442 private final void moveTaskBackwardsLocked(int task) { 8443 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 8444 } 8445 8446 @Override 8447 public IBinder getHomeActivityToken() throws RemoteException { 8448 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8449 "getHomeActivityToken()"); 8450 synchronized (this) { 8451 return mStackSupervisor.getHomeActivityToken(); 8452 } 8453 } 8454 8455 @Override 8456 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 8457 IActivityContainerCallback callback) throws RemoteException { 8458 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8459 "createActivityContainer()"); 8460 synchronized (this) { 8461 if (parentActivityToken == null) { 8462 throw new IllegalArgumentException("parent token must not be null"); 8463 } 8464 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 8465 if (r == null) { 8466 return null; 8467 } 8468 if (callback == null) { 8469 throw new IllegalArgumentException("callback must not be null"); 8470 } 8471 return mStackSupervisor.createActivityContainer(r, callback); 8472 } 8473 } 8474 8475 @Override 8476 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 8477 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8478 "deleteActivityContainer()"); 8479 synchronized (this) { 8480 mStackSupervisor.deleteActivityContainer(container); 8481 } 8482 } 8483 8484 @Override 8485 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 8486 throws RemoteException { 8487 synchronized (this) { 8488 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 8489 if (stack != null) { 8490 return stack.mActivityContainer; 8491 } 8492 return null; 8493 } 8494 } 8495 8496 @Override 8497 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 8498 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8499 "moveTaskToStack()"); 8500 if (stackId == HOME_STACK_ID) { 8501 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 8502 new RuntimeException("here").fillInStackTrace()); 8503 } 8504 synchronized (this) { 8505 long ident = Binder.clearCallingIdentity(); 8506 try { 8507 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 8508 + stackId + " toTop=" + toTop); 8509 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 8510 } finally { 8511 Binder.restoreCallingIdentity(ident); 8512 } 8513 } 8514 } 8515 8516 @Override 8517 public void resizeStack(int stackBoxId, Rect bounds) { 8518 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8519 "resizeStackBox()"); 8520 long ident = Binder.clearCallingIdentity(); 8521 try { 8522 mWindowManager.resizeStack(stackBoxId, bounds); 8523 } finally { 8524 Binder.restoreCallingIdentity(ident); 8525 } 8526 } 8527 8528 @Override 8529 public List<StackInfo> getAllStackInfos() { 8530 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8531 "getAllStackInfos()"); 8532 long ident = Binder.clearCallingIdentity(); 8533 try { 8534 synchronized (this) { 8535 return mStackSupervisor.getAllStackInfosLocked(); 8536 } 8537 } finally { 8538 Binder.restoreCallingIdentity(ident); 8539 } 8540 } 8541 8542 @Override 8543 public StackInfo getStackInfo(int stackId) { 8544 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8545 "getStackInfo()"); 8546 long ident = Binder.clearCallingIdentity(); 8547 try { 8548 synchronized (this) { 8549 return mStackSupervisor.getStackInfoLocked(stackId); 8550 } 8551 } finally { 8552 Binder.restoreCallingIdentity(ident); 8553 } 8554 } 8555 8556 @Override 8557 public boolean isInHomeStack(int taskId) { 8558 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 8559 "getStackInfo()"); 8560 long ident = Binder.clearCallingIdentity(); 8561 try { 8562 synchronized (this) { 8563 TaskRecord tr = recentTaskForIdLocked(taskId); 8564 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 8565 } 8566 } finally { 8567 Binder.restoreCallingIdentity(ident); 8568 } 8569 } 8570 8571 @Override 8572 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 8573 synchronized(this) { 8574 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 8575 } 8576 } 8577 8578 private boolean isLockTaskAuthorized(String pkg) { 8579 final DevicePolicyManager dpm = (DevicePolicyManager) 8580 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 8581 try { 8582 int uid = mContext.getPackageManager().getPackageUid(pkg, 8583 Binder.getCallingUserHandle().getIdentifier()); 8584 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 8585 } catch (NameNotFoundException e) { 8586 return false; 8587 } 8588 } 8589 8590 void startLockTaskMode(TaskRecord task) { 8591 final String pkg; 8592 synchronized (this) { 8593 pkg = task.intent.getComponent().getPackageName(); 8594 } 8595 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 8596 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 8597 final TaskRecord taskRecord = task; 8598 mHandler.post(new Runnable() { 8599 @Override 8600 public void run() { 8601 mLockToAppRequest.showLockTaskPrompt(taskRecord); 8602 } 8603 }); 8604 return; 8605 } 8606 long ident = Binder.clearCallingIdentity(); 8607 try { 8608 synchronized (this) { 8609 // Since we lost lock on task, make sure it is still there. 8610 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 8611 if (task != null) { 8612 if (!isSystemInitiated 8613 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 8614 throw new IllegalArgumentException("Invalid task, not in foreground"); 8615 } 8616 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 8617 } 8618 } 8619 } finally { 8620 Binder.restoreCallingIdentity(ident); 8621 } 8622 } 8623 8624 @Override 8625 public void startLockTaskMode(int taskId) { 8626 final TaskRecord task; 8627 long ident = Binder.clearCallingIdentity(); 8628 try { 8629 synchronized (this) { 8630 task = mStackSupervisor.anyTaskForIdLocked(taskId); 8631 } 8632 } finally { 8633 Binder.restoreCallingIdentity(ident); 8634 } 8635 if (task != null) { 8636 startLockTaskMode(task); 8637 } 8638 } 8639 8640 @Override 8641 public void startLockTaskMode(IBinder token) { 8642 final TaskRecord task; 8643 long ident = Binder.clearCallingIdentity(); 8644 try { 8645 synchronized (this) { 8646 final ActivityRecord r = ActivityRecord.forToken(token); 8647 if (r == null) { 8648 return; 8649 } 8650 task = r.task; 8651 } 8652 } finally { 8653 Binder.restoreCallingIdentity(ident); 8654 } 8655 if (task != null) { 8656 startLockTaskMode(task); 8657 } 8658 } 8659 8660 @Override 8661 public void startLockTaskModeOnCurrent() throws RemoteException { 8662 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8663 ActivityRecord r = null; 8664 synchronized (this) { 8665 r = mStackSupervisor.topRunningActivityLocked(); 8666 } 8667 startLockTaskMode(r.task); 8668 } 8669 8670 @Override 8671 public void stopLockTaskMode() { 8672 // Verify that the user matches the package of the intent for the TaskRecord 8673 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 8674 // and stopLockTaskMode. 8675 final int callingUid = Binder.getCallingUid(); 8676 if (callingUid != Process.SYSTEM_UID) { 8677 try { 8678 String pkg = 8679 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 8680 int uid = mContext.getPackageManager().getPackageUid(pkg, 8681 Binder.getCallingUserHandle().getIdentifier()); 8682 if (uid != callingUid) { 8683 throw new SecurityException("Invalid uid, expected " + uid); 8684 } 8685 } catch (NameNotFoundException e) { 8686 Log.d(TAG, "stopLockTaskMode " + e); 8687 return; 8688 } 8689 } 8690 long ident = Binder.clearCallingIdentity(); 8691 try { 8692 Log.d(TAG, "stopLockTaskMode"); 8693 // Stop lock task 8694 synchronized (this) { 8695 mStackSupervisor.setLockTaskModeLocked(null, false); 8696 } 8697 } finally { 8698 Binder.restoreCallingIdentity(ident); 8699 } 8700 } 8701 8702 @Override 8703 public void stopLockTaskModeOnCurrent() throws RemoteException { 8704 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 8705 long ident = Binder.clearCallingIdentity(); 8706 try { 8707 stopLockTaskMode(); 8708 } finally { 8709 Binder.restoreCallingIdentity(ident); 8710 } 8711 } 8712 8713 @Override 8714 public boolean isInLockTaskMode() { 8715 synchronized (this) { 8716 return mStackSupervisor.isInLockTaskMode(); 8717 } 8718 } 8719 8720 // ========================================================= 8721 // CONTENT PROVIDERS 8722 // ========================================================= 8723 8724 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8725 List<ProviderInfo> providers = null; 8726 try { 8727 providers = AppGlobals.getPackageManager(). 8728 queryContentProviders(app.processName, app.uid, 8729 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8730 } catch (RemoteException ex) { 8731 } 8732 if (DEBUG_MU) 8733 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8734 int userId = app.userId; 8735 if (providers != null) { 8736 int N = providers.size(); 8737 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8738 for (int i=0; i<N; i++) { 8739 ProviderInfo cpi = 8740 (ProviderInfo)providers.get(i); 8741 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8742 cpi.name, cpi.flags); 8743 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8744 // This is a singleton provider, but a user besides the 8745 // default user is asking to initialize a process it runs 8746 // in... well, no, it doesn't actually run in this process, 8747 // it runs in the process of the default user. Get rid of it. 8748 providers.remove(i); 8749 N--; 8750 i--; 8751 continue; 8752 } 8753 8754 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8755 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8756 if (cpr == null) { 8757 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8758 mProviderMap.putProviderByClass(comp, cpr); 8759 } 8760 if (DEBUG_MU) 8761 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8762 app.pubProviders.put(cpi.name, cpr); 8763 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8764 // Don't add this if it is a platform component that is marked 8765 // to run in multiple processes, because this is actually 8766 // part of the framework so doesn't make sense to track as a 8767 // separate apk in the process. 8768 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8769 mProcessStats); 8770 } 8771 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8772 } 8773 } 8774 return providers; 8775 } 8776 8777 /** 8778 * Check if {@link ProcessRecord} has a possible chance at accessing the 8779 * given {@link ProviderInfo}. Final permission checking is always done 8780 * in {@link ContentProvider}. 8781 */ 8782 private final String checkContentProviderPermissionLocked( 8783 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8784 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8785 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8786 boolean checkedGrants = false; 8787 if (checkUser) { 8788 // Looking for cross-user grants before enforcing the typical cross-users permissions 8789 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8790 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8791 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8792 return null; 8793 } 8794 checkedGrants = true; 8795 } 8796 userId = handleIncomingUser(callingPid, callingUid, userId, 8797 false, ALLOW_NON_FULL, 8798 "checkContentProviderPermissionLocked " + cpi.authority, null); 8799 if (userId != tmpTargetUserId) { 8800 // When we actually went to determine the final targer user ID, this ended 8801 // up different than our initial check for the authority. This is because 8802 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8803 // SELF. So we need to re-check the grants again. 8804 checkedGrants = false; 8805 } 8806 } 8807 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8808 cpi.applicationInfo.uid, cpi.exported) 8809 == PackageManager.PERMISSION_GRANTED) { 8810 return null; 8811 } 8812 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8813 cpi.applicationInfo.uid, cpi.exported) 8814 == PackageManager.PERMISSION_GRANTED) { 8815 return null; 8816 } 8817 8818 PathPermission[] pps = cpi.pathPermissions; 8819 if (pps != null) { 8820 int i = pps.length; 8821 while (i > 0) { 8822 i--; 8823 PathPermission pp = pps[i]; 8824 String pprperm = pp.getReadPermission(); 8825 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8826 cpi.applicationInfo.uid, cpi.exported) 8827 == PackageManager.PERMISSION_GRANTED) { 8828 return null; 8829 } 8830 String ppwperm = pp.getWritePermission(); 8831 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8832 cpi.applicationInfo.uid, cpi.exported) 8833 == PackageManager.PERMISSION_GRANTED) { 8834 return null; 8835 } 8836 } 8837 } 8838 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8839 return null; 8840 } 8841 8842 String msg; 8843 if (!cpi.exported) { 8844 msg = "Permission Denial: opening provider " + cpi.name 8845 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8846 + ", uid=" + callingUid + ") that is not exported from uid " 8847 + cpi.applicationInfo.uid; 8848 } else { 8849 msg = "Permission Denial: opening provider " + cpi.name 8850 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8851 + ", uid=" + callingUid + ") requires " 8852 + cpi.readPermission + " or " + cpi.writePermission; 8853 } 8854 Slog.w(TAG, msg); 8855 return msg; 8856 } 8857 8858 /** 8859 * Returns if the ContentProvider has granted a uri to callingUid 8860 */ 8861 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8862 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8863 if (perms != null) { 8864 for (int i=perms.size()-1; i>=0; i--) { 8865 GrantUri grantUri = perms.keyAt(i); 8866 if (grantUri.sourceUserId == userId || !checkUser) { 8867 if (matchesProvider(grantUri.uri, cpi)) { 8868 return true; 8869 } 8870 } 8871 } 8872 } 8873 return false; 8874 } 8875 8876 /** 8877 * Returns true if the uri authority is one of the authorities specified in the provider. 8878 */ 8879 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8880 String uriAuth = uri.getAuthority(); 8881 String cpiAuth = cpi.authority; 8882 if (cpiAuth.indexOf(';') == -1) { 8883 return cpiAuth.equals(uriAuth); 8884 } 8885 String[] cpiAuths = cpiAuth.split(";"); 8886 int length = cpiAuths.length; 8887 for (int i = 0; i < length; i++) { 8888 if (cpiAuths[i].equals(uriAuth)) return true; 8889 } 8890 return false; 8891 } 8892 8893 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8894 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8895 if (r != null) { 8896 for (int i=0; i<r.conProviders.size(); i++) { 8897 ContentProviderConnection conn = r.conProviders.get(i); 8898 if (conn.provider == cpr) { 8899 if (DEBUG_PROVIDER) Slog.v(TAG, 8900 "Adding provider requested by " 8901 + r.processName + " from process " 8902 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8903 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8904 if (stable) { 8905 conn.stableCount++; 8906 conn.numStableIncs++; 8907 } else { 8908 conn.unstableCount++; 8909 conn.numUnstableIncs++; 8910 } 8911 return conn; 8912 } 8913 } 8914 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8915 if (stable) { 8916 conn.stableCount = 1; 8917 conn.numStableIncs = 1; 8918 } else { 8919 conn.unstableCount = 1; 8920 conn.numUnstableIncs = 1; 8921 } 8922 cpr.connections.add(conn); 8923 r.conProviders.add(conn); 8924 return conn; 8925 } 8926 cpr.addExternalProcessHandleLocked(externalProcessToken); 8927 return null; 8928 } 8929 8930 boolean decProviderCountLocked(ContentProviderConnection conn, 8931 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8932 if (conn != null) { 8933 cpr = conn.provider; 8934 if (DEBUG_PROVIDER) Slog.v(TAG, 8935 "Removing provider requested by " 8936 + conn.client.processName + " from process " 8937 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8938 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8939 if (stable) { 8940 conn.stableCount--; 8941 } else { 8942 conn.unstableCount--; 8943 } 8944 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8945 cpr.connections.remove(conn); 8946 conn.client.conProviders.remove(conn); 8947 return true; 8948 } 8949 return false; 8950 } 8951 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8952 return false; 8953 } 8954 8955 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8956 String name, IBinder token, boolean stable, int userId) { 8957 ContentProviderRecord cpr; 8958 ContentProviderConnection conn = null; 8959 ProviderInfo cpi = null; 8960 8961 synchronized(this) { 8962 ProcessRecord r = null; 8963 if (caller != null) { 8964 r = getRecordForAppLocked(caller); 8965 if (r == null) { 8966 throw new SecurityException( 8967 "Unable to find app for caller " + caller 8968 + " (pid=" + Binder.getCallingPid() 8969 + ") when getting content provider " + name); 8970 } 8971 } 8972 8973 boolean checkCrossUser = true; 8974 8975 // First check if this content provider has been published... 8976 cpr = mProviderMap.getProviderByName(name, userId); 8977 // If that didn't work, check if it exists for user 0 and then 8978 // verify that it's a singleton provider before using it. 8979 if (cpr == null && userId != UserHandle.USER_OWNER) { 8980 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8981 if (cpr != null) { 8982 cpi = cpr.info; 8983 if (isSingleton(cpi.processName, cpi.applicationInfo, 8984 cpi.name, cpi.flags) 8985 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8986 userId = UserHandle.USER_OWNER; 8987 checkCrossUser = false; 8988 } else { 8989 cpr = null; 8990 cpi = null; 8991 } 8992 } 8993 } 8994 8995 boolean providerRunning = cpr != null; 8996 if (providerRunning) { 8997 cpi = cpr.info; 8998 String msg; 8999 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 9000 != null) { 9001 throw new SecurityException(msg); 9002 } 9003 9004 if (r != null && cpr.canRunHere(r)) { 9005 // This provider has been published or is in the process 9006 // of being published... but it is also allowed to run 9007 // in the caller's process, so don't make a connection 9008 // and just let the caller instantiate its own instance. 9009 ContentProviderHolder holder = cpr.newHolder(null); 9010 // don't give caller the provider object, it needs 9011 // to make its own. 9012 holder.provider = null; 9013 return holder; 9014 } 9015 9016 final long origId = Binder.clearCallingIdentity(); 9017 9018 // In this case the provider instance already exists, so we can 9019 // return it right away. 9020 conn = incProviderCountLocked(r, cpr, token, stable); 9021 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 9022 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 9023 // If this is a perceptible app accessing the provider, 9024 // make sure to count it as being accessed and thus 9025 // back up on the LRU list. This is good because 9026 // content providers are often expensive to start. 9027 updateLruProcessLocked(cpr.proc, false, null); 9028 } 9029 } 9030 9031 if (cpr.proc != null) { 9032 if (false) { 9033 if (cpr.name.flattenToShortString().equals( 9034 "com.android.providers.calendar/.CalendarProvider2")) { 9035 Slog.v(TAG, "****************** KILLING " 9036 + cpr.name.flattenToShortString()); 9037 Process.killProcess(cpr.proc.pid); 9038 } 9039 } 9040 boolean success = updateOomAdjLocked(cpr.proc); 9041 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 9042 // NOTE: there is still a race here where a signal could be 9043 // pending on the process even though we managed to update its 9044 // adj level. Not sure what to do about this, but at least 9045 // the race is now smaller. 9046 if (!success) { 9047 // Uh oh... it looks like the provider's process 9048 // has been killed on us. We need to wait for a new 9049 // process to be started, and make sure its death 9050 // doesn't kill our process. 9051 Slog.i(TAG, 9052 "Existing provider " + cpr.name.flattenToShortString() 9053 + " is crashing; detaching " + r); 9054 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 9055 appDiedLocked(cpr.proc); 9056 if (!lastRef) { 9057 // This wasn't the last ref our process had on 9058 // the provider... we have now been killed, bail. 9059 return null; 9060 } 9061 providerRunning = false; 9062 conn = null; 9063 } 9064 } 9065 9066 Binder.restoreCallingIdentity(origId); 9067 } 9068 9069 boolean singleton; 9070 if (!providerRunning) { 9071 try { 9072 cpi = AppGlobals.getPackageManager(). 9073 resolveContentProvider(name, 9074 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 9075 } catch (RemoteException ex) { 9076 } 9077 if (cpi == null) { 9078 return null; 9079 } 9080 // If the provider is a singleton AND 9081 // (it's a call within the same user || the provider is a 9082 // privileged app) 9083 // Then allow connecting to the singleton provider 9084 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 9085 cpi.name, cpi.flags) 9086 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 9087 if (singleton) { 9088 userId = UserHandle.USER_OWNER; 9089 } 9090 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 9091 9092 String msg; 9093 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 9094 != null) { 9095 throw new SecurityException(msg); 9096 } 9097 9098 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 9099 && !cpi.processName.equals("system")) { 9100 // If this content provider does not run in the system 9101 // process, and the system is not yet ready to run other 9102 // processes, then fail fast instead of hanging. 9103 throw new IllegalArgumentException( 9104 "Attempt to launch content provider before system ready"); 9105 } 9106 9107 // Make sure that the user who owns this provider is started. If not, 9108 // we don't want to allow it to run. 9109 if (mStartedUsers.get(userId) == null) { 9110 Slog.w(TAG, "Unable to launch app " 9111 + cpi.applicationInfo.packageName + "/" 9112 + cpi.applicationInfo.uid + " for provider " 9113 + name + ": user " + userId + " is stopped"); 9114 return null; 9115 } 9116 9117 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 9118 cpr = mProviderMap.getProviderByClass(comp, userId); 9119 final boolean firstClass = cpr == null; 9120 if (firstClass) { 9121 try { 9122 ApplicationInfo ai = 9123 AppGlobals.getPackageManager(). 9124 getApplicationInfo( 9125 cpi.applicationInfo.packageName, 9126 STOCK_PM_FLAGS, userId); 9127 if (ai == null) { 9128 Slog.w(TAG, "No package info for content provider " 9129 + cpi.name); 9130 return null; 9131 } 9132 ai = getAppInfoForUser(ai, userId); 9133 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 9134 } catch (RemoteException ex) { 9135 // pm is in same process, this will never happen. 9136 } 9137 } 9138 9139 if (r != null && cpr.canRunHere(r)) { 9140 // If this is a multiprocess provider, then just return its 9141 // info and allow the caller to instantiate it. Only do 9142 // this if the provider is the same user as the caller's 9143 // process, or can run as root (so can be in any process). 9144 return cpr.newHolder(null); 9145 } 9146 9147 if (DEBUG_PROVIDER) { 9148 RuntimeException e = new RuntimeException("here"); 9149 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 9150 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 9151 } 9152 9153 // This is single process, and our app is now connecting to it. 9154 // See if we are already in the process of launching this 9155 // provider. 9156 final int N = mLaunchingProviders.size(); 9157 int i; 9158 for (i=0; i<N; i++) { 9159 if (mLaunchingProviders.get(i) == cpr) { 9160 break; 9161 } 9162 } 9163 9164 // If the provider is not already being launched, then get it 9165 // started. 9166 if (i >= N) { 9167 final long origId = Binder.clearCallingIdentity(); 9168 9169 try { 9170 // Content provider is now in use, its package can't be stopped. 9171 try { 9172 AppGlobals.getPackageManager().setPackageStoppedState( 9173 cpr.appInfo.packageName, false, userId); 9174 } catch (RemoteException e) { 9175 } catch (IllegalArgumentException e) { 9176 Slog.w(TAG, "Failed trying to unstop package " 9177 + cpr.appInfo.packageName + ": " + e); 9178 } 9179 9180 // Use existing process if already started 9181 ProcessRecord proc = getProcessRecordLocked( 9182 cpi.processName, cpr.appInfo.uid, false); 9183 if (proc != null && proc.thread != null) { 9184 if (DEBUG_PROVIDER) { 9185 Slog.d(TAG, "Installing in existing process " + proc); 9186 } 9187 proc.pubProviders.put(cpi.name, cpr); 9188 try { 9189 proc.thread.scheduleInstallProvider(cpi); 9190 } catch (RemoteException e) { 9191 } 9192 } else { 9193 proc = startProcessLocked(cpi.processName, 9194 cpr.appInfo, false, 0, "content provider", 9195 new ComponentName(cpi.applicationInfo.packageName, 9196 cpi.name), false, false, false); 9197 if (proc == null) { 9198 Slog.w(TAG, "Unable to launch app " 9199 + cpi.applicationInfo.packageName + "/" 9200 + cpi.applicationInfo.uid + " for provider " 9201 + name + ": process is bad"); 9202 return null; 9203 } 9204 } 9205 cpr.launchingApp = proc; 9206 mLaunchingProviders.add(cpr); 9207 } finally { 9208 Binder.restoreCallingIdentity(origId); 9209 } 9210 } 9211 9212 // Make sure the provider is published (the same provider class 9213 // may be published under multiple names). 9214 if (firstClass) { 9215 mProviderMap.putProviderByClass(comp, cpr); 9216 } 9217 9218 mProviderMap.putProviderByName(name, cpr); 9219 conn = incProviderCountLocked(r, cpr, token, stable); 9220 if (conn != null) { 9221 conn.waiting = true; 9222 } 9223 } 9224 } 9225 9226 // Wait for the provider to be published... 9227 synchronized (cpr) { 9228 while (cpr.provider == null) { 9229 if (cpr.launchingApp == null) { 9230 Slog.w(TAG, "Unable to launch app " 9231 + cpi.applicationInfo.packageName + "/" 9232 + cpi.applicationInfo.uid + " for provider " 9233 + name + ": launching app became null"); 9234 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 9235 UserHandle.getUserId(cpi.applicationInfo.uid), 9236 cpi.applicationInfo.packageName, 9237 cpi.applicationInfo.uid, name); 9238 return null; 9239 } 9240 try { 9241 if (DEBUG_MU) { 9242 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 9243 + cpr.launchingApp); 9244 } 9245 if (conn != null) { 9246 conn.waiting = true; 9247 } 9248 cpr.wait(); 9249 } catch (InterruptedException ex) { 9250 } finally { 9251 if (conn != null) { 9252 conn.waiting = false; 9253 } 9254 } 9255 } 9256 } 9257 return cpr != null ? cpr.newHolder(conn) : null; 9258 } 9259 9260 @Override 9261 public final ContentProviderHolder getContentProvider( 9262 IApplicationThread caller, String name, int userId, boolean stable) { 9263 enforceNotIsolatedCaller("getContentProvider"); 9264 if (caller == null) { 9265 String msg = "null IApplicationThread when getting content provider " 9266 + name; 9267 Slog.w(TAG, msg); 9268 throw new SecurityException(msg); 9269 } 9270 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 9271 // with cross-user grant. 9272 return getContentProviderImpl(caller, name, null, stable, userId); 9273 } 9274 9275 public ContentProviderHolder getContentProviderExternal( 9276 String name, int userId, IBinder token) { 9277 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9278 "Do not have permission in call getContentProviderExternal()"); 9279 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 9280 false, ALLOW_FULL_ONLY, "getContentProvider", null); 9281 return getContentProviderExternalUnchecked(name, token, userId); 9282 } 9283 9284 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 9285 IBinder token, int userId) { 9286 return getContentProviderImpl(null, name, token, true, userId); 9287 } 9288 9289 /** 9290 * Drop a content provider from a ProcessRecord's bookkeeping 9291 */ 9292 public void removeContentProvider(IBinder connection, boolean stable) { 9293 enforceNotIsolatedCaller("removeContentProvider"); 9294 long ident = Binder.clearCallingIdentity(); 9295 try { 9296 synchronized (this) { 9297 ContentProviderConnection conn; 9298 try { 9299 conn = (ContentProviderConnection)connection; 9300 } catch (ClassCastException e) { 9301 String msg ="removeContentProvider: " + connection 9302 + " not a ContentProviderConnection"; 9303 Slog.w(TAG, msg); 9304 throw new IllegalArgumentException(msg); 9305 } 9306 if (conn == null) { 9307 throw new NullPointerException("connection is null"); 9308 } 9309 if (decProviderCountLocked(conn, null, null, stable)) { 9310 updateOomAdjLocked(); 9311 } 9312 } 9313 } finally { 9314 Binder.restoreCallingIdentity(ident); 9315 } 9316 } 9317 9318 public void removeContentProviderExternal(String name, IBinder token) { 9319 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 9320 "Do not have permission in call removeContentProviderExternal()"); 9321 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 9322 } 9323 9324 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 9325 synchronized (this) { 9326 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 9327 if(cpr == null) { 9328 //remove from mProvidersByClass 9329 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 9330 return; 9331 } 9332 9333 //update content provider record entry info 9334 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 9335 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 9336 if (localCpr.hasExternalProcessHandles()) { 9337 if (localCpr.removeExternalProcessHandleLocked(token)) { 9338 updateOomAdjLocked(); 9339 } else { 9340 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 9341 + " with no external reference for token: " 9342 + token + "."); 9343 } 9344 } else { 9345 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 9346 + " with no external references."); 9347 } 9348 } 9349 } 9350 9351 public final void publishContentProviders(IApplicationThread caller, 9352 List<ContentProviderHolder> providers) { 9353 if (providers == null) { 9354 return; 9355 } 9356 9357 enforceNotIsolatedCaller("publishContentProviders"); 9358 synchronized (this) { 9359 final ProcessRecord r = getRecordForAppLocked(caller); 9360 if (DEBUG_MU) 9361 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 9362 if (r == null) { 9363 throw new SecurityException( 9364 "Unable to find app for caller " + caller 9365 + " (pid=" + Binder.getCallingPid() 9366 + ") when publishing content providers"); 9367 } 9368 9369 final long origId = Binder.clearCallingIdentity(); 9370 9371 final int N = providers.size(); 9372 for (int i=0; i<N; i++) { 9373 ContentProviderHolder src = providers.get(i); 9374 if (src == null || src.info == null || src.provider == null) { 9375 continue; 9376 } 9377 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 9378 if (DEBUG_MU) 9379 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 9380 if (dst != null) { 9381 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 9382 mProviderMap.putProviderByClass(comp, dst); 9383 String names[] = dst.info.authority.split(";"); 9384 for (int j = 0; j < names.length; j++) { 9385 mProviderMap.putProviderByName(names[j], dst); 9386 } 9387 9388 int NL = mLaunchingProviders.size(); 9389 int j; 9390 for (j=0; j<NL; j++) { 9391 if (mLaunchingProviders.get(j) == dst) { 9392 mLaunchingProviders.remove(j); 9393 j--; 9394 NL--; 9395 } 9396 } 9397 synchronized (dst) { 9398 dst.provider = src.provider; 9399 dst.proc = r; 9400 dst.notifyAll(); 9401 } 9402 updateOomAdjLocked(r); 9403 } 9404 } 9405 9406 Binder.restoreCallingIdentity(origId); 9407 } 9408 } 9409 9410 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 9411 ContentProviderConnection conn; 9412 try { 9413 conn = (ContentProviderConnection)connection; 9414 } catch (ClassCastException e) { 9415 String msg ="refContentProvider: " + connection 9416 + " not a ContentProviderConnection"; 9417 Slog.w(TAG, msg); 9418 throw new IllegalArgumentException(msg); 9419 } 9420 if (conn == null) { 9421 throw new NullPointerException("connection is null"); 9422 } 9423 9424 synchronized (this) { 9425 if (stable > 0) { 9426 conn.numStableIncs += stable; 9427 } 9428 stable = conn.stableCount + stable; 9429 if (stable < 0) { 9430 throw new IllegalStateException("stableCount < 0: " + stable); 9431 } 9432 9433 if (unstable > 0) { 9434 conn.numUnstableIncs += unstable; 9435 } 9436 unstable = conn.unstableCount + unstable; 9437 if (unstable < 0) { 9438 throw new IllegalStateException("unstableCount < 0: " + unstable); 9439 } 9440 9441 if ((stable+unstable) <= 0) { 9442 throw new IllegalStateException("ref counts can't go to zero here: stable=" 9443 + stable + " unstable=" + unstable); 9444 } 9445 conn.stableCount = stable; 9446 conn.unstableCount = unstable; 9447 return !conn.dead; 9448 } 9449 } 9450 9451 public void unstableProviderDied(IBinder connection) { 9452 ContentProviderConnection conn; 9453 try { 9454 conn = (ContentProviderConnection)connection; 9455 } catch (ClassCastException e) { 9456 String msg ="refContentProvider: " + connection 9457 + " not a ContentProviderConnection"; 9458 Slog.w(TAG, msg); 9459 throw new IllegalArgumentException(msg); 9460 } 9461 if (conn == null) { 9462 throw new NullPointerException("connection is null"); 9463 } 9464 9465 // Safely retrieve the content provider associated with the connection. 9466 IContentProvider provider; 9467 synchronized (this) { 9468 provider = conn.provider.provider; 9469 } 9470 9471 if (provider == null) { 9472 // Um, yeah, we're way ahead of you. 9473 return; 9474 } 9475 9476 // Make sure the caller is being honest with us. 9477 if (provider.asBinder().pingBinder()) { 9478 // Er, no, still looks good to us. 9479 synchronized (this) { 9480 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 9481 + " says " + conn + " died, but we don't agree"); 9482 return; 9483 } 9484 } 9485 9486 // Well look at that! It's dead! 9487 synchronized (this) { 9488 if (conn.provider.provider != provider) { 9489 // But something changed... good enough. 9490 return; 9491 } 9492 9493 ProcessRecord proc = conn.provider.proc; 9494 if (proc == null || proc.thread == null) { 9495 // Seems like the process is already cleaned up. 9496 return; 9497 } 9498 9499 // As far as we're concerned, this is just like receiving a 9500 // death notification... just a bit prematurely. 9501 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 9502 + ") early provider death"); 9503 final long ident = Binder.clearCallingIdentity(); 9504 try { 9505 appDiedLocked(proc); 9506 } finally { 9507 Binder.restoreCallingIdentity(ident); 9508 } 9509 } 9510 } 9511 9512 @Override 9513 public void appNotRespondingViaProvider(IBinder connection) { 9514 enforceCallingPermission( 9515 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 9516 9517 final ContentProviderConnection conn = (ContentProviderConnection) connection; 9518 if (conn == null) { 9519 Slog.w(TAG, "ContentProviderConnection is null"); 9520 return; 9521 } 9522 9523 final ProcessRecord host = conn.provider.proc; 9524 if (host == null) { 9525 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 9526 return; 9527 } 9528 9529 final long token = Binder.clearCallingIdentity(); 9530 try { 9531 appNotResponding(host, null, null, false, "ContentProvider not responding"); 9532 } finally { 9533 Binder.restoreCallingIdentity(token); 9534 } 9535 } 9536 9537 public final void installSystemProviders() { 9538 List<ProviderInfo> providers; 9539 synchronized (this) { 9540 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 9541 providers = generateApplicationProvidersLocked(app); 9542 if (providers != null) { 9543 for (int i=providers.size()-1; i>=0; i--) { 9544 ProviderInfo pi = (ProviderInfo)providers.get(i); 9545 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 9546 Slog.w(TAG, "Not installing system proc provider " + pi.name 9547 + ": not system .apk"); 9548 providers.remove(i); 9549 } 9550 } 9551 } 9552 } 9553 if (providers != null) { 9554 mSystemThread.installSystemProviders(providers); 9555 } 9556 9557 mCoreSettingsObserver = new CoreSettingsObserver(this); 9558 9559 //mUsageStatsService.monitorPackages(); 9560 } 9561 9562 /** 9563 * Allows apps to retrieve the MIME type of a URI. 9564 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across 9565 * users, then it does not need permission to access the ContentProvider. 9566 * Either, it needs cross-user uri grants. 9567 * 9568 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 9569 * 9570 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 9571 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 9572 */ 9573 public String getProviderMimeType(Uri uri, int userId) { 9574 enforceNotIsolatedCaller("getProviderMimeType"); 9575 final String name = uri.getAuthority(); 9576 int callingUid = Binder.getCallingUid(); 9577 int callingPid = Binder.getCallingPid(); 9578 long ident = 0; 9579 boolean clearedIdentity = false; 9580 userId = unsafeConvertIncomingUser(userId); 9581 if (UserHandle.getUserId(callingUid) != userId) { 9582 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 9583 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED 9584 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 9585 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 9586 clearedIdentity = true; 9587 ident = Binder.clearCallingIdentity(); 9588 } 9589 } 9590 ContentProviderHolder holder = null; 9591 try { 9592 holder = getContentProviderExternalUnchecked(name, null, userId); 9593 if (holder != null) { 9594 return holder.provider.getType(uri); 9595 } 9596 } catch (RemoteException e) { 9597 Log.w(TAG, "Content provider dead retrieving " + uri, e); 9598 return null; 9599 } finally { 9600 // We need to clear the identity to call removeContentProviderExternalUnchecked 9601 if (!clearedIdentity) { 9602 ident = Binder.clearCallingIdentity(); 9603 } 9604 try { 9605 if (holder != null) { 9606 removeContentProviderExternalUnchecked(name, null, userId); 9607 } 9608 } finally { 9609 Binder.restoreCallingIdentity(ident); 9610 } 9611 } 9612 9613 return null; 9614 } 9615 9616 // ========================================================= 9617 // GLOBAL MANAGEMENT 9618 // ========================================================= 9619 9620 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 9621 boolean isolated, int isolatedUid) { 9622 String proc = customProcess != null ? customProcess : info.processName; 9623 BatteryStatsImpl.Uid.Proc ps = null; 9624 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9625 int uid = info.uid; 9626 if (isolated) { 9627 if (isolatedUid == 0) { 9628 int userId = UserHandle.getUserId(uid); 9629 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 9630 while (true) { 9631 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 9632 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 9633 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 9634 } 9635 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 9636 mNextIsolatedProcessUid++; 9637 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 9638 // No process for this uid, use it. 9639 break; 9640 } 9641 stepsLeft--; 9642 if (stepsLeft <= 0) { 9643 return null; 9644 } 9645 } 9646 } else { 9647 // Special case for startIsolatedProcess (internal only), where 9648 // the uid of the isolated process is specified by the caller. 9649 uid = isolatedUid; 9650 } 9651 } 9652 return new ProcessRecord(stats, info, proc, uid); 9653 } 9654 9655 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 9656 String abiOverride) { 9657 ProcessRecord app; 9658 if (!isolated) { 9659 app = getProcessRecordLocked(info.processName, info.uid, true); 9660 } else { 9661 app = null; 9662 } 9663 9664 if (app == null) { 9665 app = newProcessRecordLocked(info, null, isolated, 0); 9666 mProcessNames.put(info.processName, app.uid, app); 9667 if (isolated) { 9668 mIsolatedProcesses.put(app.uid, app); 9669 } 9670 updateLruProcessLocked(app, false, null); 9671 updateOomAdjLocked(); 9672 } 9673 9674 // This package really, really can not be stopped. 9675 try { 9676 AppGlobals.getPackageManager().setPackageStoppedState( 9677 info.packageName, false, UserHandle.getUserId(app.uid)); 9678 } catch (RemoteException e) { 9679 } catch (IllegalArgumentException e) { 9680 Slog.w(TAG, "Failed trying to unstop package " 9681 + info.packageName + ": " + e); 9682 } 9683 9684 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 9685 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 9686 app.persistent = true; 9687 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 9688 } 9689 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 9690 mPersistentStartingProcesses.add(app); 9691 startProcessLocked(app, "added application", app.processName, abiOverride, 9692 null /* entryPoint */, null /* entryPointArgs */); 9693 } 9694 9695 return app; 9696 } 9697 9698 public void unhandledBack() { 9699 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 9700 "unhandledBack()"); 9701 9702 synchronized(this) { 9703 final long origId = Binder.clearCallingIdentity(); 9704 try { 9705 getFocusedStack().unhandledBackLocked(); 9706 } finally { 9707 Binder.restoreCallingIdentity(origId); 9708 } 9709 } 9710 } 9711 9712 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 9713 enforceNotIsolatedCaller("openContentUri"); 9714 final int userId = UserHandle.getCallingUserId(); 9715 String name = uri.getAuthority(); 9716 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 9717 ParcelFileDescriptor pfd = null; 9718 if (cph != null) { 9719 // We record the binder invoker's uid in thread-local storage before 9720 // going to the content provider to open the file. Later, in the code 9721 // that handles all permissions checks, we look for this uid and use 9722 // that rather than the Activity Manager's own uid. The effect is that 9723 // we do the check against the caller's permissions even though it looks 9724 // to the content provider like the Activity Manager itself is making 9725 // the request. 9726 sCallerIdentity.set(new Identity( 9727 Binder.getCallingPid(), Binder.getCallingUid())); 9728 try { 9729 pfd = cph.provider.openFile(null, uri, "r", null); 9730 } catch (FileNotFoundException e) { 9731 // do nothing; pfd will be returned null 9732 } finally { 9733 // Ensure that whatever happens, we clean up the identity state 9734 sCallerIdentity.remove(); 9735 } 9736 9737 // We've got the fd now, so we're done with the provider. 9738 removeContentProviderExternalUnchecked(name, null, userId); 9739 } else { 9740 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9741 } 9742 return pfd; 9743 } 9744 9745 // Actually is sleeping or shutting down or whatever else in the future 9746 // is an inactive state. 9747 public boolean isSleepingOrShuttingDown() { 9748 return mSleeping || mShuttingDown; 9749 } 9750 9751 public boolean isSleeping() { 9752 return mSleeping; 9753 } 9754 9755 void goingToSleep() { 9756 synchronized(this) { 9757 mWentToSleep = true; 9758 updateEventDispatchingLocked(); 9759 goToSleepIfNeededLocked(); 9760 } 9761 } 9762 9763 void finishRunningVoiceLocked() { 9764 if (mRunningVoice) { 9765 mRunningVoice = false; 9766 goToSleepIfNeededLocked(); 9767 } 9768 } 9769 9770 void goToSleepIfNeededLocked() { 9771 if (mWentToSleep && !mRunningVoice) { 9772 if (!mSleeping) { 9773 mSleeping = true; 9774 mStackSupervisor.goingToSleepLocked(); 9775 9776 // Initialize the wake times of all processes. 9777 checkExcessivePowerUsageLocked(false); 9778 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9779 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9780 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9781 } 9782 } 9783 } 9784 9785 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9786 if (task != null && task.stack != null && task.stack.isHomeStack()) { 9787 // Never persist the home stack. 9788 return; 9789 } 9790 mTaskPersister.wakeup(task, flush); 9791 } 9792 9793 @Override 9794 public boolean shutdown(int timeout) { 9795 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9796 != PackageManager.PERMISSION_GRANTED) { 9797 throw new SecurityException("Requires permission " 9798 + android.Manifest.permission.SHUTDOWN); 9799 } 9800 9801 boolean timedout = false; 9802 9803 synchronized(this) { 9804 mShuttingDown = true; 9805 updateEventDispatchingLocked(); 9806 timedout = mStackSupervisor.shutdownLocked(timeout); 9807 } 9808 9809 mAppOpsService.shutdown(); 9810 if (mUsageStatsService != null) { 9811 mUsageStatsService.prepareShutdown(); 9812 } 9813 mBatteryStatsService.shutdown(); 9814 synchronized (this) { 9815 mProcessStats.shutdownLocked(); 9816 } 9817 notifyTaskPersisterLocked(null, true); 9818 9819 return timedout; 9820 } 9821 9822 public final void activitySlept(IBinder token) { 9823 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9824 9825 final long origId = Binder.clearCallingIdentity(); 9826 9827 synchronized (this) { 9828 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9829 if (r != null) { 9830 mStackSupervisor.activitySleptLocked(r); 9831 } 9832 } 9833 9834 Binder.restoreCallingIdentity(origId); 9835 } 9836 9837 void logLockScreen(String msg) { 9838 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9839 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9840 mWentToSleep + " mSleeping=" + mSleeping); 9841 } 9842 9843 private void comeOutOfSleepIfNeededLocked() { 9844 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9845 if (mSleeping) { 9846 mSleeping = false; 9847 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9848 } 9849 } 9850 } 9851 9852 void wakingUp() { 9853 synchronized(this) { 9854 mWentToSleep = false; 9855 updateEventDispatchingLocked(); 9856 comeOutOfSleepIfNeededLocked(); 9857 } 9858 } 9859 9860 void startRunningVoiceLocked() { 9861 if (!mRunningVoice) { 9862 mRunningVoice = true; 9863 comeOutOfSleepIfNeededLocked(); 9864 } 9865 } 9866 9867 private void updateEventDispatchingLocked() { 9868 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9869 } 9870 9871 public void setLockScreenShown(boolean shown) { 9872 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9873 != PackageManager.PERMISSION_GRANTED) { 9874 throw new SecurityException("Requires permission " 9875 + android.Manifest.permission.DEVICE_POWER); 9876 } 9877 9878 synchronized(this) { 9879 long ident = Binder.clearCallingIdentity(); 9880 try { 9881 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9882 mLockScreenShown = shown; 9883 comeOutOfSleepIfNeededLocked(); 9884 } finally { 9885 Binder.restoreCallingIdentity(ident); 9886 } 9887 } 9888 } 9889 9890 @Override 9891 public void stopAppSwitches() { 9892 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9893 != PackageManager.PERMISSION_GRANTED) { 9894 throw new SecurityException("Requires permission " 9895 + android.Manifest.permission.STOP_APP_SWITCHES); 9896 } 9897 9898 synchronized(this) { 9899 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9900 + APP_SWITCH_DELAY_TIME; 9901 mDidAppSwitch = false; 9902 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9903 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9904 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9905 } 9906 } 9907 9908 public void resumeAppSwitches() { 9909 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9910 != PackageManager.PERMISSION_GRANTED) { 9911 throw new SecurityException("Requires permission " 9912 + android.Manifest.permission.STOP_APP_SWITCHES); 9913 } 9914 9915 synchronized(this) { 9916 // Note that we don't execute any pending app switches... we will 9917 // let those wait until either the timeout, or the next start 9918 // activity request. 9919 mAppSwitchesAllowedTime = 0; 9920 } 9921 } 9922 9923 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9924 String name) { 9925 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9926 return true; 9927 } 9928 9929 final int perm = checkComponentPermission( 9930 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9931 callingUid, -1, true); 9932 if (perm == PackageManager.PERMISSION_GRANTED) { 9933 return true; 9934 } 9935 9936 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9937 return false; 9938 } 9939 9940 public void setDebugApp(String packageName, boolean waitForDebugger, 9941 boolean persistent) { 9942 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9943 "setDebugApp()"); 9944 9945 long ident = Binder.clearCallingIdentity(); 9946 try { 9947 // Note that this is not really thread safe if there are multiple 9948 // callers into it at the same time, but that's not a situation we 9949 // care about. 9950 if (persistent) { 9951 final ContentResolver resolver = mContext.getContentResolver(); 9952 Settings.Global.putString( 9953 resolver, Settings.Global.DEBUG_APP, 9954 packageName); 9955 Settings.Global.putInt( 9956 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9957 waitForDebugger ? 1 : 0); 9958 } 9959 9960 synchronized (this) { 9961 if (!persistent) { 9962 mOrigDebugApp = mDebugApp; 9963 mOrigWaitForDebugger = mWaitForDebugger; 9964 } 9965 mDebugApp = packageName; 9966 mWaitForDebugger = waitForDebugger; 9967 mDebugTransient = !persistent; 9968 if (packageName != null) { 9969 forceStopPackageLocked(packageName, -1, false, false, true, true, 9970 false, UserHandle.USER_ALL, "set debug app"); 9971 } 9972 } 9973 } finally { 9974 Binder.restoreCallingIdentity(ident); 9975 } 9976 } 9977 9978 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9979 synchronized (this) { 9980 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9981 if (!isDebuggable) { 9982 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9983 throw new SecurityException("Process not debuggable: " + app.packageName); 9984 } 9985 } 9986 9987 mOpenGlTraceApp = processName; 9988 } 9989 } 9990 9991 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) { 9992 synchronized (this) { 9993 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9994 if (!isDebuggable) { 9995 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9996 throw new SecurityException("Process not debuggable: " + app.packageName); 9997 } 9998 } 9999 mProfileApp = processName; 10000 mProfileFile = profilerInfo.profileFile; 10001 if (mProfileFd != null) { 10002 try { 10003 mProfileFd.close(); 10004 } catch (IOException e) { 10005 } 10006 mProfileFd = null; 10007 } 10008 mProfileFd = profilerInfo.profileFd; 10009 mSamplingInterval = profilerInfo.samplingInterval; 10010 mAutoStopProfiler = profilerInfo.autoStopProfiler; 10011 mProfileType = 0; 10012 } 10013 } 10014 10015 @Override 10016 public void setAlwaysFinish(boolean enabled) { 10017 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 10018 "setAlwaysFinish()"); 10019 10020 Settings.Global.putInt( 10021 mContext.getContentResolver(), 10022 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 10023 10024 synchronized (this) { 10025 mAlwaysFinishActivities = enabled; 10026 } 10027 } 10028 10029 @Override 10030 public void setActivityController(IActivityController controller) { 10031 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10032 "setActivityController()"); 10033 synchronized (this) { 10034 mController = controller; 10035 Watchdog.getInstance().setActivityController(controller); 10036 } 10037 } 10038 10039 @Override 10040 public void setUserIsMonkey(boolean userIsMonkey) { 10041 synchronized (this) { 10042 synchronized (mPidsSelfLocked) { 10043 final int callingPid = Binder.getCallingPid(); 10044 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 10045 if (precessRecord == null) { 10046 throw new SecurityException("Unknown process: " + callingPid); 10047 } 10048 if (precessRecord.instrumentationUiAutomationConnection == null) { 10049 throw new SecurityException("Only an instrumentation process " 10050 + "with a UiAutomation can call setUserIsMonkey"); 10051 } 10052 } 10053 mUserIsMonkey = userIsMonkey; 10054 } 10055 } 10056 10057 @Override 10058 public boolean isUserAMonkey() { 10059 synchronized (this) { 10060 // If there is a controller also implies the user is a monkey. 10061 return (mUserIsMonkey || mController != null); 10062 } 10063 } 10064 10065 public void requestBugReport() { 10066 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 10067 SystemProperties.set("ctl.start", "bugreport"); 10068 } 10069 10070 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 10071 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 10072 } 10073 10074 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 10075 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 10076 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 10077 } 10078 return KEY_DISPATCHING_TIMEOUT; 10079 } 10080 10081 @Override 10082 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 10083 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10084 != PackageManager.PERMISSION_GRANTED) { 10085 throw new SecurityException("Requires permission " 10086 + android.Manifest.permission.FILTER_EVENTS); 10087 } 10088 ProcessRecord proc; 10089 long timeout; 10090 synchronized (this) { 10091 synchronized (mPidsSelfLocked) { 10092 proc = mPidsSelfLocked.get(pid); 10093 } 10094 timeout = getInputDispatchingTimeoutLocked(proc); 10095 } 10096 10097 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 10098 return -1; 10099 } 10100 10101 return timeout; 10102 } 10103 10104 /** 10105 * Handle input dispatching timeouts. 10106 * Returns whether input dispatching should be aborted or not. 10107 */ 10108 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 10109 final ActivityRecord activity, final ActivityRecord parent, 10110 final boolean aboveSystem, String reason) { 10111 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 10112 != PackageManager.PERMISSION_GRANTED) { 10113 throw new SecurityException("Requires permission " 10114 + android.Manifest.permission.FILTER_EVENTS); 10115 } 10116 10117 final String annotation; 10118 if (reason == null) { 10119 annotation = "Input dispatching timed out"; 10120 } else { 10121 annotation = "Input dispatching timed out (" + reason + ")"; 10122 } 10123 10124 if (proc != null) { 10125 synchronized (this) { 10126 if (proc.debugging) { 10127 return false; 10128 } 10129 10130 if (mDidDexOpt) { 10131 // Give more time since we were dexopting. 10132 mDidDexOpt = false; 10133 return false; 10134 } 10135 10136 if (proc.instrumentationClass != null) { 10137 Bundle info = new Bundle(); 10138 info.putString("shortMsg", "keyDispatchingTimedOut"); 10139 info.putString("longMsg", annotation); 10140 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 10141 return true; 10142 } 10143 } 10144 mHandler.post(new Runnable() { 10145 @Override 10146 public void run() { 10147 appNotResponding(proc, activity, parent, aboveSystem, annotation); 10148 } 10149 }); 10150 } 10151 10152 return true; 10153 } 10154 10155 public Bundle getAssistContextExtras(int requestType) { 10156 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 10157 "getAssistContextExtras()"); 10158 PendingAssistExtras pae; 10159 Bundle extras = new Bundle(); 10160 synchronized (this) { 10161 ActivityRecord activity = getFocusedStack().mResumedActivity; 10162 if (activity == null) { 10163 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 10164 return null; 10165 } 10166 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 10167 if (activity.app == null || activity.app.thread == null) { 10168 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 10169 return extras; 10170 } 10171 if (activity.app.pid == Binder.getCallingPid()) { 10172 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 10173 return extras; 10174 } 10175 pae = new PendingAssistExtras(activity); 10176 try { 10177 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 10178 requestType); 10179 mPendingAssistExtras.add(pae); 10180 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 10181 } catch (RemoteException e) { 10182 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 10183 return extras; 10184 } 10185 } 10186 synchronized (pae) { 10187 while (!pae.haveResult) { 10188 try { 10189 pae.wait(); 10190 } catch (InterruptedException e) { 10191 } 10192 } 10193 if (pae.result != null) { 10194 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 10195 } 10196 } 10197 synchronized (this) { 10198 mPendingAssistExtras.remove(pae); 10199 mHandler.removeCallbacks(pae); 10200 } 10201 return extras; 10202 } 10203 10204 public void reportAssistContextExtras(IBinder token, Bundle extras) { 10205 PendingAssistExtras pae = (PendingAssistExtras)token; 10206 synchronized (pae) { 10207 pae.result = extras; 10208 pae.haveResult = true; 10209 pae.notifyAll(); 10210 } 10211 } 10212 10213 public void registerProcessObserver(IProcessObserver observer) { 10214 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 10215 "registerProcessObserver()"); 10216 synchronized (this) { 10217 mProcessObservers.register(observer); 10218 } 10219 } 10220 10221 @Override 10222 public void unregisterProcessObserver(IProcessObserver observer) { 10223 synchronized (this) { 10224 mProcessObservers.unregister(observer); 10225 } 10226 } 10227 10228 @Override 10229 public boolean convertFromTranslucent(IBinder token) { 10230 final long origId = Binder.clearCallingIdentity(); 10231 try { 10232 synchronized (this) { 10233 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10234 if (r == null) { 10235 return false; 10236 } 10237 if (r.changeWindowTranslucency(true)) { 10238 mWindowManager.setAppFullscreen(token, true); 10239 r.task.stack.releaseBackgroundResources(); 10240 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10241 return true; 10242 } 10243 return false; 10244 } 10245 } finally { 10246 Binder.restoreCallingIdentity(origId); 10247 } 10248 } 10249 10250 @Override 10251 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 10252 final long origId = Binder.clearCallingIdentity(); 10253 try { 10254 synchronized (this) { 10255 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10256 if (r == null) { 10257 return false; 10258 } 10259 int index = r.task.mActivities.lastIndexOf(r); 10260 if (index > 0) { 10261 ActivityRecord under = r.task.mActivities.get(index - 1); 10262 under.returningOptions = options; 10263 } 10264 if (r.changeWindowTranslucency(false)) { 10265 r.task.stack.convertToTranslucent(r); 10266 mWindowManager.setAppFullscreen(token, false); 10267 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10268 return true; 10269 } else { 10270 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 10271 return false; 10272 } 10273 } 10274 } finally { 10275 Binder.restoreCallingIdentity(origId); 10276 } 10277 } 10278 10279 @Override 10280 public boolean requestVisibleBehind(IBinder token, boolean visible) { 10281 final long origId = Binder.clearCallingIdentity(); 10282 try { 10283 synchronized (this) { 10284 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10285 if (r != null) { 10286 return mStackSupervisor.requestVisibleBehindLocked(r, visible); 10287 } 10288 } 10289 return false; 10290 } finally { 10291 Binder.restoreCallingIdentity(origId); 10292 } 10293 } 10294 10295 @Override 10296 public boolean isBackgroundVisibleBehind(IBinder token) { 10297 final long origId = Binder.clearCallingIdentity(); 10298 try { 10299 synchronized (this) { 10300 final ActivityStack stack = ActivityRecord.getStackLocked(token); 10301 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity(); 10302 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG, 10303 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible); 10304 return visible; 10305 } 10306 } finally { 10307 Binder.restoreCallingIdentity(origId); 10308 } 10309 } 10310 10311 @Override 10312 public ActivityOptions getActivityOptions(IBinder token) { 10313 final long origId = Binder.clearCallingIdentity(); 10314 try { 10315 synchronized (this) { 10316 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10317 if (r != null) { 10318 final ActivityOptions activityOptions = r.pendingOptions; 10319 r.pendingOptions = null; 10320 return activityOptions; 10321 } 10322 return null; 10323 } 10324 } finally { 10325 Binder.restoreCallingIdentity(origId); 10326 } 10327 } 10328 10329 @Override 10330 public void setImmersive(IBinder token, boolean immersive) { 10331 synchronized(this) { 10332 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 10333 if (r == null) { 10334 throw new IllegalArgumentException(); 10335 } 10336 r.immersive = immersive; 10337 10338 // update associated state if we're frontmost 10339 if (r == mFocusedActivity) { 10340 if (DEBUG_IMMERSIVE) { 10341 Slog.d(TAG, "Frontmost changed immersion: "+ r); 10342 } 10343 applyUpdateLockStateLocked(r); 10344 } 10345 } 10346 } 10347 10348 @Override 10349 public boolean isImmersive(IBinder token) { 10350 synchronized (this) { 10351 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10352 if (r == null) { 10353 throw new IllegalArgumentException(); 10354 } 10355 return r.immersive; 10356 } 10357 } 10358 10359 public boolean isTopActivityImmersive() { 10360 enforceNotIsolatedCaller("startActivity"); 10361 synchronized (this) { 10362 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 10363 return (r != null) ? r.immersive : false; 10364 } 10365 } 10366 10367 @Override 10368 public boolean isTopOfTask(IBinder token) { 10369 synchronized (this) { 10370 ActivityRecord r = ActivityRecord.isInStackLocked(token); 10371 if (r == null) { 10372 throw new IllegalArgumentException(); 10373 } 10374 return r.task.getTopActivity() == r; 10375 } 10376 } 10377 10378 public final void enterSafeMode() { 10379 synchronized(this) { 10380 // It only makes sense to do this before the system is ready 10381 // and started launching other packages. 10382 if (!mSystemReady) { 10383 try { 10384 AppGlobals.getPackageManager().enterSafeMode(); 10385 } catch (RemoteException e) { 10386 } 10387 } 10388 10389 mSafeMode = true; 10390 } 10391 } 10392 10393 public final void showSafeModeOverlay() { 10394 View v = LayoutInflater.from(mContext).inflate( 10395 com.android.internal.R.layout.safe_mode, null); 10396 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 10397 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 10398 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 10399 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 10400 lp.gravity = Gravity.BOTTOM | Gravity.START; 10401 lp.format = v.getBackground().getOpacity(); 10402 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 10403 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 10404 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 10405 ((WindowManager)mContext.getSystemService( 10406 Context.WINDOW_SERVICE)).addView(v, lp); 10407 } 10408 10409 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 10410 if (!(sender instanceof PendingIntentRecord)) { 10411 return; 10412 } 10413 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 10414 synchronized (stats) { 10415 if (mBatteryStatsService.isOnBattery()) { 10416 mBatteryStatsService.enforceCallingPermission(); 10417 PendingIntentRecord rec = (PendingIntentRecord)sender; 10418 int MY_UID = Binder.getCallingUid(); 10419 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 10420 BatteryStatsImpl.Uid.Pkg pkg = 10421 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 10422 sourcePkg != null ? sourcePkg : rec.key.packageName); 10423 pkg.incWakeupsLocked(); 10424 } 10425 } 10426 } 10427 10428 public boolean killPids(int[] pids, String pReason, boolean secure) { 10429 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10430 throw new SecurityException("killPids only available to the system"); 10431 } 10432 String reason = (pReason == null) ? "Unknown" : pReason; 10433 // XXX Note: don't acquire main activity lock here, because the window 10434 // manager calls in with its locks held. 10435 10436 boolean killed = false; 10437 synchronized (mPidsSelfLocked) { 10438 int[] types = new int[pids.length]; 10439 int worstType = 0; 10440 for (int i=0; i<pids.length; i++) { 10441 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10442 if (proc != null) { 10443 int type = proc.setAdj; 10444 types[i] = type; 10445 if (type > worstType) { 10446 worstType = type; 10447 } 10448 } 10449 } 10450 10451 // If the worst oom_adj is somewhere in the cached proc LRU range, 10452 // then constrain it so we will kill all cached procs. 10453 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 10454 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 10455 worstType = ProcessList.CACHED_APP_MIN_ADJ; 10456 } 10457 10458 // If this is not a secure call, don't let it kill processes that 10459 // are important. 10460 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 10461 worstType = ProcessList.SERVICE_ADJ; 10462 } 10463 10464 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 10465 for (int i=0; i<pids.length; i++) { 10466 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 10467 if (proc == null) { 10468 continue; 10469 } 10470 int adj = proc.setAdj; 10471 if (adj >= worstType && !proc.killedByAm) { 10472 proc.kill(reason, true); 10473 killed = true; 10474 } 10475 } 10476 } 10477 return killed; 10478 } 10479 10480 @Override 10481 public void killUid(int uid, String reason) { 10482 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10483 throw new SecurityException("killUid only available to the system"); 10484 } 10485 synchronized (this) { 10486 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 10487 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 10488 reason != null ? reason : "kill uid"); 10489 } 10490 } 10491 10492 @Override 10493 public boolean killProcessesBelowForeground(String reason) { 10494 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10495 throw new SecurityException("killProcessesBelowForeground() only available to system"); 10496 } 10497 10498 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 10499 } 10500 10501 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 10502 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 10503 throw new SecurityException("killProcessesBelowAdj() only available to system"); 10504 } 10505 10506 boolean killed = false; 10507 synchronized (mPidsSelfLocked) { 10508 final int size = mPidsSelfLocked.size(); 10509 for (int i = 0; i < size; i++) { 10510 final int pid = mPidsSelfLocked.keyAt(i); 10511 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10512 if (proc == null) continue; 10513 10514 final int adj = proc.setAdj; 10515 if (adj > belowAdj && !proc.killedByAm) { 10516 proc.kill(reason, true); 10517 killed = true; 10518 } 10519 } 10520 } 10521 return killed; 10522 } 10523 10524 @Override 10525 public void hang(final IBinder who, boolean allowRestart) { 10526 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10527 != PackageManager.PERMISSION_GRANTED) { 10528 throw new SecurityException("Requires permission " 10529 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10530 } 10531 10532 final IBinder.DeathRecipient death = new DeathRecipient() { 10533 @Override 10534 public void binderDied() { 10535 synchronized (this) { 10536 notifyAll(); 10537 } 10538 } 10539 }; 10540 10541 try { 10542 who.linkToDeath(death, 0); 10543 } catch (RemoteException e) { 10544 Slog.w(TAG, "hang: given caller IBinder is already dead."); 10545 return; 10546 } 10547 10548 synchronized (this) { 10549 Watchdog.getInstance().setAllowRestart(allowRestart); 10550 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 10551 synchronized (death) { 10552 while (who.isBinderAlive()) { 10553 try { 10554 death.wait(); 10555 } catch (InterruptedException e) { 10556 } 10557 } 10558 } 10559 Watchdog.getInstance().setAllowRestart(true); 10560 } 10561 } 10562 10563 @Override 10564 public void restart() { 10565 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10566 != PackageManager.PERMISSION_GRANTED) { 10567 throw new SecurityException("Requires permission " 10568 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10569 } 10570 10571 Log.i(TAG, "Sending shutdown broadcast..."); 10572 10573 BroadcastReceiver br = new BroadcastReceiver() { 10574 @Override public void onReceive(Context context, Intent intent) { 10575 // Now the broadcast is done, finish up the low-level shutdown. 10576 Log.i(TAG, "Shutting down activity manager..."); 10577 shutdown(10000); 10578 Log.i(TAG, "Shutdown complete, restarting!"); 10579 Process.killProcess(Process.myPid()); 10580 System.exit(10); 10581 } 10582 }; 10583 10584 // First send the high-level shut down broadcast. 10585 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 10586 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 10587 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 10588 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 10589 mContext.sendOrderedBroadcastAsUser(intent, 10590 UserHandle.ALL, null, br, mHandler, 0, null, null); 10591 */ 10592 br.onReceive(mContext, intent); 10593 } 10594 10595 private long getLowRamTimeSinceIdle(long now) { 10596 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 10597 } 10598 10599 @Override 10600 public void performIdleMaintenance() { 10601 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 10602 != PackageManager.PERMISSION_GRANTED) { 10603 throw new SecurityException("Requires permission " 10604 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 10605 } 10606 10607 synchronized (this) { 10608 final long now = SystemClock.uptimeMillis(); 10609 final long timeSinceLastIdle = now - mLastIdleTime; 10610 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 10611 mLastIdleTime = now; 10612 mLowRamTimeSinceLastIdle = 0; 10613 if (mLowRamStartTime != 0) { 10614 mLowRamStartTime = now; 10615 } 10616 10617 StringBuilder sb = new StringBuilder(128); 10618 sb.append("Idle maintenance over "); 10619 TimeUtils.formatDuration(timeSinceLastIdle, sb); 10620 sb.append(" low RAM for "); 10621 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 10622 Slog.i(TAG, sb.toString()); 10623 10624 // If at least 1/3 of our time since the last idle period has been spent 10625 // with RAM low, then we want to kill processes. 10626 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 10627 10628 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 10629 ProcessRecord proc = mLruProcesses.get(i); 10630 if (proc.notCachedSinceIdle) { 10631 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 10632 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 10633 if (doKilling && proc.initialIdlePss != 0 10634 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 10635 proc.kill("idle maint (pss " + proc.lastPss 10636 + " from " + proc.initialIdlePss + ")", true); 10637 } 10638 } 10639 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 10640 proc.notCachedSinceIdle = true; 10641 proc.initialIdlePss = 0; 10642 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 10643 isSleeping(), now); 10644 } 10645 } 10646 10647 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 10648 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 10649 } 10650 } 10651 10652 private void retrieveSettings() { 10653 final ContentResolver resolver = mContext.getContentResolver(); 10654 String debugApp = Settings.Global.getString( 10655 resolver, Settings.Global.DEBUG_APP); 10656 boolean waitForDebugger = Settings.Global.getInt( 10657 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 10658 boolean alwaysFinishActivities = Settings.Global.getInt( 10659 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 10660 boolean forceRtl = Settings.Global.getInt( 10661 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 10662 // Transfer any global setting for forcing RTL layout, into a System Property 10663 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 10664 10665 Configuration configuration = new Configuration(); 10666 Settings.System.getConfiguration(resolver, configuration); 10667 if (forceRtl) { 10668 // This will take care of setting the correct layout direction flags 10669 configuration.setLayoutDirection(configuration.locale); 10670 } 10671 10672 synchronized (this) { 10673 mDebugApp = mOrigDebugApp = debugApp; 10674 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 10675 mAlwaysFinishActivities = alwaysFinishActivities; 10676 // This happens before any activities are started, so we can 10677 // change mConfiguration in-place. 10678 updateConfigurationLocked(configuration, null, false, true); 10679 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 10680 } 10681 } 10682 10683 public boolean testIsSystemReady() { 10684 // no need to synchronize(this) just to read & return the value 10685 return mSystemReady; 10686 } 10687 10688 private static File getCalledPreBootReceiversFile() { 10689 File dataDir = Environment.getDataDirectory(); 10690 File systemDir = new File(dataDir, "system"); 10691 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME); 10692 return fname; 10693 } 10694 10695 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 10696 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 10697 File file = getCalledPreBootReceiversFile(); 10698 FileInputStream fis = null; 10699 try { 10700 fis = new FileInputStream(file); 10701 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 10702 int fvers = dis.readInt(); 10703 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) { 10704 String vers = dis.readUTF(); 10705 String codename = dis.readUTF(); 10706 String build = dis.readUTF(); 10707 if (android.os.Build.VERSION.RELEASE.equals(vers) 10708 && android.os.Build.VERSION.CODENAME.equals(codename) 10709 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 10710 int num = dis.readInt(); 10711 while (num > 0) { 10712 num--; 10713 String pkg = dis.readUTF(); 10714 String cls = dis.readUTF(); 10715 lastDoneReceivers.add(new ComponentName(pkg, cls)); 10716 } 10717 } 10718 } 10719 } catch (FileNotFoundException e) { 10720 } catch (IOException e) { 10721 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 10722 } finally { 10723 if (fis != null) { 10724 try { 10725 fis.close(); 10726 } catch (IOException e) { 10727 } 10728 } 10729 } 10730 return lastDoneReceivers; 10731 } 10732 10733 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 10734 File file = getCalledPreBootReceiversFile(); 10735 FileOutputStream fos = null; 10736 DataOutputStream dos = null; 10737 try { 10738 fos = new FileOutputStream(file); 10739 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10740 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION); 10741 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10742 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10743 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10744 dos.writeInt(list.size()); 10745 for (int i=0; i<list.size(); i++) { 10746 dos.writeUTF(list.get(i).getPackageName()); 10747 dos.writeUTF(list.get(i).getClassName()); 10748 } 10749 } catch (IOException e) { 10750 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10751 file.delete(); 10752 } finally { 10753 FileUtils.sync(fos); 10754 if (dos != null) { 10755 try { 10756 dos.close(); 10757 } catch (IOException e) { 10758 // TODO Auto-generated catch block 10759 e.printStackTrace(); 10760 } 10761 } 10762 } 10763 } 10764 10765 private boolean deliverPreBootCompleted(final Runnable onFinishCallback, 10766 ArrayList<ComponentName> doneReceivers, int userId) { 10767 boolean waitingUpdate = false; 10768 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10769 List<ResolveInfo> ris = null; 10770 try { 10771 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10772 intent, null, 0, userId); 10773 } catch (RemoteException e) { 10774 } 10775 if (ris != null) { 10776 for (int i=ris.size()-1; i>=0; i--) { 10777 if ((ris.get(i).activityInfo.applicationInfo.flags 10778 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10779 ris.remove(i); 10780 } 10781 } 10782 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10783 10784 // For User 0, load the version number. When delivering to a new user, deliver 10785 // to all receivers. 10786 if (userId == UserHandle.USER_OWNER) { 10787 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10788 for (int i=0; i<ris.size(); i++) { 10789 ActivityInfo ai = ris.get(i).activityInfo; 10790 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10791 if (lastDoneReceivers.contains(comp)) { 10792 // We already did the pre boot receiver for this app with the current 10793 // platform version, so don't do it again... 10794 ris.remove(i); 10795 i--; 10796 // ...however, do keep it as one that has been done, so we don't 10797 // forget about it when rewriting the file of last done receivers. 10798 doneReceivers.add(comp); 10799 } 10800 } 10801 } 10802 10803 // If primary user, send broadcast to all available users, else just to userId 10804 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked() 10805 : new int[] { userId }; 10806 for (int i = 0; i < ris.size(); i++) { 10807 ActivityInfo ai = ris.get(i).activityInfo; 10808 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10809 doneReceivers.add(comp); 10810 intent.setComponent(comp); 10811 for (int j=0; j<users.length; j++) { 10812 IIntentReceiver finisher = null; 10813 // On last receiver and user, set up a completion callback 10814 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) { 10815 finisher = new IIntentReceiver.Stub() { 10816 public void performReceive(Intent intent, int resultCode, 10817 String data, Bundle extras, boolean ordered, 10818 boolean sticky, int sendingUser) { 10819 // The raw IIntentReceiver interface is called 10820 // with the AM lock held, so redispatch to 10821 // execute our code without the lock. 10822 mHandler.post(onFinishCallback); 10823 } 10824 }; 10825 } 10826 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10827 + " for user " + users[j]); 10828 broadcastIntentLocked(null, null, intent, null, finisher, 10829 0, null, null, null, AppOpsManager.OP_NONE, 10830 true, false, MY_PID, Process.SYSTEM_UID, 10831 users[j]); 10832 if (finisher != null) { 10833 waitingUpdate = true; 10834 } 10835 } 10836 } 10837 } 10838 10839 return waitingUpdate; 10840 } 10841 10842 public void systemReady(final Runnable goingCallback) { 10843 synchronized(this) { 10844 if (mSystemReady) { 10845 // If we're done calling all the receivers, run the next "boot phase" passed in 10846 // by the SystemServer 10847 if (goingCallback != null) { 10848 goingCallback.run(); 10849 } 10850 return; 10851 } 10852 10853 // Make sure we have the current profile info, since it is needed for 10854 // security checks. 10855 updateCurrentProfileIdsLocked(); 10856 10857 if (mRecentTasks == null) { 10858 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10859 if (!mRecentTasks.isEmpty()) { 10860 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10861 } 10862 cleanupRecentTasksLocked(UserHandle.USER_ALL); 10863 mTaskPersister.startPersisting(); 10864 } 10865 10866 // Check to see if there are any update receivers to run. 10867 if (!mDidUpdate) { 10868 if (mWaitingUpdate) { 10869 return; 10870 } 10871 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10872 mWaitingUpdate = deliverPreBootCompleted(new Runnable() { 10873 public void run() { 10874 synchronized (ActivityManagerService.this) { 10875 mDidUpdate = true; 10876 } 10877 writeLastDonePreBootReceivers(doneReceivers); 10878 showBootMessage(mContext.getText( 10879 R.string.android_upgrading_complete), 10880 false); 10881 systemReady(goingCallback); 10882 } 10883 }, doneReceivers, UserHandle.USER_OWNER); 10884 10885 if (mWaitingUpdate) { 10886 return; 10887 } 10888 mDidUpdate = true; 10889 } 10890 10891 mAppOpsService.systemReady(); 10892 mSystemReady = true; 10893 } 10894 10895 ArrayList<ProcessRecord> procsToKill = null; 10896 synchronized(mPidsSelfLocked) { 10897 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10898 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10899 if (!isAllowedWhileBooting(proc.info)){ 10900 if (procsToKill == null) { 10901 procsToKill = new ArrayList<ProcessRecord>(); 10902 } 10903 procsToKill.add(proc); 10904 } 10905 } 10906 } 10907 10908 synchronized(this) { 10909 if (procsToKill != null) { 10910 for (int i=procsToKill.size()-1; i>=0; i--) { 10911 ProcessRecord proc = procsToKill.get(i); 10912 Slog.i(TAG, "Removing system update proc: " + proc); 10913 removeProcessLocked(proc, true, false, "system update done"); 10914 } 10915 } 10916 10917 // Now that we have cleaned up any update processes, we 10918 // are ready to start launching real processes and know that 10919 // we won't trample on them any more. 10920 mProcessesReady = true; 10921 } 10922 10923 Slog.i(TAG, "System now ready"); 10924 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10925 SystemClock.uptimeMillis()); 10926 10927 synchronized(this) { 10928 // Make sure we have no pre-ready processes sitting around. 10929 10930 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10931 ResolveInfo ri = mContext.getPackageManager() 10932 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10933 STOCK_PM_FLAGS); 10934 CharSequence errorMsg = null; 10935 if (ri != null) { 10936 ActivityInfo ai = ri.activityInfo; 10937 ApplicationInfo app = ai.applicationInfo; 10938 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10939 mTopAction = Intent.ACTION_FACTORY_TEST; 10940 mTopData = null; 10941 mTopComponent = new ComponentName(app.packageName, 10942 ai.name); 10943 } else { 10944 errorMsg = mContext.getResources().getText( 10945 com.android.internal.R.string.factorytest_not_system); 10946 } 10947 } else { 10948 errorMsg = mContext.getResources().getText( 10949 com.android.internal.R.string.factorytest_no_action); 10950 } 10951 if (errorMsg != null) { 10952 mTopAction = null; 10953 mTopData = null; 10954 mTopComponent = null; 10955 Message msg = Message.obtain(); 10956 msg.what = SHOW_FACTORY_ERROR_MSG; 10957 msg.getData().putCharSequence("msg", errorMsg); 10958 mHandler.sendMessage(msg); 10959 } 10960 } 10961 } 10962 10963 retrieveSettings(); 10964 10965 synchronized (this) { 10966 readGrantedUriPermissionsLocked(); 10967 } 10968 10969 if (goingCallback != null) goingCallback.run(); 10970 10971 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10972 Integer.toString(mCurrentUserId), mCurrentUserId); 10973 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10974 Integer.toString(mCurrentUserId), mCurrentUserId); 10975 mSystemServiceManager.startUser(mCurrentUserId); 10976 10977 synchronized (this) { 10978 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10979 try { 10980 List apps = AppGlobals.getPackageManager(). 10981 getPersistentApplications(STOCK_PM_FLAGS); 10982 if (apps != null) { 10983 int N = apps.size(); 10984 int i; 10985 for (i=0; i<N; i++) { 10986 ApplicationInfo info 10987 = (ApplicationInfo)apps.get(i); 10988 if (info != null && 10989 !info.packageName.equals("android")) { 10990 addAppLocked(info, false, null /* ABI override */); 10991 } 10992 } 10993 } 10994 } catch (RemoteException ex) { 10995 // pm is in same process, this will never happen. 10996 } 10997 } 10998 10999 // Start up initial activity. 11000 mBooting = true; 11001 11002 try { 11003 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 11004 Message msg = Message.obtain(); 11005 msg.what = SHOW_UID_ERROR_MSG; 11006 mHandler.sendMessage(msg); 11007 } 11008 } catch (RemoteException e) { 11009 } 11010 11011 long ident = Binder.clearCallingIdentity(); 11012 try { 11013 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 11014 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 11015 | Intent.FLAG_RECEIVER_FOREGROUND); 11016 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11017 broadcastIntentLocked(null, null, intent, 11018 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 11019 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 11020 intent = new Intent(Intent.ACTION_USER_STARTING); 11021 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 11022 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 11023 broadcastIntentLocked(null, null, intent, 11024 null, new IIntentReceiver.Stub() { 11025 @Override 11026 public void performReceive(Intent intent, int resultCode, String data, 11027 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 11028 throws RemoteException { 11029 } 11030 }, 0, null, null, 11031 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 11032 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 11033 } catch (Throwable t) { 11034 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 11035 } finally { 11036 Binder.restoreCallingIdentity(ident); 11037 } 11038 mStackSupervisor.resumeTopActivitiesLocked(); 11039 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 11040 } 11041 } 11042 11043 private boolean makeAppCrashingLocked(ProcessRecord app, 11044 String shortMsg, String longMsg, String stackTrace) { 11045 app.crashing = true; 11046 app.crashingReport = generateProcessError(app, 11047 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 11048 startAppProblemLocked(app); 11049 app.stopFreezingAllLocked(); 11050 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 11051 } 11052 11053 private void makeAppNotRespondingLocked(ProcessRecord app, 11054 String activity, String shortMsg, String longMsg) { 11055 app.notResponding = true; 11056 app.notRespondingReport = generateProcessError(app, 11057 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 11058 activity, shortMsg, longMsg, null); 11059 startAppProblemLocked(app); 11060 app.stopFreezingAllLocked(); 11061 } 11062 11063 /** 11064 * Generate a process error record, suitable for attachment to a ProcessRecord. 11065 * 11066 * @param app The ProcessRecord in which the error occurred. 11067 * @param condition Crashing, Application Not Responding, etc. Values are defined in 11068 * ActivityManager.AppErrorStateInfo 11069 * @param activity The activity associated with the crash, if known. 11070 * @param shortMsg Short message describing the crash. 11071 * @param longMsg Long message describing the crash. 11072 * @param stackTrace Full crash stack trace, may be null. 11073 * 11074 * @return Returns a fully-formed AppErrorStateInfo record. 11075 */ 11076 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 11077 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 11078 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 11079 11080 report.condition = condition; 11081 report.processName = app.processName; 11082 report.pid = app.pid; 11083 report.uid = app.info.uid; 11084 report.tag = activity; 11085 report.shortMsg = shortMsg; 11086 report.longMsg = longMsg; 11087 report.stackTrace = stackTrace; 11088 11089 return report; 11090 } 11091 11092 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 11093 synchronized (this) { 11094 app.crashing = false; 11095 app.crashingReport = null; 11096 app.notResponding = false; 11097 app.notRespondingReport = null; 11098 if (app.anrDialog == fromDialog) { 11099 app.anrDialog = null; 11100 } 11101 if (app.waitDialog == fromDialog) { 11102 app.waitDialog = null; 11103 } 11104 if (app.pid > 0 && app.pid != MY_PID) { 11105 handleAppCrashLocked(app, null, null, null); 11106 app.kill("user request after error", true); 11107 } 11108 } 11109 } 11110 11111 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 11112 String stackTrace) { 11113 long now = SystemClock.uptimeMillis(); 11114 11115 Long crashTime; 11116 if (!app.isolated) { 11117 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 11118 } else { 11119 crashTime = null; 11120 } 11121 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 11122 // This process loses! 11123 Slog.w(TAG, "Process " + app.info.processName 11124 + " has crashed too many times: killing!"); 11125 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 11126 app.userId, app.info.processName, app.uid); 11127 mStackSupervisor.handleAppCrashLocked(app); 11128 if (!app.persistent) { 11129 // We don't want to start this process again until the user 11130 // explicitly does so... but for persistent process, we really 11131 // need to keep it running. If a persistent process is actually 11132 // repeatedly crashing, then badness for everyone. 11133 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 11134 app.info.processName); 11135 if (!app.isolated) { 11136 // XXX We don't have a way to mark isolated processes 11137 // as bad, since they don't have a peristent identity. 11138 mBadProcesses.put(app.info.processName, app.uid, 11139 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 11140 mProcessCrashTimes.remove(app.info.processName, app.uid); 11141 } 11142 app.bad = true; 11143 app.removed = true; 11144 // Don't let services in this process be restarted and potentially 11145 // annoy the user repeatedly. Unless it is persistent, since those 11146 // processes run critical code. 11147 removeProcessLocked(app, false, false, "crash"); 11148 mStackSupervisor.resumeTopActivitiesLocked(); 11149 return false; 11150 } 11151 mStackSupervisor.resumeTopActivitiesLocked(); 11152 } else { 11153 mStackSupervisor.finishTopRunningActivityLocked(app); 11154 } 11155 11156 // Bump up the crash count of any services currently running in the proc. 11157 for (int i=app.services.size()-1; i>=0; i--) { 11158 // Any services running in the application need to be placed 11159 // back in the pending list. 11160 ServiceRecord sr = app.services.valueAt(i); 11161 sr.crashCount++; 11162 } 11163 11164 // If the crashing process is what we consider to be the "home process" and it has been 11165 // replaced by a third-party app, clear the package preferred activities from packages 11166 // with a home activity running in the process to prevent a repeatedly crashing app 11167 // from blocking the user to manually clear the list. 11168 final ArrayList<ActivityRecord> activities = app.activities; 11169 if (app == mHomeProcess && activities.size() > 0 11170 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 11171 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 11172 final ActivityRecord r = activities.get(activityNdx); 11173 if (r.isHomeActivity()) { 11174 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 11175 try { 11176 ActivityThread.getPackageManager() 11177 .clearPackagePreferredActivities(r.packageName); 11178 } catch (RemoteException c) { 11179 // pm is in same process, this will never happen. 11180 } 11181 } 11182 } 11183 } 11184 11185 if (!app.isolated) { 11186 // XXX Can't keep track of crash times for isolated processes, 11187 // because they don't have a perisistent identity. 11188 mProcessCrashTimes.put(app.info.processName, app.uid, now); 11189 } 11190 11191 if (app.crashHandler != null) mHandler.post(app.crashHandler); 11192 return true; 11193 } 11194 11195 void startAppProblemLocked(ProcessRecord app) { 11196 // If this app is not running under the current user, then we 11197 // can't give it a report button because that would require 11198 // launching the report UI under a different user. 11199 app.errorReportReceiver = null; 11200 11201 for (int userId : mCurrentProfileIds) { 11202 if (app.userId == userId) { 11203 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 11204 mContext, app.info.packageName, app.info.flags); 11205 } 11206 } 11207 skipCurrentReceiverLocked(app); 11208 } 11209 11210 void skipCurrentReceiverLocked(ProcessRecord app) { 11211 for (BroadcastQueue queue : mBroadcastQueues) { 11212 queue.skipCurrentReceiverLocked(app); 11213 } 11214 } 11215 11216 /** 11217 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 11218 * The application process will exit immediately after this call returns. 11219 * @param app object of the crashing app, null for the system server 11220 * @param crashInfo describing the exception 11221 */ 11222 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 11223 ProcessRecord r = findAppProcess(app, "Crash"); 11224 final String processName = app == null ? "system_server" 11225 : (r == null ? "unknown" : r.processName); 11226 11227 handleApplicationCrashInner("crash", r, processName, crashInfo); 11228 } 11229 11230 /* Native crash reporting uses this inner version because it needs to be somewhat 11231 * decoupled from the AM-managed cleanup lifecycle 11232 */ 11233 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 11234 ApplicationErrorReport.CrashInfo crashInfo) { 11235 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 11236 UserHandle.getUserId(Binder.getCallingUid()), processName, 11237 r == null ? -1 : r.info.flags, 11238 crashInfo.exceptionClassName, 11239 crashInfo.exceptionMessage, 11240 crashInfo.throwFileName, 11241 crashInfo.throwLineNumber); 11242 11243 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 11244 11245 crashApplication(r, crashInfo); 11246 } 11247 11248 public void handleApplicationStrictModeViolation( 11249 IBinder app, 11250 int violationMask, 11251 StrictMode.ViolationInfo info) { 11252 ProcessRecord r = findAppProcess(app, "StrictMode"); 11253 if (r == null) { 11254 return; 11255 } 11256 11257 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 11258 Integer stackFingerprint = info.hashCode(); 11259 boolean logIt = true; 11260 synchronized (mAlreadyLoggedViolatedStacks) { 11261 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 11262 logIt = false; 11263 // TODO: sub-sample into EventLog for these, with 11264 // the info.durationMillis? Then we'd get 11265 // the relative pain numbers, without logging all 11266 // the stack traces repeatedly. We'd want to do 11267 // likewise in the client code, which also does 11268 // dup suppression, before the Binder call. 11269 } else { 11270 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 11271 mAlreadyLoggedViolatedStacks.clear(); 11272 } 11273 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 11274 } 11275 } 11276 if (logIt) { 11277 logStrictModeViolationToDropBox(r, info); 11278 } 11279 } 11280 11281 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 11282 AppErrorResult result = new AppErrorResult(); 11283 synchronized (this) { 11284 final long origId = Binder.clearCallingIdentity(); 11285 11286 Message msg = Message.obtain(); 11287 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 11288 HashMap<String, Object> data = new HashMap<String, Object>(); 11289 data.put("result", result); 11290 data.put("app", r); 11291 data.put("violationMask", violationMask); 11292 data.put("info", info); 11293 msg.obj = data; 11294 mHandler.sendMessage(msg); 11295 11296 Binder.restoreCallingIdentity(origId); 11297 } 11298 int res = result.get(); 11299 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 11300 } 11301 } 11302 11303 // Depending on the policy in effect, there could be a bunch of 11304 // these in quick succession so we try to batch these together to 11305 // minimize disk writes, number of dropbox entries, and maximize 11306 // compression, by having more fewer, larger records. 11307 private void logStrictModeViolationToDropBox( 11308 ProcessRecord process, 11309 StrictMode.ViolationInfo info) { 11310 if (info == null) { 11311 return; 11312 } 11313 final boolean isSystemApp = process == null || 11314 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 11315 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 11316 final String processName = process == null ? "unknown" : process.processName; 11317 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 11318 final DropBoxManager dbox = (DropBoxManager) 11319 mContext.getSystemService(Context.DROPBOX_SERVICE); 11320 11321 // Exit early if the dropbox isn't configured to accept this report type. 11322 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11323 11324 boolean bufferWasEmpty; 11325 boolean needsFlush; 11326 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 11327 synchronized (sb) { 11328 bufferWasEmpty = sb.length() == 0; 11329 appendDropBoxProcessHeaders(process, processName, sb); 11330 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11331 sb.append("System-App: ").append(isSystemApp).append("\n"); 11332 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 11333 if (info.violationNumThisLoop != 0) { 11334 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 11335 } 11336 if (info.numAnimationsRunning != 0) { 11337 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 11338 } 11339 if (info.broadcastIntentAction != null) { 11340 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 11341 } 11342 if (info.durationMillis != -1) { 11343 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 11344 } 11345 if (info.numInstances != -1) { 11346 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 11347 } 11348 if (info.tags != null) { 11349 for (String tag : info.tags) { 11350 sb.append("Span-Tag: ").append(tag).append("\n"); 11351 } 11352 } 11353 sb.append("\n"); 11354 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 11355 sb.append(info.crashInfo.stackTrace); 11356 } 11357 sb.append("\n"); 11358 11359 // Only buffer up to ~64k. Various logging bits truncate 11360 // things at 128k. 11361 needsFlush = (sb.length() > 64 * 1024); 11362 } 11363 11364 // Flush immediately if the buffer's grown too large, or this 11365 // is a non-system app. Non-system apps are isolated with a 11366 // different tag & policy and not batched. 11367 // 11368 // Batching is useful during internal testing with 11369 // StrictMode settings turned up high. Without batching, 11370 // thousands of separate files could be created on boot. 11371 if (!isSystemApp || needsFlush) { 11372 new Thread("Error dump: " + dropboxTag) { 11373 @Override 11374 public void run() { 11375 String report; 11376 synchronized (sb) { 11377 report = sb.toString(); 11378 sb.delete(0, sb.length()); 11379 sb.trimToSize(); 11380 } 11381 if (report.length() != 0) { 11382 dbox.addText(dropboxTag, report); 11383 } 11384 } 11385 }.start(); 11386 return; 11387 } 11388 11389 // System app batching: 11390 if (!bufferWasEmpty) { 11391 // An existing dropbox-writing thread is outstanding, so 11392 // we don't need to start it up. The existing thread will 11393 // catch the buffer appends we just did. 11394 return; 11395 } 11396 11397 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 11398 // (After this point, we shouldn't access AMS internal data structures.) 11399 new Thread("Error dump: " + dropboxTag) { 11400 @Override 11401 public void run() { 11402 // 5 second sleep to let stacks arrive and be batched together 11403 try { 11404 Thread.sleep(5000); // 5 seconds 11405 } catch (InterruptedException e) {} 11406 11407 String errorReport; 11408 synchronized (mStrictModeBuffer) { 11409 errorReport = mStrictModeBuffer.toString(); 11410 if (errorReport.length() == 0) { 11411 return; 11412 } 11413 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 11414 mStrictModeBuffer.trimToSize(); 11415 } 11416 dbox.addText(dropboxTag, errorReport); 11417 } 11418 }.start(); 11419 } 11420 11421 /** 11422 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 11423 * @param app object of the crashing app, null for the system server 11424 * @param tag reported by the caller 11425 * @param system whether this wtf is coming from the system 11426 * @param crashInfo describing the context of the error 11427 * @return true if the process should exit immediately (WTF is fatal) 11428 */ 11429 public boolean handleApplicationWtf(IBinder app, final String tag, boolean system, 11430 final ApplicationErrorReport.CrashInfo crashInfo) { 11431 final ProcessRecord r = findAppProcess(app, "WTF"); 11432 final String processName = app == null ? "system_server" 11433 : (r == null ? "unknown" : r.processName); 11434 11435 EventLog.writeEvent(EventLogTags.AM_WTF, 11436 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 11437 processName, 11438 r == null ? -1 : r.info.flags, 11439 tag, crashInfo.exceptionMessage); 11440 11441 if (system) { 11442 // If this is coming from the system, we could very well have low-level 11443 // system locks held, so we want to do this all asynchronously. And we 11444 // never want this to become fatal, so there is that too. 11445 mHandler.post(new Runnable() { 11446 @Override public void run() { 11447 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, 11448 crashInfo); 11449 } 11450 }); 11451 return false; 11452 } 11453 11454 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 11455 11456 if (r != null && r.pid != Process.myPid() && 11457 Settings.Global.getInt(mContext.getContentResolver(), 11458 Settings.Global.WTF_IS_FATAL, 0) != 0) { 11459 crashApplication(r, crashInfo); 11460 return true; 11461 } else { 11462 return false; 11463 } 11464 } 11465 11466 /** 11467 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 11468 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 11469 */ 11470 private ProcessRecord findAppProcess(IBinder app, String reason) { 11471 if (app == null) { 11472 return null; 11473 } 11474 11475 synchronized (this) { 11476 final int NP = mProcessNames.getMap().size(); 11477 for (int ip=0; ip<NP; ip++) { 11478 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 11479 final int NA = apps.size(); 11480 for (int ia=0; ia<NA; ia++) { 11481 ProcessRecord p = apps.valueAt(ia); 11482 if (p.thread != null && p.thread.asBinder() == app) { 11483 return p; 11484 } 11485 } 11486 } 11487 11488 Slog.w(TAG, "Can't find mystery application for " + reason 11489 + " from pid=" + Binder.getCallingPid() 11490 + " uid=" + Binder.getCallingUid() + ": " + app); 11491 return null; 11492 } 11493 } 11494 11495 /** 11496 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 11497 * to append various headers to the dropbox log text. 11498 */ 11499 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 11500 StringBuilder sb) { 11501 // Watchdog thread ends up invoking this function (with 11502 // a null ProcessRecord) to add the stack file to dropbox. 11503 // Do not acquire a lock on this (am) in such cases, as it 11504 // could cause a potential deadlock, if and when watchdog 11505 // is invoked due to unavailability of lock on am and it 11506 // would prevent watchdog from killing system_server. 11507 if (process == null) { 11508 sb.append("Process: ").append(processName).append("\n"); 11509 return; 11510 } 11511 // Note: ProcessRecord 'process' is guarded by the service 11512 // instance. (notably process.pkgList, which could otherwise change 11513 // concurrently during execution of this method) 11514 synchronized (this) { 11515 sb.append("Process: ").append(processName).append("\n"); 11516 int flags = process.info.flags; 11517 IPackageManager pm = AppGlobals.getPackageManager(); 11518 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 11519 for (int ip=0; ip<process.pkgList.size(); ip++) { 11520 String pkg = process.pkgList.keyAt(ip); 11521 sb.append("Package: ").append(pkg); 11522 try { 11523 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 11524 if (pi != null) { 11525 sb.append(" v").append(pi.versionCode); 11526 if (pi.versionName != null) { 11527 sb.append(" (").append(pi.versionName).append(")"); 11528 } 11529 } 11530 } catch (RemoteException e) { 11531 Slog.e(TAG, "Error getting package info: " + pkg, e); 11532 } 11533 sb.append("\n"); 11534 } 11535 } 11536 } 11537 11538 private static String processClass(ProcessRecord process) { 11539 if (process == null || process.pid == MY_PID) { 11540 return "system_server"; 11541 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 11542 return "system_app"; 11543 } else { 11544 return "data_app"; 11545 } 11546 } 11547 11548 /** 11549 * Write a description of an error (crash, WTF, ANR) to the drop box. 11550 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 11551 * @param process which caused the error, null means the system server 11552 * @param activity which triggered the error, null if unknown 11553 * @param parent activity related to the error, null if unknown 11554 * @param subject line related to the error, null if absent 11555 * @param report in long form describing the error, null if absent 11556 * @param logFile to include in the report, null if none 11557 * @param crashInfo giving an application stack trace, null if absent 11558 */ 11559 public void addErrorToDropBox(String eventType, 11560 ProcessRecord process, String processName, ActivityRecord activity, 11561 ActivityRecord parent, String subject, 11562 final String report, final File logFile, 11563 final ApplicationErrorReport.CrashInfo crashInfo) { 11564 // NOTE -- this must never acquire the ActivityManagerService lock, 11565 // otherwise the watchdog may be prevented from resetting the system. 11566 11567 final String dropboxTag = processClass(process) + "_" + eventType; 11568 final DropBoxManager dbox = (DropBoxManager) 11569 mContext.getSystemService(Context.DROPBOX_SERVICE); 11570 11571 // Exit early if the dropbox isn't configured to accept this report type. 11572 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 11573 11574 final StringBuilder sb = new StringBuilder(1024); 11575 appendDropBoxProcessHeaders(process, processName, sb); 11576 if (activity != null) { 11577 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 11578 } 11579 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 11580 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 11581 } 11582 if (parent != null && parent != activity) { 11583 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 11584 } 11585 if (subject != null) { 11586 sb.append("Subject: ").append(subject).append("\n"); 11587 } 11588 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 11589 if (Debug.isDebuggerConnected()) { 11590 sb.append("Debugger: Connected\n"); 11591 } 11592 sb.append("\n"); 11593 11594 // Do the rest in a worker thread to avoid blocking the caller on I/O 11595 // (After this point, we shouldn't access AMS internal data structures.) 11596 Thread worker = new Thread("Error dump: " + dropboxTag) { 11597 @Override 11598 public void run() { 11599 if (report != null) { 11600 sb.append(report); 11601 } 11602 if (logFile != null) { 11603 try { 11604 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 11605 "\n\n[[TRUNCATED]]")); 11606 } catch (IOException e) { 11607 Slog.e(TAG, "Error reading " + logFile, e); 11608 } 11609 } 11610 if (crashInfo != null && crashInfo.stackTrace != null) { 11611 sb.append(crashInfo.stackTrace); 11612 } 11613 11614 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 11615 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 11616 if (lines > 0) { 11617 sb.append("\n"); 11618 11619 // Merge several logcat streams, and take the last N lines 11620 InputStreamReader input = null; 11621 try { 11622 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 11623 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 11624 "-b", "crash", 11625 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 11626 11627 try { logcat.getOutputStream().close(); } catch (IOException e) {} 11628 try { logcat.getErrorStream().close(); } catch (IOException e) {} 11629 input = new InputStreamReader(logcat.getInputStream()); 11630 11631 int num; 11632 char[] buf = new char[8192]; 11633 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 11634 } catch (IOException e) { 11635 Slog.e(TAG, "Error running logcat", e); 11636 } finally { 11637 if (input != null) try { input.close(); } catch (IOException e) {} 11638 } 11639 } 11640 11641 dbox.addText(dropboxTag, sb.toString()); 11642 } 11643 }; 11644 11645 if (process == null) { 11646 // If process is null, we are being called from some internal code 11647 // and may be about to die -- run this synchronously. 11648 worker.run(); 11649 } else { 11650 worker.start(); 11651 } 11652 } 11653 11654 /** 11655 * Bring up the "unexpected error" dialog box for a crashing app. 11656 * Deal with edge cases (intercepts from instrumented applications, 11657 * ActivityController, error intent receivers, that sort of thing). 11658 * @param r the application crashing 11659 * @param crashInfo describing the failure 11660 */ 11661 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 11662 long timeMillis = System.currentTimeMillis(); 11663 String shortMsg = crashInfo.exceptionClassName; 11664 String longMsg = crashInfo.exceptionMessage; 11665 String stackTrace = crashInfo.stackTrace; 11666 if (shortMsg != null && longMsg != null) { 11667 longMsg = shortMsg + ": " + longMsg; 11668 } else if (shortMsg != null) { 11669 longMsg = shortMsg; 11670 } 11671 11672 AppErrorResult result = new AppErrorResult(); 11673 synchronized (this) { 11674 if (mController != null) { 11675 try { 11676 String name = r != null ? r.processName : null; 11677 int pid = r != null ? r.pid : Binder.getCallingPid(); 11678 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 11679 if (!mController.appCrashed(name, pid, 11680 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 11681 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")) 11682 && "Native crash".equals(crashInfo.exceptionClassName)) { 11683 Slog.w(TAG, "Skip killing native crashed app " + name 11684 + "(" + pid + ") during testing"); 11685 } else { 11686 Slog.w(TAG, "Force-killing crashed app " + name 11687 + " at watcher's request"); 11688 if (r != null) { 11689 r.kill("crash", true); 11690 } else { 11691 // Huh. 11692 Process.killProcess(pid); 11693 Process.killProcessGroup(uid, pid); 11694 } 11695 } 11696 return; 11697 } 11698 } catch (RemoteException e) { 11699 mController = null; 11700 Watchdog.getInstance().setActivityController(null); 11701 } 11702 } 11703 11704 final long origId = Binder.clearCallingIdentity(); 11705 11706 // If this process is running instrumentation, finish it. 11707 if (r != null && r.instrumentationClass != null) { 11708 Slog.w(TAG, "Error in app " + r.processName 11709 + " running instrumentation " + r.instrumentationClass + ":"); 11710 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 11711 if (longMsg != null) Slog.w(TAG, " " + longMsg); 11712 Bundle info = new Bundle(); 11713 info.putString("shortMsg", shortMsg); 11714 info.putString("longMsg", longMsg); 11715 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 11716 Binder.restoreCallingIdentity(origId); 11717 return; 11718 } 11719 11720 // If we can't identify the process or it's already exceeded its crash quota, 11721 // quit right away without showing a crash dialog. 11722 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 11723 Binder.restoreCallingIdentity(origId); 11724 return; 11725 } 11726 11727 Message msg = Message.obtain(); 11728 msg.what = SHOW_ERROR_MSG; 11729 HashMap data = new HashMap(); 11730 data.put("result", result); 11731 data.put("app", r); 11732 msg.obj = data; 11733 mHandler.sendMessage(msg); 11734 11735 Binder.restoreCallingIdentity(origId); 11736 } 11737 11738 int res = result.get(); 11739 11740 Intent appErrorIntent = null; 11741 synchronized (this) { 11742 if (r != null && !r.isolated) { 11743 // XXX Can't keep track of crash time for isolated processes, 11744 // since they don't have a persistent identity. 11745 mProcessCrashTimes.put(r.info.processName, r.uid, 11746 SystemClock.uptimeMillis()); 11747 } 11748 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 11749 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 11750 } 11751 } 11752 11753 if (appErrorIntent != null) { 11754 try { 11755 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 11756 } catch (ActivityNotFoundException e) { 11757 Slog.w(TAG, "bug report receiver dissappeared", e); 11758 } 11759 } 11760 } 11761 11762 Intent createAppErrorIntentLocked(ProcessRecord r, 11763 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11764 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 11765 if (report == null) { 11766 return null; 11767 } 11768 Intent result = new Intent(Intent.ACTION_APP_ERROR); 11769 result.setComponent(r.errorReportReceiver); 11770 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 11771 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 11772 return result; 11773 } 11774 11775 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 11776 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 11777 if (r.errorReportReceiver == null) { 11778 return null; 11779 } 11780 11781 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 11782 return null; 11783 } 11784 11785 ApplicationErrorReport report = new ApplicationErrorReport(); 11786 report.packageName = r.info.packageName; 11787 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11788 report.processName = r.processName; 11789 report.time = timeMillis; 11790 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11791 11792 if (r.crashing || r.forceCrashReport) { 11793 report.type = ApplicationErrorReport.TYPE_CRASH; 11794 report.crashInfo = crashInfo; 11795 } else if (r.notResponding) { 11796 report.type = ApplicationErrorReport.TYPE_ANR; 11797 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11798 11799 report.anrInfo.activity = r.notRespondingReport.tag; 11800 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11801 report.anrInfo.info = r.notRespondingReport.longMsg; 11802 } 11803 11804 return report; 11805 } 11806 11807 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11808 enforceNotIsolatedCaller("getProcessesInErrorState"); 11809 // assume our apps are happy - lazy create the list 11810 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11811 11812 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11813 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11814 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11815 11816 synchronized (this) { 11817 11818 // iterate across all processes 11819 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11820 ProcessRecord app = mLruProcesses.get(i); 11821 if (!allUsers && app.userId != userId) { 11822 continue; 11823 } 11824 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11825 // This one's in trouble, so we'll generate a report for it 11826 // crashes are higher priority (in case there's a crash *and* an anr) 11827 ActivityManager.ProcessErrorStateInfo report = null; 11828 if (app.crashing) { 11829 report = app.crashingReport; 11830 } else if (app.notResponding) { 11831 report = app.notRespondingReport; 11832 } 11833 11834 if (report != null) { 11835 if (errList == null) { 11836 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11837 } 11838 errList.add(report); 11839 } else { 11840 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11841 " crashing = " + app.crashing + 11842 " notResponding = " + app.notResponding); 11843 } 11844 } 11845 } 11846 } 11847 11848 return errList; 11849 } 11850 11851 static int procStateToImportance(int procState, int memAdj, 11852 ActivityManager.RunningAppProcessInfo currApp) { 11853 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11854 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11855 currApp.lru = memAdj; 11856 } else { 11857 currApp.lru = 0; 11858 } 11859 return imp; 11860 } 11861 11862 private void fillInProcMemInfo(ProcessRecord app, 11863 ActivityManager.RunningAppProcessInfo outInfo) { 11864 outInfo.pid = app.pid; 11865 outInfo.uid = app.info.uid; 11866 if (mHeavyWeightProcess == app) { 11867 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11868 } 11869 if (app.persistent) { 11870 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11871 } 11872 if (app.activities.size() > 0) { 11873 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11874 } 11875 outInfo.lastTrimLevel = app.trimMemoryLevel; 11876 int adj = app.curAdj; 11877 int procState = app.curProcState; 11878 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11879 outInfo.importanceReasonCode = app.adjTypeCode; 11880 outInfo.processState = app.curProcState; 11881 } 11882 11883 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11884 enforceNotIsolatedCaller("getRunningAppProcesses"); 11885 // Lazy instantiation of list 11886 List<ActivityManager.RunningAppProcessInfo> runList = null; 11887 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11888 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11889 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11890 synchronized (this) { 11891 // Iterate across all processes 11892 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11893 ProcessRecord app = mLruProcesses.get(i); 11894 if (!allUsers && app.userId != userId) { 11895 continue; 11896 } 11897 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11898 // Generate process state info for running application 11899 ActivityManager.RunningAppProcessInfo currApp = 11900 new ActivityManager.RunningAppProcessInfo(app.processName, 11901 app.pid, app.getPackageList()); 11902 fillInProcMemInfo(app, currApp); 11903 if (app.adjSource instanceof ProcessRecord) { 11904 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11905 currApp.importanceReasonImportance = 11906 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11907 app.adjSourceProcState); 11908 } else if (app.adjSource instanceof ActivityRecord) { 11909 ActivityRecord r = (ActivityRecord)app.adjSource; 11910 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11911 } 11912 if (app.adjTarget instanceof ComponentName) { 11913 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11914 } 11915 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11916 // + " lru=" + currApp.lru); 11917 if (runList == null) { 11918 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11919 } 11920 runList.add(currApp); 11921 } 11922 } 11923 } 11924 return runList; 11925 } 11926 11927 public List<ApplicationInfo> getRunningExternalApplications() { 11928 enforceNotIsolatedCaller("getRunningExternalApplications"); 11929 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11930 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11931 if (runningApps != null && runningApps.size() > 0) { 11932 Set<String> extList = new HashSet<String>(); 11933 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11934 if (app.pkgList != null) { 11935 for (String pkg : app.pkgList) { 11936 extList.add(pkg); 11937 } 11938 } 11939 } 11940 IPackageManager pm = AppGlobals.getPackageManager(); 11941 for (String pkg : extList) { 11942 try { 11943 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11944 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11945 retList.add(info); 11946 } 11947 } catch (RemoteException e) { 11948 } 11949 } 11950 } 11951 return retList; 11952 } 11953 11954 @Override 11955 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11956 enforceNotIsolatedCaller("getMyMemoryState"); 11957 synchronized (this) { 11958 ProcessRecord proc; 11959 synchronized (mPidsSelfLocked) { 11960 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11961 } 11962 fillInProcMemInfo(proc, outInfo); 11963 } 11964 } 11965 11966 @Override 11967 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11968 if (checkCallingPermission(android.Manifest.permission.DUMP) 11969 != PackageManager.PERMISSION_GRANTED) { 11970 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11971 + Binder.getCallingPid() 11972 + ", uid=" + Binder.getCallingUid() 11973 + " without permission " 11974 + android.Manifest.permission.DUMP); 11975 return; 11976 } 11977 11978 boolean dumpAll = false; 11979 boolean dumpClient = false; 11980 String dumpPackage = null; 11981 11982 int opti = 0; 11983 while (opti < args.length) { 11984 String opt = args[opti]; 11985 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11986 break; 11987 } 11988 opti++; 11989 if ("-a".equals(opt)) { 11990 dumpAll = true; 11991 } else if ("-c".equals(opt)) { 11992 dumpClient = true; 11993 } else if ("-h".equals(opt)) { 11994 pw.println("Activity manager dump options:"); 11995 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11996 pw.println(" cmd may be one of:"); 11997 pw.println(" a[ctivities]: activity stack state"); 11998 pw.println(" r[recents]: recent activities state"); 11999 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 12000 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 12001 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 12002 pw.println(" o[om]: out of memory management"); 12003 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 12004 pw.println(" provider [COMP_SPEC]: provider client-side state"); 12005 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 12006 pw.println(" service [COMP_SPEC]: service client-side state"); 12007 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 12008 pw.println(" all: dump all activities"); 12009 pw.println(" top: dump the top activity"); 12010 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 12011 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 12012 pw.println(" a partial substring in a component name, a"); 12013 pw.println(" hex object identifier."); 12014 pw.println(" -a: include all available server state."); 12015 pw.println(" -c: include client state."); 12016 return; 12017 } else { 12018 pw.println("Unknown argument: " + opt + "; use -h for help"); 12019 } 12020 } 12021 12022 long origId = Binder.clearCallingIdentity(); 12023 boolean more = false; 12024 // Is the caller requesting to dump a particular piece of data? 12025 if (opti < args.length) { 12026 String cmd = args[opti]; 12027 opti++; 12028 if ("activities".equals(cmd) || "a".equals(cmd)) { 12029 synchronized (this) { 12030 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 12031 } 12032 } else if ("recents".equals(cmd) || "r".equals(cmd)) { 12033 synchronized (this) { 12034 dumpRecentsLocked(fd, pw, args, opti, true, null); 12035 } 12036 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 12037 String[] newArgs; 12038 String name; 12039 if (opti >= args.length) { 12040 name = null; 12041 newArgs = EMPTY_STRING_ARRAY; 12042 } else { 12043 name = args[opti]; 12044 opti++; 12045 newArgs = new String[args.length - opti]; 12046 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12047 args.length - opti); 12048 } 12049 synchronized (this) { 12050 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 12051 } 12052 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 12053 String[] newArgs; 12054 String name; 12055 if (opti >= args.length) { 12056 name = null; 12057 newArgs = EMPTY_STRING_ARRAY; 12058 } else { 12059 name = args[opti]; 12060 opti++; 12061 newArgs = new String[args.length - opti]; 12062 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12063 args.length - opti); 12064 } 12065 synchronized (this) { 12066 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 12067 } 12068 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 12069 String[] newArgs; 12070 String name; 12071 if (opti >= args.length) { 12072 name = null; 12073 newArgs = EMPTY_STRING_ARRAY; 12074 } else { 12075 name = args[opti]; 12076 opti++; 12077 newArgs = new String[args.length - opti]; 12078 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12079 args.length - opti); 12080 } 12081 synchronized (this) { 12082 dumpProcessesLocked(fd, pw, args, opti, true, name); 12083 } 12084 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 12085 synchronized (this) { 12086 dumpOomLocked(fd, pw, args, opti, true); 12087 } 12088 } else if ("provider".equals(cmd)) { 12089 String[] newArgs; 12090 String name; 12091 if (opti >= args.length) { 12092 name = null; 12093 newArgs = EMPTY_STRING_ARRAY; 12094 } else { 12095 name = args[opti]; 12096 opti++; 12097 newArgs = new String[args.length - opti]; 12098 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12099 } 12100 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 12101 pw.println("No providers match: " + name); 12102 pw.println("Use -h for help."); 12103 } 12104 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 12105 synchronized (this) { 12106 dumpProvidersLocked(fd, pw, args, opti, true, null); 12107 } 12108 } else if ("service".equals(cmd)) { 12109 String[] newArgs; 12110 String name; 12111 if (opti >= args.length) { 12112 name = null; 12113 newArgs = EMPTY_STRING_ARRAY; 12114 } else { 12115 name = args[opti]; 12116 opti++; 12117 newArgs = new String[args.length - opti]; 12118 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12119 args.length - opti); 12120 } 12121 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 12122 pw.println("No services match: " + name); 12123 pw.println("Use -h for help."); 12124 } 12125 } else if ("package".equals(cmd)) { 12126 String[] newArgs; 12127 if (opti >= args.length) { 12128 pw.println("package: no package name specified"); 12129 pw.println("Use -h for help."); 12130 } else { 12131 dumpPackage = args[opti]; 12132 opti++; 12133 newArgs = new String[args.length - opti]; 12134 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 12135 args.length - opti); 12136 args = newArgs; 12137 opti = 0; 12138 more = true; 12139 } 12140 } else if ("services".equals(cmd) || "s".equals(cmd)) { 12141 synchronized (this) { 12142 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 12143 } 12144 } else { 12145 // Dumping a single activity? 12146 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 12147 pw.println("Bad activity command, or no activities match: " + cmd); 12148 pw.println("Use -h for help."); 12149 } 12150 } 12151 if (!more) { 12152 Binder.restoreCallingIdentity(origId); 12153 return; 12154 } 12155 } 12156 12157 // No piece of data specified, dump everything. 12158 synchronized (this) { 12159 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12160 pw.println(); 12161 if (dumpAll) { 12162 pw.println("-------------------------------------------------------------------------------"); 12163 } 12164 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12165 pw.println(); 12166 if (dumpAll) { 12167 pw.println("-------------------------------------------------------------------------------"); 12168 } 12169 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12170 pw.println(); 12171 if (dumpAll) { 12172 pw.println("-------------------------------------------------------------------------------"); 12173 } 12174 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12175 pw.println(); 12176 if (dumpAll) { 12177 pw.println("-------------------------------------------------------------------------------"); 12178 } 12179 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12180 pw.println(); 12181 if (dumpAll) { 12182 pw.println("-------------------------------------------------------------------------------"); 12183 } 12184 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 12185 pw.println(); 12186 if (dumpAll) { 12187 pw.println("-------------------------------------------------------------------------------"); 12188 } 12189 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 12190 } 12191 Binder.restoreCallingIdentity(origId); 12192 } 12193 12194 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12195 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 12196 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 12197 12198 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 12199 dumpPackage); 12200 boolean needSep = printedAnything; 12201 12202 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 12203 dumpPackage, needSep, " mFocusedActivity: "); 12204 if (printed) { 12205 printedAnything = true; 12206 needSep = false; 12207 } 12208 12209 if (dumpPackage == null) { 12210 if (needSep) { 12211 pw.println(); 12212 } 12213 needSep = true; 12214 printedAnything = true; 12215 mStackSupervisor.dump(pw, " "); 12216 } 12217 12218 if (!printedAnything) { 12219 pw.println(" (nothing)"); 12220 } 12221 } 12222 12223 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12224 int opti, boolean dumpAll, String dumpPackage) { 12225 pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)"); 12226 12227 boolean printedAnything = false; 12228 12229 if (mRecentTasks.size() > 0) { 12230 boolean printedHeader = false; 12231 12232 final int N = mRecentTasks.size(); 12233 for (int i=0; i<N; i++) { 12234 TaskRecord tr = mRecentTasks.get(i); 12235 if (dumpPackage != null) { 12236 if (tr.realActivity == null || 12237 !dumpPackage.equals(tr.realActivity)) { 12238 continue; 12239 } 12240 } 12241 if (!printedHeader) { 12242 pw.println(" Recent tasks:"); 12243 printedHeader = true; 12244 printedAnything = true; 12245 } 12246 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 12247 pw.println(tr); 12248 if (dumpAll) { 12249 mRecentTasks.get(i).dump(pw, " "); 12250 } 12251 } 12252 } 12253 12254 if (!printedAnything) { 12255 pw.println(" (nothing)"); 12256 } 12257 } 12258 12259 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12260 int opti, boolean dumpAll, String dumpPackage) { 12261 boolean needSep = false; 12262 boolean printedAnything = false; 12263 int numPers = 0; 12264 12265 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 12266 12267 if (dumpAll) { 12268 final int NP = mProcessNames.getMap().size(); 12269 for (int ip=0; ip<NP; ip++) { 12270 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 12271 final int NA = procs.size(); 12272 for (int ia=0; ia<NA; ia++) { 12273 ProcessRecord r = procs.valueAt(ia); 12274 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12275 continue; 12276 } 12277 if (!needSep) { 12278 pw.println(" All known processes:"); 12279 needSep = true; 12280 printedAnything = true; 12281 } 12282 pw.print(r.persistent ? " *PERS*" : " *APP*"); 12283 pw.print(" UID "); pw.print(procs.keyAt(ia)); 12284 pw.print(" "); pw.println(r); 12285 r.dump(pw, " "); 12286 if (r.persistent) { 12287 numPers++; 12288 } 12289 } 12290 } 12291 } 12292 12293 if (mIsolatedProcesses.size() > 0) { 12294 boolean printed = false; 12295 for (int i=0; i<mIsolatedProcesses.size(); i++) { 12296 ProcessRecord r = mIsolatedProcesses.valueAt(i); 12297 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12298 continue; 12299 } 12300 if (!printed) { 12301 if (needSep) { 12302 pw.println(); 12303 } 12304 pw.println(" Isolated process list (sorted by uid):"); 12305 printedAnything = true; 12306 printed = true; 12307 needSep = true; 12308 } 12309 pw.println(String.format("%sIsolated #%2d: %s", 12310 " ", i, r.toString())); 12311 } 12312 } 12313 12314 if (mLruProcesses.size() > 0) { 12315 if (needSep) { 12316 pw.println(); 12317 } 12318 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 12319 pw.print(" total, non-act at "); 12320 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12321 pw.print(", non-svc at "); 12322 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12323 pw.println("):"); 12324 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 12325 needSep = true; 12326 printedAnything = true; 12327 } 12328 12329 if (dumpAll || dumpPackage != null) { 12330 synchronized (mPidsSelfLocked) { 12331 boolean printed = false; 12332 for (int i=0; i<mPidsSelfLocked.size(); i++) { 12333 ProcessRecord r = mPidsSelfLocked.valueAt(i); 12334 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12335 continue; 12336 } 12337 if (!printed) { 12338 if (needSep) pw.println(); 12339 needSep = true; 12340 pw.println(" PID mappings:"); 12341 printed = true; 12342 printedAnything = true; 12343 } 12344 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 12345 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 12346 } 12347 } 12348 } 12349 12350 if (mForegroundProcesses.size() > 0) { 12351 synchronized (mPidsSelfLocked) { 12352 boolean printed = false; 12353 for (int i=0; i<mForegroundProcesses.size(); i++) { 12354 ProcessRecord r = mPidsSelfLocked.get( 12355 mForegroundProcesses.valueAt(i).pid); 12356 if (dumpPackage != null && (r == null 12357 || !r.pkgList.containsKey(dumpPackage))) { 12358 continue; 12359 } 12360 if (!printed) { 12361 if (needSep) pw.println(); 12362 needSep = true; 12363 pw.println(" Foreground Processes:"); 12364 printed = true; 12365 printedAnything = true; 12366 } 12367 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 12368 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 12369 } 12370 } 12371 } 12372 12373 if (mPersistentStartingProcesses.size() > 0) { 12374 if (needSep) pw.println(); 12375 needSep = true; 12376 printedAnything = true; 12377 pw.println(" Persisent processes that are starting:"); 12378 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 12379 "Starting Norm", "Restarting PERS", dumpPackage); 12380 } 12381 12382 if (mRemovedProcesses.size() > 0) { 12383 if (needSep) pw.println(); 12384 needSep = true; 12385 printedAnything = true; 12386 pw.println(" Processes that are being removed:"); 12387 dumpProcessList(pw, this, mRemovedProcesses, " ", 12388 "Removed Norm", "Removed PERS", dumpPackage); 12389 } 12390 12391 if (mProcessesOnHold.size() > 0) { 12392 if (needSep) pw.println(); 12393 needSep = true; 12394 printedAnything = true; 12395 pw.println(" Processes that are on old until the system is ready:"); 12396 dumpProcessList(pw, this, mProcessesOnHold, " ", 12397 "OnHold Norm", "OnHold PERS", dumpPackage); 12398 } 12399 12400 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 12401 12402 if (mProcessCrashTimes.getMap().size() > 0) { 12403 boolean printed = false; 12404 long now = SystemClock.uptimeMillis(); 12405 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 12406 final int NP = pmap.size(); 12407 for (int ip=0; ip<NP; ip++) { 12408 String pname = pmap.keyAt(ip); 12409 SparseArray<Long> uids = pmap.valueAt(ip); 12410 final int N = uids.size(); 12411 for (int i=0; i<N; i++) { 12412 int puid = uids.keyAt(i); 12413 ProcessRecord r = mProcessNames.get(pname, puid); 12414 if (dumpPackage != null && (r == null 12415 || !r.pkgList.containsKey(dumpPackage))) { 12416 continue; 12417 } 12418 if (!printed) { 12419 if (needSep) pw.println(); 12420 needSep = true; 12421 pw.println(" Time since processes crashed:"); 12422 printed = true; 12423 printedAnything = true; 12424 } 12425 pw.print(" Process "); pw.print(pname); 12426 pw.print(" uid "); pw.print(puid); 12427 pw.print(": last crashed "); 12428 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 12429 pw.println(" ago"); 12430 } 12431 } 12432 } 12433 12434 if (mBadProcesses.getMap().size() > 0) { 12435 boolean printed = false; 12436 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 12437 final int NP = pmap.size(); 12438 for (int ip=0; ip<NP; ip++) { 12439 String pname = pmap.keyAt(ip); 12440 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 12441 final int N = uids.size(); 12442 for (int i=0; i<N; i++) { 12443 int puid = uids.keyAt(i); 12444 ProcessRecord r = mProcessNames.get(pname, puid); 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(" Bad processes:"); 12453 printedAnything = true; 12454 } 12455 BadProcessInfo info = uids.valueAt(i); 12456 pw.print(" Bad process "); pw.print(pname); 12457 pw.print(" uid "); pw.print(puid); 12458 pw.print(": crashed at time "); pw.println(info.time); 12459 if (info.shortMsg != null) { 12460 pw.print(" Short msg: "); pw.println(info.shortMsg); 12461 } 12462 if (info.longMsg != null) { 12463 pw.print(" Long msg: "); pw.println(info.longMsg); 12464 } 12465 if (info.stack != null) { 12466 pw.println(" Stack:"); 12467 int lastPos = 0; 12468 for (int pos=0; pos<info.stack.length(); pos++) { 12469 if (info.stack.charAt(pos) == '\n') { 12470 pw.print(" "); 12471 pw.write(info.stack, lastPos, pos-lastPos); 12472 pw.println(); 12473 lastPos = pos+1; 12474 } 12475 } 12476 if (lastPos < info.stack.length()) { 12477 pw.print(" "); 12478 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 12479 pw.println(); 12480 } 12481 } 12482 } 12483 } 12484 } 12485 12486 if (dumpPackage == null) { 12487 pw.println(); 12488 needSep = false; 12489 pw.println(" mStartedUsers:"); 12490 for (int i=0; i<mStartedUsers.size(); i++) { 12491 UserStartedState uss = mStartedUsers.valueAt(i); 12492 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 12493 pw.print(": "); uss.dump("", pw); 12494 } 12495 pw.print(" mStartedUserArray: ["); 12496 for (int i=0; i<mStartedUserArray.length; i++) { 12497 if (i > 0) pw.print(", "); 12498 pw.print(mStartedUserArray[i]); 12499 } 12500 pw.println("]"); 12501 pw.print(" mUserLru: ["); 12502 for (int i=0; i<mUserLru.size(); i++) { 12503 if (i > 0) pw.print(", "); 12504 pw.print(mUserLru.get(i)); 12505 } 12506 pw.println("]"); 12507 if (dumpAll) { 12508 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 12509 } 12510 synchronized (mUserProfileGroupIdsSelfLocked) { 12511 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 12512 pw.println(" mUserProfileGroupIds:"); 12513 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 12514 pw.print(" User #"); 12515 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 12516 pw.print(" -> profile #"); 12517 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 12518 } 12519 } 12520 } 12521 } 12522 if (mHomeProcess != null && (dumpPackage == null 12523 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 12524 if (needSep) { 12525 pw.println(); 12526 needSep = false; 12527 } 12528 pw.println(" mHomeProcess: " + mHomeProcess); 12529 } 12530 if (mPreviousProcess != null && (dumpPackage == null 12531 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 12532 if (needSep) { 12533 pw.println(); 12534 needSep = false; 12535 } 12536 pw.println(" mPreviousProcess: " + mPreviousProcess); 12537 } 12538 if (dumpAll) { 12539 StringBuilder sb = new StringBuilder(128); 12540 sb.append(" mPreviousProcessVisibleTime: "); 12541 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 12542 pw.println(sb); 12543 } 12544 if (mHeavyWeightProcess != null && (dumpPackage == null 12545 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 12546 if (needSep) { 12547 pw.println(); 12548 needSep = false; 12549 } 12550 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12551 } 12552 if (dumpPackage == null) { 12553 pw.println(" mConfiguration: " + mConfiguration); 12554 } 12555 if (dumpAll) { 12556 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 12557 if (mCompatModePackages.getPackages().size() > 0) { 12558 boolean printed = false; 12559 for (Map.Entry<String, Integer> entry 12560 : mCompatModePackages.getPackages().entrySet()) { 12561 String pkg = entry.getKey(); 12562 int mode = entry.getValue(); 12563 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 12564 continue; 12565 } 12566 if (!printed) { 12567 pw.println(" mScreenCompatPackages:"); 12568 printed = true; 12569 } 12570 pw.print(" "); pw.print(pkg); pw.print(": "); 12571 pw.print(mode); pw.println(); 12572 } 12573 } 12574 } 12575 if (dumpPackage == null) { 12576 if (mSleeping || mWentToSleep || mLockScreenShown) { 12577 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 12578 + " mLockScreenShown " + mLockScreenShown); 12579 } 12580 if (mShuttingDown || mRunningVoice) { 12581 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 12582 } 12583 } 12584 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 12585 || mOrigWaitForDebugger) { 12586 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 12587 || dumpPackage.equals(mOrigDebugApp)) { 12588 if (needSep) { 12589 pw.println(); 12590 needSep = false; 12591 } 12592 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 12593 + " mDebugTransient=" + mDebugTransient 12594 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 12595 } 12596 } 12597 if (mOpenGlTraceApp != null) { 12598 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 12599 if (needSep) { 12600 pw.println(); 12601 needSep = false; 12602 } 12603 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 12604 } 12605 } 12606 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 12607 || mProfileFd != null) { 12608 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 12609 if (needSep) { 12610 pw.println(); 12611 needSep = false; 12612 } 12613 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 12614 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 12615 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler=" 12616 + mAutoStopProfiler); 12617 pw.println(" mProfileType=" + mProfileType); 12618 } 12619 } 12620 if (dumpPackage == null) { 12621 if (mAlwaysFinishActivities || mController != null) { 12622 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 12623 + " mController=" + mController); 12624 } 12625 if (dumpAll) { 12626 pw.println(" Total persistent processes: " + numPers); 12627 pw.println(" mProcessesReady=" + mProcessesReady 12628 + " mSystemReady=" + mSystemReady); 12629 pw.println(" mBooting=" + mBooting 12630 + " mBooted=" + mBooted 12631 + " mFactoryTest=" + mFactoryTest); 12632 pw.print(" mLastPowerCheckRealtime="); 12633 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 12634 pw.println(""); 12635 pw.print(" mLastPowerCheckUptime="); 12636 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 12637 pw.println(""); 12638 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 12639 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 12640 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 12641 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 12642 + " (" + mLruProcesses.size() + " total)" 12643 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 12644 + " mNumServiceProcs=" + mNumServiceProcs 12645 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 12646 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 12647 + " mLastMemoryLevel" + mLastMemoryLevel 12648 + " mLastNumProcesses" + mLastNumProcesses); 12649 long now = SystemClock.uptimeMillis(); 12650 pw.print(" mLastIdleTime="); 12651 TimeUtils.formatDuration(now, mLastIdleTime, pw); 12652 pw.print(" mLowRamSinceLastIdle="); 12653 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 12654 pw.println(); 12655 } 12656 } 12657 12658 if (!printedAnything) { 12659 pw.println(" (nothing)"); 12660 } 12661 } 12662 12663 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 12664 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 12665 if (mProcessesToGc.size() > 0) { 12666 boolean printed = false; 12667 long now = SystemClock.uptimeMillis(); 12668 for (int i=0; i<mProcessesToGc.size(); i++) { 12669 ProcessRecord proc = mProcessesToGc.get(i); 12670 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 12671 continue; 12672 } 12673 if (!printed) { 12674 if (needSep) pw.println(); 12675 needSep = true; 12676 pw.println(" Processes that are waiting to GC:"); 12677 printed = true; 12678 } 12679 pw.print(" Process "); pw.println(proc); 12680 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 12681 pw.print(", last gced="); 12682 pw.print(now-proc.lastRequestedGc); 12683 pw.print(" ms ago, last lowMem="); 12684 pw.print(now-proc.lastLowMemory); 12685 pw.println(" ms ago"); 12686 12687 } 12688 } 12689 return needSep; 12690 } 12691 12692 void printOomLevel(PrintWriter pw, String name, int adj) { 12693 pw.print(" "); 12694 if (adj >= 0) { 12695 pw.print(' '); 12696 if (adj < 10) pw.print(' '); 12697 } else { 12698 if (adj > -10) pw.print(' '); 12699 } 12700 pw.print(adj); 12701 pw.print(": "); 12702 pw.print(name); 12703 pw.print(" ("); 12704 pw.print(mProcessList.getMemLevel(adj)/1024); 12705 pw.println(" kB)"); 12706 } 12707 12708 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12709 int opti, boolean dumpAll) { 12710 boolean needSep = false; 12711 12712 if (mLruProcesses.size() > 0) { 12713 if (needSep) pw.println(); 12714 needSep = true; 12715 pw.println(" OOM levels:"); 12716 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 12717 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 12718 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 12719 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 12720 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 12721 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 12722 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 12723 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 12724 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 12725 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 12726 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 12727 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 12728 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 12729 12730 if (needSep) pw.println(); 12731 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 12732 pw.print(" total, non-act at "); 12733 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 12734 pw.print(", non-svc at "); 12735 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 12736 pw.println("):"); 12737 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 12738 needSep = true; 12739 } 12740 12741 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 12742 12743 pw.println(); 12744 pw.println(" mHomeProcess: " + mHomeProcess); 12745 pw.println(" mPreviousProcess: " + mPreviousProcess); 12746 if (mHeavyWeightProcess != null) { 12747 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 12748 } 12749 12750 return true; 12751 } 12752 12753 /** 12754 * There are three ways to call this: 12755 * - no provider specified: dump all the providers 12756 * - a flattened component name that matched an existing provider was specified as the 12757 * first arg: dump that one provider 12758 * - the first arg isn't the flattened component name of an existing provider: 12759 * dump all providers whose component contains the first arg as a substring 12760 */ 12761 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12762 int opti, boolean dumpAll) { 12763 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 12764 } 12765 12766 static class ItemMatcher { 12767 ArrayList<ComponentName> components; 12768 ArrayList<String> strings; 12769 ArrayList<Integer> objects; 12770 boolean all; 12771 12772 ItemMatcher() { 12773 all = true; 12774 } 12775 12776 void build(String name) { 12777 ComponentName componentName = ComponentName.unflattenFromString(name); 12778 if (componentName != null) { 12779 if (components == null) { 12780 components = new ArrayList<ComponentName>(); 12781 } 12782 components.add(componentName); 12783 all = false; 12784 } else { 12785 int objectId = 0; 12786 // Not a '/' separated full component name; maybe an object ID? 12787 try { 12788 objectId = Integer.parseInt(name, 16); 12789 if (objects == null) { 12790 objects = new ArrayList<Integer>(); 12791 } 12792 objects.add(objectId); 12793 all = false; 12794 } catch (RuntimeException e) { 12795 // Not an integer; just do string match. 12796 if (strings == null) { 12797 strings = new ArrayList<String>(); 12798 } 12799 strings.add(name); 12800 all = false; 12801 } 12802 } 12803 } 12804 12805 int build(String[] args, int opti) { 12806 for (; opti<args.length; opti++) { 12807 String name = args[opti]; 12808 if ("--".equals(name)) { 12809 return opti+1; 12810 } 12811 build(name); 12812 } 12813 return opti; 12814 } 12815 12816 boolean match(Object object, ComponentName comp) { 12817 if (all) { 12818 return true; 12819 } 12820 if (components != null) { 12821 for (int i=0; i<components.size(); i++) { 12822 if (components.get(i).equals(comp)) { 12823 return true; 12824 } 12825 } 12826 } 12827 if (objects != null) { 12828 for (int i=0; i<objects.size(); i++) { 12829 if (System.identityHashCode(object) == objects.get(i)) { 12830 return true; 12831 } 12832 } 12833 } 12834 if (strings != null) { 12835 String flat = comp.flattenToString(); 12836 for (int i=0; i<strings.size(); i++) { 12837 if (flat.contains(strings.get(i))) { 12838 return true; 12839 } 12840 } 12841 } 12842 return false; 12843 } 12844 } 12845 12846 /** 12847 * There are three things that cmd can be: 12848 * - a flattened component name that matches an existing activity 12849 * - the cmd arg isn't the flattened component name of an existing activity: 12850 * dump all activity whose component contains the cmd as a substring 12851 * - A hex number of the ActivityRecord object instance. 12852 */ 12853 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12854 int opti, boolean dumpAll) { 12855 ArrayList<ActivityRecord> activities; 12856 12857 synchronized (this) { 12858 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12859 } 12860 12861 if (activities.size() <= 0) { 12862 return false; 12863 } 12864 12865 String[] newArgs = new String[args.length - opti]; 12866 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12867 12868 TaskRecord lastTask = null; 12869 boolean needSep = false; 12870 for (int i=activities.size()-1; i>=0; i--) { 12871 ActivityRecord r = activities.get(i); 12872 if (needSep) { 12873 pw.println(); 12874 } 12875 needSep = true; 12876 synchronized (this) { 12877 if (lastTask != r.task) { 12878 lastTask = r.task; 12879 pw.print("TASK "); pw.print(lastTask.affinity); 12880 pw.print(" id="); pw.println(lastTask.taskId); 12881 if (dumpAll) { 12882 lastTask.dump(pw, " "); 12883 } 12884 } 12885 } 12886 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12887 } 12888 return true; 12889 } 12890 12891 /** 12892 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12893 * there is a thread associated with the activity. 12894 */ 12895 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12896 final ActivityRecord r, String[] args, boolean dumpAll) { 12897 String innerPrefix = prefix + " "; 12898 synchronized (this) { 12899 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12900 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12901 pw.print(" pid="); 12902 if (r.app != null) pw.println(r.app.pid); 12903 else pw.println("(not running)"); 12904 if (dumpAll) { 12905 r.dump(pw, innerPrefix); 12906 } 12907 } 12908 if (r.app != null && r.app.thread != null) { 12909 // flush anything that is already in the PrintWriter since the thread is going 12910 // to write to the file descriptor directly 12911 pw.flush(); 12912 try { 12913 TransferPipe tp = new TransferPipe(); 12914 try { 12915 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12916 r.appToken, innerPrefix, args); 12917 tp.go(fd); 12918 } finally { 12919 tp.kill(); 12920 } 12921 } catch (IOException e) { 12922 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12923 } catch (RemoteException e) { 12924 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12925 } 12926 } 12927 } 12928 12929 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12930 int opti, boolean dumpAll, String dumpPackage) { 12931 boolean needSep = false; 12932 boolean onlyHistory = false; 12933 boolean printedAnything = false; 12934 12935 if ("history".equals(dumpPackage)) { 12936 if (opti < args.length && "-s".equals(args[opti])) { 12937 dumpAll = false; 12938 } 12939 onlyHistory = true; 12940 dumpPackage = null; 12941 } 12942 12943 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12944 if (!onlyHistory && dumpAll) { 12945 if (mRegisteredReceivers.size() > 0) { 12946 boolean printed = false; 12947 Iterator it = mRegisteredReceivers.values().iterator(); 12948 while (it.hasNext()) { 12949 ReceiverList r = (ReceiverList)it.next(); 12950 if (dumpPackage != null && (r.app == null || 12951 !dumpPackage.equals(r.app.info.packageName))) { 12952 continue; 12953 } 12954 if (!printed) { 12955 pw.println(" Registered Receivers:"); 12956 needSep = true; 12957 printed = true; 12958 printedAnything = true; 12959 } 12960 pw.print(" * "); pw.println(r); 12961 r.dump(pw, " "); 12962 } 12963 } 12964 12965 if (mReceiverResolver.dump(pw, needSep ? 12966 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12967 " ", dumpPackage, false)) { 12968 needSep = true; 12969 printedAnything = true; 12970 } 12971 } 12972 12973 for (BroadcastQueue q : mBroadcastQueues) { 12974 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12975 printedAnything |= needSep; 12976 } 12977 12978 needSep = true; 12979 12980 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12981 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12982 if (needSep) { 12983 pw.println(); 12984 } 12985 needSep = true; 12986 printedAnything = true; 12987 pw.print(" Sticky broadcasts for user "); 12988 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12989 StringBuilder sb = new StringBuilder(128); 12990 for (Map.Entry<String, ArrayList<Intent>> ent 12991 : mStickyBroadcasts.valueAt(user).entrySet()) { 12992 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12993 if (dumpAll) { 12994 pw.println(":"); 12995 ArrayList<Intent> intents = ent.getValue(); 12996 final int N = intents.size(); 12997 for (int i=0; i<N; i++) { 12998 sb.setLength(0); 12999 sb.append(" Intent: "); 13000 intents.get(i).toShortString(sb, false, true, false, false); 13001 pw.println(sb.toString()); 13002 Bundle bundle = intents.get(i).getExtras(); 13003 if (bundle != null) { 13004 pw.print(" "); 13005 pw.println(bundle.toString()); 13006 } 13007 } 13008 } else { 13009 pw.println(""); 13010 } 13011 } 13012 } 13013 } 13014 13015 if (!onlyHistory && dumpAll) { 13016 pw.println(); 13017 for (BroadcastQueue queue : mBroadcastQueues) { 13018 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 13019 + queue.mBroadcastsScheduled); 13020 } 13021 pw.println(" mHandler:"); 13022 mHandler.dump(new PrintWriterPrinter(pw), " "); 13023 needSep = true; 13024 printedAnything = true; 13025 } 13026 13027 if (!printedAnything) { 13028 pw.println(" (nothing)"); 13029 } 13030 } 13031 13032 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13033 int opti, boolean dumpAll, String dumpPackage) { 13034 boolean needSep; 13035 boolean printedAnything = false; 13036 13037 ItemMatcher matcher = new ItemMatcher(); 13038 matcher.build(args, opti); 13039 13040 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 13041 13042 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 13043 printedAnything |= needSep; 13044 13045 if (mLaunchingProviders.size() > 0) { 13046 boolean printed = false; 13047 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 13048 ContentProviderRecord r = mLaunchingProviders.get(i); 13049 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 13050 continue; 13051 } 13052 if (!printed) { 13053 if (needSep) pw.println(); 13054 needSep = true; 13055 pw.println(" Launching content providers:"); 13056 printed = true; 13057 printedAnything = true; 13058 } 13059 pw.print(" Launching #"); pw.print(i); pw.print(": "); 13060 pw.println(r); 13061 } 13062 } 13063 13064 if (mGrantedUriPermissions.size() > 0) { 13065 boolean printed = false; 13066 int dumpUid = -2; 13067 if (dumpPackage != null) { 13068 try { 13069 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 13070 } catch (NameNotFoundException e) { 13071 dumpUid = -1; 13072 } 13073 } 13074 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 13075 int uid = mGrantedUriPermissions.keyAt(i); 13076 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 13077 continue; 13078 } 13079 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 13080 if (!printed) { 13081 if (needSep) pw.println(); 13082 needSep = true; 13083 pw.println(" Granted Uri Permissions:"); 13084 printed = true; 13085 printedAnything = true; 13086 } 13087 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 13088 for (UriPermission perm : perms.values()) { 13089 pw.print(" "); pw.println(perm); 13090 if (dumpAll) { 13091 perm.dump(pw, " "); 13092 } 13093 } 13094 } 13095 } 13096 13097 if (!printedAnything) { 13098 pw.println(" (nothing)"); 13099 } 13100 } 13101 13102 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 13103 int opti, boolean dumpAll, String dumpPackage) { 13104 boolean printed = false; 13105 13106 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 13107 13108 if (mIntentSenderRecords.size() > 0) { 13109 Iterator<WeakReference<PendingIntentRecord>> it 13110 = mIntentSenderRecords.values().iterator(); 13111 while (it.hasNext()) { 13112 WeakReference<PendingIntentRecord> ref = it.next(); 13113 PendingIntentRecord rec = ref != null ? ref.get(): null; 13114 if (dumpPackage != null && (rec == null 13115 || !dumpPackage.equals(rec.key.packageName))) { 13116 continue; 13117 } 13118 printed = true; 13119 if (rec != null) { 13120 pw.print(" * "); pw.println(rec); 13121 if (dumpAll) { 13122 rec.dump(pw, " "); 13123 } 13124 } else { 13125 pw.print(" * "); pw.println(ref); 13126 } 13127 } 13128 } 13129 13130 if (!printed) { 13131 pw.println(" (nothing)"); 13132 } 13133 } 13134 13135 private static final int dumpProcessList(PrintWriter pw, 13136 ActivityManagerService service, List list, 13137 String prefix, String normalLabel, String persistentLabel, 13138 String dumpPackage) { 13139 int numPers = 0; 13140 final int N = list.size()-1; 13141 for (int i=N; i>=0; i--) { 13142 ProcessRecord r = (ProcessRecord)list.get(i); 13143 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 13144 continue; 13145 } 13146 pw.println(String.format("%s%s #%2d: %s", 13147 prefix, (r.persistent ? persistentLabel : normalLabel), 13148 i, r.toString())); 13149 if (r.persistent) { 13150 numPers++; 13151 } 13152 } 13153 return numPers; 13154 } 13155 13156 private static final boolean dumpProcessOomList(PrintWriter pw, 13157 ActivityManagerService service, List<ProcessRecord> origList, 13158 String prefix, String normalLabel, String persistentLabel, 13159 boolean inclDetails, String dumpPackage) { 13160 13161 ArrayList<Pair<ProcessRecord, Integer>> list 13162 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 13163 for (int i=0; i<origList.size(); i++) { 13164 ProcessRecord r = origList.get(i); 13165 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 13166 continue; 13167 } 13168 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 13169 } 13170 13171 if (list.size() <= 0) { 13172 return false; 13173 } 13174 13175 Comparator<Pair<ProcessRecord, Integer>> comparator 13176 = new Comparator<Pair<ProcessRecord, Integer>>() { 13177 @Override 13178 public int compare(Pair<ProcessRecord, Integer> object1, 13179 Pair<ProcessRecord, Integer> object2) { 13180 if (object1.first.setAdj != object2.first.setAdj) { 13181 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 13182 } 13183 if (object1.second.intValue() != object2.second.intValue()) { 13184 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 13185 } 13186 return 0; 13187 } 13188 }; 13189 13190 Collections.sort(list, comparator); 13191 13192 final long curRealtime = SystemClock.elapsedRealtime(); 13193 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 13194 final long curUptime = SystemClock.uptimeMillis(); 13195 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 13196 13197 for (int i=list.size()-1; i>=0; i--) { 13198 ProcessRecord r = list.get(i).first; 13199 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 13200 char schedGroup; 13201 switch (r.setSchedGroup) { 13202 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 13203 schedGroup = 'B'; 13204 break; 13205 case Process.THREAD_GROUP_DEFAULT: 13206 schedGroup = 'F'; 13207 break; 13208 default: 13209 schedGroup = '?'; 13210 break; 13211 } 13212 char foreground; 13213 if (r.foregroundActivities) { 13214 foreground = 'A'; 13215 } else if (r.foregroundServices) { 13216 foreground = 'S'; 13217 } else { 13218 foreground = ' '; 13219 } 13220 String procState = ProcessList.makeProcStateString(r.curProcState); 13221 pw.print(prefix); 13222 pw.print(r.persistent ? persistentLabel : normalLabel); 13223 pw.print(" #"); 13224 int num = (origList.size()-1)-list.get(i).second; 13225 if (num < 10) pw.print(' '); 13226 pw.print(num); 13227 pw.print(": "); 13228 pw.print(oomAdj); 13229 pw.print(' '); 13230 pw.print(schedGroup); 13231 pw.print('/'); 13232 pw.print(foreground); 13233 pw.print('/'); 13234 pw.print(procState); 13235 pw.print(" trm:"); 13236 if (r.trimMemoryLevel < 10) pw.print(' '); 13237 pw.print(r.trimMemoryLevel); 13238 pw.print(' '); 13239 pw.print(r.toShortString()); 13240 pw.print(" ("); 13241 pw.print(r.adjType); 13242 pw.println(')'); 13243 if (r.adjSource != null || r.adjTarget != null) { 13244 pw.print(prefix); 13245 pw.print(" "); 13246 if (r.adjTarget instanceof ComponentName) { 13247 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 13248 } else if (r.adjTarget != null) { 13249 pw.print(r.adjTarget.toString()); 13250 } else { 13251 pw.print("{null}"); 13252 } 13253 pw.print("<="); 13254 if (r.adjSource instanceof ProcessRecord) { 13255 pw.print("Proc{"); 13256 pw.print(((ProcessRecord)r.adjSource).toShortString()); 13257 pw.println("}"); 13258 } else if (r.adjSource != null) { 13259 pw.println(r.adjSource.toString()); 13260 } else { 13261 pw.println("{null}"); 13262 } 13263 } 13264 if (inclDetails) { 13265 pw.print(prefix); 13266 pw.print(" "); 13267 pw.print("oom: max="); pw.print(r.maxAdj); 13268 pw.print(" curRaw="); pw.print(r.curRawAdj); 13269 pw.print(" setRaw="); pw.print(r.setRawAdj); 13270 pw.print(" cur="); pw.print(r.curAdj); 13271 pw.print(" set="); pw.println(r.setAdj); 13272 pw.print(prefix); 13273 pw.print(" "); 13274 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 13275 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 13276 pw.print(" lastPss="); pw.print(r.lastPss); 13277 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 13278 pw.print(prefix); 13279 pw.print(" "); 13280 pw.print("cached="); pw.print(r.cached); 13281 pw.print(" empty="); pw.print(r.empty); 13282 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 13283 13284 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 13285 if (r.lastWakeTime != 0) { 13286 long wtime; 13287 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 13288 synchronized (stats) { 13289 wtime = stats.getProcessWakeTime(r.info.uid, 13290 r.pid, curRealtime); 13291 } 13292 long timeUsed = wtime - r.lastWakeTime; 13293 pw.print(prefix); 13294 pw.print(" "); 13295 pw.print("keep awake over "); 13296 TimeUtils.formatDuration(realtimeSince, pw); 13297 pw.print(" used "); 13298 TimeUtils.formatDuration(timeUsed, pw); 13299 pw.print(" ("); 13300 pw.print((timeUsed*100)/realtimeSince); 13301 pw.println("%)"); 13302 } 13303 if (r.lastCpuTime != 0) { 13304 long timeUsed = r.curCpuTime - r.lastCpuTime; 13305 pw.print(prefix); 13306 pw.print(" "); 13307 pw.print("run cpu over "); 13308 TimeUtils.formatDuration(uptimeSince, pw); 13309 pw.print(" used "); 13310 TimeUtils.formatDuration(timeUsed, pw); 13311 pw.print(" ("); 13312 pw.print((timeUsed*100)/uptimeSince); 13313 pw.println("%)"); 13314 } 13315 } 13316 } 13317 } 13318 return true; 13319 } 13320 13321 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 13322 ArrayList<ProcessRecord> procs; 13323 synchronized (this) { 13324 if (args != null && args.length > start 13325 && args[start].charAt(0) != '-') { 13326 procs = new ArrayList<ProcessRecord>(); 13327 int pid = -1; 13328 try { 13329 pid = Integer.parseInt(args[start]); 13330 } catch (NumberFormatException e) { 13331 } 13332 for (int i=mLruProcesses.size()-1; i>=0; i--) { 13333 ProcessRecord proc = mLruProcesses.get(i); 13334 if (proc.pid == pid) { 13335 procs.add(proc); 13336 } else if (proc.processName.equals(args[start])) { 13337 procs.add(proc); 13338 } 13339 } 13340 if (procs.size() <= 0) { 13341 return null; 13342 } 13343 } else { 13344 procs = new ArrayList<ProcessRecord>(mLruProcesses); 13345 } 13346 } 13347 return procs; 13348 } 13349 13350 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 13351 PrintWriter pw, String[] args) { 13352 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13353 if (procs == null) { 13354 pw.println("No process found for: " + args[0]); 13355 return; 13356 } 13357 13358 long uptime = SystemClock.uptimeMillis(); 13359 long realtime = SystemClock.elapsedRealtime(); 13360 pw.println("Applications Graphics Acceleration Info:"); 13361 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13362 13363 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13364 ProcessRecord r = procs.get(i); 13365 if (r.thread != null) { 13366 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 13367 pw.flush(); 13368 try { 13369 TransferPipe tp = new TransferPipe(); 13370 try { 13371 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 13372 tp.go(fd); 13373 } finally { 13374 tp.kill(); 13375 } 13376 } catch (IOException e) { 13377 pw.println("Failure while dumping the app: " + r); 13378 pw.flush(); 13379 } catch (RemoteException e) { 13380 pw.println("Got a RemoteException while dumping the app " + r); 13381 pw.flush(); 13382 } 13383 } 13384 } 13385 } 13386 13387 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 13388 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 13389 if (procs == null) { 13390 pw.println("No process found for: " + args[0]); 13391 return; 13392 } 13393 13394 pw.println("Applications Database Info:"); 13395 13396 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13397 ProcessRecord r = procs.get(i); 13398 if (r.thread != null) { 13399 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 13400 pw.flush(); 13401 try { 13402 TransferPipe tp = new TransferPipe(); 13403 try { 13404 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 13405 tp.go(fd); 13406 } finally { 13407 tp.kill(); 13408 } 13409 } catch (IOException e) { 13410 pw.println("Failure while dumping the app: " + r); 13411 pw.flush(); 13412 } catch (RemoteException e) { 13413 pw.println("Got a RemoteException while dumping the app " + r); 13414 pw.flush(); 13415 } 13416 } 13417 } 13418 } 13419 13420 final static class MemItem { 13421 final boolean isProc; 13422 final String label; 13423 final String shortLabel; 13424 final long pss; 13425 final int id; 13426 final boolean hasActivities; 13427 ArrayList<MemItem> subitems; 13428 13429 public MemItem(String _label, String _shortLabel, long _pss, int _id, 13430 boolean _hasActivities) { 13431 isProc = true; 13432 label = _label; 13433 shortLabel = _shortLabel; 13434 pss = _pss; 13435 id = _id; 13436 hasActivities = _hasActivities; 13437 } 13438 13439 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 13440 isProc = false; 13441 label = _label; 13442 shortLabel = _shortLabel; 13443 pss = _pss; 13444 id = _id; 13445 hasActivities = false; 13446 } 13447 } 13448 13449 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 13450 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 13451 if (sort && !isCompact) { 13452 Collections.sort(items, new Comparator<MemItem>() { 13453 @Override 13454 public int compare(MemItem lhs, MemItem rhs) { 13455 if (lhs.pss < rhs.pss) { 13456 return 1; 13457 } else if (lhs.pss > rhs.pss) { 13458 return -1; 13459 } 13460 return 0; 13461 } 13462 }); 13463 } 13464 13465 for (int i=0; i<items.size(); i++) { 13466 MemItem mi = items.get(i); 13467 if (!isCompact) { 13468 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 13469 } else if (mi.isProc) { 13470 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 13471 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 13472 pw.println(mi.hasActivities ? ",a" : ",e"); 13473 } else { 13474 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 13475 pw.println(mi.pss); 13476 } 13477 if (mi.subitems != null) { 13478 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 13479 true, isCompact); 13480 } 13481 } 13482 } 13483 13484 // These are in KB. 13485 static final long[] DUMP_MEM_BUCKETS = new long[] { 13486 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 13487 120*1024, 160*1024, 200*1024, 13488 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 13489 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 13490 }; 13491 13492 static final void appendMemBucket(StringBuilder out, long memKB, String label, 13493 boolean stackLike) { 13494 int start = label.lastIndexOf('.'); 13495 if (start >= 0) start++; 13496 else start = 0; 13497 int end = label.length(); 13498 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 13499 if (DUMP_MEM_BUCKETS[i] >= memKB) { 13500 long bucket = DUMP_MEM_BUCKETS[i]/1024; 13501 out.append(bucket); 13502 out.append(stackLike ? "MB." : "MB "); 13503 out.append(label, start, end); 13504 return; 13505 } 13506 } 13507 out.append(memKB/1024); 13508 out.append(stackLike ? "MB." : "MB "); 13509 out.append(label, start, end); 13510 } 13511 13512 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 13513 ProcessList.NATIVE_ADJ, 13514 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 13515 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 13516 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 13517 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 13518 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 13519 }; 13520 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 13521 "Native", 13522 "System", "Persistent", "Foreground", 13523 "Visible", "Perceptible", 13524 "Heavy Weight", "Backup", 13525 "A Services", "Home", 13526 "Previous", "B Services", "Cached" 13527 }; 13528 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 13529 "native", 13530 "sys", "pers", "fore", 13531 "vis", "percept", 13532 "heavy", "backup", 13533 "servicea", "home", 13534 "prev", "serviceb", "cached" 13535 }; 13536 13537 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 13538 long realtime, boolean isCheckinRequest, boolean isCompact) { 13539 if (isCheckinRequest || isCompact) { 13540 // short checkin version 13541 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 13542 } else { 13543 pw.println("Applications Memory Usage (kB):"); 13544 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 13545 } 13546 } 13547 13548 final void dumpApplicationMemoryUsage(FileDescriptor fd, 13549 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 13550 boolean dumpDetails = false; 13551 boolean dumpFullDetails = false; 13552 boolean dumpDalvik = false; 13553 boolean oomOnly = false; 13554 boolean isCompact = false; 13555 boolean localOnly = false; 13556 13557 int opti = 0; 13558 while (opti < args.length) { 13559 String opt = args[opti]; 13560 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 13561 break; 13562 } 13563 opti++; 13564 if ("-a".equals(opt)) { 13565 dumpDetails = true; 13566 dumpFullDetails = true; 13567 dumpDalvik = true; 13568 } else if ("-d".equals(opt)) { 13569 dumpDalvik = true; 13570 } else if ("-c".equals(opt)) { 13571 isCompact = true; 13572 } else if ("--oom".equals(opt)) { 13573 oomOnly = true; 13574 } else if ("--local".equals(opt)) { 13575 localOnly = true; 13576 } else if ("-h".equals(opt)) { 13577 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 13578 pw.println(" -a: include all available information for each process."); 13579 pw.println(" -d: include dalvik details when dumping process details."); 13580 pw.println(" -c: dump in a compact machine-parseable representation."); 13581 pw.println(" --oom: only show processes organized by oom adj."); 13582 pw.println(" --local: only collect details locally, don't call process."); 13583 pw.println("If [process] is specified it can be the name or "); 13584 pw.println("pid of a specific process to dump."); 13585 return; 13586 } else { 13587 pw.println("Unknown argument: " + opt + "; use -h for help"); 13588 } 13589 } 13590 13591 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 13592 long uptime = SystemClock.uptimeMillis(); 13593 long realtime = SystemClock.elapsedRealtime(); 13594 final long[] tmpLong = new long[1]; 13595 13596 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 13597 if (procs == null) { 13598 // No Java processes. Maybe they want to print a native process. 13599 if (args != null && args.length > opti 13600 && args[opti].charAt(0) != '-') { 13601 ArrayList<ProcessCpuTracker.Stats> nativeProcs 13602 = new ArrayList<ProcessCpuTracker.Stats>(); 13603 updateCpuStatsNow(); 13604 int findPid = -1; 13605 try { 13606 findPid = Integer.parseInt(args[opti]); 13607 } catch (NumberFormatException e) { 13608 } 13609 synchronized (mProcessCpuThread) { 13610 final int N = mProcessCpuTracker.countStats(); 13611 for (int i=0; i<N; i++) { 13612 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13613 if (st.pid == findPid || (st.baseName != null 13614 && st.baseName.equals(args[opti]))) { 13615 nativeProcs.add(st); 13616 } 13617 } 13618 } 13619 if (nativeProcs.size() > 0) { 13620 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 13621 isCompact); 13622 Debug.MemoryInfo mi = null; 13623 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 13624 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 13625 final int pid = r.pid; 13626 if (!isCheckinRequest && dumpDetails) { 13627 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 13628 } 13629 if (mi == null) { 13630 mi = new Debug.MemoryInfo(); 13631 } 13632 if (dumpDetails || (!brief && !oomOnly)) { 13633 Debug.getMemoryInfo(pid, mi); 13634 } else { 13635 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13636 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13637 } 13638 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13639 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 13640 if (isCheckinRequest) { 13641 pw.println(); 13642 } 13643 } 13644 return; 13645 } 13646 } 13647 pw.println("No process found for: " + args[opti]); 13648 return; 13649 } 13650 13651 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 13652 dumpDetails = true; 13653 } 13654 13655 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 13656 13657 String[] innerArgs = new String[args.length-opti]; 13658 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 13659 13660 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 13661 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 13662 long nativePss=0, dalvikPss=0, otherPss=0; 13663 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 13664 13665 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 13666 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 13667 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 13668 13669 long totalPss = 0; 13670 long cachedPss = 0; 13671 13672 Debug.MemoryInfo mi = null; 13673 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 13674 final ProcessRecord r = procs.get(i); 13675 final IApplicationThread thread; 13676 final int pid; 13677 final int oomAdj; 13678 final boolean hasActivities; 13679 synchronized (this) { 13680 thread = r.thread; 13681 pid = r.pid; 13682 oomAdj = r.getSetAdjWithServices(); 13683 hasActivities = r.activities.size() > 0; 13684 } 13685 if (thread != null) { 13686 if (!isCheckinRequest && dumpDetails) { 13687 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 13688 } 13689 if (mi == null) { 13690 mi = new Debug.MemoryInfo(); 13691 } 13692 if (dumpDetails || (!brief && !oomOnly)) { 13693 Debug.getMemoryInfo(pid, mi); 13694 } else { 13695 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 13696 mi.dalvikPrivateDirty = (int)tmpLong[0]; 13697 } 13698 if (dumpDetails) { 13699 if (localOnly) { 13700 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 13701 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 13702 if (isCheckinRequest) { 13703 pw.println(); 13704 } 13705 } else { 13706 try { 13707 pw.flush(); 13708 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 13709 dumpDalvik, innerArgs); 13710 } catch (RemoteException e) { 13711 if (!isCheckinRequest) { 13712 pw.println("Got RemoteException!"); 13713 pw.flush(); 13714 } 13715 } 13716 } 13717 } 13718 13719 final long myTotalPss = mi.getTotalPss(); 13720 final long myTotalUss = mi.getTotalUss(); 13721 13722 synchronized (this) { 13723 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 13724 // Record this for posterity if the process has been stable. 13725 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 13726 } 13727 } 13728 13729 if (!isCheckinRequest && mi != null) { 13730 totalPss += myTotalPss; 13731 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 13732 (hasActivities ? " / activities)" : ")"), 13733 r.processName, myTotalPss, pid, hasActivities); 13734 procMems.add(pssItem); 13735 procMemsMap.put(pid, pssItem); 13736 13737 nativePss += mi.nativePss; 13738 dalvikPss += mi.dalvikPss; 13739 otherPss += mi.otherPss; 13740 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13741 long mem = mi.getOtherPss(j); 13742 miscPss[j] += mem; 13743 otherPss -= mem; 13744 } 13745 13746 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 13747 cachedPss += myTotalPss; 13748 } 13749 13750 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 13751 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 13752 || oomIndex == (oomPss.length-1)) { 13753 oomPss[oomIndex] += myTotalPss; 13754 if (oomProcs[oomIndex] == null) { 13755 oomProcs[oomIndex] = new ArrayList<MemItem>(); 13756 } 13757 oomProcs[oomIndex].add(pssItem); 13758 break; 13759 } 13760 } 13761 } 13762 } 13763 } 13764 13765 long nativeProcTotalPss = 0; 13766 13767 if (!isCheckinRequest && procs.size() > 1) { 13768 // If we are showing aggregations, also look for native processes to 13769 // include so that our aggregations are more accurate. 13770 updateCpuStatsNow(); 13771 synchronized (mProcessCpuThread) { 13772 final int N = mProcessCpuTracker.countStats(); 13773 for (int i=0; i<N; i++) { 13774 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 13775 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 13776 if (mi == null) { 13777 mi = new Debug.MemoryInfo(); 13778 } 13779 if (!brief && !oomOnly) { 13780 Debug.getMemoryInfo(st.pid, mi); 13781 } else { 13782 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 13783 mi.nativePrivateDirty = (int)tmpLong[0]; 13784 } 13785 13786 final long myTotalPss = mi.getTotalPss(); 13787 totalPss += myTotalPss; 13788 nativeProcTotalPss += myTotalPss; 13789 13790 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 13791 st.name, myTotalPss, st.pid, false); 13792 procMems.add(pssItem); 13793 13794 nativePss += mi.nativePss; 13795 dalvikPss += mi.dalvikPss; 13796 otherPss += mi.otherPss; 13797 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13798 long mem = mi.getOtherPss(j); 13799 miscPss[j] += mem; 13800 otherPss -= mem; 13801 } 13802 oomPss[0] += myTotalPss; 13803 if (oomProcs[0] == null) { 13804 oomProcs[0] = new ArrayList<MemItem>(); 13805 } 13806 oomProcs[0].add(pssItem); 13807 } 13808 } 13809 } 13810 13811 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13812 13813 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13814 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13815 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13816 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13817 String label = Debug.MemoryInfo.getOtherLabel(j); 13818 catMems.add(new MemItem(label, label, miscPss[j], j)); 13819 } 13820 13821 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13822 for (int j=0; j<oomPss.length; j++) { 13823 if (oomPss[j] != 0) { 13824 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13825 : DUMP_MEM_OOM_LABEL[j]; 13826 MemItem item = new MemItem(label, label, oomPss[j], 13827 DUMP_MEM_OOM_ADJ[j]); 13828 item.subitems = oomProcs[j]; 13829 oomMems.add(item); 13830 } 13831 } 13832 13833 if (!brief && !oomOnly && !isCompact) { 13834 pw.println(); 13835 pw.println("Total PSS by process:"); 13836 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13837 pw.println(); 13838 } 13839 if (!isCompact) { 13840 pw.println("Total PSS by OOM adjustment:"); 13841 } 13842 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13843 if (!brief && !oomOnly) { 13844 PrintWriter out = categoryPw != null ? categoryPw : pw; 13845 if (!isCompact) { 13846 out.println(); 13847 out.println("Total PSS by category:"); 13848 } 13849 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13850 } 13851 if (!isCompact) { 13852 pw.println(); 13853 } 13854 MemInfoReader memInfo = new MemInfoReader(); 13855 memInfo.readMemInfo(); 13856 if (nativeProcTotalPss > 0) { 13857 synchronized (this) { 13858 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13859 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13860 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13861 nativeProcTotalPss); 13862 } 13863 } 13864 if (!brief) { 13865 if (!isCompact) { 13866 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13867 pw.print(" kB (status "); 13868 switch (mLastMemoryLevel) { 13869 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13870 pw.println("normal)"); 13871 break; 13872 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13873 pw.println("moderate)"); 13874 break; 13875 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13876 pw.println("low)"); 13877 break; 13878 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13879 pw.println("critical)"); 13880 break; 13881 default: 13882 pw.print(mLastMemoryLevel); 13883 pw.println(")"); 13884 break; 13885 } 13886 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13887 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13888 pw.print(cachedPss); pw.print(" cached pss + "); 13889 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13890 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13891 } else { 13892 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13893 pw.print(cachedPss + memInfo.getCachedSizeKb() 13894 + memInfo.getFreeSizeKb()); pw.print(","); 13895 pw.println(totalPss - cachedPss); 13896 } 13897 } 13898 if (!isCompact) { 13899 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13900 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13901 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13902 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13903 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13904 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13905 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13906 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13907 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13908 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13909 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13910 } 13911 if (!brief) { 13912 if (memInfo.getZramTotalSizeKb() != 0) { 13913 if (!isCompact) { 13914 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13915 pw.print(" kB physical used for "); 13916 pw.print(memInfo.getSwapTotalSizeKb() 13917 - memInfo.getSwapFreeSizeKb()); 13918 pw.print(" kB in swap ("); 13919 pw.print(memInfo.getSwapTotalSizeKb()); 13920 pw.println(" kB total swap)"); 13921 } else { 13922 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13923 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13924 pw.println(memInfo.getSwapFreeSizeKb()); 13925 } 13926 } 13927 final int[] SINGLE_LONG_FORMAT = new int[] { 13928 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13929 }; 13930 long[] longOut = new long[1]; 13931 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13932 SINGLE_LONG_FORMAT, null, longOut, null); 13933 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13934 longOut[0] = 0; 13935 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13936 SINGLE_LONG_FORMAT, null, longOut, null); 13937 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13938 longOut[0] = 0; 13939 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13940 SINGLE_LONG_FORMAT, null, longOut, null); 13941 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13942 longOut[0] = 0; 13943 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13944 SINGLE_LONG_FORMAT, null, longOut, null); 13945 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13946 if (!isCompact) { 13947 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13948 pw.print(" KSM: "); pw.print(sharing); 13949 pw.print(" kB saved from shared "); 13950 pw.print(shared); pw.println(" kB"); 13951 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13952 pw.print(voltile); pw.println(" kB volatile"); 13953 } 13954 pw.print(" Tuning: "); 13955 pw.print(ActivityManager.staticGetMemoryClass()); 13956 pw.print(" (large "); 13957 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13958 pw.print("), oom "); 13959 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13960 pw.print(" kB"); 13961 pw.print(", restore limit "); 13962 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13963 pw.print(" kB"); 13964 if (ActivityManager.isLowRamDeviceStatic()) { 13965 pw.print(" (low-ram)"); 13966 } 13967 if (ActivityManager.isHighEndGfx()) { 13968 pw.print(" (high-end-gfx)"); 13969 } 13970 pw.println(); 13971 } else { 13972 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13973 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13974 pw.println(voltile); 13975 pw.print("tuning,"); 13976 pw.print(ActivityManager.staticGetMemoryClass()); 13977 pw.print(','); 13978 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13979 pw.print(','); 13980 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13981 if (ActivityManager.isLowRamDeviceStatic()) { 13982 pw.print(",low-ram"); 13983 } 13984 if (ActivityManager.isHighEndGfx()) { 13985 pw.print(",high-end-gfx"); 13986 } 13987 pw.println(); 13988 } 13989 } 13990 } 13991 } 13992 13993 /** 13994 * Searches array of arguments for the specified string 13995 * @param args array of argument strings 13996 * @param value value to search for 13997 * @return true if the value is contained in the array 13998 */ 13999 private static boolean scanArgs(String[] args, String value) { 14000 if (args != null) { 14001 for (String arg : args) { 14002 if (value.equals(arg)) { 14003 return true; 14004 } 14005 } 14006 } 14007 return false; 14008 } 14009 14010 private final boolean removeDyingProviderLocked(ProcessRecord proc, 14011 ContentProviderRecord cpr, boolean always) { 14012 final boolean inLaunching = mLaunchingProviders.contains(cpr); 14013 14014 if (!inLaunching || always) { 14015 synchronized (cpr) { 14016 cpr.launchingApp = null; 14017 cpr.notifyAll(); 14018 } 14019 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 14020 String names[] = cpr.info.authority.split(";"); 14021 for (int j = 0; j < names.length; j++) { 14022 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 14023 } 14024 } 14025 14026 for (int i=0; i<cpr.connections.size(); i++) { 14027 ContentProviderConnection conn = cpr.connections.get(i); 14028 if (conn.waiting) { 14029 // If this connection is waiting for the provider, then we don't 14030 // need to mess with its process unless we are always removing 14031 // or for some reason the provider is not currently launching. 14032 if (inLaunching && !always) { 14033 continue; 14034 } 14035 } 14036 ProcessRecord capp = conn.client; 14037 conn.dead = true; 14038 if (conn.stableCount > 0) { 14039 if (!capp.persistent && capp.thread != null 14040 && capp.pid != 0 14041 && capp.pid != MY_PID) { 14042 capp.kill("depends on provider " 14043 + cpr.name.flattenToShortString() 14044 + " in dying proc " + (proc != null ? proc.processName : "??"), true); 14045 } 14046 } else if (capp.thread != null && conn.provider.provider != null) { 14047 try { 14048 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 14049 } catch (RemoteException e) { 14050 } 14051 // In the protocol here, we don't expect the client to correctly 14052 // clean up this connection, we'll just remove it. 14053 cpr.connections.remove(i); 14054 conn.client.conProviders.remove(conn); 14055 } 14056 } 14057 14058 if (inLaunching && always) { 14059 mLaunchingProviders.remove(cpr); 14060 } 14061 return inLaunching; 14062 } 14063 14064 /** 14065 * Main code for cleaning up a process when it has gone away. This is 14066 * called both as a result of the process dying, or directly when stopping 14067 * a process when running in single process mode. 14068 */ 14069 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 14070 boolean restarting, boolean allowRestart, int index) { 14071 if (index >= 0) { 14072 removeLruProcessLocked(app); 14073 ProcessList.remove(app.pid); 14074 } 14075 14076 mProcessesToGc.remove(app); 14077 mPendingPssProcesses.remove(app); 14078 14079 // Dismiss any open dialogs. 14080 if (app.crashDialog != null && !app.forceCrashReport) { 14081 app.crashDialog.dismiss(); 14082 app.crashDialog = null; 14083 } 14084 if (app.anrDialog != null) { 14085 app.anrDialog.dismiss(); 14086 app.anrDialog = null; 14087 } 14088 if (app.waitDialog != null) { 14089 app.waitDialog.dismiss(); 14090 app.waitDialog = null; 14091 } 14092 14093 app.crashing = false; 14094 app.notResponding = false; 14095 14096 app.resetPackageList(mProcessStats); 14097 app.unlinkDeathRecipient(); 14098 app.makeInactive(mProcessStats); 14099 app.waitingToKill = null; 14100 app.forcingToForeground = null; 14101 updateProcessForegroundLocked(app, false, false); 14102 app.foregroundActivities = false; 14103 app.hasShownUi = false; 14104 app.treatLikeActivity = false; 14105 app.hasAboveClient = false; 14106 app.hasClientActivities = false; 14107 14108 mServices.killServicesLocked(app, allowRestart); 14109 14110 boolean restart = false; 14111 14112 // Remove published content providers. 14113 for (int i=app.pubProviders.size()-1; i>=0; i--) { 14114 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 14115 final boolean always = app.bad || !allowRestart; 14116 if (removeDyingProviderLocked(app, cpr, always) || always) { 14117 // We left the provider in the launching list, need to 14118 // restart it. 14119 restart = true; 14120 } 14121 14122 cpr.provider = null; 14123 cpr.proc = null; 14124 } 14125 app.pubProviders.clear(); 14126 14127 // Take care of any launching providers waiting for this process. 14128 if (checkAppInLaunchingProvidersLocked(app, false)) { 14129 restart = true; 14130 } 14131 14132 // Unregister from connected content providers. 14133 if (!app.conProviders.isEmpty()) { 14134 for (int i=0; i<app.conProviders.size(); i++) { 14135 ContentProviderConnection conn = app.conProviders.get(i); 14136 conn.provider.connections.remove(conn); 14137 } 14138 app.conProviders.clear(); 14139 } 14140 14141 // At this point there may be remaining entries in mLaunchingProviders 14142 // where we were the only one waiting, so they are no longer of use. 14143 // Look for these and clean up if found. 14144 // XXX Commented out for now. Trying to figure out a way to reproduce 14145 // the actual situation to identify what is actually going on. 14146 if (false) { 14147 for (int i=0; i<mLaunchingProviders.size(); i++) { 14148 ContentProviderRecord cpr = (ContentProviderRecord) 14149 mLaunchingProviders.get(i); 14150 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 14151 synchronized (cpr) { 14152 cpr.launchingApp = null; 14153 cpr.notifyAll(); 14154 } 14155 } 14156 } 14157 } 14158 14159 skipCurrentReceiverLocked(app); 14160 14161 // Unregister any receivers. 14162 for (int i=app.receivers.size()-1; i>=0; i--) { 14163 removeReceiverLocked(app.receivers.valueAt(i)); 14164 } 14165 app.receivers.clear(); 14166 14167 // If the app is undergoing backup, tell the backup manager about it 14168 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 14169 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 14170 + mBackupTarget.appInfo + " died during backup"); 14171 try { 14172 IBackupManager bm = IBackupManager.Stub.asInterface( 14173 ServiceManager.getService(Context.BACKUP_SERVICE)); 14174 bm.agentDisconnected(app.info.packageName); 14175 } catch (RemoteException e) { 14176 // can't happen; backup manager is local 14177 } 14178 } 14179 14180 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 14181 ProcessChangeItem item = mPendingProcessChanges.get(i); 14182 if (item.pid == app.pid) { 14183 mPendingProcessChanges.remove(i); 14184 mAvailProcessChanges.add(item); 14185 } 14186 } 14187 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 14188 14189 // If the caller is restarting this app, then leave it in its 14190 // current lists and let the caller take care of it. 14191 if (restarting) { 14192 return; 14193 } 14194 14195 if (!app.persistent || app.isolated) { 14196 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 14197 "Removing non-persistent process during cleanup: " + app); 14198 mProcessNames.remove(app.processName, app.uid); 14199 mIsolatedProcesses.remove(app.uid); 14200 if (mHeavyWeightProcess == app) { 14201 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 14202 mHeavyWeightProcess.userId, 0)); 14203 mHeavyWeightProcess = null; 14204 } 14205 } else if (!app.removed) { 14206 // This app is persistent, so we need to keep its record around. 14207 // If it is not already on the pending app list, add it there 14208 // and start a new process for it. 14209 if (mPersistentStartingProcesses.indexOf(app) < 0) { 14210 mPersistentStartingProcesses.add(app); 14211 restart = true; 14212 } 14213 } 14214 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 14215 "Clean-up removing on hold: " + app); 14216 mProcessesOnHold.remove(app); 14217 14218 if (app == mHomeProcess) { 14219 mHomeProcess = null; 14220 } 14221 if (app == mPreviousProcess) { 14222 mPreviousProcess = null; 14223 } 14224 14225 if (restart && !app.isolated) { 14226 // We have components that still need to be running in the 14227 // process, so re-launch it. 14228 mProcessNames.put(app.processName, app.uid, app); 14229 startProcessLocked(app, "restart", app.processName); 14230 } else if (app.pid > 0 && app.pid != MY_PID) { 14231 // Goodbye! 14232 boolean removed; 14233 synchronized (mPidsSelfLocked) { 14234 mPidsSelfLocked.remove(app.pid); 14235 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 14236 } 14237 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 14238 if (app.isolated) { 14239 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 14240 } 14241 app.setPid(0); 14242 } 14243 } 14244 14245 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 14246 // Look through the content providers we are waiting to have launched, 14247 // and if any run in this process then either schedule a restart of 14248 // the process or kill the client waiting for it if this process has 14249 // gone bad. 14250 int NL = mLaunchingProviders.size(); 14251 boolean restart = false; 14252 for (int i=0; i<NL; i++) { 14253 ContentProviderRecord cpr = mLaunchingProviders.get(i); 14254 if (cpr.launchingApp == app) { 14255 if (!alwaysBad && !app.bad) { 14256 restart = true; 14257 } else { 14258 removeDyingProviderLocked(app, cpr, true); 14259 // cpr should have been removed from mLaunchingProviders 14260 NL = mLaunchingProviders.size(); 14261 i--; 14262 } 14263 } 14264 } 14265 return restart; 14266 } 14267 14268 // ========================================================= 14269 // SERVICES 14270 // ========================================================= 14271 14272 @Override 14273 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 14274 int flags) { 14275 enforceNotIsolatedCaller("getServices"); 14276 synchronized (this) { 14277 return mServices.getRunningServiceInfoLocked(maxNum, flags); 14278 } 14279 } 14280 14281 @Override 14282 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 14283 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 14284 synchronized (this) { 14285 return mServices.getRunningServiceControlPanelLocked(name); 14286 } 14287 } 14288 14289 @Override 14290 public ComponentName startService(IApplicationThread caller, Intent service, 14291 String resolvedType, int userId) { 14292 enforceNotIsolatedCaller("startService"); 14293 // Refuse possible leaked file descriptors 14294 if (service != null && service.hasFileDescriptors() == true) { 14295 throw new IllegalArgumentException("File descriptors passed in Intent"); 14296 } 14297 14298 if (DEBUG_SERVICE) 14299 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 14300 synchronized(this) { 14301 final int callingPid = Binder.getCallingPid(); 14302 final int callingUid = Binder.getCallingUid(); 14303 final long origId = Binder.clearCallingIdentity(); 14304 ComponentName res = mServices.startServiceLocked(caller, service, 14305 resolvedType, callingPid, callingUid, userId); 14306 Binder.restoreCallingIdentity(origId); 14307 return res; 14308 } 14309 } 14310 14311 ComponentName startServiceInPackage(int uid, 14312 Intent service, String resolvedType, int userId) { 14313 synchronized(this) { 14314 if (DEBUG_SERVICE) 14315 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 14316 final long origId = Binder.clearCallingIdentity(); 14317 ComponentName res = mServices.startServiceLocked(null, service, 14318 resolvedType, -1, uid, userId); 14319 Binder.restoreCallingIdentity(origId); 14320 return res; 14321 } 14322 } 14323 14324 @Override 14325 public int stopService(IApplicationThread caller, Intent service, 14326 String resolvedType, int userId) { 14327 enforceNotIsolatedCaller("stopService"); 14328 // Refuse possible leaked file descriptors 14329 if (service != null && service.hasFileDescriptors() == true) { 14330 throw new IllegalArgumentException("File descriptors passed in Intent"); 14331 } 14332 14333 synchronized(this) { 14334 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 14335 } 14336 } 14337 14338 @Override 14339 public IBinder peekService(Intent service, String resolvedType) { 14340 enforceNotIsolatedCaller("peekService"); 14341 // Refuse possible leaked file descriptors 14342 if (service != null && service.hasFileDescriptors() == true) { 14343 throw new IllegalArgumentException("File descriptors passed in Intent"); 14344 } 14345 synchronized(this) { 14346 return mServices.peekServiceLocked(service, resolvedType); 14347 } 14348 } 14349 14350 @Override 14351 public boolean stopServiceToken(ComponentName className, IBinder token, 14352 int startId) { 14353 synchronized(this) { 14354 return mServices.stopServiceTokenLocked(className, token, startId); 14355 } 14356 } 14357 14358 @Override 14359 public void setServiceForeground(ComponentName className, IBinder token, 14360 int id, Notification notification, boolean removeNotification) { 14361 synchronized(this) { 14362 mServices.setServiceForegroundLocked(className, token, id, notification, 14363 removeNotification); 14364 } 14365 } 14366 14367 @Override 14368 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14369 boolean requireFull, String name, String callerPackage) { 14370 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 14371 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 14372 } 14373 14374 int unsafeConvertIncomingUser(int userId) { 14375 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 14376 ? mCurrentUserId : userId; 14377 } 14378 14379 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 14380 int allowMode, String name, String callerPackage) { 14381 final int callingUserId = UserHandle.getUserId(callingUid); 14382 if (callingUserId == userId) { 14383 return userId; 14384 } 14385 14386 // Note that we may be accessing mCurrentUserId outside of a lock... 14387 // shouldn't be a big deal, if this is being called outside 14388 // of a locked context there is intrinsically a race with 14389 // the value the caller will receive and someone else changing it. 14390 // We assume that USER_CURRENT_OR_SELF will use the current user; later 14391 // we will switch to the calling user if access to the current user fails. 14392 int targetUserId = unsafeConvertIncomingUser(userId); 14393 14394 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 14395 final boolean allow; 14396 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 14397 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 14398 // If the caller has this permission, they always pass go. And collect $200. 14399 allow = true; 14400 } else if (allowMode == ALLOW_FULL_ONLY) { 14401 // We require full access, sucks to be you. 14402 allow = false; 14403 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 14404 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 14405 // If the caller does not have either permission, they are always doomed. 14406 allow = false; 14407 } else if (allowMode == ALLOW_NON_FULL) { 14408 // We are blanket allowing non-full access, you lucky caller! 14409 allow = true; 14410 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 14411 // We may or may not allow this depending on whether the two users are 14412 // in the same profile. 14413 synchronized (mUserProfileGroupIdsSelfLocked) { 14414 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 14415 UserInfo.NO_PROFILE_GROUP_ID); 14416 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 14417 UserInfo.NO_PROFILE_GROUP_ID); 14418 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 14419 && callingProfile == targetProfile; 14420 } 14421 } else { 14422 throw new IllegalArgumentException("Unknown mode: " + allowMode); 14423 } 14424 if (!allow) { 14425 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 14426 // In this case, they would like to just execute as their 14427 // owner user instead of failing. 14428 targetUserId = callingUserId; 14429 } else { 14430 StringBuilder builder = new StringBuilder(128); 14431 builder.append("Permission Denial: "); 14432 builder.append(name); 14433 if (callerPackage != null) { 14434 builder.append(" from "); 14435 builder.append(callerPackage); 14436 } 14437 builder.append(" asks to run as user "); 14438 builder.append(userId); 14439 builder.append(" but is calling from user "); 14440 builder.append(UserHandle.getUserId(callingUid)); 14441 builder.append("; this requires "); 14442 builder.append(INTERACT_ACROSS_USERS_FULL); 14443 if (allowMode != ALLOW_FULL_ONLY) { 14444 builder.append(" or "); 14445 builder.append(INTERACT_ACROSS_USERS); 14446 } 14447 String msg = builder.toString(); 14448 Slog.w(TAG, msg); 14449 throw new SecurityException(msg); 14450 } 14451 } 14452 } 14453 if (!allowAll && targetUserId < 0) { 14454 throw new IllegalArgumentException( 14455 "Call does not support special user #" + targetUserId); 14456 } 14457 return targetUserId; 14458 } 14459 14460 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 14461 String className, int flags) { 14462 boolean result = false; 14463 // For apps that don't have pre-defined UIDs, check for permission 14464 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 14465 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14466 if (ActivityManager.checkUidPermission( 14467 INTERACT_ACROSS_USERS, 14468 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 14469 ComponentName comp = new ComponentName(aInfo.packageName, className); 14470 String msg = "Permission Denial: Component " + comp.flattenToShortString() 14471 + " requests FLAG_SINGLE_USER, but app does not hold " 14472 + INTERACT_ACROSS_USERS; 14473 Slog.w(TAG, msg); 14474 throw new SecurityException(msg); 14475 } 14476 // Permission passed 14477 result = true; 14478 } 14479 } else if ("system".equals(componentProcessName)) { 14480 result = true; 14481 } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID) 14482 && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 14483 // Phone app is allowed to export singleuser providers. 14484 result = true; 14485 } else { 14486 // App with pre-defined UID, check if it's a persistent app 14487 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 14488 } 14489 if (DEBUG_MU) { 14490 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 14491 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 14492 } 14493 return result; 14494 } 14495 14496 /** 14497 * Checks to see if the caller is in the same app as the singleton 14498 * component, or the component is in a special app. It allows special apps 14499 * to export singleton components but prevents exporting singleton 14500 * components for regular apps. 14501 */ 14502 boolean isValidSingletonCall(int callingUid, int componentUid) { 14503 int componentAppId = UserHandle.getAppId(componentUid); 14504 return UserHandle.isSameApp(callingUid, componentUid) 14505 || componentAppId == Process.SYSTEM_UID 14506 || componentAppId == Process.PHONE_UID 14507 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 14508 == PackageManager.PERMISSION_GRANTED; 14509 } 14510 14511 public int bindService(IApplicationThread caller, IBinder token, 14512 Intent service, String resolvedType, 14513 IServiceConnection connection, int flags, int userId) { 14514 enforceNotIsolatedCaller("bindService"); 14515 // Refuse possible leaked file descriptors 14516 if (service != null && service.hasFileDescriptors() == true) { 14517 throw new IllegalArgumentException("File descriptors passed in Intent"); 14518 } 14519 14520 synchronized(this) { 14521 return mServices.bindServiceLocked(caller, token, service, resolvedType, 14522 connection, flags, userId); 14523 } 14524 } 14525 14526 public boolean unbindService(IServiceConnection connection) { 14527 synchronized (this) { 14528 return mServices.unbindServiceLocked(connection); 14529 } 14530 } 14531 14532 public void publishService(IBinder token, Intent intent, IBinder service) { 14533 // Refuse possible leaked file descriptors 14534 if (intent != null && intent.hasFileDescriptors() == true) { 14535 throw new IllegalArgumentException("File descriptors passed in Intent"); 14536 } 14537 14538 synchronized(this) { 14539 if (!(token instanceof ServiceRecord)) { 14540 throw new IllegalArgumentException("Invalid service token"); 14541 } 14542 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 14543 } 14544 } 14545 14546 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 14547 // Refuse possible leaked file descriptors 14548 if (intent != null && intent.hasFileDescriptors() == true) { 14549 throw new IllegalArgumentException("File descriptors passed in Intent"); 14550 } 14551 14552 synchronized(this) { 14553 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 14554 } 14555 } 14556 14557 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 14558 synchronized(this) { 14559 if (!(token instanceof ServiceRecord)) { 14560 throw new IllegalArgumentException("Invalid service token"); 14561 } 14562 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 14563 } 14564 } 14565 14566 // ========================================================= 14567 // BACKUP AND RESTORE 14568 // ========================================================= 14569 14570 // Cause the target app to be launched if necessary and its backup agent 14571 // instantiated. The backup agent will invoke backupAgentCreated() on the 14572 // activity manager to announce its creation. 14573 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 14574 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 14575 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 14576 14577 synchronized(this) { 14578 // !!! TODO: currently no check here that we're already bound 14579 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 14580 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 14581 synchronized (stats) { 14582 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 14583 } 14584 14585 // Backup agent is now in use, its package can't be stopped. 14586 try { 14587 AppGlobals.getPackageManager().setPackageStoppedState( 14588 app.packageName, false, UserHandle.getUserId(app.uid)); 14589 } catch (RemoteException e) { 14590 } catch (IllegalArgumentException e) { 14591 Slog.w(TAG, "Failed trying to unstop package " 14592 + app.packageName + ": " + e); 14593 } 14594 14595 BackupRecord r = new BackupRecord(ss, app, backupMode); 14596 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 14597 ? new ComponentName(app.packageName, app.backupAgentName) 14598 : new ComponentName("android", "FullBackupAgent"); 14599 // startProcessLocked() returns existing proc's record if it's already running 14600 ProcessRecord proc = startProcessLocked(app.processName, app, 14601 false, 0, "backup", hostingName, false, false, false); 14602 if (proc == null) { 14603 Slog.e(TAG, "Unable to start backup agent process " + r); 14604 return false; 14605 } 14606 14607 r.app = proc; 14608 mBackupTarget = r; 14609 mBackupAppName = app.packageName; 14610 14611 // Try not to kill the process during backup 14612 updateOomAdjLocked(proc); 14613 14614 // If the process is already attached, schedule the creation of the backup agent now. 14615 // If it is not yet live, this will be done when it attaches to the framework. 14616 if (proc.thread != null) { 14617 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 14618 try { 14619 proc.thread.scheduleCreateBackupAgent(app, 14620 compatibilityInfoForPackageLocked(app), backupMode); 14621 } catch (RemoteException e) { 14622 // Will time out on the backup manager side 14623 } 14624 } else { 14625 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 14626 } 14627 // Invariants: at this point, the target app process exists and the application 14628 // is either already running or in the process of coming up. mBackupTarget and 14629 // mBackupAppName describe the app, so that when it binds back to the AM we 14630 // know that it's scheduled for a backup-agent operation. 14631 } 14632 14633 return true; 14634 } 14635 14636 @Override 14637 public void clearPendingBackup() { 14638 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 14639 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 14640 14641 synchronized (this) { 14642 mBackupTarget = null; 14643 mBackupAppName = null; 14644 } 14645 } 14646 14647 // A backup agent has just come up 14648 public void backupAgentCreated(String agentPackageName, IBinder agent) { 14649 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 14650 + " = " + agent); 14651 14652 synchronized(this) { 14653 if (!agentPackageName.equals(mBackupAppName)) { 14654 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 14655 return; 14656 } 14657 } 14658 14659 long oldIdent = Binder.clearCallingIdentity(); 14660 try { 14661 IBackupManager bm = IBackupManager.Stub.asInterface( 14662 ServiceManager.getService(Context.BACKUP_SERVICE)); 14663 bm.agentConnected(agentPackageName, agent); 14664 } catch (RemoteException e) { 14665 // can't happen; the backup manager service is local 14666 } catch (Exception e) { 14667 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 14668 e.printStackTrace(); 14669 } finally { 14670 Binder.restoreCallingIdentity(oldIdent); 14671 } 14672 } 14673 14674 // done with this agent 14675 public void unbindBackupAgent(ApplicationInfo appInfo) { 14676 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 14677 if (appInfo == null) { 14678 Slog.w(TAG, "unbind backup agent for null app"); 14679 return; 14680 } 14681 14682 synchronized(this) { 14683 try { 14684 if (mBackupAppName == null) { 14685 Slog.w(TAG, "Unbinding backup agent with no active backup"); 14686 return; 14687 } 14688 14689 if (!mBackupAppName.equals(appInfo.packageName)) { 14690 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 14691 return; 14692 } 14693 14694 // Not backing this app up any more; reset its OOM adjustment 14695 final ProcessRecord proc = mBackupTarget.app; 14696 updateOomAdjLocked(proc); 14697 14698 // If the app crashed during backup, 'thread' will be null here 14699 if (proc.thread != null) { 14700 try { 14701 proc.thread.scheduleDestroyBackupAgent(appInfo, 14702 compatibilityInfoForPackageLocked(appInfo)); 14703 } catch (Exception e) { 14704 Slog.e(TAG, "Exception when unbinding backup agent:"); 14705 e.printStackTrace(); 14706 } 14707 } 14708 } finally { 14709 mBackupTarget = null; 14710 mBackupAppName = null; 14711 } 14712 } 14713 } 14714 // ========================================================= 14715 // BROADCASTS 14716 // ========================================================= 14717 14718 private final List getStickiesLocked(String action, IntentFilter filter, 14719 List cur, int userId) { 14720 final ContentResolver resolver = mContext.getContentResolver(); 14721 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14722 if (stickies == null) { 14723 return cur; 14724 } 14725 final ArrayList<Intent> list = stickies.get(action); 14726 if (list == null) { 14727 return cur; 14728 } 14729 int N = list.size(); 14730 for (int i=0; i<N; i++) { 14731 Intent intent = list.get(i); 14732 if (filter.match(resolver, intent, true, TAG) >= 0) { 14733 if (cur == null) { 14734 cur = new ArrayList<Intent>(); 14735 } 14736 cur.add(intent); 14737 } 14738 } 14739 return cur; 14740 } 14741 14742 boolean isPendingBroadcastProcessLocked(int pid) { 14743 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 14744 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 14745 } 14746 14747 void skipPendingBroadcastLocked(int pid) { 14748 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 14749 for (BroadcastQueue queue : mBroadcastQueues) { 14750 queue.skipPendingBroadcastLocked(pid); 14751 } 14752 } 14753 14754 // The app just attached; send any pending broadcasts that it should receive 14755 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 14756 boolean didSomething = false; 14757 for (BroadcastQueue queue : mBroadcastQueues) { 14758 didSomething |= queue.sendPendingBroadcastsLocked(app); 14759 } 14760 return didSomething; 14761 } 14762 14763 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 14764 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 14765 enforceNotIsolatedCaller("registerReceiver"); 14766 int callingUid; 14767 int callingPid; 14768 synchronized(this) { 14769 ProcessRecord callerApp = null; 14770 if (caller != null) { 14771 callerApp = getRecordForAppLocked(caller); 14772 if (callerApp == null) { 14773 throw new SecurityException( 14774 "Unable to find app for caller " + caller 14775 + " (pid=" + Binder.getCallingPid() 14776 + ") when registering receiver " + receiver); 14777 } 14778 if (callerApp.info.uid != Process.SYSTEM_UID && 14779 !callerApp.pkgList.containsKey(callerPackage) && 14780 !"android".equals(callerPackage)) { 14781 throw new SecurityException("Given caller package " + callerPackage 14782 + " is not running in process " + callerApp); 14783 } 14784 callingUid = callerApp.info.uid; 14785 callingPid = callerApp.pid; 14786 } else { 14787 callerPackage = null; 14788 callingUid = Binder.getCallingUid(); 14789 callingPid = Binder.getCallingPid(); 14790 } 14791 14792 userId = this.handleIncomingUser(callingPid, callingUid, userId, 14793 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 14794 14795 List allSticky = null; 14796 14797 // Look for any matching sticky broadcasts... 14798 Iterator actions = filter.actionsIterator(); 14799 if (actions != null) { 14800 while (actions.hasNext()) { 14801 String action = (String)actions.next(); 14802 allSticky = getStickiesLocked(action, filter, allSticky, 14803 UserHandle.USER_ALL); 14804 allSticky = getStickiesLocked(action, filter, allSticky, 14805 UserHandle.getUserId(callingUid)); 14806 } 14807 } else { 14808 allSticky = getStickiesLocked(null, filter, allSticky, 14809 UserHandle.USER_ALL); 14810 allSticky = getStickiesLocked(null, filter, allSticky, 14811 UserHandle.getUserId(callingUid)); 14812 } 14813 14814 // The first sticky in the list is returned directly back to 14815 // the client. 14816 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14817 14818 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14819 + ": " + sticky); 14820 14821 if (receiver == null) { 14822 return sticky; 14823 } 14824 14825 ReceiverList rl 14826 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14827 if (rl == null) { 14828 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14829 userId, receiver); 14830 if (rl.app != null) { 14831 rl.app.receivers.add(rl); 14832 } else { 14833 try { 14834 receiver.asBinder().linkToDeath(rl, 0); 14835 } catch (RemoteException e) { 14836 return sticky; 14837 } 14838 rl.linkedToDeath = true; 14839 } 14840 mRegisteredReceivers.put(receiver.asBinder(), rl); 14841 } else if (rl.uid != callingUid) { 14842 throw new IllegalArgumentException( 14843 "Receiver requested to register for uid " + callingUid 14844 + " was previously registered for uid " + rl.uid); 14845 } else if (rl.pid != callingPid) { 14846 throw new IllegalArgumentException( 14847 "Receiver requested to register for pid " + callingPid 14848 + " was previously registered for pid " + rl.pid); 14849 } else if (rl.userId != userId) { 14850 throw new IllegalArgumentException( 14851 "Receiver requested to register for user " + userId 14852 + " was previously registered for user " + rl.userId); 14853 } 14854 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14855 permission, callingUid, userId); 14856 rl.add(bf); 14857 if (!bf.debugCheck()) { 14858 Slog.w(TAG, "==> For Dynamic broadast"); 14859 } 14860 mReceiverResolver.addFilter(bf); 14861 14862 // Enqueue broadcasts for all existing stickies that match 14863 // this filter. 14864 if (allSticky != null) { 14865 ArrayList receivers = new ArrayList(); 14866 receivers.add(bf); 14867 14868 int N = allSticky.size(); 14869 for (int i=0; i<N; i++) { 14870 Intent intent = (Intent)allSticky.get(i); 14871 BroadcastQueue queue = broadcastQueueForIntent(intent); 14872 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14873 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14874 null, null, false, true, true, -1); 14875 queue.enqueueParallelBroadcastLocked(r); 14876 queue.scheduleBroadcastsLocked(); 14877 } 14878 } 14879 14880 return sticky; 14881 } 14882 } 14883 14884 public void unregisterReceiver(IIntentReceiver receiver) { 14885 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14886 14887 final long origId = Binder.clearCallingIdentity(); 14888 try { 14889 boolean doTrim = false; 14890 14891 synchronized(this) { 14892 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14893 if (rl != null) { 14894 if (rl.curBroadcast != null) { 14895 BroadcastRecord r = rl.curBroadcast; 14896 final boolean doNext = finishReceiverLocked( 14897 receiver.asBinder(), r.resultCode, r.resultData, 14898 r.resultExtras, r.resultAbort); 14899 if (doNext) { 14900 doTrim = true; 14901 r.queue.processNextBroadcast(false); 14902 } 14903 } 14904 14905 if (rl.app != null) { 14906 rl.app.receivers.remove(rl); 14907 } 14908 removeReceiverLocked(rl); 14909 if (rl.linkedToDeath) { 14910 rl.linkedToDeath = false; 14911 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14912 } 14913 } 14914 } 14915 14916 // If we actually concluded any broadcasts, we might now be able 14917 // to trim the recipients' apps from our working set 14918 if (doTrim) { 14919 trimApplications(); 14920 return; 14921 } 14922 14923 } finally { 14924 Binder.restoreCallingIdentity(origId); 14925 } 14926 } 14927 14928 void removeReceiverLocked(ReceiverList rl) { 14929 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14930 int N = rl.size(); 14931 for (int i=0; i<N; i++) { 14932 mReceiverResolver.removeFilter(rl.get(i)); 14933 } 14934 } 14935 14936 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14937 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14938 ProcessRecord r = mLruProcesses.get(i); 14939 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14940 try { 14941 r.thread.dispatchPackageBroadcast(cmd, packages); 14942 } catch (RemoteException ex) { 14943 } 14944 } 14945 } 14946 } 14947 14948 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14949 int[] users) { 14950 List<ResolveInfo> receivers = null; 14951 try { 14952 HashSet<ComponentName> singleUserReceivers = null; 14953 boolean scannedFirstReceivers = false; 14954 for (int user : users) { 14955 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14956 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14957 if (user != 0 && newReceivers != null) { 14958 // If this is not the primary user, we need to check for 14959 // any receivers that should be filtered out. 14960 for (int i=0; i<newReceivers.size(); i++) { 14961 ResolveInfo ri = newReceivers.get(i); 14962 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14963 newReceivers.remove(i); 14964 i--; 14965 } 14966 } 14967 } 14968 if (newReceivers != null && newReceivers.size() == 0) { 14969 newReceivers = null; 14970 } 14971 if (receivers == null) { 14972 receivers = newReceivers; 14973 } else if (newReceivers != null) { 14974 // We need to concatenate the additional receivers 14975 // found with what we have do far. This would be easy, 14976 // but we also need to de-dup any receivers that are 14977 // singleUser. 14978 if (!scannedFirstReceivers) { 14979 // Collect any single user receivers we had already retrieved. 14980 scannedFirstReceivers = true; 14981 for (int i=0; i<receivers.size(); i++) { 14982 ResolveInfo ri = receivers.get(i); 14983 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14984 ComponentName cn = new ComponentName( 14985 ri.activityInfo.packageName, ri.activityInfo.name); 14986 if (singleUserReceivers == null) { 14987 singleUserReceivers = new HashSet<ComponentName>(); 14988 } 14989 singleUserReceivers.add(cn); 14990 } 14991 } 14992 } 14993 // Add the new results to the existing results, tracking 14994 // and de-dupping single user receivers. 14995 for (int i=0; i<newReceivers.size(); i++) { 14996 ResolveInfo ri = newReceivers.get(i); 14997 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14998 ComponentName cn = new ComponentName( 14999 ri.activityInfo.packageName, ri.activityInfo.name); 15000 if (singleUserReceivers == null) { 15001 singleUserReceivers = new HashSet<ComponentName>(); 15002 } 15003 if (!singleUserReceivers.contains(cn)) { 15004 singleUserReceivers.add(cn); 15005 receivers.add(ri); 15006 } 15007 } else { 15008 receivers.add(ri); 15009 } 15010 } 15011 } 15012 } 15013 } catch (RemoteException ex) { 15014 // pm is in same process, this will never happen. 15015 } 15016 return receivers; 15017 } 15018 15019 private final int broadcastIntentLocked(ProcessRecord callerApp, 15020 String callerPackage, Intent intent, String resolvedType, 15021 IIntentReceiver resultTo, int resultCode, String resultData, 15022 Bundle map, String requiredPermission, int appOp, 15023 boolean ordered, boolean sticky, int callingPid, int callingUid, 15024 int userId) { 15025 intent = new Intent(intent); 15026 15027 // By default broadcasts do not go to stopped apps. 15028 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 15029 15030 if (DEBUG_BROADCAST_LIGHT) Slog.v( 15031 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 15032 + " ordered=" + ordered + " userid=" + userId); 15033 if ((resultTo != null) && !ordered) { 15034 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 15035 } 15036 15037 userId = handleIncomingUser(callingPid, callingUid, userId, 15038 true, ALLOW_NON_FULL, "broadcast", callerPackage); 15039 15040 // Make sure that the user who is receiving this broadcast is started. 15041 // If not, we will just skip it. 15042 15043 15044 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 15045 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 15046 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 15047 Slog.w(TAG, "Skipping broadcast of " + intent 15048 + ": user " + userId + " is stopped"); 15049 return ActivityManager.BROADCAST_SUCCESS; 15050 } 15051 } 15052 15053 /* 15054 * Prevent non-system code (defined here to be non-persistent 15055 * processes) from sending protected broadcasts. 15056 */ 15057 int callingAppId = UserHandle.getAppId(callingUid); 15058 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 15059 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 15060 || callingAppId == Process.NFC_UID || callingUid == 0) { 15061 // Always okay. 15062 } else if (callerApp == null || !callerApp.persistent) { 15063 try { 15064 if (AppGlobals.getPackageManager().isProtectedBroadcast( 15065 intent.getAction())) { 15066 String msg = "Permission Denial: not allowed to send broadcast " 15067 + intent.getAction() + " from pid=" 15068 + callingPid + ", uid=" + callingUid; 15069 Slog.w(TAG, msg); 15070 throw new SecurityException(msg); 15071 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 15072 // Special case for compatibility: we don't want apps to send this, 15073 // but historically it has not been protected and apps may be using it 15074 // to poke their own app widget. So, instead of making it protected, 15075 // just limit it to the caller. 15076 if (callerApp == null) { 15077 String msg = "Permission Denial: not allowed to send broadcast " 15078 + intent.getAction() + " from unknown caller."; 15079 Slog.w(TAG, msg); 15080 throw new SecurityException(msg); 15081 } else if (intent.getComponent() != null) { 15082 // They are good enough to send to an explicit component... verify 15083 // it is being sent to the calling app. 15084 if (!intent.getComponent().getPackageName().equals( 15085 callerApp.info.packageName)) { 15086 String msg = "Permission Denial: not allowed to send broadcast " 15087 + intent.getAction() + " to " 15088 + intent.getComponent().getPackageName() + " from " 15089 + callerApp.info.packageName; 15090 Slog.w(TAG, msg); 15091 throw new SecurityException(msg); 15092 } 15093 } else { 15094 // Limit broadcast to their own package. 15095 intent.setPackage(callerApp.info.packageName); 15096 } 15097 } 15098 } catch (RemoteException e) { 15099 Slog.w(TAG, "Remote exception", e); 15100 return ActivityManager.BROADCAST_SUCCESS; 15101 } 15102 } 15103 15104 // Handle special intents: if this broadcast is from the package 15105 // manager about a package being removed, we need to remove all of 15106 // its activities from the history stack. 15107 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 15108 intent.getAction()); 15109 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 15110 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 15111 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 15112 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction()) 15113 || uidRemoved) { 15114 if (checkComponentPermission( 15115 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 15116 callingPid, callingUid, -1, true) 15117 == PackageManager.PERMISSION_GRANTED) { 15118 if (uidRemoved) { 15119 final Bundle intentExtras = intent.getExtras(); 15120 final int uid = intentExtras != null 15121 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 15122 if (uid >= 0) { 15123 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 15124 synchronized (bs) { 15125 bs.removeUidStatsLocked(uid); 15126 } 15127 mAppOpsService.uidRemoved(uid); 15128 } 15129 } else { 15130 // If resources are unavailable just force stop all 15131 // those packages and flush the attribute cache as well. 15132 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 15133 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15134 if (list != null && (list.length > 0)) { 15135 for (String pkg : list) { 15136 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 15137 "storage unmount"); 15138 } 15139 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15140 sendPackageBroadcastLocked( 15141 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 15142 } 15143 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals( 15144 intent.getAction())) { 15145 cleanupRecentTasksLocked(UserHandle.USER_ALL); 15146 } else { 15147 Uri data = intent.getData(); 15148 String ssp; 15149 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15150 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 15151 intent.getAction()); 15152 boolean fullUninstall = removed && 15153 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 15154 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 15155 forceStopPackageLocked(ssp, UserHandle.getAppId( 15156 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 15157 false, fullUninstall, userId, 15158 removed ? "pkg removed" : "pkg changed"); 15159 } 15160 if (removed) { 15161 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 15162 new String[] {ssp}, userId); 15163 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 15164 mAppOpsService.packageRemoved( 15165 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 15166 15167 // Remove all permissions granted from/to this package 15168 removeUriPermissionsForPackageLocked(ssp, userId, true); 15169 } 15170 } 15171 } 15172 } 15173 } 15174 } else { 15175 String msg = "Permission Denial: " + intent.getAction() 15176 + " broadcast from " + callerPackage + " (pid=" + callingPid 15177 + ", uid=" + callingUid + ")" 15178 + " requires " 15179 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 15180 Slog.w(TAG, msg); 15181 throw new SecurityException(msg); 15182 } 15183 15184 // Special case for adding a package: by default turn on compatibility 15185 // mode. 15186 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 15187 Uri data = intent.getData(); 15188 String ssp; 15189 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 15190 mCompatModePackages.handlePackageAddedLocked(ssp, 15191 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 15192 } 15193 } 15194 15195 /* 15196 * If this is the time zone changed action, queue up a message that will reset the timezone 15197 * of all currently running processes. This message will get queued up before the broadcast 15198 * happens. 15199 */ 15200 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 15201 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 15202 } 15203 15204 /* 15205 * If the user set the time, let all running processes know. 15206 */ 15207 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 15208 final int is24Hour = intent.getBooleanExtra( 15209 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 15210 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 15211 } 15212 15213 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 15214 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 15215 } 15216 15217 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 15218 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 15219 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 15220 } 15221 15222 // Add to the sticky list if requested. 15223 if (sticky) { 15224 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 15225 callingPid, callingUid) 15226 != PackageManager.PERMISSION_GRANTED) { 15227 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 15228 + callingPid + ", uid=" + callingUid 15229 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15230 Slog.w(TAG, msg); 15231 throw new SecurityException(msg); 15232 } 15233 if (requiredPermission != null) { 15234 Slog.w(TAG, "Can't broadcast sticky intent " + intent 15235 + " and enforce permission " + requiredPermission); 15236 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 15237 } 15238 if (intent.getComponent() != null) { 15239 throw new SecurityException( 15240 "Sticky broadcasts can't target a specific component"); 15241 } 15242 // We use userId directly here, since the "all" target is maintained 15243 // as a separate set of sticky broadcasts. 15244 if (userId != UserHandle.USER_ALL) { 15245 // But first, if this is not a broadcast to all users, then 15246 // make sure it doesn't conflict with an existing broadcast to 15247 // all users. 15248 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 15249 UserHandle.USER_ALL); 15250 if (stickies != null) { 15251 ArrayList<Intent> list = stickies.get(intent.getAction()); 15252 if (list != null) { 15253 int N = list.size(); 15254 int i; 15255 for (i=0; i<N; i++) { 15256 if (intent.filterEquals(list.get(i))) { 15257 throw new IllegalArgumentException( 15258 "Sticky broadcast " + intent + " for user " 15259 + userId + " conflicts with existing global broadcast"); 15260 } 15261 } 15262 } 15263 } 15264 } 15265 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15266 if (stickies == null) { 15267 stickies = new ArrayMap<String, ArrayList<Intent>>(); 15268 mStickyBroadcasts.put(userId, stickies); 15269 } 15270 ArrayList<Intent> list = stickies.get(intent.getAction()); 15271 if (list == null) { 15272 list = new ArrayList<Intent>(); 15273 stickies.put(intent.getAction(), list); 15274 } 15275 int N = list.size(); 15276 int i; 15277 for (i=0; i<N; i++) { 15278 if (intent.filterEquals(list.get(i))) { 15279 // This sticky already exists, replace it. 15280 list.set(i, new Intent(intent)); 15281 break; 15282 } 15283 } 15284 if (i >= N) { 15285 list.add(new Intent(intent)); 15286 } 15287 } 15288 15289 int[] users; 15290 if (userId == UserHandle.USER_ALL) { 15291 // Caller wants broadcast to go to all started users. 15292 users = mStartedUserArray; 15293 } else { 15294 // Caller wants broadcast to go to one specific user. 15295 users = new int[] {userId}; 15296 } 15297 15298 // Figure out who all will receive this broadcast. 15299 List receivers = null; 15300 List<BroadcastFilter> registeredReceivers = null; 15301 // Need to resolve the intent to interested receivers... 15302 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 15303 == 0) { 15304 receivers = collectReceiverComponents(intent, resolvedType, users); 15305 } 15306 if (intent.getComponent() == null) { 15307 registeredReceivers = mReceiverResolver.queryIntent(intent, 15308 resolvedType, false, userId); 15309 } 15310 15311 final boolean replacePending = 15312 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 15313 15314 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 15315 + " replacePending=" + replacePending); 15316 15317 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 15318 if (!ordered && NR > 0) { 15319 // If we are not serializing this broadcast, then send the 15320 // registered receivers separately so they don't wait for the 15321 // components to be launched. 15322 final BroadcastQueue queue = broadcastQueueForIntent(intent); 15323 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15324 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 15325 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 15326 ordered, sticky, false, userId); 15327 if (DEBUG_BROADCAST) Slog.v( 15328 TAG, "Enqueueing parallel broadcast " + r); 15329 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 15330 if (!replaced) { 15331 queue.enqueueParallelBroadcastLocked(r); 15332 queue.scheduleBroadcastsLocked(); 15333 } 15334 registeredReceivers = null; 15335 NR = 0; 15336 } 15337 15338 // Merge into one list. 15339 int ir = 0; 15340 if (receivers != null) { 15341 // A special case for PACKAGE_ADDED: do not allow the package 15342 // being added to see this broadcast. This prevents them from 15343 // using this as a back door to get run as soon as they are 15344 // installed. Maybe in the future we want to have a special install 15345 // broadcast or such for apps, but we'd like to deliberately make 15346 // this decision. 15347 String skipPackages[] = null; 15348 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 15349 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 15350 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 15351 Uri data = intent.getData(); 15352 if (data != null) { 15353 String pkgName = data.getSchemeSpecificPart(); 15354 if (pkgName != null) { 15355 skipPackages = new String[] { pkgName }; 15356 } 15357 } 15358 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 15359 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 15360 } 15361 if (skipPackages != null && (skipPackages.length > 0)) { 15362 for (String skipPackage : skipPackages) { 15363 if (skipPackage != null) { 15364 int NT = receivers.size(); 15365 for (int it=0; it<NT; it++) { 15366 ResolveInfo curt = (ResolveInfo)receivers.get(it); 15367 if (curt.activityInfo.packageName.equals(skipPackage)) { 15368 receivers.remove(it); 15369 it--; 15370 NT--; 15371 } 15372 } 15373 } 15374 } 15375 } 15376 15377 int NT = receivers != null ? receivers.size() : 0; 15378 int it = 0; 15379 ResolveInfo curt = null; 15380 BroadcastFilter curr = null; 15381 while (it < NT && ir < NR) { 15382 if (curt == null) { 15383 curt = (ResolveInfo)receivers.get(it); 15384 } 15385 if (curr == null) { 15386 curr = registeredReceivers.get(ir); 15387 } 15388 if (curr.getPriority() >= curt.priority) { 15389 // Insert this broadcast record into the final list. 15390 receivers.add(it, curr); 15391 ir++; 15392 curr = null; 15393 it++; 15394 NT++; 15395 } else { 15396 // Skip to the next ResolveInfo in the final list. 15397 it++; 15398 curt = null; 15399 } 15400 } 15401 } 15402 while (ir < NR) { 15403 if (receivers == null) { 15404 receivers = new ArrayList(); 15405 } 15406 receivers.add(registeredReceivers.get(ir)); 15407 ir++; 15408 } 15409 15410 if ((receivers != null && receivers.size() > 0) 15411 || resultTo != null) { 15412 BroadcastQueue queue = broadcastQueueForIntent(intent); 15413 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 15414 callerPackage, callingPid, callingUid, resolvedType, 15415 requiredPermission, appOp, receivers, resultTo, resultCode, 15416 resultData, map, ordered, sticky, false, userId); 15417 if (DEBUG_BROADCAST) Slog.v( 15418 TAG, "Enqueueing ordered broadcast " + r 15419 + ": prev had " + queue.mOrderedBroadcasts.size()); 15420 if (DEBUG_BROADCAST) { 15421 int seq = r.intent.getIntExtra("seq", -1); 15422 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 15423 } 15424 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 15425 if (!replaced) { 15426 queue.enqueueOrderedBroadcastLocked(r); 15427 queue.scheduleBroadcastsLocked(); 15428 } 15429 } 15430 15431 return ActivityManager.BROADCAST_SUCCESS; 15432 } 15433 15434 final Intent verifyBroadcastLocked(Intent intent) { 15435 // Refuse possible leaked file descriptors 15436 if (intent != null && intent.hasFileDescriptors() == true) { 15437 throw new IllegalArgumentException("File descriptors passed in Intent"); 15438 } 15439 15440 int flags = intent.getFlags(); 15441 15442 if (!mProcessesReady) { 15443 // if the caller really truly claims to know what they're doing, go 15444 // ahead and allow the broadcast without launching any receivers 15445 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 15446 intent = new Intent(intent); 15447 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 15448 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 15449 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 15450 + " before boot completion"); 15451 throw new IllegalStateException("Cannot broadcast before boot completed"); 15452 } 15453 } 15454 15455 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 15456 throw new IllegalArgumentException( 15457 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 15458 } 15459 15460 return intent; 15461 } 15462 15463 public final int broadcastIntent(IApplicationThread caller, 15464 Intent intent, String resolvedType, IIntentReceiver resultTo, 15465 int resultCode, String resultData, Bundle map, 15466 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 15467 enforceNotIsolatedCaller("broadcastIntent"); 15468 synchronized(this) { 15469 intent = verifyBroadcastLocked(intent); 15470 15471 final ProcessRecord callerApp = getRecordForAppLocked(caller); 15472 final int callingPid = Binder.getCallingPid(); 15473 final int callingUid = Binder.getCallingUid(); 15474 final long origId = Binder.clearCallingIdentity(); 15475 int res = broadcastIntentLocked(callerApp, 15476 callerApp != null ? callerApp.info.packageName : null, 15477 intent, resolvedType, resultTo, 15478 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 15479 callingPid, callingUid, userId); 15480 Binder.restoreCallingIdentity(origId); 15481 return res; 15482 } 15483 } 15484 15485 int broadcastIntentInPackage(String packageName, int uid, 15486 Intent intent, String resolvedType, IIntentReceiver resultTo, 15487 int resultCode, String resultData, Bundle map, 15488 String requiredPermission, boolean serialized, boolean sticky, int userId) { 15489 synchronized(this) { 15490 intent = verifyBroadcastLocked(intent); 15491 15492 final long origId = Binder.clearCallingIdentity(); 15493 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 15494 resultTo, resultCode, resultData, map, requiredPermission, 15495 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 15496 Binder.restoreCallingIdentity(origId); 15497 return res; 15498 } 15499 } 15500 15501 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 15502 // Refuse possible leaked file descriptors 15503 if (intent != null && intent.hasFileDescriptors() == true) { 15504 throw new IllegalArgumentException("File descriptors passed in Intent"); 15505 } 15506 15507 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15508 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 15509 15510 synchronized(this) { 15511 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 15512 != PackageManager.PERMISSION_GRANTED) { 15513 String msg = "Permission Denial: unbroadcastIntent() from pid=" 15514 + Binder.getCallingPid() 15515 + ", uid=" + Binder.getCallingUid() 15516 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 15517 Slog.w(TAG, msg); 15518 throw new SecurityException(msg); 15519 } 15520 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 15521 if (stickies != null) { 15522 ArrayList<Intent> list = stickies.get(intent.getAction()); 15523 if (list != null) { 15524 int N = list.size(); 15525 int i; 15526 for (i=0; i<N; i++) { 15527 if (intent.filterEquals(list.get(i))) { 15528 list.remove(i); 15529 break; 15530 } 15531 } 15532 if (list.size() <= 0) { 15533 stickies.remove(intent.getAction()); 15534 } 15535 } 15536 if (stickies.size() <= 0) { 15537 mStickyBroadcasts.remove(userId); 15538 } 15539 } 15540 } 15541 } 15542 15543 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 15544 String resultData, Bundle resultExtras, boolean resultAbort) { 15545 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 15546 if (r == null) { 15547 Slog.w(TAG, "finishReceiver called but not found on queue"); 15548 return false; 15549 } 15550 15551 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 15552 } 15553 15554 void backgroundServicesFinishedLocked(int userId) { 15555 for (BroadcastQueue queue : mBroadcastQueues) { 15556 queue.backgroundServicesFinishedLocked(userId); 15557 } 15558 } 15559 15560 public void finishReceiver(IBinder who, int resultCode, String resultData, 15561 Bundle resultExtras, boolean resultAbort) { 15562 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 15563 15564 // Refuse possible leaked file descriptors 15565 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 15566 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15567 } 15568 15569 final long origId = Binder.clearCallingIdentity(); 15570 try { 15571 boolean doNext = false; 15572 BroadcastRecord r; 15573 15574 synchronized(this) { 15575 r = broadcastRecordForReceiverLocked(who); 15576 if (r != null) { 15577 doNext = r.queue.finishReceiverLocked(r, resultCode, 15578 resultData, resultExtras, resultAbort, true); 15579 } 15580 } 15581 15582 if (doNext) { 15583 r.queue.processNextBroadcast(false); 15584 } 15585 trimApplications(); 15586 } finally { 15587 Binder.restoreCallingIdentity(origId); 15588 } 15589 } 15590 15591 // ========================================================= 15592 // INSTRUMENTATION 15593 // ========================================================= 15594 15595 public boolean startInstrumentation(ComponentName className, 15596 String profileFile, int flags, Bundle arguments, 15597 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 15598 int userId, String abiOverride) { 15599 enforceNotIsolatedCaller("startInstrumentation"); 15600 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 15601 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 15602 // Refuse possible leaked file descriptors 15603 if (arguments != null && arguments.hasFileDescriptors()) { 15604 throw new IllegalArgumentException("File descriptors passed in Bundle"); 15605 } 15606 15607 synchronized(this) { 15608 InstrumentationInfo ii = null; 15609 ApplicationInfo ai = null; 15610 try { 15611 ii = mContext.getPackageManager().getInstrumentationInfo( 15612 className, STOCK_PM_FLAGS); 15613 ai = AppGlobals.getPackageManager().getApplicationInfo( 15614 ii.targetPackage, STOCK_PM_FLAGS, userId); 15615 } catch (PackageManager.NameNotFoundException e) { 15616 } catch (RemoteException e) { 15617 } 15618 if (ii == null) { 15619 reportStartInstrumentationFailure(watcher, className, 15620 "Unable to find instrumentation info for: " + className); 15621 return false; 15622 } 15623 if (ai == null) { 15624 reportStartInstrumentationFailure(watcher, className, 15625 "Unable to find instrumentation target package: " + ii.targetPackage); 15626 return false; 15627 } 15628 15629 int match = mContext.getPackageManager().checkSignatures( 15630 ii.targetPackage, ii.packageName); 15631 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 15632 String msg = "Permission Denial: starting instrumentation " 15633 + className + " from pid=" 15634 + Binder.getCallingPid() 15635 + ", uid=" + Binder.getCallingPid() 15636 + " not allowed because package " + ii.packageName 15637 + " does not have a signature matching the target " 15638 + ii.targetPackage; 15639 reportStartInstrumentationFailure(watcher, className, msg); 15640 throw new SecurityException(msg); 15641 } 15642 15643 final long origId = Binder.clearCallingIdentity(); 15644 // Instrumentation can kill and relaunch even persistent processes 15645 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 15646 "start instr"); 15647 ProcessRecord app = addAppLocked(ai, false, abiOverride); 15648 app.instrumentationClass = className; 15649 app.instrumentationInfo = ai; 15650 app.instrumentationProfileFile = profileFile; 15651 app.instrumentationArguments = arguments; 15652 app.instrumentationWatcher = watcher; 15653 app.instrumentationUiAutomationConnection = uiAutomationConnection; 15654 app.instrumentationResultClass = className; 15655 Binder.restoreCallingIdentity(origId); 15656 } 15657 15658 return true; 15659 } 15660 15661 /** 15662 * Report errors that occur while attempting to start Instrumentation. Always writes the 15663 * error to the logs, but if somebody is watching, send the report there too. This enables 15664 * the "am" command to report errors with more information. 15665 * 15666 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 15667 * @param cn The component name of the instrumentation. 15668 * @param report The error report. 15669 */ 15670 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 15671 ComponentName cn, String report) { 15672 Slog.w(TAG, report); 15673 try { 15674 if (watcher != null) { 15675 Bundle results = new Bundle(); 15676 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 15677 results.putString("Error", report); 15678 watcher.instrumentationStatus(cn, -1, results); 15679 } 15680 } catch (RemoteException e) { 15681 Slog.w(TAG, e); 15682 } 15683 } 15684 15685 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 15686 if (app.instrumentationWatcher != null) { 15687 try { 15688 // NOTE: IInstrumentationWatcher *must* be oneway here 15689 app.instrumentationWatcher.instrumentationFinished( 15690 app.instrumentationClass, 15691 resultCode, 15692 results); 15693 } catch (RemoteException e) { 15694 } 15695 } 15696 if (app.instrumentationUiAutomationConnection != null) { 15697 try { 15698 app.instrumentationUiAutomationConnection.shutdown(); 15699 } catch (RemoteException re) { 15700 /* ignore */ 15701 } 15702 // Only a UiAutomation can set this flag and now that 15703 // it is finished we make sure it is reset to its default. 15704 mUserIsMonkey = false; 15705 } 15706 app.instrumentationWatcher = null; 15707 app.instrumentationUiAutomationConnection = null; 15708 app.instrumentationClass = null; 15709 app.instrumentationInfo = null; 15710 app.instrumentationProfileFile = null; 15711 app.instrumentationArguments = null; 15712 15713 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 15714 "finished inst"); 15715 } 15716 15717 public void finishInstrumentation(IApplicationThread target, 15718 int resultCode, Bundle results) { 15719 int userId = UserHandle.getCallingUserId(); 15720 // Refuse possible leaked file descriptors 15721 if (results != null && results.hasFileDescriptors()) { 15722 throw new IllegalArgumentException("File descriptors passed in Intent"); 15723 } 15724 15725 synchronized(this) { 15726 ProcessRecord app = getRecordForAppLocked(target); 15727 if (app == null) { 15728 Slog.w(TAG, "finishInstrumentation: no app for " + target); 15729 return; 15730 } 15731 final long origId = Binder.clearCallingIdentity(); 15732 finishInstrumentationLocked(app, resultCode, results); 15733 Binder.restoreCallingIdentity(origId); 15734 } 15735 } 15736 15737 // ========================================================= 15738 // CONFIGURATION 15739 // ========================================================= 15740 15741 public ConfigurationInfo getDeviceConfigurationInfo() { 15742 ConfigurationInfo config = new ConfigurationInfo(); 15743 synchronized (this) { 15744 config.reqTouchScreen = mConfiguration.touchscreen; 15745 config.reqKeyboardType = mConfiguration.keyboard; 15746 config.reqNavigation = mConfiguration.navigation; 15747 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 15748 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 15749 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 15750 } 15751 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 15752 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 15753 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 15754 } 15755 config.reqGlEsVersion = GL_ES_VERSION; 15756 } 15757 return config; 15758 } 15759 15760 ActivityStack getFocusedStack() { 15761 return mStackSupervisor.getFocusedStack(); 15762 } 15763 15764 public Configuration getConfiguration() { 15765 Configuration ci; 15766 synchronized(this) { 15767 ci = new Configuration(mConfiguration); 15768 } 15769 return ci; 15770 } 15771 15772 public void updatePersistentConfiguration(Configuration values) { 15773 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15774 "updateConfiguration()"); 15775 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 15776 "updateConfiguration()"); 15777 if (values == null) { 15778 throw new NullPointerException("Configuration must not be null"); 15779 } 15780 15781 synchronized(this) { 15782 final long origId = Binder.clearCallingIdentity(); 15783 updateConfigurationLocked(values, null, true, false); 15784 Binder.restoreCallingIdentity(origId); 15785 } 15786 } 15787 15788 public void updateConfiguration(Configuration values) { 15789 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 15790 "updateConfiguration()"); 15791 15792 synchronized(this) { 15793 if (values == null && mWindowManager != null) { 15794 // sentinel: fetch the current configuration from the window manager 15795 values = mWindowManager.computeNewConfiguration(); 15796 } 15797 15798 if (mWindowManager != null) { 15799 mProcessList.applyDisplaySize(mWindowManager); 15800 } 15801 15802 final long origId = Binder.clearCallingIdentity(); 15803 if (values != null) { 15804 Settings.System.clearConfiguration(values); 15805 } 15806 updateConfigurationLocked(values, null, false, false); 15807 Binder.restoreCallingIdentity(origId); 15808 } 15809 } 15810 15811 /** 15812 * Do either or both things: (1) change the current configuration, and (2) 15813 * make sure the given activity is running with the (now) current 15814 * configuration. Returns true if the activity has been left running, or 15815 * false if <var>starting</var> is being destroyed to match the new 15816 * configuration. 15817 * @param persistent TODO 15818 */ 15819 boolean updateConfigurationLocked(Configuration values, 15820 ActivityRecord starting, boolean persistent, boolean initLocale) { 15821 int changes = 0; 15822 15823 if (values != null) { 15824 Configuration newConfig = new Configuration(mConfiguration); 15825 changes = newConfig.updateFrom(values); 15826 if (changes != 0) { 15827 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15828 Slog.i(TAG, "Updating configuration to: " + values); 15829 } 15830 15831 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15832 15833 if (values.locale != null && !initLocale) { 15834 saveLocaleLocked(values.locale, 15835 !values.locale.equals(mConfiguration.locale), 15836 values.userSetLocale); 15837 } 15838 15839 mConfigurationSeq++; 15840 if (mConfigurationSeq <= 0) { 15841 mConfigurationSeq = 1; 15842 } 15843 newConfig.seq = mConfigurationSeq; 15844 mConfiguration = newConfig; 15845 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15846 //mUsageStatsService.noteStartConfig(newConfig); 15847 15848 final Configuration configCopy = new Configuration(mConfiguration); 15849 15850 // TODO: If our config changes, should we auto dismiss any currently 15851 // showing dialogs? 15852 mShowDialogs = shouldShowDialogs(newConfig); 15853 15854 AttributeCache ac = AttributeCache.instance(); 15855 if (ac != null) { 15856 ac.updateConfiguration(configCopy); 15857 } 15858 15859 // Make sure all resources in our process are updated 15860 // right now, so that anyone who is going to retrieve 15861 // resource values after we return will be sure to get 15862 // the new ones. This is especially important during 15863 // boot, where the first config change needs to guarantee 15864 // all resources have that config before following boot 15865 // code is executed. 15866 mSystemThread.applyConfigurationToResources(configCopy); 15867 15868 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15869 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15870 msg.obj = new Configuration(configCopy); 15871 mHandler.sendMessage(msg); 15872 } 15873 15874 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15875 ProcessRecord app = mLruProcesses.get(i); 15876 try { 15877 if (app.thread != null) { 15878 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15879 + app.processName + " new config " + mConfiguration); 15880 app.thread.scheduleConfigurationChanged(configCopy); 15881 } 15882 } catch (Exception e) { 15883 } 15884 } 15885 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15886 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15887 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15888 | Intent.FLAG_RECEIVER_FOREGROUND); 15889 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15890 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15891 Process.SYSTEM_UID, UserHandle.USER_ALL); 15892 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15893 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15894 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15895 broadcastIntentLocked(null, null, intent, 15896 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15897 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15898 } 15899 } 15900 } 15901 15902 boolean kept = true; 15903 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15904 // mainStack is null during startup. 15905 if (mainStack != null) { 15906 if (changes != 0 && starting == null) { 15907 // If the configuration changed, and the caller is not already 15908 // in the process of starting an activity, then find the top 15909 // activity to check if its configuration needs to change. 15910 starting = mainStack.topRunningActivityLocked(null); 15911 } 15912 15913 if (starting != null) { 15914 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15915 // And we need to make sure at this point that all other activities 15916 // are made visible with the correct configuration. 15917 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15918 } 15919 } 15920 15921 if (values != null && mWindowManager != null) { 15922 mWindowManager.setNewConfiguration(mConfiguration); 15923 } 15924 15925 return kept; 15926 } 15927 15928 /** 15929 * Decide based on the configuration whether we should shouw the ANR, 15930 * crash, etc dialogs. The idea is that if there is no affordnace to 15931 * press the on-screen buttons, we shouldn't show the dialog. 15932 * 15933 * A thought: SystemUI might also want to get told about this, the Power 15934 * dialog / global actions also might want different behaviors. 15935 */ 15936 private static final boolean shouldShowDialogs(Configuration config) { 15937 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15938 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15939 } 15940 15941 /** 15942 * Save the locale. You must be inside a synchronized (this) block. 15943 */ 15944 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15945 if(isDiff) { 15946 SystemProperties.set("user.language", l.getLanguage()); 15947 SystemProperties.set("user.region", l.getCountry()); 15948 } 15949 15950 if(isPersist) { 15951 SystemProperties.set("persist.sys.language", l.getLanguage()); 15952 SystemProperties.set("persist.sys.country", l.getCountry()); 15953 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15954 } 15955 } 15956 15957 @Override 15958 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) { 15959 synchronized (this) { 15960 ActivityRecord srec = ActivityRecord.forToken(token); 15961 if (srec.task != null && srec.task.stack != null) { 15962 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity); 15963 } 15964 } 15965 return false; 15966 } 15967 15968 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15969 Intent resultData) { 15970 15971 synchronized (this) { 15972 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15973 if (stack != null) { 15974 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15975 } 15976 return false; 15977 } 15978 } 15979 15980 public int getLaunchedFromUid(IBinder activityToken) { 15981 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15982 if (srec == null) { 15983 return -1; 15984 } 15985 return srec.launchedFromUid; 15986 } 15987 15988 public String getLaunchedFromPackage(IBinder activityToken) { 15989 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15990 if (srec == null) { 15991 return null; 15992 } 15993 return srec.launchedFromPackage; 15994 } 15995 15996 // ========================================================= 15997 // LIFETIME MANAGEMENT 15998 // ========================================================= 15999 16000 // Returns which broadcast queue the app is the current [or imminent] receiver 16001 // on, or 'null' if the app is not an active broadcast recipient. 16002 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 16003 BroadcastRecord r = app.curReceiver; 16004 if (r != null) { 16005 return r.queue; 16006 } 16007 16008 // It's not the current receiver, but it might be starting up to become one 16009 synchronized (this) { 16010 for (BroadcastQueue queue : mBroadcastQueues) { 16011 r = queue.mPendingBroadcast; 16012 if (r != null && r.curApp == app) { 16013 // found it; report which queue it's in 16014 return queue; 16015 } 16016 } 16017 } 16018 16019 return null; 16020 } 16021 16022 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 16023 boolean doingAll, long now) { 16024 if (mAdjSeq == app.adjSeq) { 16025 // This adjustment has already been computed. 16026 return app.curRawAdj; 16027 } 16028 16029 if (app.thread == null) { 16030 app.adjSeq = mAdjSeq; 16031 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16032 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16033 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 16034 } 16035 16036 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 16037 app.adjSource = null; 16038 app.adjTarget = null; 16039 app.empty = false; 16040 app.cached = false; 16041 16042 final int activitiesSize = app.activities.size(); 16043 16044 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 16045 // The max adjustment doesn't allow this app to be anything 16046 // below foreground, so it is not worth doing work for it. 16047 app.adjType = "fixed"; 16048 app.adjSeq = mAdjSeq; 16049 app.curRawAdj = app.maxAdj; 16050 app.foregroundActivities = false; 16051 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 16052 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 16053 // System processes can do UI, and when they do we want to have 16054 // them trim their memory after the user leaves the UI. To 16055 // facilitate this, here we need to determine whether or not it 16056 // is currently showing UI. 16057 app.systemNoUi = true; 16058 if (app == TOP_APP) { 16059 app.systemNoUi = false; 16060 } else if (activitiesSize > 0) { 16061 for (int j = 0; j < activitiesSize; j++) { 16062 final ActivityRecord r = app.activities.get(j); 16063 if (r.visible) { 16064 app.systemNoUi = false; 16065 } 16066 } 16067 } 16068 if (!app.systemNoUi) { 16069 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 16070 } 16071 return (app.curAdj=app.maxAdj); 16072 } 16073 16074 app.systemNoUi = false; 16075 16076 // Determine the importance of the process, starting with most 16077 // important to least, and assign an appropriate OOM adjustment. 16078 int adj; 16079 int schedGroup; 16080 int procState; 16081 boolean foregroundActivities = false; 16082 BroadcastQueue queue; 16083 if (app == TOP_APP) { 16084 // The last app on the list is the foreground app. 16085 adj = ProcessList.FOREGROUND_APP_ADJ; 16086 schedGroup = Process.THREAD_GROUP_DEFAULT; 16087 app.adjType = "top-activity"; 16088 foregroundActivities = true; 16089 procState = ActivityManager.PROCESS_STATE_TOP; 16090 } else if (app.instrumentationClass != null) { 16091 // Don't want to kill running instrumentation. 16092 adj = ProcessList.FOREGROUND_APP_ADJ; 16093 schedGroup = Process.THREAD_GROUP_DEFAULT; 16094 app.adjType = "instrumentation"; 16095 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16096 } else if ((queue = isReceivingBroadcast(app)) != null) { 16097 // An app that is currently receiving a broadcast also 16098 // counts as being in the foreground for OOM killer purposes. 16099 // It's placed in a sched group based on the nature of the 16100 // broadcast as reflected by which queue it's active in. 16101 adj = ProcessList.FOREGROUND_APP_ADJ; 16102 schedGroup = (queue == mFgBroadcastQueue) 16103 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16104 app.adjType = "broadcast"; 16105 procState = ActivityManager.PROCESS_STATE_RECEIVER; 16106 } else if (app.executingServices.size() > 0) { 16107 // An app that is currently executing a service callback also 16108 // counts as being in the foreground. 16109 adj = ProcessList.FOREGROUND_APP_ADJ; 16110 schedGroup = app.execServicesFg ? 16111 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 16112 app.adjType = "exec-service"; 16113 procState = ActivityManager.PROCESS_STATE_SERVICE; 16114 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 16115 } else { 16116 // As far as we know the process is empty. We may change our mind later. 16117 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16118 // At this point we don't actually know the adjustment. Use the cached adj 16119 // value that the caller wants us to. 16120 adj = cachedAdj; 16121 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16122 app.cached = true; 16123 app.empty = true; 16124 app.adjType = "cch-empty"; 16125 } 16126 16127 // Examine all activities if not already foreground. 16128 if (!foregroundActivities && activitiesSize > 0) { 16129 for (int j = 0; j < activitiesSize; j++) { 16130 final ActivityRecord r = app.activities.get(j); 16131 if (r.app != app) { 16132 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 16133 + app + "?!?"); 16134 continue; 16135 } 16136 if (r.visible) { 16137 // App has a visible activity; only upgrade adjustment. 16138 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16139 adj = ProcessList.VISIBLE_APP_ADJ; 16140 app.adjType = "visible"; 16141 } 16142 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16143 procState = ActivityManager.PROCESS_STATE_TOP; 16144 } 16145 schedGroup = Process.THREAD_GROUP_DEFAULT; 16146 app.cached = false; 16147 app.empty = false; 16148 foregroundActivities = true; 16149 break; 16150 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 16151 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16152 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16153 app.adjType = "pausing"; 16154 } 16155 if (procState > ActivityManager.PROCESS_STATE_TOP) { 16156 procState = ActivityManager.PROCESS_STATE_TOP; 16157 } 16158 schedGroup = Process.THREAD_GROUP_DEFAULT; 16159 app.cached = false; 16160 app.empty = false; 16161 foregroundActivities = true; 16162 } else if (r.state == ActivityState.STOPPING) { 16163 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16164 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16165 app.adjType = "stopping"; 16166 } 16167 // For the process state, we will at this point consider the 16168 // process to be cached. It will be cached either as an activity 16169 // or empty depending on whether the activity is finishing. We do 16170 // this so that we can treat the process as cached for purposes of 16171 // memory trimming (determing current memory level, trim command to 16172 // send to process) since there can be an arbitrary number of stopping 16173 // processes and they should soon all go into the cached state. 16174 if (!r.finishing) { 16175 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16176 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16177 } 16178 } 16179 app.cached = false; 16180 app.empty = false; 16181 foregroundActivities = true; 16182 } else { 16183 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16184 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16185 app.adjType = "cch-act"; 16186 } 16187 } 16188 } 16189 } 16190 16191 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16192 if (app.foregroundServices) { 16193 // The user is aware of this app, so make it visible. 16194 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16195 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16196 app.cached = false; 16197 app.adjType = "fg-service"; 16198 schedGroup = Process.THREAD_GROUP_DEFAULT; 16199 } else if (app.forcingToForeground != null) { 16200 // The user is aware of this app, so make it visible. 16201 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16202 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16203 app.cached = false; 16204 app.adjType = "force-fg"; 16205 app.adjSource = app.forcingToForeground; 16206 schedGroup = Process.THREAD_GROUP_DEFAULT; 16207 } 16208 } 16209 16210 if (app == mHeavyWeightProcess) { 16211 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 16212 // We don't want to kill the current heavy-weight process. 16213 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 16214 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16215 app.cached = false; 16216 app.adjType = "heavy"; 16217 } 16218 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16219 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 16220 } 16221 } 16222 16223 if (app == mHomeProcess) { 16224 if (adj > ProcessList.HOME_APP_ADJ) { 16225 // This process is hosting what we currently consider to be the 16226 // home app, so we don't want to let it go into the background. 16227 adj = ProcessList.HOME_APP_ADJ; 16228 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16229 app.cached = false; 16230 app.adjType = "home"; 16231 } 16232 if (procState > ActivityManager.PROCESS_STATE_HOME) { 16233 procState = ActivityManager.PROCESS_STATE_HOME; 16234 } 16235 } 16236 16237 if (app == mPreviousProcess && app.activities.size() > 0) { 16238 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 16239 // This was the previous process that showed UI to the user. 16240 // We want to try to keep it around more aggressively, to give 16241 // a good experience around switching between two apps. 16242 adj = ProcessList.PREVIOUS_APP_ADJ; 16243 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 16244 app.cached = false; 16245 app.adjType = "previous"; 16246 } 16247 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 16248 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 16249 } 16250 } 16251 16252 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 16253 + " reason=" + app.adjType); 16254 16255 // By default, we use the computed adjustment. It may be changed if 16256 // there are applications dependent on our services or providers, but 16257 // this gives us a baseline and makes sure we don't get into an 16258 // infinite recursion. 16259 app.adjSeq = mAdjSeq; 16260 app.curRawAdj = adj; 16261 app.hasStartedServices = false; 16262 16263 if (mBackupTarget != null && app == mBackupTarget.app) { 16264 // If possible we want to avoid killing apps while they're being backed up 16265 if (adj > ProcessList.BACKUP_APP_ADJ) { 16266 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 16267 adj = ProcessList.BACKUP_APP_ADJ; 16268 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16269 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16270 } 16271 app.adjType = "backup"; 16272 app.cached = false; 16273 } 16274 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 16275 procState = ActivityManager.PROCESS_STATE_BACKUP; 16276 } 16277 } 16278 16279 boolean mayBeTop = false; 16280 16281 for (int is = app.services.size()-1; 16282 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16283 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16284 || procState > ActivityManager.PROCESS_STATE_TOP); 16285 is--) { 16286 ServiceRecord s = app.services.valueAt(is); 16287 if (s.startRequested) { 16288 app.hasStartedServices = true; 16289 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 16290 procState = ActivityManager.PROCESS_STATE_SERVICE; 16291 } 16292 if (app.hasShownUi && app != mHomeProcess) { 16293 // If this process has shown some UI, let it immediately 16294 // go to the LRU list because it may be pretty heavy with 16295 // UI stuff. We'll tag it with a label just to help 16296 // debug and understand what is going on. 16297 if (adj > ProcessList.SERVICE_ADJ) { 16298 app.adjType = "cch-started-ui-services"; 16299 } 16300 } else { 16301 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16302 // This service has seen some activity within 16303 // recent memory, so we will keep its process ahead 16304 // of the background processes. 16305 if (adj > ProcessList.SERVICE_ADJ) { 16306 adj = ProcessList.SERVICE_ADJ; 16307 app.adjType = "started-services"; 16308 app.cached = false; 16309 } 16310 } 16311 // If we have let the service slide into the background 16312 // state, still have some text describing what it is doing 16313 // even though the service no longer has an impact. 16314 if (adj > ProcessList.SERVICE_ADJ) { 16315 app.adjType = "cch-started-services"; 16316 } 16317 } 16318 } 16319 for (int conni = s.connections.size()-1; 16320 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16321 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16322 || procState > ActivityManager.PROCESS_STATE_TOP); 16323 conni--) { 16324 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 16325 for (int i = 0; 16326 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 16327 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16328 || procState > ActivityManager.PROCESS_STATE_TOP); 16329 i++) { 16330 // XXX should compute this based on the max of 16331 // all connected clients. 16332 ConnectionRecord cr = clist.get(i); 16333 if (cr.binding.client == app) { 16334 // Binding to ourself is not interesting. 16335 continue; 16336 } 16337 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 16338 ProcessRecord client = cr.binding.client; 16339 int clientAdj = computeOomAdjLocked(client, cachedAdj, 16340 TOP_APP, doingAll, now); 16341 int clientProcState = client.curProcState; 16342 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16343 // If the other app is cached for any reason, for purposes here 16344 // we are going to consider it empty. The specific cached state 16345 // doesn't propagate except under certain conditions. 16346 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16347 } 16348 String adjType = null; 16349 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 16350 // Not doing bind OOM management, so treat 16351 // this guy more like a started service. 16352 if (app.hasShownUi && app != mHomeProcess) { 16353 // If this process has shown some UI, let it immediately 16354 // go to the LRU list because it may be pretty heavy with 16355 // UI stuff. We'll tag it with a label just to help 16356 // debug and understand what is going on. 16357 if (adj > clientAdj) { 16358 adjType = "cch-bound-ui-services"; 16359 } 16360 app.cached = false; 16361 clientAdj = adj; 16362 clientProcState = procState; 16363 } else { 16364 if (now >= (s.lastActivity 16365 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 16366 // This service has not seen activity within 16367 // recent memory, so allow it to drop to the 16368 // LRU list if there is no other reason to keep 16369 // it around. We'll also tag it with a label just 16370 // to help debug and undertand what is going on. 16371 if (adj > clientAdj) { 16372 adjType = "cch-bound-services"; 16373 } 16374 clientAdj = adj; 16375 } 16376 } 16377 } 16378 if (adj > clientAdj) { 16379 // If this process has recently shown UI, and 16380 // the process that is binding to it is less 16381 // important than being visible, then we don't 16382 // care about the binding as much as we care 16383 // about letting this process get into the LRU 16384 // list to be killed and restarted if needed for 16385 // memory. 16386 if (app.hasShownUi && app != mHomeProcess 16387 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16388 adjType = "cch-bound-ui-services"; 16389 } else { 16390 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 16391 |Context.BIND_IMPORTANT)) != 0) { 16392 adj = clientAdj; 16393 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 16394 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 16395 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16396 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 16397 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 16398 adj = clientAdj; 16399 } else { 16400 if (adj > ProcessList.VISIBLE_APP_ADJ) { 16401 adj = ProcessList.VISIBLE_APP_ADJ; 16402 } 16403 } 16404 if (!client.cached) { 16405 app.cached = false; 16406 } 16407 adjType = "service"; 16408 } 16409 } 16410 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16411 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16412 schedGroup = Process.THREAD_GROUP_DEFAULT; 16413 } 16414 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16415 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16416 // Special handling of clients who are in the top state. 16417 // We *may* want to consider this process to be in the 16418 // top state as well, but only if there is not another 16419 // reason for it to be running. Being on the top is a 16420 // special state, meaning you are specifically running 16421 // for the current top app. If the process is already 16422 // running in the background for some other reason, it 16423 // is more important to continue considering it to be 16424 // in the background state. 16425 mayBeTop = true; 16426 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16427 } else { 16428 // Special handling for above-top states (persistent 16429 // processes). These should not bring the current process 16430 // into the top state, since they are not on top. Instead 16431 // give them the best state after that. 16432 clientProcState = 16433 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16434 } 16435 } 16436 } else { 16437 if (clientProcState < 16438 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 16439 clientProcState = 16440 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 16441 } 16442 } 16443 if (procState > clientProcState) { 16444 procState = clientProcState; 16445 } 16446 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16447 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 16448 app.pendingUiClean = true; 16449 } 16450 if (adjType != null) { 16451 app.adjType = adjType; 16452 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16453 .REASON_SERVICE_IN_USE; 16454 app.adjSource = cr.binding.client; 16455 app.adjSourceProcState = clientProcState; 16456 app.adjTarget = s.name; 16457 } 16458 } 16459 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 16460 app.treatLikeActivity = true; 16461 } 16462 final ActivityRecord a = cr.activity; 16463 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 16464 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 16465 (a.visible || a.state == ActivityState.RESUMED 16466 || a.state == ActivityState.PAUSING)) { 16467 adj = ProcessList.FOREGROUND_APP_ADJ; 16468 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 16469 schedGroup = Process.THREAD_GROUP_DEFAULT; 16470 } 16471 app.cached = false; 16472 app.adjType = "service"; 16473 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16474 .REASON_SERVICE_IN_USE; 16475 app.adjSource = a; 16476 app.adjSourceProcState = procState; 16477 app.adjTarget = s.name; 16478 } 16479 } 16480 } 16481 } 16482 } 16483 16484 for (int provi = app.pubProviders.size()-1; 16485 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16486 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16487 || procState > ActivityManager.PROCESS_STATE_TOP); 16488 provi--) { 16489 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 16490 for (int i = cpr.connections.size()-1; 16491 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 16492 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 16493 || procState > ActivityManager.PROCESS_STATE_TOP); 16494 i--) { 16495 ContentProviderConnection conn = cpr.connections.get(i); 16496 ProcessRecord client = conn.client; 16497 if (client == app) { 16498 // Being our own client is not interesting. 16499 continue; 16500 } 16501 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 16502 int clientProcState = client.curProcState; 16503 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 16504 // If the other app is cached for any reason, for purposes here 16505 // we are going to consider it empty. 16506 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16507 } 16508 if (adj > clientAdj) { 16509 if (app.hasShownUi && app != mHomeProcess 16510 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 16511 app.adjType = "cch-ui-provider"; 16512 } else { 16513 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 16514 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 16515 app.adjType = "provider"; 16516 } 16517 app.cached &= client.cached; 16518 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 16519 .REASON_PROVIDER_IN_USE; 16520 app.adjSource = client; 16521 app.adjSourceProcState = clientProcState; 16522 app.adjTarget = cpr.name; 16523 } 16524 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 16525 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 16526 // Special handling of clients who are in the top state. 16527 // We *may* want to consider this process to be in the 16528 // top state as well, but only if there is not another 16529 // reason for it to be running. Being on the top is a 16530 // special state, meaning you are specifically running 16531 // for the current top app. If the process is already 16532 // running in the background for some other reason, it 16533 // is more important to continue considering it to be 16534 // in the background state. 16535 mayBeTop = true; 16536 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 16537 } else { 16538 // Special handling for above-top states (persistent 16539 // processes). These should not bring the current process 16540 // into the top state, since they are not on top. Instead 16541 // give them the best state after that. 16542 clientProcState = 16543 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16544 } 16545 } 16546 if (procState > clientProcState) { 16547 procState = clientProcState; 16548 } 16549 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 16550 schedGroup = Process.THREAD_GROUP_DEFAULT; 16551 } 16552 } 16553 // If the provider has external (non-framework) process 16554 // dependencies, ensure that its adjustment is at least 16555 // FOREGROUND_APP_ADJ. 16556 if (cpr.hasExternalProcessHandles()) { 16557 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 16558 adj = ProcessList.FOREGROUND_APP_ADJ; 16559 schedGroup = Process.THREAD_GROUP_DEFAULT; 16560 app.cached = false; 16561 app.adjType = "provider"; 16562 app.adjTarget = cpr.name; 16563 } 16564 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 16565 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16566 } 16567 } 16568 } 16569 16570 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 16571 // A client of one of our services or providers is in the top state. We 16572 // *may* want to be in the top state, but not if we are already running in 16573 // the background for some other reason. For the decision here, we are going 16574 // to pick out a few specific states that we want to remain in when a client 16575 // is top (states that tend to be longer-term) and otherwise allow it to go 16576 // to the top state. 16577 switch (procState) { 16578 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 16579 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 16580 case ActivityManager.PROCESS_STATE_SERVICE: 16581 // These all are longer-term states, so pull them up to the top 16582 // of the background states, but not all the way to the top state. 16583 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 16584 break; 16585 default: 16586 // Otherwise, top is a better choice, so take it. 16587 procState = ActivityManager.PROCESS_STATE_TOP; 16588 break; 16589 } 16590 } 16591 16592 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 16593 if (app.hasClientActivities) { 16594 // This is a cached process, but with client activities. Mark it so. 16595 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 16596 app.adjType = "cch-client-act"; 16597 } else if (app.treatLikeActivity) { 16598 // This is a cached process, but somebody wants us to treat it like it has 16599 // an activity, okay! 16600 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 16601 app.adjType = "cch-as-act"; 16602 } 16603 } 16604 16605 if (adj == ProcessList.SERVICE_ADJ) { 16606 if (doingAll) { 16607 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 16608 mNewNumServiceProcs++; 16609 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 16610 if (!app.serviceb) { 16611 // This service isn't far enough down on the LRU list to 16612 // normally be a B service, but if we are low on RAM and it 16613 // is large we want to force it down since we would prefer to 16614 // keep launcher over it. 16615 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 16616 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 16617 app.serviceHighRam = true; 16618 app.serviceb = true; 16619 //Slog.i(TAG, "ADJ " + app + " high ram!"); 16620 } else { 16621 mNewNumAServiceProcs++; 16622 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 16623 } 16624 } else { 16625 app.serviceHighRam = false; 16626 } 16627 } 16628 if (app.serviceb) { 16629 adj = ProcessList.SERVICE_B_ADJ; 16630 } 16631 } 16632 16633 app.curRawAdj = adj; 16634 16635 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 16636 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 16637 if (adj > app.maxAdj) { 16638 adj = app.maxAdj; 16639 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 16640 schedGroup = Process.THREAD_GROUP_DEFAULT; 16641 } 16642 } 16643 16644 // Do final modification to adj. Everything we do between here and applying 16645 // the final setAdj must be done in this function, because we will also use 16646 // it when computing the final cached adj later. Note that we don't need to 16647 // worry about this for max adj above, since max adj will always be used to 16648 // keep it out of the cached vaues. 16649 app.curAdj = app.modifyRawOomAdj(adj); 16650 app.curSchedGroup = schedGroup; 16651 app.curProcState = procState; 16652 app.foregroundActivities = foregroundActivities; 16653 16654 return app.curRawAdj; 16655 } 16656 16657 /** 16658 * Schedule PSS collection of a process. 16659 */ 16660 void requestPssLocked(ProcessRecord proc, int procState) { 16661 if (mPendingPssProcesses.contains(proc)) { 16662 return; 16663 } 16664 if (mPendingPssProcesses.size() == 0) { 16665 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16666 } 16667 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 16668 proc.pssProcState = procState; 16669 mPendingPssProcesses.add(proc); 16670 } 16671 16672 /** 16673 * Schedule PSS collection of all processes. 16674 */ 16675 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 16676 if (!always) { 16677 if (now < (mLastFullPssTime + 16678 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 16679 return; 16680 } 16681 } 16682 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 16683 mLastFullPssTime = now; 16684 mFullPssPending = true; 16685 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 16686 mPendingPssProcesses.clear(); 16687 for (int i=mLruProcesses.size()-1; i>=0; i--) { 16688 ProcessRecord app = mLruProcesses.get(i); 16689 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 16690 app.pssProcState = app.setProcState; 16691 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16692 isSleeping(), now); 16693 mPendingPssProcesses.add(app); 16694 } 16695 } 16696 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 16697 } 16698 16699 /** 16700 * Ask a given process to GC right now. 16701 */ 16702 final void performAppGcLocked(ProcessRecord app) { 16703 try { 16704 app.lastRequestedGc = SystemClock.uptimeMillis(); 16705 if (app.thread != null) { 16706 if (app.reportLowMemory) { 16707 app.reportLowMemory = false; 16708 app.thread.scheduleLowMemory(); 16709 } else { 16710 app.thread.processInBackground(); 16711 } 16712 } 16713 } catch (Exception e) { 16714 // whatever. 16715 } 16716 } 16717 16718 /** 16719 * Returns true if things are idle enough to perform GCs. 16720 */ 16721 private final boolean canGcNowLocked() { 16722 boolean processingBroadcasts = false; 16723 for (BroadcastQueue q : mBroadcastQueues) { 16724 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 16725 processingBroadcasts = true; 16726 } 16727 } 16728 return !processingBroadcasts 16729 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 16730 } 16731 16732 /** 16733 * Perform GCs on all processes that are waiting for it, but only 16734 * if things are idle. 16735 */ 16736 final void performAppGcsLocked() { 16737 final int N = mProcessesToGc.size(); 16738 if (N <= 0) { 16739 return; 16740 } 16741 if (canGcNowLocked()) { 16742 while (mProcessesToGc.size() > 0) { 16743 ProcessRecord proc = mProcessesToGc.remove(0); 16744 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 16745 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 16746 <= SystemClock.uptimeMillis()) { 16747 // To avoid spamming the system, we will GC processes one 16748 // at a time, waiting a few seconds between each. 16749 performAppGcLocked(proc); 16750 scheduleAppGcsLocked(); 16751 return; 16752 } else { 16753 // It hasn't been long enough since we last GCed this 16754 // process... put it in the list to wait for its time. 16755 addProcessToGcListLocked(proc); 16756 break; 16757 } 16758 } 16759 } 16760 16761 scheduleAppGcsLocked(); 16762 } 16763 } 16764 16765 /** 16766 * If all looks good, perform GCs on all processes waiting for them. 16767 */ 16768 final void performAppGcsIfAppropriateLocked() { 16769 if (canGcNowLocked()) { 16770 performAppGcsLocked(); 16771 return; 16772 } 16773 // Still not idle, wait some more. 16774 scheduleAppGcsLocked(); 16775 } 16776 16777 /** 16778 * Schedule the execution of all pending app GCs. 16779 */ 16780 final void scheduleAppGcsLocked() { 16781 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 16782 16783 if (mProcessesToGc.size() > 0) { 16784 // Schedule a GC for the time to the next process. 16785 ProcessRecord proc = mProcessesToGc.get(0); 16786 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 16787 16788 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 16789 long now = SystemClock.uptimeMillis(); 16790 if (when < (now+GC_TIMEOUT)) { 16791 when = now + GC_TIMEOUT; 16792 } 16793 mHandler.sendMessageAtTime(msg, when); 16794 } 16795 } 16796 16797 /** 16798 * Add a process to the array of processes waiting to be GCed. Keeps the 16799 * list in sorted order by the last GC time. The process can't already be 16800 * on the list. 16801 */ 16802 final void addProcessToGcListLocked(ProcessRecord proc) { 16803 boolean added = false; 16804 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 16805 if (mProcessesToGc.get(i).lastRequestedGc < 16806 proc.lastRequestedGc) { 16807 added = true; 16808 mProcessesToGc.add(i+1, proc); 16809 break; 16810 } 16811 } 16812 if (!added) { 16813 mProcessesToGc.add(0, proc); 16814 } 16815 } 16816 16817 /** 16818 * Set up to ask a process to GC itself. This will either do it 16819 * immediately, or put it on the list of processes to gc the next 16820 * time things are idle. 16821 */ 16822 final void scheduleAppGcLocked(ProcessRecord app) { 16823 long now = SystemClock.uptimeMillis(); 16824 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16825 return; 16826 } 16827 if (!mProcessesToGc.contains(app)) { 16828 addProcessToGcListLocked(app); 16829 scheduleAppGcsLocked(); 16830 } 16831 } 16832 16833 final void checkExcessivePowerUsageLocked(boolean doKills) { 16834 updateCpuStatsNow(); 16835 16836 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16837 boolean doWakeKills = doKills; 16838 boolean doCpuKills = doKills; 16839 if (mLastPowerCheckRealtime == 0) { 16840 doWakeKills = false; 16841 } 16842 if (mLastPowerCheckUptime == 0) { 16843 doCpuKills = false; 16844 } 16845 if (stats.isScreenOn()) { 16846 doWakeKills = false; 16847 } 16848 final long curRealtime = SystemClock.elapsedRealtime(); 16849 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16850 final long curUptime = SystemClock.uptimeMillis(); 16851 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16852 mLastPowerCheckRealtime = curRealtime; 16853 mLastPowerCheckUptime = curUptime; 16854 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16855 doWakeKills = false; 16856 } 16857 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16858 doCpuKills = false; 16859 } 16860 int i = mLruProcesses.size(); 16861 while (i > 0) { 16862 i--; 16863 ProcessRecord app = mLruProcesses.get(i); 16864 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16865 long wtime; 16866 synchronized (stats) { 16867 wtime = stats.getProcessWakeTime(app.info.uid, 16868 app.pid, curRealtime); 16869 } 16870 long wtimeUsed = wtime - app.lastWakeTime; 16871 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16872 if (DEBUG_POWER) { 16873 StringBuilder sb = new StringBuilder(128); 16874 sb.append("Wake for "); 16875 app.toShortString(sb); 16876 sb.append(": over "); 16877 TimeUtils.formatDuration(realtimeSince, sb); 16878 sb.append(" used "); 16879 TimeUtils.formatDuration(wtimeUsed, sb); 16880 sb.append(" ("); 16881 sb.append((wtimeUsed*100)/realtimeSince); 16882 sb.append("%)"); 16883 Slog.i(TAG, sb.toString()); 16884 sb.setLength(0); 16885 sb.append("CPU for "); 16886 app.toShortString(sb); 16887 sb.append(": over "); 16888 TimeUtils.formatDuration(uptimeSince, sb); 16889 sb.append(" used "); 16890 TimeUtils.formatDuration(cputimeUsed, sb); 16891 sb.append(" ("); 16892 sb.append((cputimeUsed*100)/uptimeSince); 16893 sb.append("%)"); 16894 Slog.i(TAG, sb.toString()); 16895 } 16896 // If a process has held a wake lock for more 16897 // than 50% of the time during this period, 16898 // that sounds bad. Kill! 16899 if (doWakeKills && realtimeSince > 0 16900 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16901 synchronized (stats) { 16902 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16903 realtimeSince, wtimeUsed); 16904 } 16905 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true); 16906 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16907 } else if (doCpuKills && uptimeSince > 0 16908 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16909 synchronized (stats) { 16910 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16911 uptimeSince, cputimeUsed); 16912 } 16913 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true); 16914 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16915 } else { 16916 app.lastWakeTime = wtime; 16917 app.lastCpuTime = app.curCpuTime; 16918 } 16919 } 16920 } 16921 } 16922 16923 private final boolean applyOomAdjLocked(ProcessRecord app, 16924 ProcessRecord TOP_APP, boolean doingAll, long now) { 16925 boolean success = true; 16926 16927 if (app.curRawAdj != app.setRawAdj) { 16928 app.setRawAdj = app.curRawAdj; 16929 } 16930 16931 int changes = 0; 16932 16933 if (app.curAdj != app.setAdj) { 16934 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16935 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16936 TAG, "Set " + app.pid + " " + app.processName + 16937 " adj " + app.curAdj + ": " + app.adjType); 16938 app.setAdj = app.curAdj; 16939 } 16940 16941 if (app.setSchedGroup != app.curSchedGroup) { 16942 app.setSchedGroup = app.curSchedGroup; 16943 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16944 "Setting process group of " + app.processName 16945 + " to " + app.curSchedGroup); 16946 if (app.waitingToKill != null && 16947 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16948 app.kill(app.waitingToKill, true); 16949 success = false; 16950 } else { 16951 if (true) { 16952 long oldId = Binder.clearCallingIdentity(); 16953 try { 16954 Process.setProcessGroup(app.pid, app.curSchedGroup); 16955 } catch (Exception e) { 16956 Slog.w(TAG, "Failed setting process group of " + app.pid 16957 + " to " + app.curSchedGroup); 16958 e.printStackTrace(); 16959 } finally { 16960 Binder.restoreCallingIdentity(oldId); 16961 } 16962 } else { 16963 if (app.thread != null) { 16964 try { 16965 app.thread.setSchedulingGroup(app.curSchedGroup); 16966 } catch (RemoteException e) { 16967 } 16968 } 16969 } 16970 Process.setSwappiness(app.pid, 16971 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16972 } 16973 } 16974 if (app.repForegroundActivities != app.foregroundActivities) { 16975 app.repForegroundActivities = app.foregroundActivities; 16976 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16977 } 16978 if (app.repProcState != app.curProcState) { 16979 app.repProcState = app.curProcState; 16980 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16981 if (app.thread != null) { 16982 try { 16983 if (false) { 16984 //RuntimeException h = new RuntimeException("here"); 16985 Slog.i(TAG, "Sending new process state " + app.repProcState 16986 + " to " + app /*, h*/); 16987 } 16988 app.thread.setProcessState(app.repProcState); 16989 } catch (RemoteException e) { 16990 } 16991 } 16992 } 16993 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16994 app.setProcState)) { 16995 app.lastStateTime = now; 16996 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16997 isSleeping(), now); 16998 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16999 + ProcessList.makeProcStateString(app.setProcState) + " to " 17000 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 17001 + (app.nextPssTime-now) + ": " + app); 17002 } else { 17003 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 17004 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 17005 requestPssLocked(app, app.setProcState); 17006 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 17007 isSleeping(), now); 17008 } else if (false && DEBUG_PSS) { 17009 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 17010 } 17011 } 17012 if (app.setProcState != app.curProcState) { 17013 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17014 "Proc state change of " + app.processName 17015 + " to " + app.curProcState); 17016 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 17017 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 17018 if (setImportant && !curImportant) { 17019 // This app is no longer something we consider important enough to allow to 17020 // use arbitrary amounts of battery power. Note 17021 // its current wake lock time to later know to kill it if 17022 // it is not behaving well. 17023 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 17024 synchronized (stats) { 17025 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 17026 app.pid, SystemClock.elapsedRealtime()); 17027 } 17028 app.lastCpuTime = app.curCpuTime; 17029 17030 } 17031 app.setProcState = app.curProcState; 17032 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 17033 app.notCachedSinceIdle = false; 17034 } 17035 if (!doingAll) { 17036 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 17037 } else { 17038 app.procStateChanged = true; 17039 } 17040 } 17041 17042 if (changes != 0) { 17043 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 17044 int i = mPendingProcessChanges.size()-1; 17045 ProcessChangeItem item = null; 17046 while (i >= 0) { 17047 item = mPendingProcessChanges.get(i); 17048 if (item.pid == app.pid) { 17049 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 17050 break; 17051 } 17052 i--; 17053 } 17054 if (i < 0) { 17055 // No existing item in pending changes; need a new one. 17056 final int NA = mAvailProcessChanges.size(); 17057 if (NA > 0) { 17058 item = mAvailProcessChanges.remove(NA-1); 17059 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 17060 } else { 17061 item = new ProcessChangeItem(); 17062 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 17063 } 17064 item.changes = 0; 17065 item.pid = app.pid; 17066 item.uid = app.info.uid; 17067 if (mPendingProcessChanges.size() == 0) { 17068 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 17069 "*** Enqueueing dispatch processes changed!"); 17070 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 17071 } 17072 mPendingProcessChanges.add(item); 17073 } 17074 item.changes |= changes; 17075 item.processState = app.repProcState; 17076 item.foregroundActivities = app.repForegroundActivities; 17077 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 17078 + Integer.toHexString(System.identityHashCode(item)) 17079 + " " + app.toShortString() + ": changes=" + item.changes 17080 + " procState=" + item.processState 17081 + " foreground=" + item.foregroundActivities 17082 + " type=" + app.adjType + " source=" + app.adjSource 17083 + " target=" + app.adjTarget); 17084 } 17085 17086 return success; 17087 } 17088 17089 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 17090 if (proc.thread != null) { 17091 if (proc.baseProcessTracker != null) { 17092 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 17093 } 17094 if (proc.repProcState >= 0) { 17095 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 17096 proc.repProcState); 17097 } 17098 } 17099 } 17100 17101 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 17102 ProcessRecord TOP_APP, boolean doingAll, long now) { 17103 if (app.thread == null) { 17104 return false; 17105 } 17106 17107 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 17108 17109 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 17110 } 17111 17112 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 17113 boolean oomAdj) { 17114 if (isForeground != proc.foregroundServices) { 17115 proc.foregroundServices = isForeground; 17116 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 17117 proc.info.uid); 17118 if (isForeground) { 17119 if (curProcs == null) { 17120 curProcs = new ArrayList<ProcessRecord>(); 17121 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 17122 } 17123 if (!curProcs.contains(proc)) { 17124 curProcs.add(proc); 17125 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 17126 proc.info.packageName, proc.info.uid); 17127 } 17128 } else { 17129 if (curProcs != null) { 17130 if (curProcs.remove(proc)) { 17131 mBatteryStatsService.noteEvent( 17132 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 17133 proc.info.packageName, proc.info.uid); 17134 if (curProcs.size() <= 0) { 17135 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 17136 } 17137 } 17138 } 17139 } 17140 if (oomAdj) { 17141 updateOomAdjLocked(); 17142 } 17143 } 17144 } 17145 17146 private final ActivityRecord resumedAppLocked() { 17147 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 17148 String pkg; 17149 int uid; 17150 if (act != null) { 17151 pkg = act.packageName; 17152 uid = act.info.applicationInfo.uid; 17153 } else { 17154 pkg = null; 17155 uid = -1; 17156 } 17157 // Has the UID or resumed package name changed? 17158 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 17159 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 17160 if (mCurResumedPackage != null) { 17161 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 17162 mCurResumedPackage, mCurResumedUid); 17163 } 17164 mCurResumedPackage = pkg; 17165 mCurResumedUid = uid; 17166 if (mCurResumedPackage != null) { 17167 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 17168 mCurResumedPackage, mCurResumedUid); 17169 } 17170 } 17171 return act; 17172 } 17173 17174 final boolean updateOomAdjLocked(ProcessRecord app) { 17175 final ActivityRecord TOP_ACT = resumedAppLocked(); 17176 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17177 final boolean wasCached = app.cached; 17178 17179 mAdjSeq++; 17180 17181 // This is the desired cached adjusment we want to tell it to use. 17182 // If our app is currently cached, we know it, and that is it. Otherwise, 17183 // we don't know it yet, and it needs to now be cached we will then 17184 // need to do a complete oom adj. 17185 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 17186 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 17187 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 17188 SystemClock.uptimeMillis()); 17189 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 17190 // Changed to/from cached state, so apps after it in the LRU 17191 // list may also be changed. 17192 updateOomAdjLocked(); 17193 } 17194 return success; 17195 } 17196 17197 final void updateOomAdjLocked() { 17198 final ActivityRecord TOP_ACT = resumedAppLocked(); 17199 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 17200 final long now = SystemClock.uptimeMillis(); 17201 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 17202 final int N = mLruProcesses.size(); 17203 17204 if (false) { 17205 RuntimeException e = new RuntimeException(); 17206 e.fillInStackTrace(); 17207 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 17208 } 17209 17210 mAdjSeq++; 17211 mNewNumServiceProcs = 0; 17212 mNewNumAServiceProcs = 0; 17213 17214 final int emptyProcessLimit; 17215 final int cachedProcessLimit; 17216 if (mProcessLimit <= 0) { 17217 emptyProcessLimit = cachedProcessLimit = 0; 17218 } else if (mProcessLimit == 1) { 17219 emptyProcessLimit = 1; 17220 cachedProcessLimit = 0; 17221 } else { 17222 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 17223 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 17224 } 17225 17226 // Let's determine how many processes we have running vs. 17227 // how many slots we have for background processes; we may want 17228 // to put multiple processes in a slot of there are enough of 17229 // them. 17230 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 17231 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 17232 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 17233 if (numEmptyProcs > cachedProcessLimit) { 17234 // If there are more empty processes than our limit on cached 17235 // processes, then use the cached process limit for the factor. 17236 // This ensures that the really old empty processes get pushed 17237 // down to the bottom, so if we are running low on memory we will 17238 // have a better chance at keeping around more cached processes 17239 // instead of a gazillion empty processes. 17240 numEmptyProcs = cachedProcessLimit; 17241 } 17242 int emptyFactor = numEmptyProcs/numSlots; 17243 if (emptyFactor < 1) emptyFactor = 1; 17244 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 17245 if (cachedFactor < 1) cachedFactor = 1; 17246 int stepCached = 0; 17247 int stepEmpty = 0; 17248 int numCached = 0; 17249 int numEmpty = 0; 17250 int numTrimming = 0; 17251 17252 mNumNonCachedProcs = 0; 17253 mNumCachedHiddenProcs = 0; 17254 17255 // First update the OOM adjustment for each of the 17256 // application processes based on their current state. 17257 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 17258 int nextCachedAdj = curCachedAdj+1; 17259 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 17260 int nextEmptyAdj = curEmptyAdj+2; 17261 for (int i=N-1; i>=0; i--) { 17262 ProcessRecord app = mLruProcesses.get(i); 17263 if (!app.killedByAm && app.thread != null) { 17264 app.procStateChanged = false; 17265 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 17266 17267 // If we haven't yet assigned the final cached adj 17268 // to the process, do that now. 17269 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 17270 switch (app.curProcState) { 17271 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17272 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17273 // This process is a cached process holding activities... 17274 // assign it the next cached value for that type, and then 17275 // step that cached level. 17276 app.curRawAdj = curCachedAdj; 17277 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 17278 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 17279 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 17280 + ")"); 17281 if (curCachedAdj != nextCachedAdj) { 17282 stepCached++; 17283 if (stepCached >= cachedFactor) { 17284 stepCached = 0; 17285 curCachedAdj = nextCachedAdj; 17286 nextCachedAdj += 2; 17287 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17288 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 17289 } 17290 } 17291 } 17292 break; 17293 default: 17294 // For everything else, assign next empty cached process 17295 // level and bump that up. Note that this means that 17296 // long-running services that have dropped down to the 17297 // cached level will be treated as empty (since their process 17298 // state is still as a service), which is what we want. 17299 app.curRawAdj = curEmptyAdj; 17300 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 17301 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 17302 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 17303 + ")"); 17304 if (curEmptyAdj != nextEmptyAdj) { 17305 stepEmpty++; 17306 if (stepEmpty >= emptyFactor) { 17307 stepEmpty = 0; 17308 curEmptyAdj = nextEmptyAdj; 17309 nextEmptyAdj += 2; 17310 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 17311 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 17312 } 17313 } 17314 } 17315 break; 17316 } 17317 } 17318 17319 applyOomAdjLocked(app, TOP_APP, true, now); 17320 17321 // Count the number of process types. 17322 switch (app.curProcState) { 17323 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 17324 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 17325 mNumCachedHiddenProcs++; 17326 numCached++; 17327 if (numCached > cachedProcessLimit) { 17328 app.kill("cached #" + numCached, true); 17329 } 17330 break; 17331 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 17332 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 17333 && app.lastActivityTime < oldTime) { 17334 app.kill("empty for " 17335 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 17336 / 1000) + "s", true); 17337 } else { 17338 numEmpty++; 17339 if (numEmpty > emptyProcessLimit) { 17340 app.kill("empty #" + numEmpty, true); 17341 } 17342 } 17343 break; 17344 default: 17345 mNumNonCachedProcs++; 17346 break; 17347 } 17348 17349 if (app.isolated && app.services.size() <= 0) { 17350 // If this is an isolated process, and there are no 17351 // services running in it, then the process is no longer 17352 // needed. We agressively kill these because we can by 17353 // definition not re-use the same process again, and it is 17354 // good to avoid having whatever code was running in them 17355 // left sitting around after no longer needed. 17356 app.kill("isolated not needed", true); 17357 } 17358 17359 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17360 && !app.killedByAm) { 17361 numTrimming++; 17362 } 17363 } 17364 } 17365 17366 mNumServiceProcs = mNewNumServiceProcs; 17367 17368 // Now determine the memory trimming level of background processes. 17369 // Unfortunately we need to start at the back of the list to do this 17370 // properly. We only do this if the number of background apps we 17371 // are managing to keep around is less than half the maximum we desire; 17372 // if we are keeping a good number around, we'll let them use whatever 17373 // memory they want. 17374 final int numCachedAndEmpty = numCached + numEmpty; 17375 int memFactor; 17376 if (numCached <= ProcessList.TRIM_CACHED_APPS 17377 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 17378 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 17379 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 17380 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 17381 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 17382 } else { 17383 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 17384 } 17385 } else { 17386 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 17387 } 17388 // We always allow the memory level to go up (better). We only allow it to go 17389 // down if we are in a state where that is allowed, *and* the total number of processes 17390 // has gone down since last time. 17391 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 17392 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 17393 + " last=" + mLastNumProcesses); 17394 if (memFactor > mLastMemoryLevel) { 17395 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 17396 memFactor = mLastMemoryLevel; 17397 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 17398 } 17399 } 17400 mLastMemoryLevel = memFactor; 17401 mLastNumProcesses = mLruProcesses.size(); 17402 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 17403 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 17404 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 17405 if (mLowRamStartTime == 0) { 17406 mLowRamStartTime = now; 17407 } 17408 int step = 0; 17409 int fgTrimLevel; 17410 switch (memFactor) { 17411 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 17412 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 17413 break; 17414 case ProcessStats.ADJ_MEM_FACTOR_LOW: 17415 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 17416 break; 17417 default: 17418 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 17419 break; 17420 } 17421 int factor = numTrimming/3; 17422 int minFactor = 2; 17423 if (mHomeProcess != null) minFactor++; 17424 if (mPreviousProcess != null) minFactor++; 17425 if (factor < minFactor) factor = minFactor; 17426 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 17427 for (int i=N-1; i>=0; i--) { 17428 ProcessRecord app = mLruProcesses.get(i); 17429 if (allChanged || app.procStateChanged) { 17430 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17431 app.procStateChanged = false; 17432 } 17433 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 17434 && !app.killedByAm) { 17435 if (app.trimMemoryLevel < curLevel && app.thread != null) { 17436 try { 17437 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17438 "Trimming memory of " + app.processName 17439 + " to " + curLevel); 17440 app.thread.scheduleTrimMemory(curLevel); 17441 } catch (RemoteException e) { 17442 } 17443 if (false) { 17444 // For now we won't do this; our memory trimming seems 17445 // to be good enough at this point that destroying 17446 // activities causes more harm than good. 17447 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 17448 && app != mHomeProcess && app != mPreviousProcess) { 17449 // Need to do this on its own message because the stack may not 17450 // be in a consistent state at this point. 17451 // For these apps we will also finish their activities 17452 // to help them free memory. 17453 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 17454 } 17455 } 17456 } 17457 app.trimMemoryLevel = curLevel; 17458 step++; 17459 if (step >= factor) { 17460 step = 0; 17461 switch (curLevel) { 17462 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 17463 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 17464 break; 17465 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 17466 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17467 break; 17468 } 17469 } 17470 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 17471 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 17472 && app.thread != null) { 17473 try { 17474 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17475 "Trimming memory of heavy-weight " + app.processName 17476 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17477 app.thread.scheduleTrimMemory( 17478 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 17479 } catch (RemoteException e) { 17480 } 17481 } 17482 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 17483 } else { 17484 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17485 || app.systemNoUi) && app.pendingUiClean) { 17486 // If this application is now in the background and it 17487 // had done UI, then give it the special trim level to 17488 // have it free UI resources. 17489 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 17490 if (app.trimMemoryLevel < level && app.thread != null) { 17491 try { 17492 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17493 "Trimming memory of bg-ui " + app.processName 17494 + " to " + level); 17495 app.thread.scheduleTrimMemory(level); 17496 } catch (RemoteException e) { 17497 } 17498 } 17499 app.pendingUiClean = false; 17500 } 17501 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 17502 try { 17503 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17504 "Trimming memory of fg " + app.processName 17505 + " to " + fgTrimLevel); 17506 app.thread.scheduleTrimMemory(fgTrimLevel); 17507 } catch (RemoteException e) { 17508 } 17509 } 17510 app.trimMemoryLevel = fgTrimLevel; 17511 } 17512 } 17513 } else { 17514 if (mLowRamStartTime != 0) { 17515 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 17516 mLowRamStartTime = 0; 17517 } 17518 for (int i=N-1; i>=0; i--) { 17519 ProcessRecord app = mLruProcesses.get(i); 17520 if (allChanged || app.procStateChanged) { 17521 setProcessTrackerStateLocked(app, trackerMemFactor, now); 17522 app.procStateChanged = false; 17523 } 17524 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 17525 || app.systemNoUi) && app.pendingUiClean) { 17526 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 17527 && app.thread != null) { 17528 try { 17529 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 17530 "Trimming memory of ui hidden " + app.processName 17531 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17532 app.thread.scheduleTrimMemory( 17533 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 17534 } catch (RemoteException e) { 17535 } 17536 } 17537 app.pendingUiClean = false; 17538 } 17539 app.trimMemoryLevel = 0; 17540 } 17541 } 17542 17543 if (mAlwaysFinishActivities) { 17544 // Need to do this on its own message because the stack may not 17545 // be in a consistent state at this point. 17546 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 17547 } 17548 17549 if (allChanged) { 17550 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 17551 } 17552 17553 if (mProcessStats.shouldWriteNowLocked(now)) { 17554 mHandler.post(new Runnable() { 17555 @Override public void run() { 17556 synchronized (ActivityManagerService.this) { 17557 mProcessStats.writeStateAsyncLocked(); 17558 } 17559 } 17560 }); 17561 } 17562 17563 if (DEBUG_OOM_ADJ) { 17564 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 17565 } 17566 } 17567 17568 final void trimApplications() { 17569 synchronized (this) { 17570 int i; 17571 17572 // First remove any unused application processes whose package 17573 // has been removed. 17574 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 17575 final ProcessRecord app = mRemovedProcesses.get(i); 17576 if (app.activities.size() == 0 17577 && app.curReceiver == null && app.services.size() == 0) { 17578 Slog.i( 17579 TAG, "Exiting empty application process " 17580 + app.processName + " (" 17581 + (app.thread != null ? app.thread.asBinder() : null) 17582 + ")\n"); 17583 if (app.pid > 0 && app.pid != MY_PID) { 17584 app.kill("empty", false); 17585 } else { 17586 try { 17587 app.thread.scheduleExit(); 17588 } catch (Exception e) { 17589 // Ignore exceptions. 17590 } 17591 } 17592 cleanUpApplicationRecordLocked(app, false, true, -1); 17593 mRemovedProcesses.remove(i); 17594 17595 if (app.persistent) { 17596 addAppLocked(app.info, false, null /* ABI override */); 17597 } 17598 } 17599 } 17600 17601 // Now update the oom adj for all processes. 17602 updateOomAdjLocked(); 17603 } 17604 } 17605 17606 /** This method sends the specified signal to each of the persistent apps */ 17607 public void signalPersistentProcesses(int sig) throws RemoteException { 17608 if (sig != Process.SIGNAL_USR1) { 17609 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 17610 } 17611 17612 synchronized (this) { 17613 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 17614 != PackageManager.PERMISSION_GRANTED) { 17615 throw new SecurityException("Requires permission " 17616 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 17617 } 17618 17619 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 17620 ProcessRecord r = mLruProcesses.get(i); 17621 if (r.thread != null && r.persistent) { 17622 Process.sendSignal(r.pid, sig); 17623 } 17624 } 17625 } 17626 } 17627 17628 private void stopProfilerLocked(ProcessRecord proc, int profileType) { 17629 if (proc == null || proc == mProfileProc) { 17630 proc = mProfileProc; 17631 profileType = mProfileType; 17632 clearProfilerLocked(); 17633 } 17634 if (proc == null) { 17635 return; 17636 } 17637 try { 17638 proc.thread.profilerControl(false, null, profileType); 17639 } catch (RemoteException e) { 17640 throw new IllegalStateException("Process disappeared"); 17641 } 17642 } 17643 17644 private void clearProfilerLocked() { 17645 if (mProfileFd != null) { 17646 try { 17647 mProfileFd.close(); 17648 } catch (IOException e) { 17649 } 17650 } 17651 mProfileApp = null; 17652 mProfileProc = null; 17653 mProfileFile = null; 17654 mProfileType = 0; 17655 mAutoStopProfiler = false; 17656 mSamplingInterval = 0; 17657 } 17658 17659 public boolean profileControl(String process, int userId, boolean start, 17660 ProfilerInfo profilerInfo, int profileType) throws RemoteException { 17661 17662 try { 17663 synchronized (this) { 17664 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17665 // its own permission. 17666 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17667 != PackageManager.PERMISSION_GRANTED) { 17668 throw new SecurityException("Requires permission " 17669 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17670 } 17671 17672 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { 17673 throw new IllegalArgumentException("null profile info or fd"); 17674 } 17675 17676 ProcessRecord proc = null; 17677 if (process != null) { 17678 proc = findProcessLocked(process, userId, "profileControl"); 17679 } 17680 17681 if (start && (proc == null || proc.thread == null)) { 17682 throw new IllegalArgumentException("Unknown process: " + process); 17683 } 17684 17685 if (start) { 17686 stopProfilerLocked(null, 0); 17687 setProfileApp(proc.info, proc.processName, profilerInfo); 17688 mProfileProc = proc; 17689 mProfileType = profileType; 17690 ParcelFileDescriptor fd = profilerInfo.profileFd; 17691 try { 17692 fd = fd.dup(); 17693 } catch (IOException e) { 17694 fd = null; 17695 } 17696 profilerInfo.profileFd = fd; 17697 proc.thread.profilerControl(start, profilerInfo, profileType); 17698 fd = null; 17699 mProfileFd = null; 17700 } else { 17701 stopProfilerLocked(proc, profileType); 17702 if (profilerInfo != null && profilerInfo.profileFd != null) { 17703 try { 17704 profilerInfo.profileFd.close(); 17705 } catch (IOException e) { 17706 } 17707 } 17708 } 17709 17710 return true; 17711 } 17712 } catch (RemoteException e) { 17713 throw new IllegalStateException("Process disappeared"); 17714 } finally { 17715 if (profilerInfo != null && profilerInfo.profileFd != null) { 17716 try { 17717 profilerInfo.profileFd.close(); 17718 } catch (IOException e) { 17719 } 17720 } 17721 } 17722 } 17723 17724 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 17725 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 17726 userId, true, ALLOW_FULL_ONLY, callName, null); 17727 ProcessRecord proc = null; 17728 try { 17729 int pid = Integer.parseInt(process); 17730 synchronized (mPidsSelfLocked) { 17731 proc = mPidsSelfLocked.get(pid); 17732 } 17733 } catch (NumberFormatException e) { 17734 } 17735 17736 if (proc == null) { 17737 ArrayMap<String, SparseArray<ProcessRecord>> all 17738 = mProcessNames.getMap(); 17739 SparseArray<ProcessRecord> procs = all.get(process); 17740 if (procs != null && procs.size() > 0) { 17741 proc = procs.valueAt(0); 17742 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 17743 for (int i=1; i<procs.size(); i++) { 17744 ProcessRecord thisProc = procs.valueAt(i); 17745 if (thisProc.userId == userId) { 17746 proc = thisProc; 17747 break; 17748 } 17749 } 17750 } 17751 } 17752 } 17753 17754 return proc; 17755 } 17756 17757 public boolean dumpHeap(String process, int userId, boolean managed, 17758 String path, ParcelFileDescriptor fd) throws RemoteException { 17759 17760 try { 17761 synchronized (this) { 17762 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 17763 // its own permission (same as profileControl). 17764 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 17765 != PackageManager.PERMISSION_GRANTED) { 17766 throw new SecurityException("Requires permission " 17767 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 17768 } 17769 17770 if (fd == null) { 17771 throw new IllegalArgumentException("null fd"); 17772 } 17773 17774 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 17775 if (proc == null || proc.thread == null) { 17776 throw new IllegalArgumentException("Unknown process: " + process); 17777 } 17778 17779 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 17780 if (!isDebuggable) { 17781 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 17782 throw new SecurityException("Process not debuggable: " + proc); 17783 } 17784 } 17785 17786 proc.thread.dumpHeap(managed, path, fd); 17787 fd = null; 17788 return true; 17789 } 17790 } catch (RemoteException e) { 17791 throw new IllegalStateException("Process disappeared"); 17792 } finally { 17793 if (fd != null) { 17794 try { 17795 fd.close(); 17796 } catch (IOException e) { 17797 } 17798 } 17799 } 17800 } 17801 17802 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 17803 public void monitor() { 17804 synchronized (this) { } 17805 } 17806 17807 void onCoreSettingsChange(Bundle settings) { 17808 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 17809 ProcessRecord processRecord = mLruProcesses.get(i); 17810 try { 17811 if (processRecord.thread != null) { 17812 processRecord.thread.setCoreSettings(settings); 17813 } 17814 } catch (RemoteException re) { 17815 /* ignore */ 17816 } 17817 } 17818 } 17819 17820 // Multi-user methods 17821 17822 /** 17823 * Start user, if its not already running, but don't bring it to foreground. 17824 */ 17825 @Override 17826 public boolean startUserInBackground(final int userId) { 17827 return startUser(userId, /* foreground */ false); 17828 } 17829 17830 /** 17831 * Start user, if its not already running, and bring it to foreground. 17832 */ 17833 boolean startUserInForeground(final int userId, Dialog dlg) { 17834 boolean result = startUser(userId, /* foreground */ true); 17835 dlg.dismiss(); 17836 return result; 17837 } 17838 17839 /** 17840 * Refreshes the list of users related to the current user when either a 17841 * user switch happens or when a new related user is started in the 17842 * background. 17843 */ 17844 private void updateCurrentProfileIdsLocked() { 17845 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17846 mCurrentUserId, false /* enabledOnly */); 17847 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17848 for (int i = 0; i < currentProfileIds.length; i++) { 17849 currentProfileIds[i] = profiles.get(i).id; 17850 } 17851 mCurrentProfileIds = currentProfileIds; 17852 17853 synchronized (mUserProfileGroupIdsSelfLocked) { 17854 mUserProfileGroupIdsSelfLocked.clear(); 17855 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17856 for (int i = 0; i < users.size(); i++) { 17857 UserInfo user = users.get(i); 17858 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17859 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17860 } 17861 } 17862 } 17863 } 17864 17865 private Set getProfileIdsLocked(int userId) { 17866 Set userIds = new HashSet<Integer>(); 17867 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17868 userId, false /* enabledOnly */); 17869 for (UserInfo user : profiles) { 17870 userIds.add(Integer.valueOf(user.id)); 17871 } 17872 return userIds; 17873 } 17874 17875 @Override 17876 public boolean switchUser(final int userId) { 17877 String userName; 17878 synchronized (this) { 17879 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17880 if (userInfo == null) { 17881 Slog.w(TAG, "No user info for user #" + userId); 17882 return false; 17883 } 17884 if (userInfo.isManagedProfile()) { 17885 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17886 return false; 17887 } 17888 userName = userInfo.name; 17889 } 17890 mHandler.removeMessages(START_USER_SWITCH_MSG); 17891 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName)); 17892 return true; 17893 } 17894 17895 private void showUserSwitchDialog(int userId, String userName) { 17896 // The dialog will show and then initiate the user switch by calling startUserInForeground 17897 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName, 17898 true /* above system */); 17899 d.show(); 17900 } 17901 17902 private boolean startUser(final int userId, final boolean foreground) { 17903 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17904 != PackageManager.PERMISSION_GRANTED) { 17905 String msg = "Permission Denial: switchUser() from pid=" 17906 + Binder.getCallingPid() 17907 + ", uid=" + Binder.getCallingUid() 17908 + " requires " + INTERACT_ACROSS_USERS_FULL; 17909 Slog.w(TAG, msg); 17910 throw new SecurityException(msg); 17911 } 17912 17913 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17914 17915 final long ident = Binder.clearCallingIdentity(); 17916 try { 17917 synchronized (this) { 17918 final int oldUserId = mCurrentUserId; 17919 if (oldUserId == userId) { 17920 return true; 17921 } 17922 17923 mStackSupervisor.setLockTaskModeLocked(null, false); 17924 17925 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17926 if (userInfo == null) { 17927 Slog.w(TAG, "No user info for user #" + userId); 17928 return false; 17929 } 17930 if (foreground && userInfo.isManagedProfile()) { 17931 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user"); 17932 return false; 17933 } 17934 17935 if (foreground) { 17936 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17937 R.anim.screen_user_enter); 17938 } 17939 17940 boolean needStart = false; 17941 17942 // If the user we are switching to is not currently started, then 17943 // we need to start it now. 17944 if (mStartedUsers.get(userId) == null) { 17945 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17946 updateStartedUserArrayLocked(); 17947 needStart = true; 17948 } 17949 17950 final Integer userIdInt = Integer.valueOf(userId); 17951 mUserLru.remove(userIdInt); 17952 mUserLru.add(userIdInt); 17953 17954 if (foreground) { 17955 mCurrentUserId = userId; 17956 updateCurrentProfileIdsLocked(); 17957 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17958 // Once the internal notion of the active user has switched, we lock the device 17959 // with the option to show the user switcher on the keyguard. 17960 mWindowManager.lockNow(null); 17961 } else { 17962 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17963 updateCurrentProfileIdsLocked(); 17964 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17965 mUserLru.remove(currentUserIdInt); 17966 mUserLru.add(currentUserIdInt); 17967 } 17968 17969 final UserStartedState uss = mStartedUsers.get(userId); 17970 17971 // Make sure user is in the started state. If it is currently 17972 // stopping, we need to knock that off. 17973 if (uss.mState == UserStartedState.STATE_STOPPING) { 17974 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17975 // so we can just fairly silently bring the user back from 17976 // the almost-dead. 17977 uss.mState = UserStartedState.STATE_RUNNING; 17978 updateStartedUserArrayLocked(); 17979 needStart = true; 17980 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17981 // This means ACTION_SHUTDOWN has been sent, so we will 17982 // need to treat this as a new boot of the user. 17983 uss.mState = UserStartedState.STATE_BOOTING; 17984 updateStartedUserArrayLocked(); 17985 needStart = true; 17986 } 17987 17988 if (uss.mState == UserStartedState.STATE_BOOTING) { 17989 // Booting up a new user, need to tell system services about it. 17990 // Note that this is on the same handler as scheduling of broadcasts, 17991 // which is important because it needs to go first. 17992 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0)); 17993 } 17994 17995 if (foreground) { 17996 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 17997 oldUserId)); 17998 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17999 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18000 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 18001 oldUserId, userId, uss)); 18002 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 18003 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 18004 } 18005 18006 if (needStart) { 18007 // Send USER_STARTED broadcast 18008 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 18009 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18010 | Intent.FLAG_RECEIVER_FOREGROUND); 18011 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18012 broadcastIntentLocked(null, null, intent, 18013 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18014 false, false, MY_PID, Process.SYSTEM_UID, userId); 18015 } 18016 18017 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 18018 if (userId != UserHandle.USER_OWNER) { 18019 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 18020 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 18021 broadcastIntentLocked(null, null, intent, null, 18022 new IIntentReceiver.Stub() { 18023 public void performReceive(Intent intent, int resultCode, 18024 String data, Bundle extras, boolean ordered, 18025 boolean sticky, int sendingUser) { 18026 onUserInitialized(uss, foreground, oldUserId, userId); 18027 } 18028 }, 0, null, null, null, AppOpsManager.OP_NONE, 18029 true, false, MY_PID, Process.SYSTEM_UID, 18030 userId); 18031 uss.initializing = true; 18032 } else { 18033 getUserManagerLocked().makeInitialized(userInfo.id); 18034 } 18035 } 18036 18037 if (foreground) { 18038 if (!uss.initializing) { 18039 moveUserToForeground(uss, oldUserId, userId); 18040 } 18041 } else { 18042 mStackSupervisor.startBackgroundUserLocked(userId, uss); 18043 } 18044 18045 if (needStart) { 18046 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 18047 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18048 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18049 broadcastIntentLocked(null, null, intent, 18050 null, new IIntentReceiver.Stub() { 18051 @Override 18052 public void performReceive(Intent intent, int resultCode, String data, 18053 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 18054 throws RemoteException { 18055 } 18056 }, 0, null, null, 18057 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18058 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18059 } 18060 } 18061 } finally { 18062 Binder.restoreCallingIdentity(ident); 18063 } 18064 18065 return true; 18066 } 18067 18068 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 18069 long ident = Binder.clearCallingIdentity(); 18070 try { 18071 Intent intent; 18072 if (oldUserId >= 0) { 18073 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 18074 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 18075 int count = profiles.size(); 18076 for (int i = 0; i < count; i++) { 18077 int profileUserId = profiles.get(i).id; 18078 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 18079 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18080 | Intent.FLAG_RECEIVER_FOREGROUND); 18081 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18082 broadcastIntentLocked(null, null, intent, 18083 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18084 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18085 } 18086 } 18087 if (newUserId >= 0) { 18088 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 18089 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 18090 int count = profiles.size(); 18091 for (int i = 0; i < count; i++) { 18092 int profileUserId = profiles.get(i).id; 18093 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 18094 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18095 | Intent.FLAG_RECEIVER_FOREGROUND); 18096 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 18097 broadcastIntentLocked(null, null, intent, 18098 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 18099 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 18100 } 18101 intent = new Intent(Intent.ACTION_USER_SWITCHED); 18102 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 18103 | Intent.FLAG_RECEIVER_FOREGROUND); 18104 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 18105 broadcastIntentLocked(null, null, intent, 18106 null, null, 0, null, null, 18107 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 18108 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18109 } 18110 } finally { 18111 Binder.restoreCallingIdentity(ident); 18112 } 18113 } 18114 18115 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 18116 final int newUserId) { 18117 final int N = mUserSwitchObservers.beginBroadcast(); 18118 if (N > 0) { 18119 final IRemoteCallback callback = new IRemoteCallback.Stub() { 18120 int mCount = 0; 18121 @Override 18122 public void sendResult(Bundle data) throws RemoteException { 18123 synchronized (ActivityManagerService.this) { 18124 if (mCurUserSwitchCallback == this) { 18125 mCount++; 18126 if (mCount == N) { 18127 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18128 } 18129 } 18130 } 18131 } 18132 }; 18133 synchronized (this) { 18134 uss.switching = true; 18135 mCurUserSwitchCallback = callback; 18136 } 18137 for (int i=0; i<N; i++) { 18138 try { 18139 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 18140 newUserId, callback); 18141 } catch (RemoteException e) { 18142 } 18143 } 18144 } else { 18145 synchronized (this) { 18146 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18147 } 18148 } 18149 mUserSwitchObservers.finishBroadcast(); 18150 } 18151 18152 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18153 synchronized (this) { 18154 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 18155 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 18156 } 18157 } 18158 18159 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 18160 mCurUserSwitchCallback = null; 18161 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 18162 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 18163 oldUserId, newUserId, uss)); 18164 } 18165 18166 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) { 18167 synchronized (this) { 18168 if (foreground) { 18169 moveUserToForeground(uss, oldUserId, newUserId); 18170 } 18171 } 18172 18173 completeSwitchAndInitalize(uss, newUserId, true, false); 18174 } 18175 18176 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) { 18177 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss); 18178 if (homeInFront) { 18179 startHomeActivityLocked(newUserId); 18180 } else { 18181 mStackSupervisor.resumeTopActivitiesLocked(); 18182 } 18183 EventLogTags.writeAmSwitchUser(newUserId); 18184 getUserManagerLocked().userForeground(newUserId); 18185 sendUserSwitchBroadcastsLocked(oldUserId, newUserId); 18186 } 18187 18188 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 18189 completeSwitchAndInitalize(uss, newUserId, false, true); 18190 } 18191 18192 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 18193 boolean clearInitializing, boolean clearSwitching) { 18194 boolean unfrozen = false; 18195 synchronized (this) { 18196 if (clearInitializing) { 18197 uss.initializing = false; 18198 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 18199 } 18200 if (clearSwitching) { 18201 uss.switching = false; 18202 } 18203 if (!uss.switching && !uss.initializing) { 18204 mWindowManager.stopFreezingScreen(); 18205 unfrozen = true; 18206 } 18207 } 18208 if (unfrozen) { 18209 final int N = mUserSwitchObservers.beginBroadcast(); 18210 for (int i=0; i<N; i++) { 18211 try { 18212 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 18213 } catch (RemoteException e) { 18214 } 18215 } 18216 mUserSwitchObservers.finishBroadcast(); 18217 } 18218 } 18219 18220 void scheduleStartProfilesLocked() { 18221 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 18222 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 18223 DateUtils.SECOND_IN_MILLIS); 18224 } 18225 } 18226 18227 void startProfilesLocked() { 18228 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 18229 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 18230 mCurrentUserId, false /* enabledOnly */); 18231 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 18232 for (UserInfo user : profiles) { 18233 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 18234 && user.id != mCurrentUserId) { 18235 toStart.add(user); 18236 } 18237 } 18238 final int n = toStart.size(); 18239 int i = 0; 18240 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 18241 startUserInBackground(toStart.get(i).id); 18242 } 18243 if (i < n) { 18244 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 18245 } 18246 } 18247 18248 void finishUserBoot(UserStartedState uss) { 18249 synchronized (this) { 18250 if (uss.mState == UserStartedState.STATE_BOOTING 18251 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 18252 uss.mState = UserStartedState.STATE_RUNNING; 18253 final int userId = uss.mHandle.getIdentifier(); 18254 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 18255 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18256 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 18257 broadcastIntentLocked(null, null, intent, 18258 null, null, 0, null, null, 18259 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 18260 true, false, MY_PID, Process.SYSTEM_UID, userId); 18261 } 18262 } 18263 } 18264 18265 void finishUserSwitch(UserStartedState uss) { 18266 synchronized (this) { 18267 finishUserBoot(uss); 18268 18269 startProfilesLocked(); 18270 18271 int num = mUserLru.size(); 18272 int i = 0; 18273 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 18274 Integer oldUserId = mUserLru.get(i); 18275 UserStartedState oldUss = mStartedUsers.get(oldUserId); 18276 if (oldUss == null) { 18277 // Shouldn't happen, but be sane if it does. 18278 mUserLru.remove(i); 18279 num--; 18280 continue; 18281 } 18282 if (oldUss.mState == UserStartedState.STATE_STOPPING 18283 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 18284 // This user is already stopping, doesn't count. 18285 num--; 18286 i++; 18287 continue; 18288 } 18289 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 18290 // Owner and current can't be stopped, but count as running. 18291 i++; 18292 continue; 18293 } 18294 // This is a user to be stopped. 18295 stopUserLocked(oldUserId, null); 18296 num--; 18297 i++; 18298 } 18299 } 18300 } 18301 18302 @Override 18303 public int stopUser(final int userId, final IStopUserCallback callback) { 18304 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18305 != PackageManager.PERMISSION_GRANTED) { 18306 String msg = "Permission Denial: switchUser() from pid=" 18307 + Binder.getCallingPid() 18308 + ", uid=" + Binder.getCallingUid() 18309 + " requires " + INTERACT_ACROSS_USERS_FULL; 18310 Slog.w(TAG, msg); 18311 throw new SecurityException(msg); 18312 } 18313 if (userId <= 0) { 18314 throw new IllegalArgumentException("Can't stop primary user " + userId); 18315 } 18316 synchronized (this) { 18317 return stopUserLocked(userId, callback); 18318 } 18319 } 18320 18321 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 18322 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 18323 if (mCurrentUserId == userId) { 18324 return ActivityManager.USER_OP_IS_CURRENT; 18325 } 18326 18327 final UserStartedState uss = mStartedUsers.get(userId); 18328 if (uss == null) { 18329 // User is not started, nothing to do... but we do need to 18330 // callback if requested. 18331 if (callback != null) { 18332 mHandler.post(new Runnable() { 18333 @Override 18334 public void run() { 18335 try { 18336 callback.userStopped(userId); 18337 } catch (RemoteException e) { 18338 } 18339 } 18340 }); 18341 } 18342 return ActivityManager.USER_OP_SUCCESS; 18343 } 18344 18345 if (callback != null) { 18346 uss.mStopCallbacks.add(callback); 18347 } 18348 18349 if (uss.mState != UserStartedState.STATE_STOPPING 18350 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18351 uss.mState = UserStartedState.STATE_STOPPING; 18352 updateStartedUserArrayLocked(); 18353 18354 long ident = Binder.clearCallingIdentity(); 18355 try { 18356 // We are going to broadcast ACTION_USER_STOPPING and then 18357 // once that is done send a final ACTION_SHUTDOWN and then 18358 // stop the user. 18359 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 18360 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 18361 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 18362 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 18363 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 18364 // This is the result receiver for the final shutdown broadcast. 18365 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 18366 @Override 18367 public void performReceive(Intent intent, int resultCode, String data, 18368 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18369 finishUserStop(uss); 18370 } 18371 }; 18372 // This is the result receiver for the initial stopping broadcast. 18373 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 18374 @Override 18375 public void performReceive(Intent intent, int resultCode, String data, 18376 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 18377 // On to the next. 18378 synchronized (ActivityManagerService.this) { 18379 if (uss.mState != UserStartedState.STATE_STOPPING) { 18380 // Whoops, we are being started back up. Abort, abort! 18381 return; 18382 } 18383 uss.mState = UserStartedState.STATE_SHUTDOWN; 18384 } 18385 mBatteryStatsService.noteEvent( 18386 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 18387 Integer.toString(userId), userId); 18388 mSystemServiceManager.stopUser(userId); 18389 broadcastIntentLocked(null, null, shutdownIntent, 18390 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 18391 true, false, MY_PID, Process.SYSTEM_UID, userId); 18392 } 18393 }; 18394 // Kick things off. 18395 broadcastIntentLocked(null, null, stoppingIntent, 18396 null, stoppingReceiver, 0, null, null, 18397 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 18398 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 18399 } finally { 18400 Binder.restoreCallingIdentity(ident); 18401 } 18402 } 18403 18404 return ActivityManager.USER_OP_SUCCESS; 18405 } 18406 18407 void finishUserStop(UserStartedState uss) { 18408 final int userId = uss.mHandle.getIdentifier(); 18409 boolean stopped; 18410 ArrayList<IStopUserCallback> callbacks; 18411 synchronized (this) { 18412 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 18413 if (mStartedUsers.get(userId) != uss) { 18414 stopped = false; 18415 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 18416 stopped = false; 18417 } else { 18418 stopped = true; 18419 // User can no longer run. 18420 mStartedUsers.remove(userId); 18421 mUserLru.remove(Integer.valueOf(userId)); 18422 updateStartedUserArrayLocked(); 18423 18424 // Clean up all state and processes associated with the user. 18425 // Kill all the processes for the user. 18426 forceStopUserLocked(userId, "finish user"); 18427 } 18428 18429 // Explicitly remove the old information in mRecentTasks. 18430 removeRecentTasksForUserLocked(userId); 18431 } 18432 18433 for (int i=0; i<callbacks.size(); i++) { 18434 try { 18435 if (stopped) callbacks.get(i).userStopped(userId); 18436 else callbacks.get(i).userStopAborted(userId); 18437 } catch (RemoteException e) { 18438 } 18439 } 18440 18441 if (stopped) { 18442 mSystemServiceManager.cleanupUser(userId); 18443 synchronized (this) { 18444 mStackSupervisor.removeUserLocked(userId); 18445 } 18446 } 18447 } 18448 18449 @Override 18450 public UserInfo getCurrentUser() { 18451 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 18452 != PackageManager.PERMISSION_GRANTED) && ( 18453 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18454 != PackageManager.PERMISSION_GRANTED)) { 18455 String msg = "Permission Denial: getCurrentUser() from pid=" 18456 + Binder.getCallingPid() 18457 + ", uid=" + Binder.getCallingUid() 18458 + " requires " + INTERACT_ACROSS_USERS; 18459 Slog.w(TAG, msg); 18460 throw new SecurityException(msg); 18461 } 18462 synchronized (this) { 18463 return getUserManagerLocked().getUserInfo(mCurrentUserId); 18464 } 18465 } 18466 18467 int getCurrentUserIdLocked() { 18468 return mCurrentUserId; 18469 } 18470 18471 @Override 18472 public boolean isUserRunning(int userId, boolean orStopped) { 18473 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18474 != PackageManager.PERMISSION_GRANTED) { 18475 String msg = "Permission Denial: isUserRunning() from pid=" 18476 + Binder.getCallingPid() 18477 + ", uid=" + Binder.getCallingUid() 18478 + " requires " + INTERACT_ACROSS_USERS; 18479 Slog.w(TAG, msg); 18480 throw new SecurityException(msg); 18481 } 18482 synchronized (this) { 18483 return isUserRunningLocked(userId, orStopped); 18484 } 18485 } 18486 18487 boolean isUserRunningLocked(int userId, boolean orStopped) { 18488 UserStartedState state = mStartedUsers.get(userId); 18489 if (state == null) { 18490 return false; 18491 } 18492 if (orStopped) { 18493 return true; 18494 } 18495 return state.mState != UserStartedState.STATE_STOPPING 18496 && state.mState != UserStartedState.STATE_SHUTDOWN; 18497 } 18498 18499 @Override 18500 public int[] getRunningUserIds() { 18501 if (checkCallingPermission(INTERACT_ACROSS_USERS) 18502 != PackageManager.PERMISSION_GRANTED) { 18503 String msg = "Permission Denial: isUserRunning() from pid=" 18504 + Binder.getCallingPid() 18505 + ", uid=" + Binder.getCallingUid() 18506 + " requires " + INTERACT_ACROSS_USERS; 18507 Slog.w(TAG, msg); 18508 throw new SecurityException(msg); 18509 } 18510 synchronized (this) { 18511 return mStartedUserArray; 18512 } 18513 } 18514 18515 private void updateStartedUserArrayLocked() { 18516 int num = 0; 18517 for (int i=0; i<mStartedUsers.size(); i++) { 18518 UserStartedState uss = mStartedUsers.valueAt(i); 18519 // This list does not include stopping users. 18520 if (uss.mState != UserStartedState.STATE_STOPPING 18521 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18522 num++; 18523 } 18524 } 18525 mStartedUserArray = new int[num]; 18526 num = 0; 18527 for (int i=0; i<mStartedUsers.size(); i++) { 18528 UserStartedState uss = mStartedUsers.valueAt(i); 18529 if (uss.mState != UserStartedState.STATE_STOPPING 18530 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 18531 mStartedUserArray[num] = mStartedUsers.keyAt(i); 18532 num++; 18533 } 18534 } 18535 } 18536 18537 @Override 18538 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 18539 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 18540 != PackageManager.PERMISSION_GRANTED) { 18541 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 18542 + Binder.getCallingPid() 18543 + ", uid=" + Binder.getCallingUid() 18544 + " requires " + INTERACT_ACROSS_USERS_FULL; 18545 Slog.w(TAG, msg); 18546 throw new SecurityException(msg); 18547 } 18548 18549 mUserSwitchObservers.register(observer); 18550 } 18551 18552 @Override 18553 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 18554 mUserSwitchObservers.unregister(observer); 18555 } 18556 18557 private boolean userExists(int userId) { 18558 if (userId == 0) { 18559 return true; 18560 } 18561 UserManagerService ums = getUserManagerLocked(); 18562 return ums != null ? (ums.getUserInfo(userId) != null) : false; 18563 } 18564 18565 int[] getUsersLocked() { 18566 UserManagerService ums = getUserManagerLocked(); 18567 return ums != null ? ums.getUserIds() : new int[] { 0 }; 18568 } 18569 18570 UserManagerService getUserManagerLocked() { 18571 if (mUserManager == null) { 18572 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 18573 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 18574 } 18575 return mUserManager; 18576 } 18577 18578 private int applyUserId(int uid, int userId) { 18579 return UserHandle.getUid(userId, uid); 18580 } 18581 18582 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 18583 if (info == null) return null; 18584 ApplicationInfo newInfo = new ApplicationInfo(info); 18585 newInfo.uid = applyUserId(info.uid, userId); 18586 newInfo.dataDir = USER_DATA_DIR + userId + "/" 18587 + info.packageName; 18588 return newInfo; 18589 } 18590 18591 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 18592 if (aInfo == null 18593 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 18594 return aInfo; 18595 } 18596 18597 ActivityInfo info = new ActivityInfo(aInfo); 18598 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 18599 return info; 18600 } 18601 18602 private final class LocalService extends ActivityManagerInternal { 18603 @Override 18604 public void goingToSleep() { 18605 ActivityManagerService.this.goingToSleep(); 18606 } 18607 18608 @Override 18609 public void wakingUp() { 18610 ActivityManagerService.this.wakingUp(); 18611 } 18612 18613 @Override 18614 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs, 18615 String processName, String abiOverride, int uid, Runnable crashHandler) { 18616 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs, 18617 processName, abiOverride, uid, crashHandler); 18618 } 18619 } 18620 18621 /** 18622 * An implementation of IAppTask, that allows an app to manage its own tasks via 18623 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 18624 * only the process that calls getAppTasks() can call the AppTask methods. 18625 */ 18626 class AppTaskImpl extends IAppTask.Stub { 18627 private int mTaskId; 18628 private int mCallingUid; 18629 18630 public AppTaskImpl(int taskId, int callingUid) { 18631 mTaskId = taskId; 18632 mCallingUid = callingUid; 18633 } 18634 18635 private void checkCaller() { 18636 if (mCallingUid != Binder.getCallingUid()) { 18637 throw new SecurityException("Caller " + mCallingUid 18638 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 18639 } 18640 } 18641 18642 @Override 18643 public void finishAndRemoveTask() { 18644 checkCaller(); 18645 18646 synchronized (ActivityManagerService.this) { 18647 long origId = Binder.clearCallingIdentity(); 18648 try { 18649 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18650 if (tr == null) { 18651 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18652 } 18653 // Only kill the process if we are not a new document 18654 int flags = tr.getBaseIntent().getFlags(); 18655 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 18656 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 18657 removeTaskByIdLocked(mTaskId, 18658 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 18659 } finally { 18660 Binder.restoreCallingIdentity(origId); 18661 } 18662 } 18663 } 18664 18665 @Override 18666 public ActivityManager.RecentTaskInfo getTaskInfo() { 18667 checkCaller(); 18668 18669 synchronized (ActivityManagerService.this) { 18670 long origId = Binder.clearCallingIdentity(); 18671 try { 18672 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18673 if (tr == null) { 18674 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18675 } 18676 return createRecentTaskInfoFromTaskRecord(tr); 18677 } finally { 18678 Binder.restoreCallingIdentity(origId); 18679 } 18680 } 18681 } 18682 18683 @Override 18684 public void moveToFront() { 18685 checkCaller(); 18686 18687 final TaskRecord tr; 18688 synchronized (ActivityManagerService.this) { 18689 tr = recentTaskForIdLocked(mTaskId); 18690 if (tr == null) { 18691 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18692 } 18693 if (tr.getRootActivity() != null) { 18694 long origId = Binder.clearCallingIdentity(); 18695 try { 18696 moveTaskToFrontLocked(tr.taskId, 0, null); 18697 return; 18698 } finally { 18699 Binder.restoreCallingIdentity(origId); 18700 } 18701 } 18702 } 18703 18704 startActivityFromRecentsInner(tr.taskId, null); 18705 } 18706 18707 @Override 18708 public int startActivity(IBinder whoThread, String callingPackage, 18709 Intent intent, String resolvedType, Bundle options) { 18710 checkCaller(); 18711 18712 int callingUser = UserHandle.getCallingUserId(); 18713 TaskRecord tr; 18714 IApplicationThread appThread; 18715 synchronized (ActivityManagerService.this) { 18716 tr = recentTaskForIdLocked(mTaskId); 18717 if (tr == null) { 18718 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18719 } 18720 appThread = ApplicationThreadNative.asInterface(whoThread); 18721 if (appThread == null) { 18722 throw new IllegalArgumentException("Bad app thread " + appThread); 18723 } 18724 } 18725 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent, 18726 resolvedType, null, null, null, null, 0, 0, null, null, 18727 null, options, callingUser, null, tr); 18728 } 18729 18730 @Override 18731 public void setExcludeFromRecents(boolean exclude) { 18732 checkCaller(); 18733 18734 synchronized (ActivityManagerService.this) { 18735 long origId = Binder.clearCallingIdentity(); 18736 try { 18737 TaskRecord tr = recentTaskForIdLocked(mTaskId); 18738 if (tr == null) { 18739 throw new IllegalArgumentException("Unable to find task ID " + mTaskId); 18740 } 18741 Intent intent = tr.getBaseIntent(); 18742 if (exclude) { 18743 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18744 } else { 18745 intent.setFlags(intent.getFlags() 18746 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); 18747 } 18748 } finally { 18749 Binder.restoreCallingIdentity(origId); 18750 } 18751 } 18752 } 18753 } 18754} 18755