ActivityManagerService.java revision f1939901d2ed0480069f0b23be64f122fce93995
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.IActivityContainer; 37import android.app.IActivityContainerCallback; 38import android.app.IAppTask; 39import android.app.admin.DevicePolicyManager; 40import android.app.usage.UsageStats; 41import android.app.usage.UsageStatsManagerInternal; 42import android.appwidget.AppWidgetManager; 43import android.graphics.Rect; 44import android.os.BatteryStats; 45import android.os.PersistableBundle; 46import android.service.voice.IVoiceInteractionSession; 47import android.util.ArrayMap; 48import android.util.ArraySet; 49 50import android.util.SparseIntArray; 51import com.android.internal.R; 52import com.android.internal.annotations.GuardedBy; 53import com.android.internal.app.IAppOpsService; 54import com.android.internal.app.IVoiceInteractor; 55import com.android.internal.app.ProcessMap; 56import com.android.internal.app.ProcessStats; 57import com.android.internal.content.PackageMonitor; 58import com.android.internal.os.BackgroundThread; 59import com.android.internal.os.BatteryStatsImpl; 60import com.android.internal.os.ProcessCpuTracker; 61import com.android.internal.os.TransferPipe; 62import com.android.internal.os.Zygote; 63import com.android.internal.util.FastPrintWriter; 64import com.android.internal.util.FastXmlSerializer; 65import com.android.internal.util.MemInfoReader; 66import com.android.internal.util.Preconditions; 67import com.android.server.AppOpsService; 68import com.android.server.AttributeCache; 69import com.android.server.IntentResolver; 70import com.android.server.LocalServices; 71import com.android.server.ServiceThread; 72import com.android.server.SystemService; 73import com.android.server.SystemServiceManager; 74import com.android.server.Watchdog; 75import com.android.server.am.ActivityStack.ActivityState; 76import com.android.server.firewall.IntentFirewall; 77import com.android.server.pm.UserManagerService; 78import com.android.server.wm.AppTransition; 79import com.android.server.wm.WindowManagerService; 80import com.google.android.collect.Lists; 81import com.google.android.collect.Maps; 82 83import libcore.io.IoUtils; 84 85import org.xmlpull.v1.XmlPullParser; 86import org.xmlpull.v1.XmlPullParserException; 87import org.xmlpull.v1.XmlSerializer; 88 89import android.app.Activity; 90import android.app.ActivityManager; 91import android.app.ActivityManager.RunningTaskInfo; 92import android.app.ActivityManager.StackInfo; 93import android.app.ActivityManagerInternal; 94import android.app.ActivityManagerNative; 95import android.app.ActivityOptions; 96import android.app.ActivityThread; 97import android.app.AlertDialog; 98import android.app.AppGlobals; 99import android.app.ApplicationErrorReport; 100import android.app.Dialog; 101import android.app.IActivityController; 102import android.app.IApplicationThread; 103import android.app.IInstrumentationWatcher; 104import android.app.INotificationManager; 105import android.app.IProcessObserver; 106import android.app.IServiceConnection; 107import android.app.IStopUserCallback; 108import android.app.IUiAutomationConnection; 109import android.app.IUserSwitchObserver; 110import android.app.Instrumentation; 111import android.app.Notification; 112import android.app.NotificationManager; 113import android.app.PendingIntent; 114import android.app.backup.IBackupManager; 115import android.content.ActivityNotFoundException; 116import android.content.BroadcastReceiver; 117import android.content.ClipData; 118import android.content.ComponentCallbacks2; 119import android.content.ComponentName; 120import android.content.ContentProvider; 121import android.content.ContentResolver; 122import android.content.Context; 123import android.content.DialogInterface; 124import android.content.IContentProvider; 125import android.content.IIntentReceiver; 126import android.content.IIntentSender; 127import android.content.Intent; 128import android.content.IntentFilter; 129import android.content.IntentSender; 130import android.content.pm.ActivityInfo; 131import android.content.pm.ApplicationInfo; 132import android.content.pm.ConfigurationInfo; 133import android.content.pm.IPackageDataObserver; 134import android.content.pm.IPackageManager; 135import android.content.pm.InstrumentationInfo; 136import android.content.pm.PackageInfo; 137import android.content.pm.PackageManager; 138import android.content.pm.ParceledListSlice; 139import android.content.pm.UserInfo; 140import android.content.pm.PackageManager.NameNotFoundException; 141import android.content.pm.PathPermission; 142import android.content.pm.ProviderInfo; 143import android.content.pm.ResolveInfo; 144import android.content.pm.ServiceInfo; 145import android.content.res.CompatibilityInfo; 146import android.content.res.Configuration; 147import android.net.Proxy; 148import android.net.ProxyInfo; 149import android.net.Uri; 150import android.os.Binder; 151import android.os.Build; 152import android.os.Bundle; 153import android.os.Debug; 154import android.os.DropBoxManager; 155import android.os.Environment; 156import android.os.FactoryTest; 157import android.os.FileObserver; 158import android.os.FileUtils; 159import android.os.Handler; 160import android.os.IBinder; 161import android.os.IPermissionController; 162import android.os.IRemoteCallback; 163import android.os.IUserManager; 164import android.os.Looper; 165import android.os.Message; 166import android.os.Parcel; 167import android.os.ParcelFileDescriptor; 168import android.os.Process; 169import android.os.RemoteCallbackList; 170import android.os.RemoteException; 171import android.os.SELinux; 172import android.os.ServiceManager; 173import android.os.StrictMode; 174import android.os.SystemClock; 175import android.os.SystemProperties; 176import android.os.UpdateLock; 177import android.os.UserHandle; 178import android.provider.Settings; 179import android.text.format.DateUtils; 180import android.text.format.Time; 181import android.util.AtomicFile; 182import android.util.EventLog; 183import android.util.Log; 184import android.util.Pair; 185import android.util.PrintWriterPrinter; 186import android.util.Slog; 187import android.util.SparseArray; 188import android.util.TimeUtils; 189import android.util.Xml; 190import android.view.Gravity; 191import android.view.LayoutInflater; 192import android.view.View; 193import android.view.WindowManager; 194 195import java.io.BufferedInputStream; 196import java.io.BufferedOutputStream; 197import java.io.DataInputStream; 198import java.io.DataOutputStream; 199import java.io.File; 200import java.io.FileDescriptor; 201import java.io.FileInputStream; 202import java.io.FileNotFoundException; 203import java.io.FileOutputStream; 204import java.io.IOException; 205import java.io.InputStreamReader; 206import java.io.PrintWriter; 207import java.io.StringWriter; 208import java.lang.ref.WeakReference; 209import java.util.ArrayList; 210import java.util.Arrays; 211import java.util.Collections; 212import java.util.Comparator; 213import java.util.HashMap; 214import java.util.HashSet; 215import java.util.Iterator; 216import java.util.List; 217import java.util.Locale; 218import java.util.Map; 219import java.util.Set; 220import java.util.concurrent.atomic.AtomicBoolean; 221import java.util.concurrent.atomic.AtomicLong; 222 223public final class ActivityManagerService extends ActivityManagerNative 224 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 225 private static final String USER_DATA_DIR = "/data/user/"; 226 static final String TAG = "ActivityManager"; 227 static final String TAG_MU = "ActivityManagerServiceMU"; 228 static final boolean DEBUG = false; 229 static final boolean localLOGV = DEBUG; 230 static final boolean DEBUG_BACKUP = localLOGV || false; 231 static final boolean DEBUG_BROADCAST = localLOGV || false; 232 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 233 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 234 static final boolean DEBUG_CLEANUP = localLOGV || false; 235 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 236 static final boolean DEBUG_FOCUS = false; 237 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 238 static final boolean DEBUG_MU = localLOGV || false; 239 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 240 static final boolean DEBUG_LRU = localLOGV || false; 241 static final boolean DEBUG_PAUSE = localLOGV || false; 242 static final boolean DEBUG_POWER = localLOGV || false; 243 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 244 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 245 static final boolean DEBUG_PROCESSES = localLOGV || false; 246 static final boolean DEBUG_PROVIDER = localLOGV || false; 247 static final boolean DEBUG_RESULTS = localLOGV || false; 248 static final boolean DEBUG_SERVICE = localLOGV || false; 249 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 250 static final boolean DEBUG_STACK = localLOGV || false; 251 static final boolean DEBUG_SWITCH = localLOGV || false; 252 static final boolean DEBUG_TASKS = localLOGV || false; 253 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 254 static final boolean DEBUG_TRANSITION = localLOGV || false; 255 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 256 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 257 static final boolean DEBUG_VISBILITY = localLOGV || false; 258 static final boolean DEBUG_PSS = localLOGV || false; 259 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 260 static final boolean VALIDATE_TOKENS = false; 261 static final boolean SHOW_ACTIVITY_START_TIME = true; 262 263 // Control over CPU and battery monitoring. 264 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 265 static final boolean MONITOR_CPU_USAGE = true; 266 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 267 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 268 static final boolean MONITOR_THREAD_CPU_USAGE = false; 269 270 // The flags that are set for all calls we make to the package manager. 271 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 272 273 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 274 275 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 276 277 // Maximum number of recent tasks that we can remember. 278 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200; 279 280 // Maximum number recent bitmaps to keep in memory. 281 static final int MAX_RECENT_BITMAPS = 5; 282 283 // Amount of time after a call to stopAppSwitches() during which we will 284 // prevent further untrusted switches from happening. 285 static final long APP_SWITCH_DELAY_TIME = 5*1000; 286 287 // How long we wait for a launched process to attach to the activity manager 288 // before we decide it's never going to come up for real. 289 static final int PROC_START_TIMEOUT = 10*1000; 290 291 // How long we wait for a launched process to attach to the activity manager 292 // before we decide it's never going to come up for real, when the process was 293 // started with a wrapper for instrumentation (such as Valgrind) because it 294 // could take much longer than usual. 295 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000; 296 297 // How long to wait after going idle before forcing apps to GC. 298 static final int GC_TIMEOUT = 5*1000; 299 300 // The minimum amount of time between successive GC requests for a process. 301 static final int GC_MIN_INTERVAL = 60*1000; 302 303 // The minimum amount of time between successive PSS requests for a process. 304 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 305 306 // The minimum amount of time between successive PSS requests for a process 307 // when the request is due to the memory state being lowered. 308 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 309 310 // The rate at which we check for apps using excessive power -- 15 mins. 311 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 312 313 // The minimum sample duration we will allow before deciding we have 314 // enough data on wake locks to start killing things. 315 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 316 317 // The minimum sample duration we will allow before deciding we have 318 // enough data on CPU usage to start killing things. 319 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 320 321 // How long we allow a receiver to run before giving up on it. 322 static final int BROADCAST_FG_TIMEOUT = 10*1000; 323 static final int BROADCAST_BG_TIMEOUT = 60*1000; 324 325 // How long we wait until we timeout on key dispatching. 326 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 327 328 // How long we wait until we timeout on key dispatching during instrumentation. 329 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 330 331 // Amount of time we wait for observers to handle a user switch before 332 // giving up on them and unfreezing the screen. 333 static final int USER_SWITCH_TIMEOUT = 2*1000; 334 335 // Maximum number of users we allow to be running at a time. 336 static final int MAX_RUNNING_USERS = 3; 337 338 // How long to wait in getAssistContextExtras for the activity and foreground services 339 // to respond with the result. 340 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 341 342 // Maximum number of persisted Uri grants a package is allowed 343 static final int MAX_PERSISTED_URI_GRANTS = 128; 344 345 static final int MY_PID = Process.myPid(); 346 347 static final String[] EMPTY_STRING_ARRAY = new String[0]; 348 349 // How many bytes to write into the dropbox log before truncating 350 static final int DROPBOX_MAX_SIZE = 256 * 1024; 351 352 // Access modes for handleIncomingUser. 353 static final int ALLOW_NON_FULL = 0; 354 static final int ALLOW_NON_FULL_IN_PROFILE = 1; 355 static final int ALLOW_FULL_ONLY = 2; 356 357 /** All system services */ 358 SystemServiceManager mSystemServiceManager; 359 360 /** Run all ActivityStacks through this */ 361 ActivityStackSupervisor mStackSupervisor; 362 363 public IntentFirewall mIntentFirewall; 364 365 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 366 // default actuion automatically. Important for devices without direct input 367 // devices. 368 private boolean mShowDialogs = true; 369 370 BroadcastQueue mFgBroadcastQueue; 371 BroadcastQueue mBgBroadcastQueue; 372 // Convenient for easy iteration over the queues. Foreground is first 373 // so that dispatch of foreground broadcasts gets precedence. 374 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 375 376 BroadcastQueue broadcastQueueForIntent(Intent intent) { 377 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 378 if (DEBUG_BACKGROUND_BROADCAST) { 379 Slog.i(TAG, "Broadcast intent " + intent + " on " 380 + (isFg ? "foreground" : "background") 381 + " queue"); 382 } 383 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 384 } 385 386 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 387 for (BroadcastQueue queue : mBroadcastQueues) { 388 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 389 if (r != null) { 390 return r; 391 } 392 } 393 return null; 394 } 395 396 /** 397 * Activity we have told the window manager to have key focus. 398 */ 399 ActivityRecord mFocusedActivity = null; 400 401 /** 402 * List of intents that were used to start the most recent tasks. 403 */ 404 ArrayList<TaskRecord> mRecentTasks; 405 ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>(); 406 407 public class PendingAssistExtras extends Binder implements Runnable { 408 public final ActivityRecord activity; 409 public boolean haveResult = false; 410 public Bundle result = null; 411 public PendingAssistExtras(ActivityRecord _activity) { 412 activity = _activity; 413 } 414 @Override 415 public void run() { 416 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 417 synchronized (this) { 418 haveResult = true; 419 notifyAll(); 420 } 421 } 422 } 423 424 final ArrayList<PendingAssistExtras> mPendingAssistExtras 425 = new ArrayList<PendingAssistExtras>(); 426 427 /** 428 * Process management. 429 */ 430 final ProcessList mProcessList = new ProcessList(); 431 432 /** 433 * All of the applications we currently have running organized by name. 434 * The keys are strings of the application package name (as 435 * returned by the package manager), and the keys are ApplicationRecord 436 * objects. 437 */ 438 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 439 440 /** 441 * Tracking long-term execution of processes to look for abuse and other 442 * bad app behavior. 443 */ 444 final ProcessStatsService mProcessStats; 445 446 /** 447 * The currently running isolated processes. 448 */ 449 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 450 451 /** 452 * Counter for assigning isolated process uids, to avoid frequently reusing the 453 * same ones. 454 */ 455 int mNextIsolatedProcessUid = 0; 456 457 /** 458 * The currently running heavy-weight process, if any. 459 */ 460 ProcessRecord mHeavyWeightProcess = null; 461 462 /** 463 * The last time that various processes have crashed. 464 */ 465 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 466 467 /** 468 * Information about a process that is currently marked as bad. 469 */ 470 static final class BadProcessInfo { 471 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 472 this.time = time; 473 this.shortMsg = shortMsg; 474 this.longMsg = longMsg; 475 this.stack = stack; 476 } 477 478 final long time; 479 final String shortMsg; 480 final String longMsg; 481 final String stack; 482 } 483 484 /** 485 * Set of applications that we consider to be bad, and will reject 486 * incoming broadcasts from (which the user has no control over). 487 * Processes are added to this set when they have crashed twice within 488 * a minimum amount of time; they are removed from it when they are 489 * later restarted (hopefully due to some user action). The value is the 490 * time it was added to the list. 491 */ 492 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 493 494 /** 495 * All of the processes we currently have running organized by pid. 496 * The keys are the pid running the application. 497 * 498 * <p>NOTE: This object is protected by its own lock, NOT the global 499 * activity manager lock! 500 */ 501 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 502 503 /** 504 * All of the processes that have been forced to be foreground. The key 505 * is the pid of the caller who requested it (we hold a death 506 * link on it). 507 */ 508 abstract class ForegroundToken implements IBinder.DeathRecipient { 509 int pid; 510 IBinder token; 511 } 512 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 513 514 /** 515 * List of records for processes that someone had tried to start before the 516 * system was ready. We don't start them at that point, but ensure they 517 * are started by the time booting is complete. 518 */ 519 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 520 521 /** 522 * List of persistent applications that are in the process 523 * of being started. 524 */ 525 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 526 527 /** 528 * Processes that are being forcibly torn down. 529 */ 530 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * List of running applications, sorted by recent usage. 534 * The first entry in the list is the least recently used. 535 */ 536 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 537 538 /** 539 * Where in mLruProcesses that the processes hosting activities start. 540 */ 541 int mLruProcessActivityStart = 0; 542 543 /** 544 * Where in mLruProcesses that the processes hosting services start. 545 * This is after (lower index) than mLruProcessesActivityStart. 546 */ 547 int mLruProcessServiceStart = 0; 548 549 /** 550 * List of processes that should gc as soon as things are idle. 551 */ 552 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 553 554 /** 555 * Processes we want to collect PSS data from. 556 */ 557 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 558 559 /** 560 * Last time we requested PSS data of all processes. 561 */ 562 long mLastFullPssTime = SystemClock.uptimeMillis(); 563 564 /** 565 * If set, the next time we collect PSS data we should do a full collection 566 * with data from native processes and the kernel. 567 */ 568 boolean mFullPssPending = false; 569 570 /** 571 * This is the process holding what we currently consider to be 572 * the "home" activity. 573 */ 574 ProcessRecord mHomeProcess; 575 576 /** 577 * This is the process holding the activity the user last visited that 578 * is in a different process from the one they are currently in. 579 */ 580 ProcessRecord mPreviousProcess; 581 582 /** 583 * The time at which the previous process was last visible. 584 */ 585 long mPreviousProcessVisibleTime; 586 587 /** 588 * Which uses have been started, so are allowed to run code. 589 */ 590 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 591 592 /** 593 * LRU list of history of current users. Most recently current is at the end. 594 */ 595 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 596 597 /** 598 * Constant array of the users that are currently started. 599 */ 600 int[] mStartedUserArray = new int[] { 0 }; 601 602 /** 603 * Registered observers of the user switching mechanics. 604 */ 605 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 606 = new RemoteCallbackList<IUserSwitchObserver>(); 607 608 /** 609 * Currently active user switch. 610 */ 611 Object mCurUserSwitchCallback; 612 613 /** 614 * Packages that the user has asked to have run in screen size 615 * compatibility mode instead of filling the screen. 616 */ 617 final CompatModePackages mCompatModePackages; 618 619 /** 620 * Set of IntentSenderRecord objects that are currently active. 621 */ 622 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 623 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 624 625 /** 626 * Fingerprints (hashCode()) of stack traces that we've 627 * already logged DropBox entries for. Guarded by itself. If 628 * something (rogue user app) forces this over 629 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 630 */ 631 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 632 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 633 634 /** 635 * Strict Mode background batched logging state. 636 * 637 * The string buffer is guarded by itself, and its lock is also 638 * used to determine if another batched write is already 639 * in-flight. 640 */ 641 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 642 643 /** 644 * Keeps track of all IIntentReceivers that have been registered for 645 * broadcasts. Hash keys are the receiver IBinder, hash value is 646 * a ReceiverList. 647 */ 648 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 649 new HashMap<IBinder, ReceiverList>(); 650 651 /** 652 * Resolver for broadcast intents to registered receivers. 653 * Holds BroadcastFilter (subclass of IntentFilter). 654 */ 655 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 656 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 657 @Override 658 protected boolean allowFilterResult( 659 BroadcastFilter filter, List<BroadcastFilter> dest) { 660 IBinder target = filter.receiverList.receiver.asBinder(); 661 for (int i=dest.size()-1; i>=0; i--) { 662 if (dest.get(i).receiverList.receiver.asBinder() == target) { 663 return false; 664 } 665 } 666 return true; 667 } 668 669 @Override 670 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 671 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 672 || userId == filter.owningUserId) { 673 return super.newResult(filter, match, userId); 674 } 675 return null; 676 } 677 678 @Override 679 protected BroadcastFilter[] newArray(int size) { 680 return new BroadcastFilter[size]; 681 } 682 683 @Override 684 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 685 return packageName.equals(filter.packageName); 686 } 687 }; 688 689 /** 690 * State of all active sticky broadcasts per user. Keys are the action of the 691 * sticky Intent, values are an ArrayList of all broadcasted intents with 692 * that action (which should usually be one). The SparseArray is keyed 693 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 694 * for stickies that are sent to all users. 695 */ 696 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 697 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 698 699 final ActiveServices mServices; 700 701 /** 702 * Backup/restore process management 703 */ 704 String mBackupAppName = null; 705 BackupRecord mBackupTarget = null; 706 707 final ProviderMap mProviderMap; 708 709 /** 710 * List of content providers who have clients waiting for them. The 711 * application is currently being launched and the provider will be 712 * removed from this list once it is published. 713 */ 714 final ArrayList<ContentProviderRecord> mLaunchingProviders 715 = new ArrayList<ContentProviderRecord>(); 716 717 /** 718 * File storing persisted {@link #mGrantedUriPermissions}. 719 */ 720 private final AtomicFile mGrantFile; 721 722 /** XML constants used in {@link #mGrantFile} */ 723 private static final String TAG_URI_GRANTS = "uri-grants"; 724 private static final String TAG_URI_GRANT = "uri-grant"; 725 private static final String ATTR_USER_HANDLE = "userHandle"; 726 private static final String ATTR_SOURCE_USER_ID = "sourceUserId"; 727 private static final String ATTR_TARGET_USER_ID = "targetUserId"; 728 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 729 private static final String ATTR_TARGET_PKG = "targetPkg"; 730 private static final String ATTR_URI = "uri"; 731 private static final String ATTR_MODE_FLAGS = "modeFlags"; 732 private static final String ATTR_CREATED_TIME = "createdTime"; 733 private static final String ATTR_PREFIX = "prefix"; 734 735 /** 736 * Global set of specific {@link Uri} permissions that have been granted. 737 * This optimized lookup structure maps from {@link UriPermission#targetUid} 738 * to {@link UriPermission#uri} to {@link UriPermission}. 739 */ 740 @GuardedBy("this") 741 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 742 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 743 744 public static class GrantUri { 745 public final int sourceUserId; 746 public final Uri uri; 747 public boolean prefix; 748 749 public GrantUri(int sourceUserId, Uri uri, boolean prefix) { 750 this.sourceUserId = sourceUserId; 751 this.uri = uri; 752 this.prefix = prefix; 753 } 754 755 @Override 756 public int hashCode() { 757 return toString().hashCode(); 758 } 759 760 @Override 761 public boolean equals(Object o) { 762 if (o instanceof GrantUri) { 763 GrantUri other = (GrantUri) o; 764 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId) 765 && prefix == other.prefix; 766 } 767 return false; 768 } 769 770 @Override 771 public String toString() { 772 String result = Integer.toString(sourceUserId) + " @ " + uri.toString(); 773 if (prefix) result += " [prefix]"; 774 return result; 775 } 776 777 public String toSafeString() { 778 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString(); 779 if (prefix) result += " [prefix]"; 780 return result; 781 } 782 783 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) { 784 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle), 785 ContentProvider.getUriWithoutUserId(uri), false); 786 } 787 } 788 789 CoreSettingsObserver mCoreSettingsObserver; 790 791 /** 792 * Thread-local storage used to carry caller permissions over through 793 * indirect content-provider access. 794 */ 795 private class Identity { 796 public int pid; 797 public int uid; 798 799 Identity(int _pid, int _uid) { 800 pid = _pid; 801 uid = _uid; 802 } 803 } 804 805 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 806 807 /** 808 * All information we have collected about the runtime performance of 809 * any user id that can impact battery performance. 810 */ 811 final BatteryStatsService mBatteryStatsService; 812 813 /** 814 * Information about component usage 815 */ 816 UsageStatsManagerInternal mUsageStatsService; 817 818 /** 819 * Information about and control over application operations 820 */ 821 final AppOpsService mAppOpsService; 822 823 /** 824 * Save recent tasks information across reboots. 825 */ 826 final TaskPersister mTaskPersister; 827 828 /** 829 * Current configuration information. HistoryRecord objects are given 830 * a reference to this object to indicate which configuration they are 831 * currently running in, so this object must be kept immutable. 832 */ 833 Configuration mConfiguration = new Configuration(); 834 835 /** 836 * Current sequencing integer of the configuration, for skipping old 837 * configurations. 838 */ 839 int mConfigurationSeq = 0; 840 841 /** 842 * Hardware-reported OpenGLES version. 843 */ 844 final int GL_ES_VERSION; 845 846 /** 847 * List of initialization arguments to pass to all processes when binding applications to them. 848 * For example, references to the commonly used services. 849 */ 850 HashMap<String, IBinder> mAppBindArgs; 851 852 /** 853 * Temporary to avoid allocations. Protected by main lock. 854 */ 855 final StringBuilder mStringBuilder = new StringBuilder(256); 856 857 /** 858 * Used to control how we initialize the service. 859 */ 860 ComponentName mTopComponent; 861 String mTopAction = Intent.ACTION_MAIN; 862 String mTopData; 863 boolean mProcessesReady = false; 864 boolean mSystemReady = false; 865 boolean mBooting = false; 866 boolean mWaitingUpdate = false; 867 boolean mDidUpdate = false; 868 boolean mOnBattery = false; 869 boolean mLaunchWarningShown = false; 870 871 Context mContext; 872 873 int mFactoryTest; 874 875 boolean mCheckedForSetup; 876 877 /** 878 * The time at which we will allow normal application switches again, 879 * after a call to {@link #stopAppSwitches()}. 880 */ 881 long mAppSwitchesAllowedTime; 882 883 /** 884 * This is set to true after the first switch after mAppSwitchesAllowedTime 885 * is set; any switches after that will clear the time. 886 */ 887 boolean mDidAppSwitch; 888 889 /** 890 * Last time (in realtime) at which we checked for power usage. 891 */ 892 long mLastPowerCheckRealtime; 893 894 /** 895 * Last time (in uptime) at which we checked for power usage. 896 */ 897 long mLastPowerCheckUptime; 898 899 /** 900 * Set while we are wanting to sleep, to prevent any 901 * activities from being started/resumed. 902 */ 903 private boolean mSleeping = false; 904 905 /** 906 * Set while we are running a voice interaction. This overrides 907 * sleeping while it is active. 908 */ 909 private boolean mRunningVoice = false; 910 911 /** 912 * State of external calls telling us if the device is asleep. 913 */ 914 private boolean mWentToSleep = false; 915 916 /** 917 * State of external call telling us if the lock screen is shown. 918 */ 919 private boolean mLockScreenShown = false; 920 921 /** 922 * Set if we are shutting down the system, similar to sleeping. 923 */ 924 boolean mShuttingDown = false; 925 926 /** 927 * Current sequence id for oom_adj computation traversal. 928 */ 929 int mAdjSeq = 0; 930 931 /** 932 * Current sequence id for process LRU updating. 933 */ 934 int mLruSeq = 0; 935 936 /** 937 * Keep track of the non-cached/empty process we last found, to help 938 * determine how to distribute cached/empty processes next time. 939 */ 940 int mNumNonCachedProcs = 0; 941 942 /** 943 * Keep track of the number of cached hidden procs, to balance oom adj 944 * distribution between those and empty procs. 945 */ 946 int mNumCachedHiddenProcs = 0; 947 948 /** 949 * Keep track of the number of service processes we last found, to 950 * determine on the next iteration which should be B services. 951 */ 952 int mNumServiceProcs = 0; 953 int mNewNumAServiceProcs = 0; 954 int mNewNumServiceProcs = 0; 955 956 /** 957 * Allow the current computed overall memory level of the system to go down? 958 * This is set to false when we are killing processes for reasons other than 959 * memory management, so that the now smaller process list will not be taken as 960 * an indication that memory is tighter. 961 */ 962 boolean mAllowLowerMemLevel = false; 963 964 /** 965 * The last computed memory level, for holding when we are in a state that 966 * processes are going away for other reasons. 967 */ 968 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 969 970 /** 971 * The last total number of process we have, to determine if changes actually look 972 * like a shrinking number of process due to lower RAM. 973 */ 974 int mLastNumProcesses; 975 976 /** 977 * The uptime of the last time we performed idle maintenance. 978 */ 979 long mLastIdleTime = SystemClock.uptimeMillis(); 980 981 /** 982 * Total time spent with RAM that has been added in the past since the last idle time. 983 */ 984 long mLowRamTimeSinceLastIdle = 0; 985 986 /** 987 * If RAM is currently low, when that horrible situation started. 988 */ 989 long mLowRamStartTime = 0; 990 991 /** 992 * For reporting to battery stats the current top application. 993 */ 994 private String mCurResumedPackage = null; 995 private int mCurResumedUid = -1; 996 997 /** 998 * For reporting to battery stats the apps currently running foreground 999 * service. The ProcessMap is package/uid tuples; each of these contain 1000 * an array of the currently foreground processes. 1001 */ 1002 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 1003 = new ProcessMap<ArrayList<ProcessRecord>>(); 1004 1005 /** 1006 * This is set if we had to do a delayed dexopt of an app before launching 1007 * it, to increase the ANR timeouts in that case. 1008 */ 1009 boolean mDidDexOpt; 1010 1011 /** 1012 * Set if the systemServer made a call to enterSafeMode. 1013 */ 1014 boolean mSafeMode; 1015 1016 String mDebugApp = null; 1017 boolean mWaitForDebugger = false; 1018 boolean mDebugTransient = false; 1019 String mOrigDebugApp = null; 1020 boolean mOrigWaitForDebugger = false; 1021 boolean mAlwaysFinishActivities = false; 1022 IActivityController mController = null; 1023 String mProfileApp = null; 1024 ProcessRecord mProfileProc = null; 1025 String mProfileFile; 1026 ParcelFileDescriptor mProfileFd; 1027 int mProfileType = 0; 1028 boolean mAutoStopProfiler = false; 1029 String mOpenGlTraceApp = null; 1030 1031 static class ProcessChangeItem { 1032 static final int CHANGE_ACTIVITIES = 1<<0; 1033 static final int CHANGE_PROCESS_STATE = 1<<1; 1034 int changes; 1035 int uid; 1036 int pid; 1037 int processState; 1038 boolean foregroundActivities; 1039 } 1040 1041 final RemoteCallbackList<IProcessObserver> mProcessObservers 1042 = new RemoteCallbackList<IProcessObserver>(); 1043 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1044 1045 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1046 = new ArrayList<ProcessChangeItem>(); 1047 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1048 = new ArrayList<ProcessChangeItem>(); 1049 1050 /** 1051 * Runtime CPU use collection thread. This object's lock is used to 1052 * protect all related state. 1053 */ 1054 final Thread mProcessCpuThread; 1055 1056 /** 1057 * Used to collect process stats when showing not responding dialog. 1058 * Protected by mProcessCpuThread. 1059 */ 1060 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1061 MONITOR_THREAD_CPU_USAGE); 1062 final AtomicLong mLastCpuTime = new AtomicLong(0); 1063 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1064 1065 long mLastWriteTime = 0; 1066 1067 /** 1068 * Used to retain an update lock when the foreground activity is in 1069 * immersive mode. 1070 */ 1071 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1072 1073 /** 1074 * Set to true after the system has finished booting. 1075 */ 1076 boolean mBooted = false; 1077 1078 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1079 int mProcessLimitOverride = -1; 1080 1081 WindowManagerService mWindowManager; 1082 1083 final ActivityThread mSystemThread; 1084 1085 int mCurrentUserId = 0; 1086 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1087 1088 /** 1089 * Mapping from each known user ID to the profile group ID it is associated with. 1090 */ 1091 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray(); 1092 1093 private UserManagerService mUserManager; 1094 1095 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1096 final ProcessRecord mApp; 1097 final int mPid; 1098 final IApplicationThread mAppThread; 1099 1100 AppDeathRecipient(ProcessRecord app, int pid, 1101 IApplicationThread thread) { 1102 if (localLOGV) Slog.v( 1103 TAG, "New death recipient " + this 1104 + " for thread " + thread.asBinder()); 1105 mApp = app; 1106 mPid = pid; 1107 mAppThread = thread; 1108 } 1109 1110 @Override 1111 public void binderDied() { 1112 if (localLOGV) Slog.v( 1113 TAG, "Death received in " + this 1114 + " for thread " + mAppThread.asBinder()); 1115 synchronized(ActivityManagerService.this) { 1116 appDiedLocked(mApp, mPid, mAppThread); 1117 } 1118 } 1119 } 1120 1121 static final int SHOW_ERROR_MSG = 1; 1122 static final int SHOW_NOT_RESPONDING_MSG = 2; 1123 static final int SHOW_FACTORY_ERROR_MSG = 3; 1124 static final int UPDATE_CONFIGURATION_MSG = 4; 1125 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1126 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1127 static final int SERVICE_TIMEOUT_MSG = 12; 1128 static final int UPDATE_TIME_ZONE = 13; 1129 static final int SHOW_UID_ERROR_MSG = 14; 1130 static final int IM_FEELING_LUCKY_MSG = 15; 1131 static final int PROC_START_TIMEOUT_MSG = 20; 1132 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1133 static final int KILL_APPLICATION_MSG = 22; 1134 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1135 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1136 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1137 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1138 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1139 static final int CLEAR_DNS_CACHE_MSG = 28; 1140 static final int UPDATE_HTTP_PROXY_MSG = 29; 1141 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1142 static final int DISPATCH_PROCESSES_CHANGED = 31; 1143 static final int DISPATCH_PROCESS_DIED = 32; 1144 static final int REPORT_MEM_USAGE_MSG = 33; 1145 static final int REPORT_USER_SWITCH_MSG = 34; 1146 static final int CONTINUE_USER_SWITCH_MSG = 35; 1147 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1148 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1149 static final int PERSIST_URI_GRANTS_MSG = 38; 1150 static final int REQUEST_ALL_PSS_MSG = 39; 1151 static final int START_PROFILES_MSG = 40; 1152 static final int UPDATE_TIME = 41; 1153 static final int SYSTEM_USER_START_MSG = 42; 1154 static final int SYSTEM_USER_CURRENT_MSG = 43; 1155 1156 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1157 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1158 static final int FIRST_COMPAT_MODE_MSG = 300; 1159 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1160 1161 AlertDialog mUidAlert; 1162 CompatModeDialog mCompatModeDialog; 1163 long mLastMemUsageReportTime = 0; 1164 1165 private LockToAppRequestDialog mLockToAppRequest; 1166 1167 /** 1168 * Flag whether the current user is a "monkey", i.e. whether 1169 * the UI is driven by a UI automation tool. 1170 */ 1171 private boolean mUserIsMonkey; 1172 1173 /** Flag whether the device has a recents UI */ 1174 final boolean mHasRecents; 1175 1176 final ServiceThread mHandlerThread; 1177 final MainHandler mHandler; 1178 1179 final class MainHandler extends Handler { 1180 public MainHandler(Looper looper) { 1181 super(looper, null, true); 1182 } 1183 1184 @Override 1185 public void handleMessage(Message msg) { 1186 switch (msg.what) { 1187 case SHOW_ERROR_MSG: { 1188 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1189 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1190 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1191 synchronized (ActivityManagerService.this) { 1192 ProcessRecord proc = (ProcessRecord)data.get("app"); 1193 AppErrorResult res = (AppErrorResult) data.get("result"); 1194 if (proc != null && proc.crashDialog != null) { 1195 Slog.e(TAG, "App already has crash dialog: " + proc); 1196 if (res != null) { 1197 res.set(0); 1198 } 1199 return; 1200 } 1201 if (!showBackground && UserHandle.getAppId(proc.uid) 1202 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1203 && proc.pid != MY_PID) { 1204 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1205 if (res != null) { 1206 res.set(0); 1207 } 1208 return; 1209 } 1210 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1211 Dialog d = new AppErrorDialog(mContext, 1212 ActivityManagerService.this, res, proc); 1213 d.show(); 1214 proc.crashDialog = d; 1215 } else { 1216 // The device is asleep, so just pretend that the user 1217 // saw a crash dialog and hit "force quit". 1218 if (res != null) { 1219 res.set(0); 1220 } 1221 } 1222 } 1223 1224 ensureBootCompleted(); 1225 } break; 1226 case SHOW_NOT_RESPONDING_MSG: { 1227 synchronized (ActivityManagerService.this) { 1228 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1229 ProcessRecord proc = (ProcessRecord)data.get("app"); 1230 if (proc != null && proc.anrDialog != null) { 1231 Slog.e(TAG, "App already has anr dialog: " + proc); 1232 return; 1233 } 1234 1235 Intent intent = new Intent("android.intent.action.ANR"); 1236 if (!mProcessesReady) { 1237 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1238 | Intent.FLAG_RECEIVER_FOREGROUND); 1239 } 1240 broadcastIntentLocked(null, null, intent, 1241 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1242 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1243 1244 if (mShowDialogs) { 1245 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1246 mContext, proc, (ActivityRecord)data.get("activity"), 1247 msg.arg1 != 0); 1248 d.show(); 1249 proc.anrDialog = d; 1250 } else { 1251 // Just kill the app if there is no dialog to be shown. 1252 killAppAtUsersRequest(proc, null); 1253 } 1254 } 1255 1256 ensureBootCompleted(); 1257 } break; 1258 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1259 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1260 synchronized (ActivityManagerService.this) { 1261 ProcessRecord proc = (ProcessRecord) data.get("app"); 1262 if (proc == null) { 1263 Slog.e(TAG, "App not found when showing strict mode dialog."); 1264 break; 1265 } 1266 if (proc.crashDialog != null) { 1267 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1268 return; 1269 } 1270 AppErrorResult res = (AppErrorResult) data.get("result"); 1271 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1272 Dialog d = new StrictModeViolationDialog(mContext, 1273 ActivityManagerService.this, res, proc); 1274 d.show(); 1275 proc.crashDialog = d; 1276 } else { 1277 // The device is asleep, so just pretend that the user 1278 // saw a crash dialog and hit "force quit". 1279 res.set(0); 1280 } 1281 } 1282 ensureBootCompleted(); 1283 } break; 1284 case SHOW_FACTORY_ERROR_MSG: { 1285 Dialog d = new FactoryErrorDialog( 1286 mContext, msg.getData().getCharSequence("msg")); 1287 d.show(); 1288 ensureBootCompleted(); 1289 } break; 1290 case UPDATE_CONFIGURATION_MSG: { 1291 final ContentResolver resolver = mContext.getContentResolver(); 1292 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1293 } break; 1294 case GC_BACKGROUND_PROCESSES_MSG: { 1295 synchronized (ActivityManagerService.this) { 1296 performAppGcsIfAppropriateLocked(); 1297 } 1298 } break; 1299 case WAIT_FOR_DEBUGGER_MSG: { 1300 synchronized (ActivityManagerService.this) { 1301 ProcessRecord app = (ProcessRecord)msg.obj; 1302 if (msg.arg1 != 0) { 1303 if (!app.waitedForDebugger) { 1304 Dialog d = new AppWaitingForDebuggerDialog( 1305 ActivityManagerService.this, 1306 mContext, app); 1307 app.waitDialog = d; 1308 app.waitedForDebugger = true; 1309 d.show(); 1310 } 1311 } else { 1312 if (app.waitDialog != null) { 1313 app.waitDialog.dismiss(); 1314 app.waitDialog = null; 1315 } 1316 } 1317 } 1318 } break; 1319 case SERVICE_TIMEOUT_MSG: { 1320 if (mDidDexOpt) { 1321 mDidDexOpt = false; 1322 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1323 nmsg.obj = msg.obj; 1324 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1325 return; 1326 } 1327 mServices.serviceTimeout((ProcessRecord)msg.obj); 1328 } break; 1329 case UPDATE_TIME_ZONE: { 1330 synchronized (ActivityManagerService.this) { 1331 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1332 ProcessRecord r = mLruProcesses.get(i); 1333 if (r.thread != null) { 1334 try { 1335 r.thread.updateTimeZone(); 1336 } catch (RemoteException ex) { 1337 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1338 } 1339 } 1340 } 1341 } 1342 } break; 1343 case CLEAR_DNS_CACHE_MSG: { 1344 synchronized (ActivityManagerService.this) { 1345 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1346 ProcessRecord r = mLruProcesses.get(i); 1347 if (r.thread != null) { 1348 try { 1349 r.thread.clearDnsCache(); 1350 } catch (RemoteException ex) { 1351 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1352 } 1353 } 1354 } 1355 } 1356 } break; 1357 case UPDATE_HTTP_PROXY_MSG: { 1358 ProxyInfo proxy = (ProxyInfo)msg.obj; 1359 String host = ""; 1360 String port = ""; 1361 String exclList = ""; 1362 Uri pacFileUrl = Uri.EMPTY; 1363 if (proxy != null) { 1364 host = proxy.getHost(); 1365 port = Integer.toString(proxy.getPort()); 1366 exclList = proxy.getExclusionListAsString(); 1367 pacFileUrl = proxy.getPacFileUrl(); 1368 } 1369 synchronized (ActivityManagerService.this) { 1370 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1371 ProcessRecord r = mLruProcesses.get(i); 1372 if (r.thread != null) { 1373 try { 1374 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1375 } catch (RemoteException ex) { 1376 Slog.w(TAG, "Failed to update http proxy for: " + 1377 r.info.processName); 1378 } 1379 } 1380 } 1381 } 1382 } break; 1383 case SHOW_UID_ERROR_MSG: { 1384 String title = "System UIDs Inconsistent"; 1385 String text = "UIDs on the system are inconsistent, you need to wipe your" 1386 + " data partition or your device will be unstable."; 1387 Log.e(TAG, title + ": " + text); 1388 if (mShowDialogs) { 1389 // XXX This is a temporary dialog, no need to localize. 1390 AlertDialog d = new BaseErrorDialog(mContext); 1391 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1392 d.setCancelable(false); 1393 d.setTitle(title); 1394 d.setMessage(text); 1395 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1396 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1397 mUidAlert = d; 1398 d.show(); 1399 } 1400 } break; 1401 case IM_FEELING_LUCKY_MSG: { 1402 if (mUidAlert != null) { 1403 mUidAlert.dismiss(); 1404 mUidAlert = null; 1405 } 1406 } break; 1407 case PROC_START_TIMEOUT_MSG: { 1408 if (mDidDexOpt) { 1409 mDidDexOpt = false; 1410 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1411 nmsg.obj = msg.obj; 1412 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1413 return; 1414 } 1415 ProcessRecord app = (ProcessRecord)msg.obj; 1416 synchronized (ActivityManagerService.this) { 1417 processStartTimedOutLocked(app); 1418 } 1419 } break; 1420 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1421 synchronized (ActivityManagerService.this) { 1422 mStackSupervisor.doPendingActivityLaunchesLocked(true); 1423 } 1424 } break; 1425 case KILL_APPLICATION_MSG: { 1426 synchronized (ActivityManagerService.this) { 1427 int appid = msg.arg1; 1428 boolean restart = (msg.arg2 == 1); 1429 Bundle bundle = (Bundle)msg.obj; 1430 String pkg = bundle.getString("pkg"); 1431 String reason = bundle.getString("reason"); 1432 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1433 false, UserHandle.USER_ALL, reason); 1434 } 1435 } break; 1436 case FINALIZE_PENDING_INTENT_MSG: { 1437 ((PendingIntentRecord)msg.obj).completeFinalize(); 1438 } break; 1439 case POST_HEAVY_NOTIFICATION_MSG: { 1440 INotificationManager inm = NotificationManager.getService(); 1441 if (inm == null) { 1442 return; 1443 } 1444 1445 ActivityRecord root = (ActivityRecord)msg.obj; 1446 ProcessRecord process = root.app; 1447 if (process == null) { 1448 return; 1449 } 1450 1451 try { 1452 Context context = mContext.createPackageContext(process.info.packageName, 0); 1453 String text = mContext.getString(R.string.heavy_weight_notification, 1454 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1455 Notification notification = new Notification(); 1456 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1457 notification.when = 0; 1458 notification.flags = Notification.FLAG_ONGOING_EVENT; 1459 notification.tickerText = text; 1460 notification.defaults = 0; // please be quiet 1461 notification.sound = null; 1462 notification.vibrate = null; 1463 notification.setLatestEventInfo(context, text, 1464 mContext.getText(R.string.heavy_weight_notification_detail), 1465 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1466 PendingIntent.FLAG_CANCEL_CURRENT, null, 1467 new UserHandle(root.userId))); 1468 1469 try { 1470 int[] outId = new int[1]; 1471 inm.enqueueNotificationWithTag("android", "android", null, 1472 R.string.heavy_weight_notification, 1473 notification, outId, root.userId); 1474 } catch (RuntimeException e) { 1475 Slog.w(ActivityManagerService.TAG, 1476 "Error showing notification for heavy-weight app", e); 1477 } catch (RemoteException e) { 1478 } 1479 } catch (NameNotFoundException e) { 1480 Slog.w(TAG, "Unable to create context for heavy notification", e); 1481 } 1482 } break; 1483 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1484 INotificationManager inm = NotificationManager.getService(); 1485 if (inm == null) { 1486 return; 1487 } 1488 try { 1489 inm.cancelNotificationWithTag("android", null, 1490 R.string.heavy_weight_notification, msg.arg1); 1491 } catch (RuntimeException e) { 1492 Slog.w(ActivityManagerService.TAG, 1493 "Error canceling notification for service", e); 1494 } catch (RemoteException e) { 1495 } 1496 } break; 1497 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1498 synchronized (ActivityManagerService.this) { 1499 checkExcessivePowerUsageLocked(true); 1500 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1501 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1502 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1503 } 1504 } break; 1505 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1506 synchronized (ActivityManagerService.this) { 1507 ActivityRecord ar = (ActivityRecord)msg.obj; 1508 if (mCompatModeDialog != null) { 1509 if (mCompatModeDialog.mAppInfo.packageName.equals( 1510 ar.info.applicationInfo.packageName)) { 1511 return; 1512 } 1513 mCompatModeDialog.dismiss(); 1514 mCompatModeDialog = null; 1515 } 1516 if (ar != null && false) { 1517 if (mCompatModePackages.getPackageAskCompatModeLocked( 1518 ar.packageName)) { 1519 int mode = mCompatModePackages.computeCompatModeLocked( 1520 ar.info.applicationInfo); 1521 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1522 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1523 mCompatModeDialog = new CompatModeDialog( 1524 ActivityManagerService.this, mContext, 1525 ar.info.applicationInfo); 1526 mCompatModeDialog.show(); 1527 } 1528 } 1529 } 1530 } 1531 break; 1532 } 1533 case DISPATCH_PROCESSES_CHANGED: { 1534 dispatchProcessesChanged(); 1535 break; 1536 } 1537 case DISPATCH_PROCESS_DIED: { 1538 final int pid = msg.arg1; 1539 final int uid = msg.arg2; 1540 dispatchProcessDied(pid, uid); 1541 break; 1542 } 1543 case REPORT_MEM_USAGE_MSG: { 1544 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1545 Thread thread = new Thread() { 1546 @Override public void run() { 1547 final SparseArray<ProcessMemInfo> infoMap 1548 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1549 for (int i=0, N=memInfos.size(); i<N; i++) { 1550 ProcessMemInfo mi = memInfos.get(i); 1551 infoMap.put(mi.pid, mi); 1552 } 1553 updateCpuStatsNow(); 1554 synchronized (mProcessCpuThread) { 1555 final int N = mProcessCpuTracker.countStats(); 1556 for (int i=0; i<N; i++) { 1557 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1558 if (st.vsize > 0) { 1559 long pss = Debug.getPss(st.pid, null); 1560 if (pss > 0) { 1561 if (infoMap.indexOfKey(st.pid) < 0) { 1562 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1563 ProcessList.NATIVE_ADJ, -1, "native", null); 1564 mi.pss = pss; 1565 memInfos.add(mi); 1566 } 1567 } 1568 } 1569 } 1570 } 1571 1572 long totalPss = 0; 1573 for (int i=0, N=memInfos.size(); i<N; i++) { 1574 ProcessMemInfo mi = memInfos.get(i); 1575 if (mi.pss == 0) { 1576 mi.pss = Debug.getPss(mi.pid, null); 1577 } 1578 totalPss += mi.pss; 1579 } 1580 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1581 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1582 if (lhs.oomAdj != rhs.oomAdj) { 1583 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1584 } 1585 if (lhs.pss != rhs.pss) { 1586 return lhs.pss < rhs.pss ? 1 : -1; 1587 } 1588 return 0; 1589 } 1590 }); 1591 1592 StringBuilder tag = new StringBuilder(128); 1593 StringBuilder stack = new StringBuilder(128); 1594 tag.append("Low on memory -- "); 1595 appendMemBucket(tag, totalPss, "total", false); 1596 appendMemBucket(stack, totalPss, "total", true); 1597 1598 StringBuilder logBuilder = new StringBuilder(1024); 1599 logBuilder.append("Low on memory:\n"); 1600 1601 boolean firstLine = true; 1602 int lastOomAdj = Integer.MIN_VALUE; 1603 for (int i=0, N=memInfos.size(); i<N; i++) { 1604 ProcessMemInfo mi = memInfos.get(i); 1605 1606 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1607 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1608 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1609 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1610 if (lastOomAdj != mi.oomAdj) { 1611 lastOomAdj = mi.oomAdj; 1612 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1613 tag.append(" / "); 1614 } 1615 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1616 if (firstLine) { 1617 stack.append(":"); 1618 firstLine = false; 1619 } 1620 stack.append("\n\t at "); 1621 } else { 1622 stack.append("$"); 1623 } 1624 } else { 1625 tag.append(" "); 1626 stack.append("$"); 1627 } 1628 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1629 appendMemBucket(tag, mi.pss, mi.name, false); 1630 } 1631 appendMemBucket(stack, mi.pss, mi.name, true); 1632 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1633 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1634 stack.append("("); 1635 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1636 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1637 stack.append(DUMP_MEM_OOM_LABEL[k]); 1638 stack.append(":"); 1639 stack.append(DUMP_MEM_OOM_ADJ[k]); 1640 } 1641 } 1642 stack.append(")"); 1643 } 1644 } 1645 1646 logBuilder.append(" "); 1647 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1648 logBuilder.append(' '); 1649 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1650 logBuilder.append(' '); 1651 ProcessList.appendRamKb(logBuilder, mi.pss); 1652 logBuilder.append(" kB: "); 1653 logBuilder.append(mi.name); 1654 logBuilder.append(" ("); 1655 logBuilder.append(mi.pid); 1656 logBuilder.append(") "); 1657 logBuilder.append(mi.adjType); 1658 logBuilder.append('\n'); 1659 if (mi.adjReason != null) { 1660 logBuilder.append(" "); 1661 logBuilder.append(mi.adjReason); 1662 logBuilder.append('\n'); 1663 } 1664 } 1665 1666 logBuilder.append(" "); 1667 ProcessList.appendRamKb(logBuilder, totalPss); 1668 logBuilder.append(" kB: TOTAL\n"); 1669 1670 long[] infos = new long[Debug.MEMINFO_COUNT]; 1671 Debug.getMemInfo(infos); 1672 logBuilder.append(" MemInfo: "); 1673 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1674 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1675 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1676 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1677 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1678 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1679 logBuilder.append(" ZRAM: "); 1680 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1681 logBuilder.append(" kB RAM, "); 1682 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1683 logBuilder.append(" kB swap total, "); 1684 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1685 logBuilder.append(" kB swap free\n"); 1686 } 1687 Slog.i(TAG, logBuilder.toString()); 1688 1689 StringBuilder dropBuilder = new StringBuilder(1024); 1690 /* 1691 StringWriter oomSw = new StringWriter(); 1692 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1693 StringWriter catSw = new StringWriter(); 1694 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1695 String[] emptyArgs = new String[] { }; 1696 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1697 oomPw.flush(); 1698 String oomString = oomSw.toString(); 1699 */ 1700 dropBuilder.append(stack); 1701 dropBuilder.append('\n'); 1702 dropBuilder.append('\n'); 1703 dropBuilder.append(logBuilder); 1704 dropBuilder.append('\n'); 1705 /* 1706 dropBuilder.append(oomString); 1707 dropBuilder.append('\n'); 1708 */ 1709 StringWriter catSw = new StringWriter(); 1710 synchronized (ActivityManagerService.this) { 1711 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1712 String[] emptyArgs = new String[] { }; 1713 catPw.println(); 1714 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1715 catPw.println(); 1716 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1717 false, false, null); 1718 catPw.println(); 1719 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1720 catPw.flush(); 1721 } 1722 dropBuilder.append(catSw.toString()); 1723 addErrorToDropBox("lowmem", null, "system_server", null, 1724 null, tag.toString(), dropBuilder.toString(), null, null); 1725 //Slog.i(TAG, "Sent to dropbox:"); 1726 //Slog.i(TAG, dropBuilder.toString()); 1727 synchronized (ActivityManagerService.this) { 1728 long now = SystemClock.uptimeMillis(); 1729 if (mLastMemUsageReportTime < now) { 1730 mLastMemUsageReportTime = now; 1731 } 1732 } 1733 } 1734 }; 1735 thread.start(); 1736 break; 1737 } 1738 case REPORT_USER_SWITCH_MSG: { 1739 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1740 break; 1741 } 1742 case CONTINUE_USER_SWITCH_MSG: { 1743 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1744 break; 1745 } 1746 case USER_SWITCH_TIMEOUT_MSG: { 1747 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1748 break; 1749 } 1750 case IMMERSIVE_MODE_LOCK_MSG: { 1751 final boolean nextState = (msg.arg1 != 0); 1752 if (mUpdateLock.isHeld() != nextState) { 1753 if (DEBUG_IMMERSIVE) { 1754 final ActivityRecord r = (ActivityRecord) msg.obj; 1755 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1756 } 1757 if (nextState) { 1758 mUpdateLock.acquire(); 1759 } else { 1760 mUpdateLock.release(); 1761 } 1762 } 1763 break; 1764 } 1765 case PERSIST_URI_GRANTS_MSG: { 1766 writeGrantedUriPermissions(); 1767 break; 1768 } 1769 case REQUEST_ALL_PSS_MSG: { 1770 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1771 break; 1772 } 1773 case START_PROFILES_MSG: { 1774 synchronized (ActivityManagerService.this) { 1775 startProfilesLocked(); 1776 } 1777 break; 1778 } 1779 case UPDATE_TIME: { 1780 synchronized (ActivityManagerService.this) { 1781 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1782 ProcessRecord r = mLruProcesses.get(i); 1783 if (r.thread != null) { 1784 try { 1785 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1786 } catch (RemoteException ex) { 1787 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1788 } 1789 } 1790 } 1791 } 1792 break; 1793 } 1794 case SYSTEM_USER_START_MSG: { 1795 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 1796 Integer.toString(msg.arg1), msg.arg1); 1797 mSystemServiceManager.startUser(msg.arg1); 1798 break; 1799 } 1800 case SYSTEM_USER_CURRENT_MSG: { 1801 mBatteryStatsService.noteEvent( 1802 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH, 1803 Integer.toString(msg.arg2), msg.arg2); 1804 mBatteryStatsService.noteEvent( 1805 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 1806 Integer.toString(msg.arg1), msg.arg1); 1807 mSystemServiceManager.switchUser(msg.arg1); 1808 break; 1809 } 1810 } 1811 } 1812 }; 1813 1814 static final int COLLECT_PSS_BG_MSG = 1; 1815 1816 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1817 @Override 1818 public void handleMessage(Message msg) { 1819 switch (msg.what) { 1820 case COLLECT_PSS_BG_MSG: { 1821 long start = SystemClock.uptimeMillis(); 1822 MemInfoReader memInfo = null; 1823 synchronized (ActivityManagerService.this) { 1824 if (mFullPssPending) { 1825 mFullPssPending = false; 1826 memInfo = new MemInfoReader(); 1827 } 1828 } 1829 if (memInfo != null) { 1830 updateCpuStatsNow(); 1831 long nativeTotalPss = 0; 1832 synchronized (mProcessCpuThread) { 1833 final int N = mProcessCpuTracker.countStats(); 1834 for (int j=0; j<N; j++) { 1835 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j); 1836 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) { 1837 // This is definitely an application process; skip it. 1838 continue; 1839 } 1840 synchronized (mPidsSelfLocked) { 1841 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) { 1842 // This is one of our own processes; skip it. 1843 continue; 1844 } 1845 } 1846 nativeTotalPss += Debug.getPss(st.pid, null); 1847 } 1848 } 1849 memInfo.readMemInfo(); 1850 synchronized (this) { 1851 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in " 1852 + (SystemClock.uptimeMillis()-start) + "ms"); 1853 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 1854 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 1855 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb() 1856 +memInfo.getSlabSizeKb(), 1857 nativeTotalPss); 1858 } 1859 } 1860 1861 int i=0, num=0; 1862 long[] tmp = new long[1]; 1863 do { 1864 ProcessRecord proc; 1865 int procState; 1866 int pid; 1867 synchronized (ActivityManagerService.this) { 1868 if (i >= mPendingPssProcesses.size()) { 1869 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1870 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1871 mPendingPssProcesses.clear(); 1872 return; 1873 } 1874 proc = mPendingPssProcesses.get(i); 1875 procState = proc.pssProcState; 1876 if (proc.thread != null && procState == proc.setProcState) { 1877 pid = proc.pid; 1878 } else { 1879 proc = null; 1880 pid = 0; 1881 } 1882 i++; 1883 } 1884 if (proc != null) { 1885 long pss = Debug.getPss(pid, tmp); 1886 synchronized (ActivityManagerService.this) { 1887 if (proc.thread != null && proc.setProcState == procState 1888 && proc.pid == pid) { 1889 num++; 1890 proc.lastPssTime = SystemClock.uptimeMillis(); 1891 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1892 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1893 + ": " + pss + " lastPss=" + proc.lastPss 1894 + " state=" + ProcessList.makeProcStateString(procState)); 1895 if (proc.initialIdlePss == 0) { 1896 proc.initialIdlePss = pss; 1897 } 1898 proc.lastPss = pss; 1899 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1900 proc.lastCachedPss = pss; 1901 } 1902 } 1903 } 1904 } 1905 } while (true); 1906 } 1907 } 1908 } 1909 }; 1910 1911 /** 1912 * Monitor for package changes and update our internal state. 1913 */ 1914 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1915 @Override 1916 public void onPackageRemoved(String packageName, int uid) { 1917 // Remove all tasks with activities in the specified package from the list of recent tasks 1918 synchronized (ActivityManagerService.this) { 1919 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1920 TaskRecord tr = mRecentTasks.get(i); 1921 ComponentName cn = tr.intent.getComponent(); 1922 if (cn != null && cn.getPackageName().equals(packageName)) { 1923 // If the package name matches, remove the task and kill the process 1924 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1925 } 1926 } 1927 } 1928 } 1929 1930 @Override 1931 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1932 onPackageModified(packageName); 1933 return true; 1934 } 1935 1936 @Override 1937 public void onPackageModified(String packageName) { 1938 final PackageManager pm = mContext.getPackageManager(); 1939 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1940 new ArrayList<Pair<Intent, Integer>>(); 1941 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1942 // Copy the list of recent tasks so that we don't hold onto the lock on 1943 // ActivityManagerService for long periods while checking if components exist. 1944 synchronized (ActivityManagerService.this) { 1945 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1946 TaskRecord tr = mRecentTasks.get(i); 1947 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1948 } 1949 } 1950 // Check the recent tasks and filter out all tasks with components that no longer exist. 1951 Intent tmpI = new Intent(); 1952 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1953 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1954 ComponentName cn = p.first.getComponent(); 1955 if (cn != null && cn.getPackageName().equals(packageName)) { 1956 try { 1957 // Add the task to the list to remove if the component no longer exists 1958 tmpI.setComponent(cn); 1959 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1960 tasksToRemove.add(p.second); 1961 } 1962 } catch (Exception e) {} 1963 } 1964 } 1965 // Prune all the tasks with removed components from the list of recent tasks 1966 synchronized (ActivityManagerService.this) { 1967 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1968 // Remove the task but don't kill the process (since other components in that 1969 // package may still be running and in the background) 1970 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1971 } 1972 } 1973 } 1974 1975 @Override 1976 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1977 // Force stop the specified packages 1978 if (packages != null) { 1979 for (String pkg : packages) { 1980 synchronized (ActivityManagerService.this) { 1981 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1982 "finished booting")) { 1983 return true; 1984 } 1985 } 1986 } 1987 } 1988 return false; 1989 } 1990 }; 1991 1992 public void setSystemProcess() { 1993 try { 1994 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1995 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1996 ServiceManager.addService("meminfo", new MemBinder(this)); 1997 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1998 ServiceManager.addService("dbinfo", new DbBinder(this)); 1999 if (MONITOR_CPU_USAGE) { 2000 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 2001 } 2002 ServiceManager.addService("permission", new PermissionController(this)); 2003 2004 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 2005 "android", STOCK_PM_FLAGS); 2006 mSystemThread.installSystemApplicationInfo(info); 2007 2008 synchronized (this) { 2009 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 2010 app.persistent = true; 2011 app.pid = MY_PID; 2012 app.maxAdj = ProcessList.SYSTEM_ADJ; 2013 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 2014 mProcessNames.put(app.processName, app.uid, app); 2015 synchronized (mPidsSelfLocked) { 2016 mPidsSelfLocked.put(app.pid, app); 2017 } 2018 updateLruProcessLocked(app, false, null); 2019 updateOomAdjLocked(); 2020 } 2021 } catch (PackageManager.NameNotFoundException e) { 2022 throw new RuntimeException( 2023 "Unable to find android system package", e); 2024 } 2025 } 2026 2027 public void setWindowManager(WindowManagerService wm) { 2028 mWindowManager = wm; 2029 mStackSupervisor.setWindowManager(wm); 2030 } 2031 2032 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) { 2033 mUsageStatsService = usageStatsManager; 2034 } 2035 2036 public void startObservingNativeCrashes() { 2037 final NativeCrashListener ncl = new NativeCrashListener(this); 2038 ncl.start(); 2039 } 2040 2041 public IAppOpsService getAppOpsService() { 2042 return mAppOpsService; 2043 } 2044 2045 static class MemBinder extends Binder { 2046 ActivityManagerService mActivityManagerService; 2047 MemBinder(ActivityManagerService activityManagerService) { 2048 mActivityManagerService = activityManagerService; 2049 } 2050 2051 @Override 2052 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2053 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2054 != PackageManager.PERMISSION_GRANTED) { 2055 pw.println("Permission Denial: can't dump meminfo from from pid=" 2056 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2057 + " without permission " + android.Manifest.permission.DUMP); 2058 return; 2059 } 2060 2061 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 2062 } 2063 } 2064 2065 static class GraphicsBinder extends Binder { 2066 ActivityManagerService mActivityManagerService; 2067 GraphicsBinder(ActivityManagerService activityManagerService) { 2068 mActivityManagerService = activityManagerService; 2069 } 2070 2071 @Override 2072 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2073 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2074 != PackageManager.PERMISSION_GRANTED) { 2075 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2076 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2077 + " without permission " + android.Manifest.permission.DUMP); 2078 return; 2079 } 2080 2081 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2082 } 2083 } 2084 2085 static class DbBinder extends Binder { 2086 ActivityManagerService mActivityManagerService; 2087 DbBinder(ActivityManagerService activityManagerService) { 2088 mActivityManagerService = activityManagerService; 2089 } 2090 2091 @Override 2092 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2093 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2094 != PackageManager.PERMISSION_GRANTED) { 2095 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2096 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2097 + " without permission " + android.Manifest.permission.DUMP); 2098 return; 2099 } 2100 2101 mActivityManagerService.dumpDbInfo(fd, pw, args); 2102 } 2103 } 2104 2105 static class CpuBinder extends Binder { 2106 ActivityManagerService mActivityManagerService; 2107 CpuBinder(ActivityManagerService activityManagerService) { 2108 mActivityManagerService = activityManagerService; 2109 } 2110 2111 @Override 2112 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2113 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2114 != PackageManager.PERMISSION_GRANTED) { 2115 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2116 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2117 + " without permission " + android.Manifest.permission.DUMP); 2118 return; 2119 } 2120 2121 synchronized (mActivityManagerService.mProcessCpuThread) { 2122 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2123 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2124 SystemClock.uptimeMillis())); 2125 } 2126 } 2127 } 2128 2129 public static final class Lifecycle extends SystemService { 2130 private final ActivityManagerService mService; 2131 2132 public Lifecycle(Context context) { 2133 super(context); 2134 mService = new ActivityManagerService(context); 2135 } 2136 2137 @Override 2138 public void onStart() { 2139 mService.start(); 2140 } 2141 2142 public ActivityManagerService getService() { 2143 return mService; 2144 } 2145 } 2146 2147 // Note: This method is invoked on the main thread but may need to attach various 2148 // handlers to other threads. So take care to be explicit about the looper. 2149 public ActivityManagerService(Context systemContext) { 2150 mContext = systemContext; 2151 mFactoryTest = FactoryTest.getMode(); 2152 mSystemThread = ActivityThread.currentActivityThread(); 2153 2154 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2155 2156 mHandlerThread = new ServiceThread(TAG, 2157 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2158 mHandlerThread.start(); 2159 mHandler = new MainHandler(mHandlerThread.getLooper()); 2160 2161 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2162 "foreground", BROADCAST_FG_TIMEOUT, false); 2163 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2164 "background", BROADCAST_BG_TIMEOUT, true); 2165 mBroadcastQueues[0] = mFgBroadcastQueue; 2166 mBroadcastQueues[1] = mBgBroadcastQueue; 2167 2168 mServices = new ActiveServices(this); 2169 mProviderMap = new ProviderMap(this); 2170 2171 // TODO: Move creation of battery stats service outside of activity manager service. 2172 File dataDir = Environment.getDataDirectory(); 2173 File systemDir = new File(dataDir, "system"); 2174 systemDir.mkdirs(); 2175 mBatteryStatsService = new BatteryStatsService(new File( 2176 systemDir, "batterystats.bin").toString(), mHandler); 2177 mBatteryStatsService.getActiveStatistics().readLocked(); 2178 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2179 mOnBattery = DEBUG_POWER ? true 2180 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2181 mBatteryStatsService.getActiveStatistics().setCallback(this); 2182 2183 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2184 2185 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2186 2187 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2188 2189 // User 0 is the first and only user that runs at boot. 2190 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2191 mUserLru.add(Integer.valueOf(0)); 2192 updateStartedUserArrayLocked(); 2193 2194 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2195 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2196 2197 mConfiguration.setToDefaults(); 2198 mConfiguration.setLocale(Locale.getDefault()); 2199 2200 mConfigurationSeq = mConfiguration.seq = 1; 2201 mProcessCpuTracker.init(); 2202 2203 mHasRecents = mContext.getResources().getBoolean( 2204 com.android.internal.R.bool.config_hasRecents); 2205 2206 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2207 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2208 mStackSupervisor = new ActivityStackSupervisor(this); 2209 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor); 2210 2211 mProcessCpuThread = new Thread("CpuTracker") { 2212 @Override 2213 public void run() { 2214 while (true) { 2215 try { 2216 try { 2217 synchronized(this) { 2218 final long now = SystemClock.uptimeMillis(); 2219 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2220 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2221 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2222 // + ", write delay=" + nextWriteDelay); 2223 if (nextWriteDelay < nextCpuDelay) { 2224 nextCpuDelay = nextWriteDelay; 2225 } 2226 if (nextCpuDelay > 0) { 2227 mProcessCpuMutexFree.set(true); 2228 this.wait(nextCpuDelay); 2229 } 2230 } 2231 } catch (InterruptedException e) { 2232 } 2233 updateCpuStatsNow(); 2234 } catch (Exception e) { 2235 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2236 } 2237 } 2238 } 2239 }; 2240 2241 mLockToAppRequest = new LockToAppRequestDialog(mContext, this); 2242 2243 Watchdog.getInstance().addMonitor(this); 2244 Watchdog.getInstance().addThread(mHandler); 2245 } 2246 2247 public void setSystemServiceManager(SystemServiceManager mgr) { 2248 mSystemServiceManager = mgr; 2249 } 2250 2251 private void start() { 2252 Process.removeAllProcessGroups(); 2253 mProcessCpuThread.start(); 2254 2255 mBatteryStatsService.publish(mContext); 2256 mAppOpsService.publish(mContext); 2257 Slog.d("AppOps", "AppOpsService published"); 2258 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2259 } 2260 2261 public void initPowerManagement() { 2262 mStackSupervisor.initPowerManagement(); 2263 mBatteryStatsService.initPowerManagement(); 2264 } 2265 2266 @Override 2267 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2268 throws RemoteException { 2269 if (code == SYSPROPS_TRANSACTION) { 2270 // We need to tell all apps about the system property change. 2271 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2272 synchronized(this) { 2273 final int NP = mProcessNames.getMap().size(); 2274 for (int ip=0; ip<NP; ip++) { 2275 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2276 final int NA = apps.size(); 2277 for (int ia=0; ia<NA; ia++) { 2278 ProcessRecord app = apps.valueAt(ia); 2279 if (app.thread != null) { 2280 procs.add(app.thread.asBinder()); 2281 } 2282 } 2283 } 2284 } 2285 2286 int N = procs.size(); 2287 for (int i=0; i<N; i++) { 2288 Parcel data2 = Parcel.obtain(); 2289 try { 2290 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2291 } catch (RemoteException e) { 2292 } 2293 data2.recycle(); 2294 } 2295 } 2296 try { 2297 return super.onTransact(code, data, reply, flags); 2298 } catch (RuntimeException e) { 2299 // The activity manager only throws security exceptions, so let's 2300 // log all others. 2301 if (!(e instanceof SecurityException)) { 2302 Slog.wtf(TAG, "Activity Manager Crash", e); 2303 } 2304 throw e; 2305 } 2306 } 2307 2308 void updateCpuStats() { 2309 final long now = SystemClock.uptimeMillis(); 2310 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2311 return; 2312 } 2313 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2314 synchronized (mProcessCpuThread) { 2315 mProcessCpuThread.notify(); 2316 } 2317 } 2318 } 2319 2320 void updateCpuStatsNow() { 2321 synchronized (mProcessCpuThread) { 2322 mProcessCpuMutexFree.set(false); 2323 final long now = SystemClock.uptimeMillis(); 2324 boolean haveNewCpuStats = false; 2325 2326 if (MONITOR_CPU_USAGE && 2327 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2328 mLastCpuTime.set(now); 2329 haveNewCpuStats = true; 2330 mProcessCpuTracker.update(); 2331 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2332 //Slog.i(TAG, "Total CPU usage: " 2333 // + mProcessCpu.getTotalCpuPercent() + "%"); 2334 2335 // Slog the cpu usage if the property is set. 2336 if ("true".equals(SystemProperties.get("events.cpu"))) { 2337 int user = mProcessCpuTracker.getLastUserTime(); 2338 int system = mProcessCpuTracker.getLastSystemTime(); 2339 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2340 int irq = mProcessCpuTracker.getLastIrqTime(); 2341 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2342 int idle = mProcessCpuTracker.getLastIdleTime(); 2343 2344 int total = user + system + iowait + irq + softIrq + idle; 2345 if (total == 0) total = 1; 2346 2347 EventLog.writeEvent(EventLogTags.CPU, 2348 ((user+system+iowait+irq+softIrq) * 100) / total, 2349 (user * 100) / total, 2350 (system * 100) / total, 2351 (iowait * 100) / total, 2352 (irq * 100) / total, 2353 (softIrq * 100) / total); 2354 } 2355 } 2356 2357 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2358 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2359 synchronized(bstats) { 2360 synchronized(mPidsSelfLocked) { 2361 if (haveNewCpuStats) { 2362 if (mOnBattery) { 2363 int perc = bstats.startAddingCpuLocked(); 2364 int totalUTime = 0; 2365 int totalSTime = 0; 2366 final int N = mProcessCpuTracker.countStats(); 2367 for (int i=0; i<N; i++) { 2368 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2369 if (!st.working) { 2370 continue; 2371 } 2372 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2373 int otherUTime = (st.rel_utime*perc)/100; 2374 int otherSTime = (st.rel_stime*perc)/100; 2375 totalUTime += otherUTime; 2376 totalSTime += otherSTime; 2377 if (pr != null) { 2378 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2379 if (ps == null || !ps.isActive()) { 2380 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2381 pr.info.uid, pr.processName); 2382 } 2383 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2384 st.rel_stime-otherSTime); 2385 ps.addSpeedStepTimes(cpuSpeedTimes); 2386 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2387 } else { 2388 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2389 if (ps == null || !ps.isActive()) { 2390 st.batteryStats = ps = bstats.getProcessStatsLocked( 2391 bstats.mapUid(st.uid), st.name); 2392 } 2393 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2394 st.rel_stime-otherSTime); 2395 ps.addSpeedStepTimes(cpuSpeedTimes); 2396 } 2397 } 2398 bstats.finishAddingCpuLocked(perc, totalUTime, 2399 totalSTime, cpuSpeedTimes); 2400 } 2401 } 2402 } 2403 2404 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2405 mLastWriteTime = now; 2406 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2407 } 2408 } 2409 } 2410 } 2411 2412 @Override 2413 public void batteryNeedsCpuUpdate() { 2414 updateCpuStatsNow(); 2415 } 2416 2417 @Override 2418 public void batteryPowerChanged(boolean onBattery) { 2419 // When plugging in, update the CPU stats first before changing 2420 // the plug state. 2421 updateCpuStatsNow(); 2422 synchronized (this) { 2423 synchronized(mPidsSelfLocked) { 2424 mOnBattery = DEBUG_POWER ? true : onBattery; 2425 } 2426 } 2427 } 2428 2429 /** 2430 * Initialize the application bind args. These are passed to each 2431 * process when the bindApplication() IPC is sent to the process. They're 2432 * lazily setup to make sure the services are running when they're asked for. 2433 */ 2434 private HashMap<String, IBinder> getCommonServicesLocked() { 2435 if (mAppBindArgs == null) { 2436 mAppBindArgs = new HashMap<String, IBinder>(); 2437 2438 // Setup the application init args 2439 mAppBindArgs.put("package", ServiceManager.getService("package")); 2440 mAppBindArgs.put("window", ServiceManager.getService("window")); 2441 mAppBindArgs.put(Context.ALARM_SERVICE, 2442 ServiceManager.getService(Context.ALARM_SERVICE)); 2443 } 2444 return mAppBindArgs; 2445 } 2446 2447 final void setFocusedActivityLocked(ActivityRecord r) { 2448 if (mFocusedActivity != r) { 2449 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2450 mFocusedActivity = r; 2451 if (r.task != null && r.task.voiceInteractor != null) { 2452 startRunningVoiceLocked(); 2453 } else { 2454 finishRunningVoiceLocked(); 2455 } 2456 mStackSupervisor.setFocusedStack(r); 2457 if (r != null) { 2458 mWindowManager.setFocusedApp(r.appToken, true); 2459 } 2460 applyUpdateLockStateLocked(r); 2461 } 2462 } 2463 2464 final void clearFocusedActivity(ActivityRecord r) { 2465 if (mFocusedActivity == r) { 2466 mFocusedActivity = null; 2467 } 2468 } 2469 2470 @Override 2471 public void setFocusedStack(int stackId) { 2472 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2473 synchronized (ActivityManagerService.this) { 2474 ActivityStack stack = mStackSupervisor.getStack(stackId); 2475 if (stack != null) { 2476 ActivityRecord r = stack.topRunningActivityLocked(null); 2477 if (r != null) { 2478 setFocusedActivityLocked(r); 2479 } 2480 } 2481 } 2482 } 2483 2484 @Override 2485 public void notifyActivityDrawn(IBinder token) { 2486 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2487 synchronized (this) { 2488 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2489 if (r != null) { 2490 r.task.stack.notifyActivityDrawnLocked(r); 2491 } 2492 } 2493 } 2494 2495 final void applyUpdateLockStateLocked(ActivityRecord r) { 2496 // Modifications to the UpdateLock state are done on our handler, outside 2497 // the activity manager's locks. The new state is determined based on the 2498 // state *now* of the relevant activity record. The object is passed to 2499 // the handler solely for logging detail, not to be consulted/modified. 2500 final boolean nextState = r != null && r.immersive; 2501 mHandler.sendMessage( 2502 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2503 } 2504 2505 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2506 Message msg = Message.obtain(); 2507 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2508 msg.obj = r.task.askedCompatMode ? null : r; 2509 mHandler.sendMessage(msg); 2510 } 2511 2512 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2513 String what, Object obj, ProcessRecord srcApp) { 2514 app.lastActivityTime = now; 2515 2516 if (app.activities.size() > 0) { 2517 // Don't want to touch dependent processes that are hosting activities. 2518 return index; 2519 } 2520 2521 int lrui = mLruProcesses.lastIndexOf(app); 2522 if (lrui < 0) { 2523 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2524 + what + " " + obj + " from " + srcApp); 2525 return index; 2526 } 2527 2528 if (lrui >= index) { 2529 // Don't want to cause this to move dependent processes *back* in the 2530 // list as if they were less frequently used. 2531 return index; 2532 } 2533 2534 if (lrui >= mLruProcessActivityStart) { 2535 // Don't want to touch dependent processes that are hosting activities. 2536 return index; 2537 } 2538 2539 mLruProcesses.remove(lrui); 2540 if (index > 0) { 2541 index--; 2542 } 2543 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2544 + " in LRU list: " + app); 2545 mLruProcesses.add(index, app); 2546 return index; 2547 } 2548 2549 final void removeLruProcessLocked(ProcessRecord app) { 2550 int lrui = mLruProcesses.lastIndexOf(app); 2551 if (lrui >= 0) { 2552 if (lrui <= mLruProcessActivityStart) { 2553 mLruProcessActivityStart--; 2554 } 2555 if (lrui <= mLruProcessServiceStart) { 2556 mLruProcessServiceStart--; 2557 } 2558 mLruProcesses.remove(lrui); 2559 } 2560 } 2561 2562 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2563 ProcessRecord client) { 2564 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2565 || app.treatLikeActivity; 2566 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2567 if (!activityChange && hasActivity) { 2568 // The process has activities, so we are only allowing activity-based adjustments 2569 // to move it. It should be kept in the front of the list with other 2570 // processes that have activities, and we don't want those to change their 2571 // order except due to activity operations. 2572 return; 2573 } 2574 2575 mLruSeq++; 2576 final long now = SystemClock.uptimeMillis(); 2577 app.lastActivityTime = now; 2578 2579 // First a quick reject: if the app is already at the position we will 2580 // put it, then there is nothing to do. 2581 if (hasActivity) { 2582 final int N = mLruProcesses.size(); 2583 if (N > 0 && mLruProcesses.get(N-1) == app) { 2584 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2585 return; 2586 } 2587 } else { 2588 if (mLruProcessServiceStart > 0 2589 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2590 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2591 return; 2592 } 2593 } 2594 2595 int lrui = mLruProcesses.lastIndexOf(app); 2596 2597 if (app.persistent && lrui >= 0) { 2598 // We don't care about the position of persistent processes, as long as 2599 // they are in the list. 2600 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2601 return; 2602 } 2603 2604 /* In progress: compute new position first, so we can avoid doing work 2605 if the process is not actually going to move. Not yet working. 2606 int addIndex; 2607 int nextIndex; 2608 boolean inActivity = false, inService = false; 2609 if (hasActivity) { 2610 // Process has activities, put it at the very tipsy-top. 2611 addIndex = mLruProcesses.size(); 2612 nextIndex = mLruProcessServiceStart; 2613 inActivity = true; 2614 } else if (hasService) { 2615 // Process has services, put it at the top of the service list. 2616 addIndex = mLruProcessActivityStart; 2617 nextIndex = mLruProcessServiceStart; 2618 inActivity = true; 2619 inService = true; 2620 } else { 2621 // Process not otherwise of interest, it goes to the top of the non-service area. 2622 addIndex = mLruProcessServiceStart; 2623 if (client != null) { 2624 int clientIndex = mLruProcesses.lastIndexOf(client); 2625 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2626 + app); 2627 if (clientIndex >= 0 && addIndex > clientIndex) { 2628 addIndex = clientIndex; 2629 } 2630 } 2631 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2632 } 2633 2634 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2635 + mLruProcessActivityStart + "): " + app); 2636 */ 2637 2638 if (lrui >= 0) { 2639 if (lrui < mLruProcessActivityStart) { 2640 mLruProcessActivityStart--; 2641 } 2642 if (lrui < mLruProcessServiceStart) { 2643 mLruProcessServiceStart--; 2644 } 2645 /* 2646 if (addIndex > lrui) { 2647 addIndex--; 2648 } 2649 if (nextIndex > lrui) { 2650 nextIndex--; 2651 } 2652 */ 2653 mLruProcesses.remove(lrui); 2654 } 2655 2656 /* 2657 mLruProcesses.add(addIndex, app); 2658 if (inActivity) { 2659 mLruProcessActivityStart++; 2660 } 2661 if (inService) { 2662 mLruProcessActivityStart++; 2663 } 2664 */ 2665 2666 int nextIndex; 2667 if (hasActivity) { 2668 final int N = mLruProcesses.size(); 2669 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2670 // Process doesn't have activities, but has clients with 2671 // activities... move it up, but one below the top (the top 2672 // should always have a real activity). 2673 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2674 mLruProcesses.add(N-1, app); 2675 // To keep it from spamming the LRU list (by making a bunch of clients), 2676 // we will push down any other entries owned by the app. 2677 final int uid = app.info.uid; 2678 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2679 ProcessRecord subProc = mLruProcesses.get(i); 2680 if (subProc.info.uid == uid) { 2681 // We want to push this one down the list. If the process after 2682 // it is for the same uid, however, don't do so, because we don't 2683 // want them internally to be re-ordered. 2684 if (mLruProcesses.get(i-1).info.uid != uid) { 2685 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2686 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2687 ProcessRecord tmp = mLruProcesses.get(i); 2688 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2689 mLruProcesses.set(i-1, tmp); 2690 i--; 2691 } 2692 } else { 2693 // A gap, we can stop here. 2694 break; 2695 } 2696 } 2697 } else { 2698 // Process has activities, put it at the very tipsy-top. 2699 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2700 mLruProcesses.add(app); 2701 } 2702 nextIndex = mLruProcessServiceStart; 2703 } else if (hasService) { 2704 // Process has services, put it at the top of the service list. 2705 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2706 mLruProcesses.add(mLruProcessActivityStart, app); 2707 nextIndex = mLruProcessServiceStart; 2708 mLruProcessActivityStart++; 2709 } else { 2710 // Process not otherwise of interest, it goes to the top of the non-service area. 2711 int index = mLruProcessServiceStart; 2712 if (client != null) { 2713 // If there is a client, don't allow the process to be moved up higher 2714 // in the list than that client. 2715 int clientIndex = mLruProcesses.lastIndexOf(client); 2716 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2717 + " when updating " + app); 2718 if (clientIndex <= lrui) { 2719 // Don't allow the client index restriction to push it down farther in the 2720 // list than it already is. 2721 clientIndex = lrui; 2722 } 2723 if (clientIndex >= 0 && index > clientIndex) { 2724 index = clientIndex; 2725 } 2726 } 2727 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2728 mLruProcesses.add(index, app); 2729 nextIndex = index-1; 2730 mLruProcessActivityStart++; 2731 mLruProcessServiceStart++; 2732 } 2733 2734 // If the app is currently using a content provider or service, 2735 // bump those processes as well. 2736 for (int j=app.connections.size()-1; j>=0; j--) { 2737 ConnectionRecord cr = app.connections.valueAt(j); 2738 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2739 && cr.binding.service.app != null 2740 && cr.binding.service.app.lruSeq != mLruSeq 2741 && !cr.binding.service.app.persistent) { 2742 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2743 "service connection", cr, app); 2744 } 2745 } 2746 for (int j=app.conProviders.size()-1; j>=0; j--) { 2747 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2748 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2749 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2750 "provider reference", cpr, app); 2751 } 2752 } 2753 } 2754 2755 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2756 if (uid == Process.SYSTEM_UID) { 2757 // The system gets to run in any process. If there are multiple 2758 // processes with the same uid, just pick the first (this 2759 // should never happen). 2760 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2761 if (procs == null) return null; 2762 final int N = procs.size(); 2763 for (int i = 0; i < N; i++) { 2764 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2765 } 2766 } 2767 ProcessRecord proc = mProcessNames.get(processName, uid); 2768 if (false && proc != null && !keepIfLarge 2769 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2770 && proc.lastCachedPss >= 4000) { 2771 // Turn this condition on to cause killing to happen regularly, for testing. 2772 if (proc.baseProcessTracker != null) { 2773 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2774 } 2775 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2776 + "k from cached"); 2777 } else if (proc != null && !keepIfLarge 2778 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2779 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2780 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2781 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2782 if (proc.baseProcessTracker != null) { 2783 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2784 } 2785 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2786 + "k from cached"); 2787 } 2788 } 2789 return proc; 2790 } 2791 2792 void ensurePackageDexOpt(String packageName) { 2793 IPackageManager pm = AppGlobals.getPackageManager(); 2794 try { 2795 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) { 2796 mDidDexOpt = true; 2797 } 2798 } catch (RemoteException e) { 2799 } 2800 } 2801 2802 boolean isNextTransitionForward() { 2803 int transit = mWindowManager.getPendingAppTransition(); 2804 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2805 || transit == AppTransition.TRANSIT_TASK_OPEN 2806 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2807 } 2808 2809 final ProcessRecord startProcessLocked(String processName, 2810 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2811 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2812 boolean isolated, boolean keepIfLarge) { 2813 ProcessRecord app; 2814 if (!isolated) { 2815 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2816 } else { 2817 // If this is an isolated process, it can't re-use an existing process. 2818 app = null; 2819 } 2820 // We don't have to do anything more if: 2821 // (1) There is an existing application record; and 2822 // (2) The caller doesn't think it is dead, OR there is no thread 2823 // object attached to it so we know it couldn't have crashed; and 2824 // (3) There is a pid assigned to it, so it is either starting or 2825 // already running. 2826 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2827 + " app=" + app + " knownToBeDead=" + knownToBeDead 2828 + " thread=" + (app != null ? app.thread : null) 2829 + " pid=" + (app != null ? app.pid : -1)); 2830 if (app != null && app.pid > 0) { 2831 if (!knownToBeDead || app.thread == null) { 2832 // We already have the app running, or are waiting for it to 2833 // come up (we have a pid but not yet its thread), so keep it. 2834 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2835 // If this is a new package in the process, add the package to the list 2836 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2837 return app; 2838 } 2839 2840 // An application record is attached to a previous process, 2841 // clean it up now. 2842 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2843 Process.killProcessGroup(app.info.uid, app.pid); 2844 handleAppDiedLocked(app, true, true); 2845 } 2846 2847 String hostingNameStr = hostingName != null 2848 ? hostingName.flattenToShortString() : null; 2849 2850 if (!isolated) { 2851 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2852 // If we are in the background, then check to see if this process 2853 // is bad. If so, we will just silently fail. 2854 if (mBadProcesses.get(info.processName, info.uid) != null) { 2855 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2856 + "/" + info.processName); 2857 return null; 2858 } 2859 } else { 2860 // When the user is explicitly starting a process, then clear its 2861 // crash count so that we won't make it bad until they see at 2862 // least one crash dialog again, and make the process good again 2863 // if it had been bad. 2864 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2865 + "/" + info.processName); 2866 mProcessCrashTimes.remove(info.processName, info.uid); 2867 if (mBadProcesses.get(info.processName, info.uid) != null) { 2868 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2869 UserHandle.getUserId(info.uid), info.uid, 2870 info.processName); 2871 mBadProcesses.remove(info.processName, info.uid); 2872 if (app != null) { 2873 app.bad = false; 2874 } 2875 } 2876 } 2877 } 2878 2879 if (app == null) { 2880 app = newProcessRecordLocked(info, processName, isolated); 2881 if (app == null) { 2882 Slog.w(TAG, "Failed making new process record for " 2883 + processName + "/" + info.uid + " isolated=" + isolated); 2884 return null; 2885 } 2886 mProcessNames.put(processName, app.uid, app); 2887 if (isolated) { 2888 mIsolatedProcesses.put(app.uid, app); 2889 } 2890 } else { 2891 // If this is a new package in the process, add the package to the list 2892 app.addPackage(info.packageName, info.versionCode, mProcessStats); 2893 } 2894 2895 // If the system is not ready yet, then hold off on starting this 2896 // process until it is. 2897 if (!mProcessesReady 2898 && !isAllowedWhileBooting(info) 2899 && !allowWhileBooting) { 2900 if (!mProcessesOnHold.contains(app)) { 2901 mProcessesOnHold.add(app); 2902 } 2903 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2904 return app; 2905 } 2906 2907 startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */); 2908 return (app.pid != 0) ? app : null; 2909 } 2910 2911 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2912 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2913 } 2914 2915 private final void startProcessLocked(ProcessRecord app, 2916 String hostingType, String hostingNameStr, String abiOverride) { 2917 if (app.pid > 0 && app.pid != MY_PID) { 2918 synchronized (mPidsSelfLocked) { 2919 mPidsSelfLocked.remove(app.pid); 2920 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2921 } 2922 app.setPid(0); 2923 } 2924 2925 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2926 "startProcessLocked removing on hold: " + app); 2927 mProcessesOnHold.remove(app); 2928 2929 updateCpuStats(); 2930 2931 try { 2932 int uid = app.uid; 2933 2934 int[] gids = null; 2935 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2936 if (!app.isolated) { 2937 int[] permGids = null; 2938 try { 2939 final PackageManager pm = mContext.getPackageManager(); 2940 permGids = pm.getPackageGids(app.info.packageName); 2941 2942 if (Environment.isExternalStorageEmulated()) { 2943 if (pm.checkPermission( 2944 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2945 app.info.packageName) == PERMISSION_GRANTED) { 2946 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2947 } else { 2948 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2949 } 2950 } 2951 } catch (PackageManager.NameNotFoundException e) { 2952 Slog.w(TAG, "Unable to retrieve gids", e); 2953 } 2954 2955 /* 2956 * Add shared application and profile GIDs so applications can share some 2957 * resources like shared libraries and access user-wide resources 2958 */ 2959 if (permGids == null) { 2960 gids = new int[2]; 2961 } else { 2962 gids = new int[permGids.length + 2]; 2963 System.arraycopy(permGids, 0, gids, 2, permGids.length); 2964 } 2965 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2966 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 2967 } 2968 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2969 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2970 && mTopComponent != null 2971 && app.processName.equals(mTopComponent.getPackageName())) { 2972 uid = 0; 2973 } 2974 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2975 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2976 uid = 0; 2977 } 2978 } 2979 int debugFlags = 0; 2980 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2981 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2982 // Also turn on CheckJNI for debuggable apps. It's quite 2983 // awkward to turn on otherwise. 2984 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2985 } 2986 // Run the app in safe mode if its manifest requests so or the 2987 // system is booted in safe mode. 2988 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2989 mSafeMode == true) { 2990 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2991 } 2992 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2993 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2994 } 2995 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2996 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2997 } 2998 if ("1".equals(SystemProperties.get("debug.assert"))) { 2999 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 3000 } 3001 3002 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 3003 if (requiredAbi == null) { 3004 requiredAbi = Build.SUPPORTED_ABIS[0]; 3005 } 3006 3007 // Start the process. It will either succeed and return a result containing 3008 // the PID of the new process, or else throw a RuntimeException. 3009 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 3010 app.processName, uid, uid, gids, debugFlags, mountExternal, 3011 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 3012 3013 if (app.isolated) { 3014 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 3015 } 3016 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 3017 3018 EventLog.writeEvent(EventLogTags.AM_PROC_START, 3019 UserHandle.getUserId(uid), startResult.pid, uid, 3020 app.processName, hostingType, 3021 hostingNameStr != null ? hostingNameStr : ""); 3022 3023 if (app.persistent) { 3024 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 3025 } 3026 3027 StringBuilder buf = mStringBuilder; 3028 buf.setLength(0); 3029 buf.append("Start proc "); 3030 buf.append(app.processName); 3031 buf.append(" for "); 3032 buf.append(hostingType); 3033 if (hostingNameStr != null) { 3034 buf.append(" "); 3035 buf.append(hostingNameStr); 3036 } 3037 buf.append(": pid="); 3038 buf.append(startResult.pid); 3039 buf.append(" uid="); 3040 buf.append(uid); 3041 buf.append(" gids={"); 3042 if (gids != null) { 3043 for (int gi=0; gi<gids.length; gi++) { 3044 if (gi != 0) buf.append(", "); 3045 buf.append(gids[gi]); 3046 3047 } 3048 } 3049 buf.append("}"); 3050 if (requiredAbi != null) { 3051 buf.append(" abi="); 3052 buf.append(requiredAbi); 3053 } 3054 Slog.i(TAG, buf.toString()); 3055 app.setPid(startResult.pid); 3056 app.usingWrapper = startResult.usingWrapper; 3057 app.removed = false; 3058 app.killedByAm = false; 3059 synchronized (mPidsSelfLocked) { 3060 this.mPidsSelfLocked.put(startResult.pid, app); 3061 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 3062 msg.obj = app; 3063 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 3064 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 3065 } 3066 } catch (RuntimeException e) { 3067 // XXX do better error recovery. 3068 app.setPid(0); 3069 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 3070 if (app.isolated) { 3071 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 3072 } 3073 Slog.e(TAG, "Failure starting process " + app.processName, e); 3074 } 3075 } 3076 3077 void updateUsageStats(ActivityRecord component, boolean resumed) { 3078 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 3079 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3080 if (resumed) { 3081 if (mUsageStatsService != null) { 3082 mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(), 3083 UsageStats.Event.MOVE_TO_FOREGROUND); 3084 } 3085 synchronized (stats) { 3086 stats.noteActivityResumedLocked(component.app.uid); 3087 } 3088 } else { 3089 if (mUsageStatsService != null) { 3090 mUsageStatsService.reportEvent(component.realActivity, System.currentTimeMillis(), 3091 UsageStats.Event.MOVE_TO_BACKGROUND); 3092 } 3093 synchronized (stats) { 3094 stats.noteActivityPausedLocked(component.app.uid); 3095 } 3096 } 3097 } 3098 3099 Intent getHomeIntent() { 3100 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3101 intent.setComponent(mTopComponent); 3102 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3103 intent.addCategory(Intent.CATEGORY_HOME); 3104 } 3105 return intent; 3106 } 3107 3108 boolean startHomeActivityLocked(int userId) { 3109 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3110 && mTopAction == null) { 3111 // We are running in factory test mode, but unable to find 3112 // the factory test app, so just sit around displaying the 3113 // error message and don't try to start anything. 3114 return false; 3115 } 3116 Intent intent = getHomeIntent(); 3117 ActivityInfo aInfo = 3118 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3119 if (aInfo != null) { 3120 intent.setComponent(new ComponentName( 3121 aInfo.applicationInfo.packageName, aInfo.name)); 3122 // Don't do this if the home app is currently being 3123 // instrumented. 3124 aInfo = new ActivityInfo(aInfo); 3125 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3126 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3127 aInfo.applicationInfo.uid, true); 3128 if (app == null || app.instrumentationClass == null) { 3129 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3130 mStackSupervisor.startHomeActivity(intent, aInfo); 3131 } 3132 } 3133 3134 return true; 3135 } 3136 3137 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3138 ActivityInfo ai = null; 3139 ComponentName comp = intent.getComponent(); 3140 try { 3141 if (comp != null) { 3142 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3143 } else { 3144 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3145 intent, 3146 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3147 flags, userId); 3148 3149 if (info != null) { 3150 ai = info.activityInfo; 3151 } 3152 } 3153 } catch (RemoteException e) { 3154 // ignore 3155 } 3156 3157 return ai; 3158 } 3159 3160 /** 3161 * Starts the "new version setup screen" if appropriate. 3162 */ 3163 void startSetupActivityLocked() { 3164 // Only do this once per boot. 3165 if (mCheckedForSetup) { 3166 return; 3167 } 3168 3169 // We will show this screen if the current one is a different 3170 // version than the last one shown, and we are not running in 3171 // low-level factory test mode. 3172 final ContentResolver resolver = mContext.getContentResolver(); 3173 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3174 Settings.Global.getInt(resolver, 3175 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3176 mCheckedForSetup = true; 3177 3178 // See if we should be showing the platform update setup UI. 3179 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3180 List<ResolveInfo> ris = mContext.getPackageManager() 3181 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3182 3183 // We don't allow third party apps to replace this. 3184 ResolveInfo ri = null; 3185 for (int i=0; ris != null && i<ris.size(); i++) { 3186 if ((ris.get(i).activityInfo.applicationInfo.flags 3187 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3188 ri = ris.get(i); 3189 break; 3190 } 3191 } 3192 3193 if (ri != null) { 3194 String vers = ri.activityInfo.metaData != null 3195 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3196 : null; 3197 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3198 vers = ri.activityInfo.applicationInfo.metaData.getString( 3199 Intent.METADATA_SETUP_VERSION); 3200 } 3201 String lastVers = Settings.Secure.getString( 3202 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3203 if (vers != null && !vers.equals(lastVers)) { 3204 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3205 intent.setComponent(new ComponentName( 3206 ri.activityInfo.packageName, ri.activityInfo.name)); 3207 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3208 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3209 } 3210 } 3211 } 3212 } 3213 3214 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3215 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3216 } 3217 3218 void enforceNotIsolatedCaller(String caller) { 3219 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3220 throw new SecurityException("Isolated process not allowed to call " + caller); 3221 } 3222 } 3223 3224 @Override 3225 public int getFrontActivityScreenCompatMode() { 3226 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3227 synchronized (this) { 3228 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3229 } 3230 } 3231 3232 @Override 3233 public void setFrontActivityScreenCompatMode(int mode) { 3234 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3235 "setFrontActivityScreenCompatMode"); 3236 synchronized (this) { 3237 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3238 } 3239 } 3240 3241 @Override 3242 public int getPackageScreenCompatMode(String packageName) { 3243 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3244 synchronized (this) { 3245 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3246 } 3247 } 3248 3249 @Override 3250 public void setPackageScreenCompatMode(String packageName, int mode) { 3251 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3252 "setPackageScreenCompatMode"); 3253 synchronized (this) { 3254 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3255 } 3256 } 3257 3258 @Override 3259 public boolean getPackageAskScreenCompat(String packageName) { 3260 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3261 synchronized (this) { 3262 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3263 } 3264 } 3265 3266 @Override 3267 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3268 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3269 "setPackageAskScreenCompat"); 3270 synchronized (this) { 3271 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3272 } 3273 } 3274 3275 private void dispatchProcessesChanged() { 3276 int N; 3277 synchronized (this) { 3278 N = mPendingProcessChanges.size(); 3279 if (mActiveProcessChanges.length < N) { 3280 mActiveProcessChanges = new ProcessChangeItem[N]; 3281 } 3282 mPendingProcessChanges.toArray(mActiveProcessChanges); 3283 mAvailProcessChanges.addAll(mPendingProcessChanges); 3284 mPendingProcessChanges.clear(); 3285 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3286 } 3287 3288 int i = mProcessObservers.beginBroadcast(); 3289 while (i > 0) { 3290 i--; 3291 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3292 if (observer != null) { 3293 try { 3294 for (int j=0; j<N; j++) { 3295 ProcessChangeItem item = mActiveProcessChanges[j]; 3296 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3297 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3298 + item.pid + " uid=" + item.uid + ": " 3299 + item.foregroundActivities); 3300 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3301 item.foregroundActivities); 3302 } 3303 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3304 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3305 + item.pid + " uid=" + item.uid + ": " + item.processState); 3306 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3307 } 3308 } 3309 } catch (RemoteException e) { 3310 } 3311 } 3312 } 3313 mProcessObservers.finishBroadcast(); 3314 } 3315 3316 private void dispatchProcessDied(int pid, int uid) { 3317 int i = mProcessObservers.beginBroadcast(); 3318 while (i > 0) { 3319 i--; 3320 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3321 if (observer != null) { 3322 try { 3323 observer.onProcessDied(pid, uid); 3324 } catch (RemoteException e) { 3325 } 3326 } 3327 } 3328 mProcessObservers.finishBroadcast(); 3329 } 3330 3331 @Override 3332 public final int startActivity(IApplicationThread caller, String callingPackage, 3333 Intent intent, String resolvedType, IBinder resultTo, 3334 String resultWho, int requestCode, int startFlags, 3335 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3336 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3337 resultWho, requestCode, 3338 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3339 } 3340 3341 @Override 3342 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3343 Intent intent, String resolvedType, IBinder resultTo, 3344 String resultWho, int requestCode, int startFlags, 3345 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3346 enforceNotIsolatedCaller("startActivity"); 3347 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3348 false, ALLOW_FULL_ONLY, "startActivity", null); 3349 // TODO: Switch to user app stacks here. 3350 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3351 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3352 null, null, options, userId, null); 3353 } 3354 3355 @Override 3356 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3357 Intent intent, String resolvedType, IBinder resultTo, 3358 String resultWho, int requestCode, int startFlags, String profileFile, 3359 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3360 enforceNotIsolatedCaller("startActivityAndWait"); 3361 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3362 false, ALLOW_FULL_ONLY, "startActivityAndWait", null); 3363 WaitResult res = new WaitResult(); 3364 // TODO: Switch to user app stacks here. 3365 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3366 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3367 res, null, options, userId, null); 3368 return res; 3369 } 3370 3371 @Override 3372 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3373 Intent intent, String resolvedType, IBinder resultTo, 3374 String resultWho, int requestCode, int startFlags, Configuration config, 3375 Bundle options, int userId) { 3376 enforceNotIsolatedCaller("startActivityWithConfig"); 3377 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3378 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null); 3379 // TODO: Switch to user app stacks here. 3380 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3381 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3382 null, null, null, config, options, userId, null); 3383 return ret; 3384 } 3385 3386 @Override 3387 public int startActivityIntentSender(IApplicationThread caller, 3388 IntentSender intent, Intent fillInIntent, String resolvedType, 3389 IBinder resultTo, String resultWho, int requestCode, 3390 int flagsMask, int flagsValues, Bundle options) { 3391 enforceNotIsolatedCaller("startActivityIntentSender"); 3392 // Refuse possible leaked file descriptors 3393 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3394 throw new IllegalArgumentException("File descriptors passed in Intent"); 3395 } 3396 3397 IIntentSender sender = intent.getTarget(); 3398 if (!(sender instanceof PendingIntentRecord)) { 3399 throw new IllegalArgumentException("Bad PendingIntent object"); 3400 } 3401 3402 PendingIntentRecord pir = (PendingIntentRecord)sender; 3403 3404 synchronized (this) { 3405 // If this is coming from the currently resumed activity, it is 3406 // effectively saying that app switches are allowed at this point. 3407 final ActivityStack stack = getFocusedStack(); 3408 if (stack.mResumedActivity != null && 3409 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3410 mAppSwitchesAllowedTime = 0; 3411 } 3412 } 3413 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3414 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3415 return ret; 3416 } 3417 3418 @Override 3419 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3420 Intent intent, String resolvedType, IVoiceInteractionSession session, 3421 IVoiceInteractor interactor, int startFlags, String profileFile, 3422 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3423 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3424 != PackageManager.PERMISSION_GRANTED) { 3425 String msg = "Permission Denial: startVoiceActivity() from pid=" 3426 + Binder.getCallingPid() 3427 + ", uid=" + Binder.getCallingUid() 3428 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3429 Slog.w(TAG, msg); 3430 throw new SecurityException(msg); 3431 } 3432 if (session == null || interactor == null) { 3433 throw new NullPointerException("null session or interactor"); 3434 } 3435 userId = handleIncomingUser(callingPid, callingUid, userId, 3436 false, ALLOW_FULL_ONLY, "startVoiceActivity", null); 3437 // TODO: Switch to user app stacks here. 3438 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3439 resolvedType, session, interactor, null, null, 0, startFlags, 3440 profileFile, profileFd, null, null, options, userId, null); 3441 } 3442 3443 @Override 3444 public boolean startNextMatchingActivity(IBinder callingActivity, 3445 Intent intent, Bundle options) { 3446 // Refuse possible leaked file descriptors 3447 if (intent != null && intent.hasFileDescriptors() == true) { 3448 throw new IllegalArgumentException("File descriptors passed in Intent"); 3449 } 3450 3451 synchronized (this) { 3452 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3453 if (r == null) { 3454 ActivityOptions.abort(options); 3455 return false; 3456 } 3457 if (r.app == null || r.app.thread == null) { 3458 // The caller is not running... d'oh! 3459 ActivityOptions.abort(options); 3460 return false; 3461 } 3462 intent = new Intent(intent); 3463 // The caller is not allowed to change the data. 3464 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3465 // And we are resetting to find the next component... 3466 intent.setComponent(null); 3467 3468 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3469 3470 ActivityInfo aInfo = null; 3471 try { 3472 List<ResolveInfo> resolves = 3473 AppGlobals.getPackageManager().queryIntentActivities( 3474 intent, r.resolvedType, 3475 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3476 UserHandle.getCallingUserId()); 3477 3478 // Look for the original activity in the list... 3479 final int N = resolves != null ? resolves.size() : 0; 3480 for (int i=0; i<N; i++) { 3481 ResolveInfo rInfo = resolves.get(i); 3482 if (rInfo.activityInfo.packageName.equals(r.packageName) 3483 && rInfo.activityInfo.name.equals(r.info.name)) { 3484 // We found the current one... the next matching is 3485 // after it. 3486 i++; 3487 if (i<N) { 3488 aInfo = resolves.get(i).activityInfo; 3489 } 3490 if (debug) { 3491 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3492 + "/" + r.info.name); 3493 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3494 + "/" + aInfo.name); 3495 } 3496 break; 3497 } 3498 } 3499 } catch (RemoteException e) { 3500 } 3501 3502 if (aInfo == null) { 3503 // Nobody who is next! 3504 ActivityOptions.abort(options); 3505 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3506 return false; 3507 } 3508 3509 intent.setComponent(new ComponentName( 3510 aInfo.applicationInfo.packageName, aInfo.name)); 3511 intent.setFlags(intent.getFlags()&~( 3512 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3513 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3514 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3515 Intent.FLAG_ACTIVITY_NEW_TASK)); 3516 3517 // Okay now we need to start the new activity, replacing the 3518 // currently running activity. This is a little tricky because 3519 // we want to start the new one as if the current one is finished, 3520 // but not finish the current one first so that there is no flicker. 3521 // And thus... 3522 final boolean wasFinishing = r.finishing; 3523 r.finishing = true; 3524 3525 // Propagate reply information over to the new activity. 3526 final ActivityRecord resultTo = r.resultTo; 3527 final String resultWho = r.resultWho; 3528 final int requestCode = r.requestCode; 3529 r.resultTo = null; 3530 if (resultTo != null) { 3531 resultTo.removeResultsLocked(r, resultWho, requestCode); 3532 } 3533 3534 final long origId = Binder.clearCallingIdentity(); 3535 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3536 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3537 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3538 options, false, null, null); 3539 Binder.restoreCallingIdentity(origId); 3540 3541 r.finishing = wasFinishing; 3542 if (res != ActivityManager.START_SUCCESS) { 3543 return false; 3544 } 3545 return true; 3546 } 3547 } 3548 3549 @Override 3550 public final int startActivityFromRecents(int taskId, Bundle options) { 3551 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) { 3552 String msg = "Permission Denial: startActivityFromRecents called without " + 3553 START_TASKS_FROM_RECENTS; 3554 Slog.w(TAG, msg); 3555 throw new SecurityException(msg); 3556 } 3557 final int callingUid; 3558 final String callingPackage; 3559 final Intent intent; 3560 final int userId; 3561 synchronized (this) { 3562 final TaskRecord task = recentTaskForIdLocked(taskId); 3563 if (task == null) { 3564 throw new ActivityNotFoundException("Task " + taskId + " not found."); 3565 } 3566 callingUid = task.mCallingUid; 3567 callingPackage = task.mCallingPackage; 3568 intent = task.intent; 3569 userId = task.userId; 3570 } 3571 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0, 3572 options, userId, null); 3573 } 3574 3575 final int startActivityInPackage(int uid, String callingPackage, 3576 Intent intent, String resolvedType, IBinder resultTo, 3577 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3578 IActivityContainer container) { 3579 3580 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3581 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3582 3583 // TODO: Switch to user app stacks here. 3584 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3585 null, null, resultTo, resultWho, requestCode, startFlags, 3586 null, null, null, null, options, userId, container); 3587 return ret; 3588 } 3589 3590 @Override 3591 public final int startActivities(IApplicationThread caller, String callingPackage, 3592 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3593 int userId) { 3594 enforceNotIsolatedCaller("startActivities"); 3595 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3596 false, ALLOW_FULL_ONLY, "startActivity", null); 3597 // TODO: Switch to user app stacks here. 3598 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3599 resolvedTypes, resultTo, options, userId); 3600 return ret; 3601 } 3602 3603 final int startActivitiesInPackage(int uid, String callingPackage, 3604 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3605 Bundle options, int userId) { 3606 3607 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3608 false, ALLOW_FULL_ONLY, "startActivityInPackage", null); 3609 // TODO: Switch to user app stacks here. 3610 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3611 resultTo, options, userId); 3612 return ret; 3613 } 3614 3615 final void addRecentTaskLocked(TaskRecord task) { 3616 int N = mRecentTasks.size(); 3617 // Quick case: check if the top-most recent task is the same. 3618 if (N > 0 && mRecentTasks.get(0) == task) { 3619 return; 3620 } 3621 // Another quick case: never add voice sessions. 3622 if (task.voiceSession != null) { 3623 return; 3624 } 3625 // Remove any existing entries that are the same kind of task. 3626 final Intent intent = task.intent; 3627 final boolean document = intent != null && intent.isDocument(); 3628 final ComponentName comp = intent.getComponent(); 3629 3630 int maxRecents = task.maxRecents - 1; 3631 for (int i=0; i<N; i++) { 3632 final TaskRecord tr = mRecentTasks.get(i); 3633 if (task != tr) { 3634 if (task.userId != tr.userId) { 3635 continue; 3636 } 3637 if (i > MAX_RECENT_BITMAPS) { 3638 tr.freeLastThumbnail(); 3639 } 3640 final Intent trIntent = tr.intent; 3641 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3642 (intent == null || !intent.filterEquals(trIntent))) { 3643 continue; 3644 } 3645 final boolean trIsDocument = trIntent != null && trIntent.isDocument(); 3646 if (document && trIsDocument) { 3647 // These are the same document activity (not necessarily the same doc). 3648 if (maxRecents > 0) { 3649 --maxRecents; 3650 continue; 3651 } 3652 // Hit the maximum number of documents for this task. Fall through 3653 // and remove this document from recents. 3654 } else if (document || trIsDocument) { 3655 // Only one of these is a document. Not the droid we're looking for. 3656 continue; 3657 } 3658 } 3659 3660 // Either task and tr are the same or, their affinities match or their intents match 3661 // and neither of them is a document, or they are documents using the same activity 3662 // and their maxRecents has been reached. 3663 tr.disposeThumbnail(); 3664 mRecentTasks.remove(i); 3665 if (task != tr) { 3666 tr.closeRecentsChain(); 3667 } 3668 i--; 3669 N--; 3670 if (task.intent == null) { 3671 // If the new recent task we are adding is not fully 3672 // specified, then replace it with the existing recent task. 3673 task = tr; 3674 } 3675 mTaskPersister.notify(tr, false); 3676 } 3677 if (N >= MAX_RECENT_TASKS) { 3678 final TaskRecord tr = mRecentTasks.remove(N - 1); 3679 tr.disposeThumbnail(); 3680 tr.closeRecentsChain(); 3681 } 3682 mRecentTasks.add(0, task); 3683 } 3684 3685 @Override 3686 public void reportActivityFullyDrawn(IBinder token) { 3687 synchronized (this) { 3688 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3689 if (r == null) { 3690 return; 3691 } 3692 r.reportFullyDrawnLocked(); 3693 } 3694 } 3695 3696 @Override 3697 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3698 synchronized (this) { 3699 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3700 if (r == null) { 3701 return; 3702 } 3703 final long origId = Binder.clearCallingIdentity(); 3704 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3705 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3706 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3707 if (config != null) { 3708 r.frozenBeforeDestroy = true; 3709 if (!updateConfigurationLocked(config, r, false, false)) { 3710 mStackSupervisor.resumeTopActivitiesLocked(); 3711 } 3712 } 3713 Binder.restoreCallingIdentity(origId); 3714 } 3715 } 3716 3717 @Override 3718 public int getRequestedOrientation(IBinder token) { 3719 synchronized (this) { 3720 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3721 if (r == null) { 3722 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3723 } 3724 return mWindowManager.getAppOrientation(r.appToken); 3725 } 3726 } 3727 3728 /** 3729 * This is the internal entry point for handling Activity.finish(). 3730 * 3731 * @param token The Binder token referencing the Activity we want to finish. 3732 * @param resultCode Result code, if any, from this Activity. 3733 * @param resultData Result data (Intent), if any, from this Activity. 3734 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3735 * the root Activity in the task. 3736 * 3737 * @return Returns true if the activity successfully finished, or false if it is still running. 3738 */ 3739 @Override 3740 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3741 boolean finishTask) { 3742 // Refuse possible leaked file descriptors 3743 if (resultData != null && resultData.hasFileDescriptors() == true) { 3744 throw new IllegalArgumentException("File descriptors passed in Intent"); 3745 } 3746 3747 synchronized(this) { 3748 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3749 if (r == null) { 3750 return true; 3751 } 3752 // Keep track of the root activity of the task before we finish it 3753 TaskRecord tr = r.task; 3754 ActivityRecord rootR = tr.getRootActivity(); 3755 // Do not allow task to finish in Lock Task mode. 3756 if (tr == mStackSupervisor.mLockTaskModeTask) { 3757 if (rootR == r) { 3758 mStackSupervisor.showLockTaskToast(); 3759 return false; 3760 } 3761 } 3762 if (mController != null) { 3763 // Find the first activity that is not finishing. 3764 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3765 if (next != null) { 3766 // ask watcher if this is allowed 3767 boolean resumeOK = true; 3768 try { 3769 resumeOK = mController.activityResuming(next.packageName); 3770 } catch (RemoteException e) { 3771 mController = null; 3772 Watchdog.getInstance().setActivityController(null); 3773 } 3774 3775 if (!resumeOK) { 3776 return false; 3777 } 3778 } 3779 } 3780 final long origId = Binder.clearCallingIdentity(); 3781 try { 3782 boolean res; 3783 if (finishTask && r == rootR) { 3784 // If requested, remove the task that is associated to this activity only if it 3785 // was the root activity in the task. The result code and data is ignored because 3786 // we don't support returning them across task boundaries. 3787 res = removeTaskByIdLocked(tr.taskId, 0); 3788 } else { 3789 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3790 resultData, "app-request", true); 3791 } 3792 return res; 3793 } finally { 3794 Binder.restoreCallingIdentity(origId); 3795 } 3796 } 3797 } 3798 3799 @Override 3800 public final void finishHeavyWeightApp() { 3801 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3802 != PackageManager.PERMISSION_GRANTED) { 3803 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3804 + Binder.getCallingPid() 3805 + ", uid=" + Binder.getCallingUid() 3806 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3807 Slog.w(TAG, msg); 3808 throw new SecurityException(msg); 3809 } 3810 3811 synchronized(this) { 3812 if (mHeavyWeightProcess == null) { 3813 return; 3814 } 3815 3816 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3817 mHeavyWeightProcess.activities); 3818 for (int i=0; i<activities.size(); i++) { 3819 ActivityRecord r = activities.get(i); 3820 if (!r.finishing) { 3821 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3822 null, "finish-heavy", true); 3823 } 3824 } 3825 3826 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3827 mHeavyWeightProcess.userId, 0)); 3828 mHeavyWeightProcess = null; 3829 } 3830 } 3831 3832 @Override 3833 public void crashApplication(int uid, int initialPid, String packageName, 3834 String message) { 3835 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3836 != PackageManager.PERMISSION_GRANTED) { 3837 String msg = "Permission Denial: crashApplication() from pid=" 3838 + Binder.getCallingPid() 3839 + ", uid=" + Binder.getCallingUid() 3840 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3841 Slog.w(TAG, msg); 3842 throw new SecurityException(msg); 3843 } 3844 3845 synchronized(this) { 3846 ProcessRecord proc = null; 3847 3848 // Figure out which process to kill. We don't trust that initialPid 3849 // still has any relation to current pids, so must scan through the 3850 // list. 3851 synchronized (mPidsSelfLocked) { 3852 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3853 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3854 if (p.uid != uid) { 3855 continue; 3856 } 3857 if (p.pid == initialPid) { 3858 proc = p; 3859 break; 3860 } 3861 if (p.pkgList.containsKey(packageName)) { 3862 proc = p; 3863 } 3864 } 3865 } 3866 3867 if (proc == null) { 3868 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3869 + " initialPid=" + initialPid 3870 + " packageName=" + packageName); 3871 return; 3872 } 3873 3874 if (proc.thread != null) { 3875 if (proc.pid == Process.myPid()) { 3876 Log.w(TAG, "crashApplication: trying to crash self!"); 3877 return; 3878 } 3879 long ident = Binder.clearCallingIdentity(); 3880 try { 3881 proc.thread.scheduleCrash(message); 3882 } catch (RemoteException e) { 3883 } 3884 Binder.restoreCallingIdentity(ident); 3885 } 3886 } 3887 } 3888 3889 @Override 3890 public final void finishSubActivity(IBinder token, String resultWho, 3891 int requestCode) { 3892 synchronized(this) { 3893 final long origId = Binder.clearCallingIdentity(); 3894 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3895 if (r != null) { 3896 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3897 } 3898 Binder.restoreCallingIdentity(origId); 3899 } 3900 } 3901 3902 @Override 3903 public boolean finishActivityAffinity(IBinder token) { 3904 synchronized(this) { 3905 final long origId = Binder.clearCallingIdentity(); 3906 try { 3907 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3908 3909 ActivityRecord rootR = r.task.getRootActivity(); 3910 // Do not allow task to finish in Lock Task mode. 3911 if (r.task == mStackSupervisor.mLockTaskModeTask) { 3912 if (rootR == r) { 3913 mStackSupervisor.showLockTaskToast(); 3914 return false; 3915 } 3916 } 3917 boolean res = false; 3918 if (r != null) { 3919 res = r.task.stack.finishActivityAffinityLocked(r); 3920 } 3921 return res; 3922 } finally { 3923 Binder.restoreCallingIdentity(origId); 3924 } 3925 } 3926 } 3927 3928 @Override 3929 public void finishVoiceTask(IVoiceInteractionSession session) { 3930 synchronized(this) { 3931 final long origId = Binder.clearCallingIdentity(); 3932 try { 3933 mStackSupervisor.finishVoiceTask(session); 3934 } finally { 3935 Binder.restoreCallingIdentity(origId); 3936 } 3937 } 3938 3939 } 3940 3941 @Override 3942 public boolean willActivityBeVisible(IBinder token) { 3943 synchronized(this) { 3944 ActivityStack stack = ActivityRecord.getStackLocked(token); 3945 if (stack != null) { 3946 return stack.willActivityBeVisibleLocked(token); 3947 } 3948 return false; 3949 } 3950 } 3951 3952 @Override 3953 public void overridePendingTransition(IBinder token, String packageName, 3954 int enterAnim, int exitAnim) { 3955 synchronized(this) { 3956 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3957 if (self == null) { 3958 return; 3959 } 3960 3961 final long origId = Binder.clearCallingIdentity(); 3962 3963 if (self.state == ActivityState.RESUMED 3964 || self.state == ActivityState.PAUSING) { 3965 mWindowManager.overridePendingAppTransition(packageName, 3966 enterAnim, exitAnim, null); 3967 } 3968 3969 Binder.restoreCallingIdentity(origId); 3970 } 3971 } 3972 3973 /** 3974 * Main function for removing an existing process from the activity manager 3975 * as a result of that process going away. Clears out all connections 3976 * to the process. 3977 */ 3978 private final void handleAppDiedLocked(ProcessRecord app, 3979 boolean restarting, boolean allowRestart) { 3980 int pid = app.pid; 3981 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3982 if (!restarting) { 3983 removeLruProcessLocked(app); 3984 if (pid > 0) { 3985 ProcessList.remove(pid); 3986 } 3987 } 3988 3989 if (mProfileProc == app) { 3990 clearProfilerLocked(); 3991 } 3992 3993 // Remove this application's activities from active lists. 3994 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3995 3996 app.activities.clear(); 3997 3998 if (app.instrumentationClass != null) { 3999 Slog.w(TAG, "Crash of app " + app.processName 4000 + " running instrumentation " + app.instrumentationClass); 4001 Bundle info = new Bundle(); 4002 info.putString("shortMsg", "Process crashed."); 4003 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 4004 } 4005 4006 if (!restarting) { 4007 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 4008 // If there was nothing to resume, and we are not already 4009 // restarting this process, but there is a visible activity that 4010 // is hosted by the process... then make sure all visible 4011 // activities are running, taking care of restarting this 4012 // process. 4013 if (hasVisibleActivities) { 4014 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 4015 } 4016 } 4017 } 4018 } 4019 4020 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 4021 IBinder threadBinder = thread.asBinder(); 4022 // Find the application record. 4023 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4024 ProcessRecord rec = mLruProcesses.get(i); 4025 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 4026 return i; 4027 } 4028 } 4029 return -1; 4030 } 4031 4032 final ProcessRecord getRecordForAppLocked( 4033 IApplicationThread thread) { 4034 if (thread == null) { 4035 return null; 4036 } 4037 4038 int appIndex = getLRURecordIndexForAppLocked(thread); 4039 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 4040 } 4041 4042 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 4043 // If there are no longer any background processes running, 4044 // and the app that died was not running instrumentation, 4045 // then tell everyone we are now low on memory. 4046 boolean haveBg = false; 4047 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4048 ProcessRecord rec = mLruProcesses.get(i); 4049 if (rec.thread != null 4050 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 4051 haveBg = true; 4052 break; 4053 } 4054 } 4055 4056 if (!haveBg) { 4057 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 4058 if (doReport) { 4059 long now = SystemClock.uptimeMillis(); 4060 if (now < (mLastMemUsageReportTime+5*60*1000)) { 4061 doReport = false; 4062 } else { 4063 mLastMemUsageReportTime = now; 4064 } 4065 } 4066 final ArrayList<ProcessMemInfo> memInfos 4067 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 4068 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 4069 long now = SystemClock.uptimeMillis(); 4070 for (int i=mLruProcesses.size()-1; i>=0; i--) { 4071 ProcessRecord rec = mLruProcesses.get(i); 4072 if (rec == dyingProc || rec.thread == null) { 4073 continue; 4074 } 4075 if (doReport) { 4076 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 4077 rec.setProcState, rec.adjType, rec.makeAdjReason())); 4078 } 4079 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 4080 // The low memory report is overriding any current 4081 // state for a GC request. Make sure to do 4082 // heavy/important/visible/foreground processes first. 4083 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 4084 rec.lastRequestedGc = 0; 4085 } else { 4086 rec.lastRequestedGc = rec.lastLowMemory; 4087 } 4088 rec.reportLowMemory = true; 4089 rec.lastLowMemory = now; 4090 mProcessesToGc.remove(rec); 4091 addProcessToGcListLocked(rec); 4092 } 4093 } 4094 if (doReport) { 4095 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 4096 mHandler.sendMessage(msg); 4097 } 4098 scheduleAppGcsLocked(); 4099 } 4100 } 4101 4102 final void appDiedLocked(ProcessRecord app, int pid, 4103 IApplicationThread thread) { 4104 4105 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 4106 synchronized (stats) { 4107 stats.noteProcessDiedLocked(app.info.uid, pid); 4108 } 4109 4110 Process.killProcessGroup(app.info.uid, pid); 4111 4112 // Clean up already done if the process has been re-started. 4113 if (app.pid == pid && app.thread != null && 4114 app.thread.asBinder() == thread.asBinder()) { 4115 boolean doLowMem = app.instrumentationClass == null; 4116 boolean doOomAdj = doLowMem; 4117 if (!app.killedByAm) { 4118 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4119 + ") has died."); 4120 mAllowLowerMemLevel = true; 4121 } else { 4122 // Note that we always want to do oom adj to update our state with the 4123 // new number of procs. 4124 mAllowLowerMemLevel = false; 4125 doLowMem = false; 4126 } 4127 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4128 if (DEBUG_CLEANUP) Slog.v( 4129 TAG, "Dying app: " + app + ", pid: " + pid 4130 + ", thread: " + thread.asBinder()); 4131 handleAppDiedLocked(app, false, true); 4132 4133 if (doOomAdj) { 4134 updateOomAdjLocked(); 4135 } 4136 if (doLowMem) { 4137 doLowMemReportIfNeededLocked(app); 4138 } 4139 } else if (app.pid != pid) { 4140 // A new process has already been started. 4141 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 4142 + ") has died and restarted (pid " + app.pid + ")."); 4143 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 4144 } else if (DEBUG_PROCESSES) { 4145 Slog.d(TAG, "Received spurious death notification for thread " 4146 + thread.asBinder()); 4147 } 4148 } 4149 4150 /** 4151 * If a stack trace dump file is configured, dump process stack traces. 4152 * @param clearTraces causes the dump file to be erased prior to the new 4153 * traces being written, if true; when false, the new traces will be 4154 * appended to any existing file content. 4155 * @param firstPids of dalvik VM processes to dump stack traces for first 4156 * @param lastPids of dalvik VM processes to dump stack traces for last 4157 * @param nativeProcs optional list of native process names to dump stack crawls 4158 * @return file containing stack traces, or null if no dump file is configured 4159 */ 4160 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4161 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4162 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4163 if (tracesPath == null || tracesPath.length() == 0) { 4164 return null; 4165 } 4166 4167 File tracesFile = new File(tracesPath); 4168 try { 4169 File tracesDir = tracesFile.getParentFile(); 4170 if (!tracesDir.exists()) { 4171 tracesFile.mkdirs(); 4172 if (!SELinux.restorecon(tracesDir)) { 4173 return null; 4174 } 4175 } 4176 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4177 4178 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4179 tracesFile.createNewFile(); 4180 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4181 } catch (IOException e) { 4182 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4183 return null; 4184 } 4185 4186 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4187 return tracesFile; 4188 } 4189 4190 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4191 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4192 // Use a FileObserver to detect when traces finish writing. 4193 // The order of traces is considered important to maintain for legibility. 4194 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4195 @Override 4196 public synchronized void onEvent(int event, String path) { notify(); } 4197 }; 4198 4199 try { 4200 observer.startWatching(); 4201 4202 // First collect all of the stacks of the most important pids. 4203 if (firstPids != null) { 4204 try { 4205 int num = firstPids.size(); 4206 for (int i = 0; i < num; i++) { 4207 synchronized (observer) { 4208 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4209 observer.wait(200); // Wait for write-close, give up after 200msec 4210 } 4211 } 4212 } catch (InterruptedException e) { 4213 Log.wtf(TAG, e); 4214 } 4215 } 4216 4217 // Next collect the stacks of the native pids 4218 if (nativeProcs != null) { 4219 int[] pids = Process.getPidsForCommands(nativeProcs); 4220 if (pids != null) { 4221 for (int pid : pids) { 4222 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4223 } 4224 } 4225 } 4226 4227 // Lastly, measure CPU usage. 4228 if (processCpuTracker != null) { 4229 processCpuTracker.init(); 4230 System.gc(); 4231 processCpuTracker.update(); 4232 try { 4233 synchronized (processCpuTracker) { 4234 processCpuTracker.wait(500); // measure over 1/2 second. 4235 } 4236 } catch (InterruptedException e) { 4237 } 4238 processCpuTracker.update(); 4239 4240 // We'll take the stack crawls of just the top apps using CPU. 4241 final int N = processCpuTracker.countWorkingStats(); 4242 int numProcs = 0; 4243 for (int i=0; i<N && numProcs<5; i++) { 4244 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4245 if (lastPids.indexOfKey(stats.pid) >= 0) { 4246 numProcs++; 4247 try { 4248 synchronized (observer) { 4249 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4250 observer.wait(200); // Wait for write-close, give up after 200msec 4251 } 4252 } catch (InterruptedException e) { 4253 Log.wtf(TAG, e); 4254 } 4255 4256 } 4257 } 4258 } 4259 } finally { 4260 observer.stopWatching(); 4261 } 4262 } 4263 4264 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4265 if (true || IS_USER_BUILD) { 4266 return; 4267 } 4268 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4269 if (tracesPath == null || tracesPath.length() == 0) { 4270 return; 4271 } 4272 4273 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4274 StrictMode.allowThreadDiskWrites(); 4275 try { 4276 final File tracesFile = new File(tracesPath); 4277 final File tracesDir = tracesFile.getParentFile(); 4278 final File tracesTmp = new File(tracesDir, "__tmp__"); 4279 try { 4280 if (!tracesDir.exists()) { 4281 tracesFile.mkdirs(); 4282 if (!SELinux.restorecon(tracesDir.getPath())) { 4283 return; 4284 } 4285 } 4286 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4287 4288 if (tracesFile.exists()) { 4289 tracesTmp.delete(); 4290 tracesFile.renameTo(tracesTmp); 4291 } 4292 StringBuilder sb = new StringBuilder(); 4293 Time tobj = new Time(); 4294 tobj.set(System.currentTimeMillis()); 4295 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4296 sb.append(": "); 4297 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4298 sb.append(" since "); 4299 sb.append(msg); 4300 FileOutputStream fos = new FileOutputStream(tracesFile); 4301 fos.write(sb.toString().getBytes()); 4302 if (app == null) { 4303 fos.write("\n*** No application process!".getBytes()); 4304 } 4305 fos.close(); 4306 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4307 } catch (IOException e) { 4308 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4309 return; 4310 } 4311 4312 if (app != null) { 4313 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4314 firstPids.add(app.pid); 4315 dumpStackTraces(tracesPath, firstPids, null, null, null); 4316 } 4317 4318 File lastTracesFile = null; 4319 File curTracesFile = null; 4320 for (int i=9; i>=0; i--) { 4321 String name = String.format(Locale.US, "slow%02d.txt", i); 4322 curTracesFile = new File(tracesDir, name); 4323 if (curTracesFile.exists()) { 4324 if (lastTracesFile != null) { 4325 curTracesFile.renameTo(lastTracesFile); 4326 } else { 4327 curTracesFile.delete(); 4328 } 4329 } 4330 lastTracesFile = curTracesFile; 4331 } 4332 tracesFile.renameTo(curTracesFile); 4333 if (tracesTmp.exists()) { 4334 tracesTmp.renameTo(tracesFile); 4335 } 4336 } finally { 4337 StrictMode.setThreadPolicy(oldPolicy); 4338 } 4339 } 4340 4341 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4342 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4343 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4344 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4345 4346 if (mController != null) { 4347 try { 4348 // 0 == continue, -1 = kill process immediately 4349 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4350 if (res < 0 && app.pid != MY_PID) { 4351 Process.killProcess(app.pid); 4352 Process.killProcessGroup(app.info.uid, app.pid); 4353 } 4354 } catch (RemoteException e) { 4355 mController = null; 4356 Watchdog.getInstance().setActivityController(null); 4357 } 4358 } 4359 4360 long anrTime = SystemClock.uptimeMillis(); 4361 if (MONITOR_CPU_USAGE) { 4362 updateCpuStatsNow(); 4363 } 4364 4365 synchronized (this) { 4366 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4367 if (mShuttingDown) { 4368 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4369 return; 4370 } else if (app.notResponding) { 4371 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4372 return; 4373 } else if (app.crashing) { 4374 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4375 return; 4376 } 4377 4378 // In case we come through here for the same app before completing 4379 // this one, mark as anring now so we will bail out. 4380 app.notResponding = true; 4381 4382 // Log the ANR to the event log. 4383 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4384 app.processName, app.info.flags, annotation); 4385 4386 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4387 firstPids.add(app.pid); 4388 4389 int parentPid = app.pid; 4390 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4391 if (parentPid != app.pid) firstPids.add(parentPid); 4392 4393 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4394 4395 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4396 ProcessRecord r = mLruProcesses.get(i); 4397 if (r != null && r.thread != null) { 4398 int pid = r.pid; 4399 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4400 if (r.persistent) { 4401 firstPids.add(pid); 4402 } else { 4403 lastPids.put(pid, Boolean.TRUE); 4404 } 4405 } 4406 } 4407 } 4408 } 4409 4410 // Log the ANR to the main log. 4411 StringBuilder info = new StringBuilder(); 4412 info.setLength(0); 4413 info.append("ANR in ").append(app.processName); 4414 if (activity != null && activity.shortComponentName != null) { 4415 info.append(" (").append(activity.shortComponentName).append(")"); 4416 } 4417 info.append("\n"); 4418 info.append("PID: ").append(app.pid).append("\n"); 4419 if (annotation != null) { 4420 info.append("Reason: ").append(annotation).append("\n"); 4421 } 4422 if (parent != null && parent != activity) { 4423 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4424 } 4425 4426 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4427 4428 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4429 NATIVE_STACKS_OF_INTEREST); 4430 4431 String cpuInfo = null; 4432 if (MONITOR_CPU_USAGE) { 4433 updateCpuStatsNow(); 4434 synchronized (mProcessCpuThread) { 4435 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4436 } 4437 info.append(processCpuTracker.printCurrentLoad()); 4438 info.append(cpuInfo); 4439 } 4440 4441 info.append(processCpuTracker.printCurrentState(anrTime)); 4442 4443 Slog.e(TAG, info.toString()); 4444 if (tracesFile == null) { 4445 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4446 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4447 } 4448 4449 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4450 cpuInfo, tracesFile, null); 4451 4452 if (mController != null) { 4453 try { 4454 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4455 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4456 if (res != 0) { 4457 if (res < 0 && app.pid != MY_PID) { 4458 Process.killProcess(app.pid); 4459 Process.killProcessGroup(app.info.uid, app.pid); 4460 } else { 4461 synchronized (this) { 4462 mServices.scheduleServiceTimeoutLocked(app); 4463 } 4464 } 4465 return; 4466 } 4467 } catch (RemoteException e) { 4468 mController = null; 4469 Watchdog.getInstance().setActivityController(null); 4470 } 4471 } 4472 4473 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4474 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4475 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4476 4477 synchronized (this) { 4478 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4479 killUnneededProcessLocked(app, "background ANR"); 4480 return; 4481 } 4482 4483 // Set the app's notResponding state, and look up the errorReportReceiver 4484 makeAppNotRespondingLocked(app, 4485 activity != null ? activity.shortComponentName : null, 4486 annotation != null ? "ANR " + annotation : "ANR", 4487 info.toString()); 4488 4489 // Bring up the infamous App Not Responding dialog 4490 Message msg = Message.obtain(); 4491 HashMap<String, Object> map = new HashMap<String, Object>(); 4492 msg.what = SHOW_NOT_RESPONDING_MSG; 4493 msg.obj = map; 4494 msg.arg1 = aboveSystem ? 1 : 0; 4495 map.put("app", app); 4496 if (activity != null) { 4497 map.put("activity", activity); 4498 } 4499 4500 mHandler.sendMessage(msg); 4501 } 4502 } 4503 4504 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4505 if (!mLaunchWarningShown) { 4506 mLaunchWarningShown = true; 4507 mHandler.post(new Runnable() { 4508 @Override 4509 public void run() { 4510 synchronized (ActivityManagerService.this) { 4511 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4512 d.show(); 4513 mHandler.postDelayed(new Runnable() { 4514 @Override 4515 public void run() { 4516 synchronized (ActivityManagerService.this) { 4517 d.dismiss(); 4518 mLaunchWarningShown = false; 4519 } 4520 } 4521 }, 4000); 4522 } 4523 } 4524 }); 4525 } 4526 } 4527 4528 @Override 4529 public boolean clearApplicationUserData(final String packageName, 4530 final IPackageDataObserver observer, int userId) { 4531 enforceNotIsolatedCaller("clearApplicationUserData"); 4532 int uid = Binder.getCallingUid(); 4533 int pid = Binder.getCallingPid(); 4534 userId = handleIncomingUser(pid, uid, 4535 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null); 4536 long callingId = Binder.clearCallingIdentity(); 4537 try { 4538 IPackageManager pm = AppGlobals.getPackageManager(); 4539 int pkgUid = -1; 4540 synchronized(this) { 4541 try { 4542 pkgUid = pm.getPackageUid(packageName, userId); 4543 } catch (RemoteException e) { 4544 } 4545 if (pkgUid == -1) { 4546 Slog.w(TAG, "Invalid packageName: " + packageName); 4547 if (observer != null) { 4548 try { 4549 observer.onRemoveCompleted(packageName, false); 4550 } catch (RemoteException e) { 4551 Slog.i(TAG, "Observer no longer exists."); 4552 } 4553 } 4554 return false; 4555 } 4556 if (uid == pkgUid || checkComponentPermission( 4557 android.Manifest.permission.CLEAR_APP_USER_DATA, 4558 pid, uid, -1, true) 4559 == PackageManager.PERMISSION_GRANTED) { 4560 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4561 } else { 4562 throw new SecurityException("PID " + pid + " does not have permission " 4563 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4564 + " of package " + packageName); 4565 } 4566 } 4567 4568 try { 4569 // Clear application user data 4570 pm.clearApplicationUserData(packageName, observer, userId); 4571 4572 // Remove all permissions granted from/to this package 4573 removeUriPermissionsForPackageLocked(packageName, userId, true); 4574 4575 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4576 Uri.fromParts("package", packageName, null)); 4577 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4578 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4579 null, null, 0, null, null, null, false, false, userId); 4580 } catch (RemoteException e) { 4581 } 4582 } finally { 4583 Binder.restoreCallingIdentity(callingId); 4584 } 4585 return true; 4586 } 4587 4588 @Override 4589 public void killBackgroundProcesses(final String packageName, int userId) { 4590 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4591 != PackageManager.PERMISSION_GRANTED && 4592 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4593 != PackageManager.PERMISSION_GRANTED) { 4594 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4595 + Binder.getCallingPid() 4596 + ", uid=" + Binder.getCallingUid() 4597 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4598 Slog.w(TAG, msg); 4599 throw new SecurityException(msg); 4600 } 4601 4602 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4603 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null); 4604 long callingId = Binder.clearCallingIdentity(); 4605 try { 4606 IPackageManager pm = AppGlobals.getPackageManager(); 4607 synchronized(this) { 4608 int appId = -1; 4609 try { 4610 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4611 } catch (RemoteException e) { 4612 } 4613 if (appId == -1) { 4614 Slog.w(TAG, "Invalid packageName: " + packageName); 4615 return; 4616 } 4617 killPackageProcessesLocked(packageName, appId, userId, 4618 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4619 } 4620 } finally { 4621 Binder.restoreCallingIdentity(callingId); 4622 } 4623 } 4624 4625 @Override 4626 public void killAllBackgroundProcesses() { 4627 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4628 != PackageManager.PERMISSION_GRANTED) { 4629 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4630 + Binder.getCallingPid() 4631 + ", uid=" + Binder.getCallingUid() 4632 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4633 Slog.w(TAG, msg); 4634 throw new SecurityException(msg); 4635 } 4636 4637 long callingId = Binder.clearCallingIdentity(); 4638 try { 4639 synchronized(this) { 4640 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4641 final int NP = mProcessNames.getMap().size(); 4642 for (int ip=0; ip<NP; ip++) { 4643 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4644 final int NA = apps.size(); 4645 for (int ia=0; ia<NA; ia++) { 4646 ProcessRecord app = apps.valueAt(ia); 4647 if (app.persistent) { 4648 // we don't kill persistent processes 4649 continue; 4650 } 4651 if (app.removed) { 4652 procs.add(app); 4653 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4654 app.removed = true; 4655 procs.add(app); 4656 } 4657 } 4658 } 4659 4660 int N = procs.size(); 4661 for (int i=0; i<N; i++) { 4662 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4663 } 4664 mAllowLowerMemLevel = true; 4665 updateOomAdjLocked(); 4666 doLowMemReportIfNeededLocked(null); 4667 } 4668 } finally { 4669 Binder.restoreCallingIdentity(callingId); 4670 } 4671 } 4672 4673 @Override 4674 public void forceStopPackage(final String packageName, int userId) { 4675 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4676 != PackageManager.PERMISSION_GRANTED) { 4677 String msg = "Permission Denial: forceStopPackage() from pid=" 4678 + Binder.getCallingPid() 4679 + ", uid=" + Binder.getCallingUid() 4680 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4681 Slog.w(TAG, msg); 4682 throw new SecurityException(msg); 4683 } 4684 final int callingPid = Binder.getCallingPid(); 4685 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4686 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null); 4687 long callingId = Binder.clearCallingIdentity(); 4688 try { 4689 IPackageManager pm = AppGlobals.getPackageManager(); 4690 synchronized(this) { 4691 int[] users = userId == UserHandle.USER_ALL 4692 ? getUsersLocked() : new int[] { userId }; 4693 for (int user : users) { 4694 int pkgUid = -1; 4695 try { 4696 pkgUid = pm.getPackageUid(packageName, user); 4697 } catch (RemoteException e) { 4698 } 4699 if (pkgUid == -1) { 4700 Slog.w(TAG, "Invalid packageName: " + packageName); 4701 continue; 4702 } 4703 try { 4704 pm.setPackageStoppedState(packageName, true, user); 4705 } catch (RemoteException e) { 4706 } catch (IllegalArgumentException e) { 4707 Slog.w(TAG, "Failed trying to unstop package " 4708 + packageName + ": " + e); 4709 } 4710 if (isUserRunningLocked(user, false)) { 4711 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4712 } 4713 } 4714 } 4715 } finally { 4716 Binder.restoreCallingIdentity(callingId); 4717 } 4718 } 4719 4720 @Override 4721 public void addPackageDependency(String packageName) { 4722 synchronized (this) { 4723 int callingPid = Binder.getCallingPid(); 4724 if (callingPid == Process.myPid()) { 4725 // Yeah, um, no. 4726 Slog.w(TAG, "Can't addPackageDependency on system process"); 4727 return; 4728 } 4729 ProcessRecord proc; 4730 synchronized (mPidsSelfLocked) { 4731 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 4732 } 4733 if (proc != null) { 4734 if (proc.pkgDeps == null) { 4735 proc.pkgDeps = new ArraySet<String>(1); 4736 } 4737 proc.pkgDeps.add(packageName); 4738 } 4739 } 4740 } 4741 4742 /* 4743 * The pkg name and app id have to be specified. 4744 */ 4745 @Override 4746 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4747 if (pkg == null) { 4748 return; 4749 } 4750 // Make sure the uid is valid. 4751 if (appid < 0) { 4752 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4753 return; 4754 } 4755 int callerUid = Binder.getCallingUid(); 4756 // Only the system server can kill an application 4757 if (callerUid == Process.SYSTEM_UID) { 4758 // Post an aysnc message to kill the application 4759 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4760 msg.arg1 = appid; 4761 msg.arg2 = 0; 4762 Bundle bundle = new Bundle(); 4763 bundle.putString("pkg", pkg); 4764 bundle.putString("reason", reason); 4765 msg.obj = bundle; 4766 mHandler.sendMessage(msg); 4767 } else { 4768 throw new SecurityException(callerUid + " cannot kill pkg: " + 4769 pkg); 4770 } 4771 } 4772 4773 @Override 4774 public void closeSystemDialogs(String reason) { 4775 enforceNotIsolatedCaller("closeSystemDialogs"); 4776 4777 final int pid = Binder.getCallingPid(); 4778 final int uid = Binder.getCallingUid(); 4779 final long origId = Binder.clearCallingIdentity(); 4780 try { 4781 synchronized (this) { 4782 // Only allow this from foreground processes, so that background 4783 // applications can't abuse it to prevent system UI from being shown. 4784 if (uid >= Process.FIRST_APPLICATION_UID) { 4785 ProcessRecord proc; 4786 synchronized (mPidsSelfLocked) { 4787 proc = mPidsSelfLocked.get(pid); 4788 } 4789 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4790 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4791 + " from background process " + proc); 4792 return; 4793 } 4794 } 4795 closeSystemDialogsLocked(reason); 4796 } 4797 } finally { 4798 Binder.restoreCallingIdentity(origId); 4799 } 4800 } 4801 4802 void closeSystemDialogsLocked(String reason) { 4803 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4804 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4805 | Intent.FLAG_RECEIVER_FOREGROUND); 4806 if (reason != null) { 4807 intent.putExtra("reason", reason); 4808 } 4809 mWindowManager.closeSystemDialogs(reason); 4810 4811 mStackSupervisor.closeSystemDialogsLocked(); 4812 4813 broadcastIntentLocked(null, null, intent, null, 4814 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4815 Process.SYSTEM_UID, UserHandle.USER_ALL); 4816 } 4817 4818 @Override 4819 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4820 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4821 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4822 for (int i=pids.length-1; i>=0; i--) { 4823 ProcessRecord proc; 4824 int oomAdj; 4825 synchronized (this) { 4826 synchronized (mPidsSelfLocked) { 4827 proc = mPidsSelfLocked.get(pids[i]); 4828 oomAdj = proc != null ? proc.setAdj : 0; 4829 } 4830 } 4831 infos[i] = new Debug.MemoryInfo(); 4832 Debug.getMemoryInfo(pids[i], infos[i]); 4833 if (proc != null) { 4834 synchronized (this) { 4835 if (proc.thread != null && proc.setAdj == oomAdj) { 4836 // Record this for posterity if the process has been stable. 4837 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4838 infos[i].getTotalUss(), false, proc.pkgList); 4839 } 4840 } 4841 } 4842 } 4843 return infos; 4844 } 4845 4846 @Override 4847 public long[] getProcessPss(int[] pids) { 4848 enforceNotIsolatedCaller("getProcessPss"); 4849 long[] pss = new long[pids.length]; 4850 for (int i=pids.length-1; i>=0; i--) { 4851 ProcessRecord proc; 4852 int oomAdj; 4853 synchronized (this) { 4854 synchronized (mPidsSelfLocked) { 4855 proc = mPidsSelfLocked.get(pids[i]); 4856 oomAdj = proc != null ? proc.setAdj : 0; 4857 } 4858 } 4859 long[] tmpUss = new long[1]; 4860 pss[i] = Debug.getPss(pids[i], tmpUss); 4861 if (proc != null) { 4862 synchronized (this) { 4863 if (proc.thread != null && proc.setAdj == oomAdj) { 4864 // Record this for posterity if the process has been stable. 4865 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4866 } 4867 } 4868 } 4869 } 4870 return pss; 4871 } 4872 4873 @Override 4874 public void killApplicationProcess(String processName, int uid) { 4875 if (processName == null) { 4876 return; 4877 } 4878 4879 int callerUid = Binder.getCallingUid(); 4880 // Only the system server can kill an application 4881 if (callerUid == Process.SYSTEM_UID) { 4882 synchronized (this) { 4883 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4884 if (app != null && app.thread != null) { 4885 try { 4886 app.thread.scheduleSuicide(); 4887 } catch (RemoteException e) { 4888 // If the other end already died, then our work here is done. 4889 } 4890 } else { 4891 Slog.w(TAG, "Process/uid not found attempting kill of " 4892 + processName + " / " + uid); 4893 } 4894 } 4895 } else { 4896 throw new SecurityException(callerUid + " cannot kill app process: " + 4897 processName); 4898 } 4899 } 4900 4901 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4902 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4903 false, true, false, false, UserHandle.getUserId(uid), reason); 4904 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4905 Uri.fromParts("package", packageName, null)); 4906 if (!mProcessesReady) { 4907 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4908 | Intent.FLAG_RECEIVER_FOREGROUND); 4909 } 4910 intent.putExtra(Intent.EXTRA_UID, uid); 4911 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4912 broadcastIntentLocked(null, null, intent, 4913 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4914 false, false, 4915 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4916 } 4917 4918 private void forceStopUserLocked(int userId, String reason) { 4919 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4920 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4921 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4922 | Intent.FLAG_RECEIVER_FOREGROUND); 4923 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4924 broadcastIntentLocked(null, null, intent, 4925 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4926 false, false, 4927 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4928 } 4929 4930 private final boolean killPackageProcessesLocked(String packageName, int appId, 4931 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4932 boolean doit, boolean evenPersistent, String reason) { 4933 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4934 4935 // Remove all processes this package may have touched: all with the 4936 // same UID (except for the system or root user), and all whose name 4937 // matches the package name. 4938 final int NP = mProcessNames.getMap().size(); 4939 for (int ip=0; ip<NP; ip++) { 4940 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4941 final int NA = apps.size(); 4942 for (int ia=0; ia<NA; ia++) { 4943 ProcessRecord app = apps.valueAt(ia); 4944 if (app.persistent && !evenPersistent) { 4945 // we don't kill persistent processes 4946 continue; 4947 } 4948 if (app.removed) { 4949 if (doit) { 4950 procs.add(app); 4951 } 4952 continue; 4953 } 4954 4955 // Skip process if it doesn't meet our oom adj requirement. 4956 if (app.setAdj < minOomAdj) { 4957 continue; 4958 } 4959 4960 // If no package is specified, we call all processes under the 4961 // give user id. 4962 if (packageName == null) { 4963 if (app.userId != userId) { 4964 continue; 4965 } 4966 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4967 continue; 4968 } 4969 // Package has been specified, we want to hit all processes 4970 // that match it. We need to qualify this by the processes 4971 // that are running under the specified app and user ID. 4972 } else { 4973 final boolean isDep = app.pkgDeps != null 4974 && app.pkgDeps.contains(packageName); 4975 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 4976 continue; 4977 } 4978 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4979 continue; 4980 } 4981 if (!app.pkgList.containsKey(packageName) && !isDep) { 4982 continue; 4983 } 4984 } 4985 4986 // Process has passed all conditions, kill it! 4987 if (!doit) { 4988 return true; 4989 } 4990 app.removed = true; 4991 procs.add(app); 4992 } 4993 } 4994 4995 int N = procs.size(); 4996 for (int i=0; i<N; i++) { 4997 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4998 } 4999 updateOomAdjLocked(); 5000 return N > 0; 5001 } 5002 5003 private final boolean forceStopPackageLocked(String name, int appId, 5004 boolean callerWillRestart, boolean purgeCache, boolean doit, 5005 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 5006 int i; 5007 int N; 5008 5009 if (userId == UserHandle.USER_ALL && name == null) { 5010 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 5011 } 5012 5013 if (appId < 0 && name != null) { 5014 try { 5015 appId = UserHandle.getAppId( 5016 AppGlobals.getPackageManager().getPackageUid(name, 0)); 5017 } catch (RemoteException e) { 5018 } 5019 } 5020 5021 if (doit) { 5022 if (name != null) { 5023 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 5024 + " user=" + userId + ": " + reason); 5025 } else { 5026 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 5027 } 5028 5029 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 5030 for (int ip=pmap.size()-1; ip>=0; ip--) { 5031 SparseArray<Long> ba = pmap.valueAt(ip); 5032 for (i=ba.size()-1; i>=0; i--) { 5033 boolean remove = false; 5034 final int entUid = ba.keyAt(i); 5035 if (name != null) { 5036 if (userId == UserHandle.USER_ALL) { 5037 if (UserHandle.getAppId(entUid) == appId) { 5038 remove = true; 5039 } 5040 } else { 5041 if (entUid == UserHandle.getUid(userId, appId)) { 5042 remove = true; 5043 } 5044 } 5045 } else if (UserHandle.getUserId(entUid) == userId) { 5046 remove = true; 5047 } 5048 if (remove) { 5049 ba.removeAt(i); 5050 } 5051 } 5052 if (ba.size() == 0) { 5053 pmap.removeAt(ip); 5054 } 5055 } 5056 } 5057 5058 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 5059 -100, callerWillRestart, true, doit, evenPersistent, 5060 name == null ? ("stop user " + userId) : ("stop " + name)); 5061 5062 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 5063 if (!doit) { 5064 return true; 5065 } 5066 didSomething = true; 5067 } 5068 5069 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 5070 if (!doit) { 5071 return true; 5072 } 5073 didSomething = true; 5074 } 5075 5076 if (name == null) { 5077 // Remove all sticky broadcasts from this user. 5078 mStickyBroadcasts.remove(userId); 5079 } 5080 5081 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 5082 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 5083 userId, providers)) { 5084 if (!doit) { 5085 return true; 5086 } 5087 didSomething = true; 5088 } 5089 N = providers.size(); 5090 for (i=0; i<N; i++) { 5091 removeDyingProviderLocked(null, providers.get(i), true); 5092 } 5093 5094 // Remove transient permissions granted from/to this package/user 5095 removeUriPermissionsForPackageLocked(name, userId, false); 5096 5097 if (name == null || uninstalling) { 5098 // Remove pending intents. For now we only do this when force 5099 // stopping users, because we have some problems when doing this 5100 // for packages -- app widgets are not currently cleaned up for 5101 // such packages, so they can be left with bad pending intents. 5102 if (mIntentSenderRecords.size() > 0) { 5103 Iterator<WeakReference<PendingIntentRecord>> it 5104 = mIntentSenderRecords.values().iterator(); 5105 while (it.hasNext()) { 5106 WeakReference<PendingIntentRecord> wpir = it.next(); 5107 if (wpir == null) { 5108 it.remove(); 5109 continue; 5110 } 5111 PendingIntentRecord pir = wpir.get(); 5112 if (pir == null) { 5113 it.remove(); 5114 continue; 5115 } 5116 if (name == null) { 5117 // Stopping user, remove all objects for the user. 5118 if (pir.key.userId != userId) { 5119 // Not the same user, skip it. 5120 continue; 5121 } 5122 } else { 5123 if (UserHandle.getAppId(pir.uid) != appId) { 5124 // Different app id, skip it. 5125 continue; 5126 } 5127 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 5128 // Different user, skip it. 5129 continue; 5130 } 5131 if (!pir.key.packageName.equals(name)) { 5132 // Different package, skip it. 5133 continue; 5134 } 5135 } 5136 if (!doit) { 5137 return true; 5138 } 5139 didSomething = true; 5140 it.remove(); 5141 pir.canceled = true; 5142 if (pir.key.activity != null) { 5143 pir.key.activity.pendingResults.remove(pir.ref); 5144 } 5145 } 5146 } 5147 } 5148 5149 if (doit) { 5150 if (purgeCache && name != null) { 5151 AttributeCache ac = AttributeCache.instance(); 5152 if (ac != null) { 5153 ac.removePackage(name); 5154 } 5155 } 5156 if (mBooted) { 5157 mStackSupervisor.resumeTopActivitiesLocked(); 5158 mStackSupervisor.scheduleIdleLocked(); 5159 } 5160 } 5161 5162 return didSomething; 5163 } 5164 5165 private final boolean removeProcessLocked(ProcessRecord app, 5166 boolean callerWillRestart, boolean allowRestart, String reason) { 5167 final String name = app.processName; 5168 final int uid = app.uid; 5169 if (DEBUG_PROCESSES) Slog.d( 5170 TAG, "Force removing proc " + app.toShortString() + " (" + name 5171 + "/" + uid + ")"); 5172 5173 mProcessNames.remove(name, uid); 5174 mIsolatedProcesses.remove(app.uid); 5175 if (mHeavyWeightProcess == app) { 5176 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5177 mHeavyWeightProcess.userId, 0)); 5178 mHeavyWeightProcess = null; 5179 } 5180 boolean needRestart = false; 5181 if (app.pid > 0 && app.pid != MY_PID) { 5182 int pid = app.pid; 5183 synchronized (mPidsSelfLocked) { 5184 mPidsSelfLocked.remove(pid); 5185 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5186 } 5187 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5188 if (app.isolated) { 5189 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5190 } 5191 killUnneededProcessLocked(app, reason); 5192 Process.killProcessGroup(app.info.uid, app.pid); 5193 handleAppDiedLocked(app, true, allowRestart); 5194 removeLruProcessLocked(app); 5195 5196 if (app.persistent && !app.isolated) { 5197 if (!callerWillRestart) { 5198 addAppLocked(app.info, false, null /* ABI override */); 5199 } else { 5200 needRestart = true; 5201 } 5202 } 5203 } else { 5204 mRemovedProcesses.add(app); 5205 } 5206 5207 return needRestart; 5208 } 5209 5210 private final void processStartTimedOutLocked(ProcessRecord app) { 5211 final int pid = app.pid; 5212 boolean gone = false; 5213 synchronized (mPidsSelfLocked) { 5214 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5215 if (knownApp != null && knownApp.thread == null) { 5216 mPidsSelfLocked.remove(pid); 5217 gone = true; 5218 } 5219 } 5220 5221 if (gone) { 5222 Slog.w(TAG, "Process " + app + " failed to attach"); 5223 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5224 pid, app.uid, app.processName); 5225 mProcessNames.remove(app.processName, app.uid); 5226 mIsolatedProcesses.remove(app.uid); 5227 if (mHeavyWeightProcess == app) { 5228 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5229 mHeavyWeightProcess.userId, 0)); 5230 mHeavyWeightProcess = null; 5231 } 5232 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 5233 if (app.isolated) { 5234 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5235 } 5236 // Take care of any launching providers waiting for this process. 5237 checkAppInLaunchingProvidersLocked(app, true); 5238 // Take care of any services that are waiting for the process. 5239 mServices.processStartTimedOutLocked(app); 5240 killUnneededProcessLocked(app, "start timeout"); 5241 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5242 Slog.w(TAG, "Unattached app died before backup, skipping"); 5243 try { 5244 IBackupManager bm = IBackupManager.Stub.asInterface( 5245 ServiceManager.getService(Context.BACKUP_SERVICE)); 5246 bm.agentDisconnected(app.info.packageName); 5247 } catch (RemoteException e) { 5248 // Can't happen; the backup manager is local 5249 } 5250 } 5251 if (isPendingBroadcastProcessLocked(pid)) { 5252 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5253 skipPendingBroadcastLocked(pid); 5254 } 5255 } else { 5256 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5257 } 5258 } 5259 5260 private final boolean attachApplicationLocked(IApplicationThread thread, 5261 int pid) { 5262 5263 // Find the application record that is being attached... either via 5264 // the pid if we are running in multiple processes, or just pull the 5265 // next app record if we are emulating process with anonymous threads. 5266 ProcessRecord app; 5267 if (pid != MY_PID && pid >= 0) { 5268 synchronized (mPidsSelfLocked) { 5269 app = mPidsSelfLocked.get(pid); 5270 } 5271 } else { 5272 app = null; 5273 } 5274 5275 if (app == null) { 5276 Slog.w(TAG, "No pending application record for pid " + pid 5277 + " (IApplicationThread " + thread + "); dropping process"); 5278 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5279 if (pid > 0 && pid != MY_PID) { 5280 Process.killProcessQuiet(pid); 5281 //TODO: Process.killProcessGroup(app.info.uid, pid); 5282 } else { 5283 try { 5284 thread.scheduleExit(); 5285 } catch (Exception e) { 5286 // Ignore exceptions. 5287 } 5288 } 5289 return false; 5290 } 5291 5292 // If this application record is still attached to a previous 5293 // process, clean it up now. 5294 if (app.thread != null) { 5295 handleAppDiedLocked(app, true, true); 5296 } 5297 5298 // Tell the process all about itself. 5299 5300 if (localLOGV) Slog.v( 5301 TAG, "Binding process pid " + pid + " to record " + app); 5302 5303 final String processName = app.processName; 5304 try { 5305 AppDeathRecipient adr = new AppDeathRecipient( 5306 app, pid, thread); 5307 thread.asBinder().linkToDeath(adr, 0); 5308 app.deathRecipient = adr; 5309 } catch (RemoteException e) { 5310 app.resetPackageList(mProcessStats); 5311 startProcessLocked(app, "link fail", processName, null /* ABI override */); 5312 return false; 5313 } 5314 5315 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5316 5317 app.makeActive(thread, mProcessStats); 5318 app.curAdj = app.setAdj = -100; 5319 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5320 app.forcingToForeground = null; 5321 updateProcessForegroundLocked(app, false, false); 5322 app.hasShownUi = false; 5323 app.debugging = false; 5324 app.cached = false; 5325 5326 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5327 5328 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5329 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5330 5331 if (!normalMode) { 5332 Slog.i(TAG, "Launching preboot mode app: " + app); 5333 } 5334 5335 if (localLOGV) Slog.v( 5336 TAG, "New app record " + app 5337 + " thread=" + thread.asBinder() + " pid=" + pid); 5338 try { 5339 int testMode = IApplicationThread.DEBUG_OFF; 5340 if (mDebugApp != null && mDebugApp.equals(processName)) { 5341 testMode = mWaitForDebugger 5342 ? IApplicationThread.DEBUG_WAIT 5343 : IApplicationThread.DEBUG_ON; 5344 app.debugging = true; 5345 if (mDebugTransient) { 5346 mDebugApp = mOrigDebugApp; 5347 mWaitForDebugger = mOrigWaitForDebugger; 5348 } 5349 } 5350 String profileFile = app.instrumentationProfileFile; 5351 ParcelFileDescriptor profileFd = null; 5352 boolean profileAutoStop = false; 5353 if (mProfileApp != null && mProfileApp.equals(processName)) { 5354 mProfileProc = app; 5355 profileFile = mProfileFile; 5356 profileFd = mProfileFd; 5357 profileAutoStop = mAutoStopProfiler; 5358 } 5359 boolean enableOpenGlTrace = false; 5360 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5361 enableOpenGlTrace = true; 5362 mOpenGlTraceApp = null; 5363 } 5364 5365 // If the app is being launched for restore or full backup, set it up specially 5366 boolean isRestrictedBackupMode = false; 5367 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5368 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5369 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5370 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5371 } 5372 5373 ensurePackageDexOpt(app.instrumentationInfo != null 5374 ? app.instrumentationInfo.packageName 5375 : app.info.packageName); 5376 if (app.instrumentationClass != null) { 5377 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5378 } 5379 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5380 + processName + " with config " + mConfiguration); 5381 ApplicationInfo appInfo = app.instrumentationInfo != null 5382 ? app.instrumentationInfo : app.info; 5383 app.compat = compatibilityInfoForPackageLocked(appInfo); 5384 if (profileFd != null) { 5385 profileFd = profileFd.dup(); 5386 } 5387 thread.bindApplication(processName, appInfo, providers, 5388 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5389 app.instrumentationArguments, app.instrumentationWatcher, 5390 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5391 isRestrictedBackupMode || !normalMode, app.persistent, 5392 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5393 mCoreSettingsObserver.getCoreSettingsLocked()); 5394 updateLruProcessLocked(app, false, null); 5395 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5396 } catch (Exception e) { 5397 // todo: Yikes! What should we do? For now we will try to 5398 // start another process, but that could easily get us in 5399 // an infinite loop of restarting processes... 5400 Slog.w(TAG, "Exception thrown during bind!", e); 5401 5402 app.resetPackageList(mProcessStats); 5403 app.unlinkDeathRecipient(); 5404 startProcessLocked(app, "bind fail", processName, null /* ABI override */); 5405 return false; 5406 } 5407 5408 // Remove this record from the list of starting applications. 5409 mPersistentStartingProcesses.remove(app); 5410 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5411 "Attach application locked removing on hold: " + app); 5412 mProcessesOnHold.remove(app); 5413 5414 boolean badApp = false; 5415 boolean didSomething = false; 5416 5417 // See if the top visible activity is waiting to run in this process... 5418 if (normalMode) { 5419 try { 5420 if (mStackSupervisor.attachApplicationLocked(app)) { 5421 didSomething = true; 5422 } 5423 } catch (Exception e) { 5424 badApp = true; 5425 } 5426 } 5427 5428 // Find any services that should be running in this process... 5429 if (!badApp) { 5430 try { 5431 didSomething |= mServices.attachApplicationLocked(app, processName); 5432 } catch (Exception e) { 5433 badApp = true; 5434 } 5435 } 5436 5437 // Check if a next-broadcast receiver is in this process... 5438 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5439 try { 5440 didSomething |= sendPendingBroadcastsLocked(app); 5441 } catch (Exception e) { 5442 // If the app died trying to launch the receiver we declare it 'bad' 5443 badApp = true; 5444 } 5445 } 5446 5447 // Check whether the next backup agent is in this process... 5448 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5449 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5450 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5451 try { 5452 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5453 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5454 mBackupTarget.backupMode); 5455 } catch (Exception e) { 5456 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5457 e.printStackTrace(); 5458 } 5459 } 5460 5461 if (badApp) { 5462 // todo: Also need to kill application to deal with all 5463 // kinds of exceptions. 5464 handleAppDiedLocked(app, false, true); 5465 return false; 5466 } 5467 5468 if (!didSomething) { 5469 updateOomAdjLocked(); 5470 } 5471 5472 return true; 5473 } 5474 5475 @Override 5476 public final void attachApplication(IApplicationThread thread) { 5477 synchronized (this) { 5478 int callingPid = Binder.getCallingPid(); 5479 final long origId = Binder.clearCallingIdentity(); 5480 attachApplicationLocked(thread, callingPid); 5481 Binder.restoreCallingIdentity(origId); 5482 } 5483 } 5484 5485 @Override 5486 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5487 final long origId = Binder.clearCallingIdentity(); 5488 synchronized (this) { 5489 ActivityStack stack = ActivityRecord.getStackLocked(token); 5490 if (stack != null) { 5491 ActivityRecord r = 5492 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5493 if (stopProfiling) { 5494 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5495 try { 5496 mProfileFd.close(); 5497 } catch (IOException e) { 5498 } 5499 clearProfilerLocked(); 5500 } 5501 } 5502 } 5503 } 5504 Binder.restoreCallingIdentity(origId); 5505 } 5506 5507 void enableScreenAfterBoot() { 5508 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5509 SystemClock.uptimeMillis()); 5510 mWindowManager.enableScreenAfterBoot(); 5511 5512 synchronized (this) { 5513 updateEventDispatchingLocked(); 5514 } 5515 } 5516 5517 @Override 5518 public void showBootMessage(final CharSequence msg, final boolean always) { 5519 enforceNotIsolatedCaller("showBootMessage"); 5520 mWindowManager.showBootMessage(msg, always); 5521 } 5522 5523 @Override 5524 public void dismissKeyguardOnNextActivity() { 5525 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5526 final long token = Binder.clearCallingIdentity(); 5527 try { 5528 synchronized (this) { 5529 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5530 if (mLockScreenShown) { 5531 mLockScreenShown = false; 5532 comeOutOfSleepIfNeededLocked(); 5533 } 5534 mStackSupervisor.setDismissKeyguard(true); 5535 } 5536 } finally { 5537 Binder.restoreCallingIdentity(token); 5538 } 5539 } 5540 5541 final void finishBooting() { 5542 // Register receivers to handle package update events 5543 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5544 5545 synchronized (this) { 5546 // Ensure that any processes we had put on hold are now started 5547 // up. 5548 final int NP = mProcessesOnHold.size(); 5549 if (NP > 0) { 5550 ArrayList<ProcessRecord> procs = 5551 new ArrayList<ProcessRecord>(mProcessesOnHold); 5552 for (int ip=0; ip<NP; ip++) { 5553 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5554 + procs.get(ip)); 5555 startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */); 5556 } 5557 } 5558 5559 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5560 // Start looking for apps that are abusing wake locks. 5561 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5562 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5563 // Tell anyone interested that we are done booting! 5564 SystemProperties.set("sys.boot_completed", "1"); 5565 SystemProperties.set("dev.bootcomplete", "1"); 5566 for (int i=0; i<mStartedUsers.size(); i++) { 5567 UserStartedState uss = mStartedUsers.valueAt(i); 5568 if (uss.mState == UserStartedState.STATE_BOOTING) { 5569 uss.mState = UserStartedState.STATE_RUNNING; 5570 final int userId = mStartedUsers.keyAt(i); 5571 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5572 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5573 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5574 broadcastIntentLocked(null, null, intent, null, 5575 new IIntentReceiver.Stub() { 5576 @Override 5577 public void performReceive(Intent intent, int resultCode, 5578 String data, Bundle extras, boolean ordered, 5579 boolean sticky, int sendingUser) { 5580 synchronized (ActivityManagerService.this) { 5581 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5582 true, false); 5583 } 5584 } 5585 }, 5586 0, null, null, 5587 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5588 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5589 userId); 5590 } 5591 } 5592 scheduleStartProfilesLocked(); 5593 } 5594 } 5595 } 5596 5597 final void ensureBootCompleted() { 5598 boolean booting; 5599 boolean enableScreen; 5600 synchronized (this) { 5601 booting = mBooting; 5602 mBooting = false; 5603 enableScreen = !mBooted; 5604 mBooted = true; 5605 } 5606 5607 if (booting) { 5608 finishBooting(); 5609 } 5610 5611 if (enableScreen) { 5612 enableScreenAfterBoot(); 5613 } 5614 } 5615 5616 @Override 5617 public final void activityResumed(IBinder token) { 5618 final long origId = Binder.clearCallingIdentity(); 5619 synchronized(this) { 5620 ActivityStack stack = ActivityRecord.getStackLocked(token); 5621 if (stack != null) { 5622 ActivityRecord.activityResumedLocked(token); 5623 } 5624 } 5625 Binder.restoreCallingIdentity(origId); 5626 } 5627 5628 @Override 5629 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5630 final long origId = Binder.clearCallingIdentity(); 5631 synchronized(this) { 5632 ActivityStack stack = ActivityRecord.getStackLocked(token); 5633 if (stack != null) { 5634 stack.activityPausedLocked(token, false, persistentState); 5635 } 5636 } 5637 Binder.restoreCallingIdentity(origId); 5638 } 5639 5640 @Override 5641 public final void activityStopped(IBinder token, Bundle icicle, 5642 PersistableBundle persistentState, CharSequence description) { 5643 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5644 5645 // Refuse possible leaked file descriptors 5646 if (icicle != null && icicle.hasFileDescriptors()) { 5647 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5648 } 5649 5650 final long origId = Binder.clearCallingIdentity(); 5651 5652 synchronized (this) { 5653 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5654 if (r != null) { 5655 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5656 } 5657 } 5658 5659 trimApplications(); 5660 5661 Binder.restoreCallingIdentity(origId); 5662 } 5663 5664 @Override 5665 public final void activityDestroyed(IBinder token) { 5666 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5667 synchronized (this) { 5668 ActivityStack stack = ActivityRecord.getStackLocked(token); 5669 if (stack != null) { 5670 stack.activityDestroyedLocked(token); 5671 } 5672 } 5673 } 5674 5675 @Override 5676 public final void mediaResourcesReleased(IBinder token) { 5677 final long origId = Binder.clearCallingIdentity(); 5678 try { 5679 synchronized (this) { 5680 ActivityStack stack = ActivityRecord.getStackLocked(token); 5681 if (stack != null) { 5682 stack.mediaResourcesReleased(token); 5683 } 5684 } 5685 } finally { 5686 Binder.restoreCallingIdentity(origId); 5687 } 5688 } 5689 5690 @Override 5691 public final void notifyLaunchTaskBehindComplete(IBinder token) { 5692 mStackSupervisor.scheduleLaunchTaskBehindComplete(token); 5693 } 5694 5695 @Override 5696 public String getCallingPackage(IBinder token) { 5697 synchronized (this) { 5698 ActivityRecord r = getCallingRecordLocked(token); 5699 return r != null ? r.info.packageName : null; 5700 } 5701 } 5702 5703 @Override 5704 public ComponentName getCallingActivity(IBinder token) { 5705 synchronized (this) { 5706 ActivityRecord r = getCallingRecordLocked(token); 5707 return r != null ? r.intent.getComponent() : null; 5708 } 5709 } 5710 5711 private ActivityRecord getCallingRecordLocked(IBinder token) { 5712 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5713 if (r == null) { 5714 return null; 5715 } 5716 return r.resultTo; 5717 } 5718 5719 @Override 5720 public ComponentName getActivityClassForToken(IBinder token) { 5721 synchronized(this) { 5722 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5723 if (r == null) { 5724 return null; 5725 } 5726 return r.intent.getComponent(); 5727 } 5728 } 5729 5730 @Override 5731 public String getPackageForToken(IBinder token) { 5732 synchronized(this) { 5733 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5734 if (r == null) { 5735 return null; 5736 } 5737 return r.packageName; 5738 } 5739 } 5740 5741 @Override 5742 public IIntentSender getIntentSender(int type, 5743 String packageName, IBinder token, String resultWho, 5744 int requestCode, Intent[] intents, String[] resolvedTypes, 5745 int flags, Bundle options, int userId) { 5746 enforceNotIsolatedCaller("getIntentSender"); 5747 // Refuse possible leaked file descriptors 5748 if (intents != null) { 5749 if (intents.length < 1) { 5750 throw new IllegalArgumentException("Intents array length must be >= 1"); 5751 } 5752 for (int i=0; i<intents.length; i++) { 5753 Intent intent = intents[i]; 5754 if (intent != null) { 5755 if (intent.hasFileDescriptors()) { 5756 throw new IllegalArgumentException("File descriptors passed in Intent"); 5757 } 5758 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5759 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5760 throw new IllegalArgumentException( 5761 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5762 } 5763 intents[i] = new Intent(intent); 5764 } 5765 } 5766 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5767 throw new IllegalArgumentException( 5768 "Intent array length does not match resolvedTypes length"); 5769 } 5770 } 5771 if (options != null) { 5772 if (options.hasFileDescriptors()) { 5773 throw new IllegalArgumentException("File descriptors passed in options"); 5774 } 5775 } 5776 5777 synchronized(this) { 5778 int callingUid = Binder.getCallingUid(); 5779 int origUserId = userId; 5780 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5781 type == ActivityManager.INTENT_SENDER_BROADCAST, 5782 ALLOW_NON_FULL, "getIntentSender", null); 5783 if (origUserId == UserHandle.USER_CURRENT) { 5784 // We don't want to evaluate this until the pending intent is 5785 // actually executed. However, we do want to always do the 5786 // security checking for it above. 5787 userId = UserHandle.USER_CURRENT; 5788 } 5789 try { 5790 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5791 int uid = AppGlobals.getPackageManager() 5792 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5793 if (!UserHandle.isSameApp(callingUid, uid)) { 5794 String msg = "Permission Denial: getIntentSender() from pid=" 5795 + Binder.getCallingPid() 5796 + ", uid=" + Binder.getCallingUid() 5797 + ", (need uid=" + uid + ")" 5798 + " is not allowed to send as package " + packageName; 5799 Slog.w(TAG, msg); 5800 throw new SecurityException(msg); 5801 } 5802 } 5803 5804 return getIntentSenderLocked(type, packageName, callingUid, userId, 5805 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5806 5807 } catch (RemoteException e) { 5808 throw new SecurityException(e); 5809 } 5810 } 5811 } 5812 5813 IIntentSender getIntentSenderLocked(int type, String packageName, 5814 int callingUid, int userId, IBinder token, String resultWho, 5815 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5816 Bundle options) { 5817 if (DEBUG_MU) 5818 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5819 ActivityRecord activity = null; 5820 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5821 activity = ActivityRecord.isInStackLocked(token); 5822 if (activity == null) { 5823 return null; 5824 } 5825 if (activity.finishing) { 5826 return null; 5827 } 5828 } 5829 5830 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5831 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5832 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5833 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5834 |PendingIntent.FLAG_UPDATE_CURRENT); 5835 5836 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5837 type, packageName, activity, resultWho, 5838 requestCode, intents, resolvedTypes, flags, options, userId); 5839 WeakReference<PendingIntentRecord> ref; 5840 ref = mIntentSenderRecords.get(key); 5841 PendingIntentRecord rec = ref != null ? ref.get() : null; 5842 if (rec != null) { 5843 if (!cancelCurrent) { 5844 if (updateCurrent) { 5845 if (rec.key.requestIntent != null) { 5846 rec.key.requestIntent.replaceExtras(intents != null ? 5847 intents[intents.length - 1] : null); 5848 } 5849 if (intents != null) { 5850 intents[intents.length-1] = rec.key.requestIntent; 5851 rec.key.allIntents = intents; 5852 rec.key.allResolvedTypes = resolvedTypes; 5853 } else { 5854 rec.key.allIntents = null; 5855 rec.key.allResolvedTypes = null; 5856 } 5857 } 5858 return rec; 5859 } 5860 rec.canceled = true; 5861 mIntentSenderRecords.remove(key); 5862 } 5863 if (noCreate) { 5864 return rec; 5865 } 5866 rec = new PendingIntentRecord(this, key, callingUid); 5867 mIntentSenderRecords.put(key, rec.ref); 5868 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5869 if (activity.pendingResults == null) { 5870 activity.pendingResults 5871 = new HashSet<WeakReference<PendingIntentRecord>>(); 5872 } 5873 activity.pendingResults.add(rec.ref); 5874 } 5875 return rec; 5876 } 5877 5878 @Override 5879 public void cancelIntentSender(IIntentSender sender) { 5880 if (!(sender instanceof PendingIntentRecord)) { 5881 return; 5882 } 5883 synchronized(this) { 5884 PendingIntentRecord rec = (PendingIntentRecord)sender; 5885 try { 5886 int uid = AppGlobals.getPackageManager() 5887 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5888 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5889 String msg = "Permission Denial: cancelIntentSender() from pid=" 5890 + Binder.getCallingPid() 5891 + ", uid=" + Binder.getCallingUid() 5892 + " is not allowed to cancel packges " 5893 + rec.key.packageName; 5894 Slog.w(TAG, msg); 5895 throw new SecurityException(msg); 5896 } 5897 } catch (RemoteException e) { 5898 throw new SecurityException(e); 5899 } 5900 cancelIntentSenderLocked(rec, true); 5901 } 5902 } 5903 5904 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5905 rec.canceled = true; 5906 mIntentSenderRecords.remove(rec.key); 5907 if (cleanActivity && rec.key.activity != null) { 5908 rec.key.activity.pendingResults.remove(rec.ref); 5909 } 5910 } 5911 5912 @Override 5913 public String getPackageForIntentSender(IIntentSender pendingResult) { 5914 if (!(pendingResult instanceof PendingIntentRecord)) { 5915 return null; 5916 } 5917 try { 5918 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5919 return res.key.packageName; 5920 } catch (ClassCastException e) { 5921 } 5922 return null; 5923 } 5924 5925 @Override 5926 public int getUidForIntentSender(IIntentSender sender) { 5927 if (sender instanceof PendingIntentRecord) { 5928 try { 5929 PendingIntentRecord res = (PendingIntentRecord)sender; 5930 return res.uid; 5931 } catch (ClassCastException e) { 5932 } 5933 } 5934 return -1; 5935 } 5936 5937 @Override 5938 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5939 if (!(pendingResult instanceof PendingIntentRecord)) { 5940 return false; 5941 } 5942 try { 5943 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5944 if (res.key.allIntents == null) { 5945 return false; 5946 } 5947 for (int i=0; i<res.key.allIntents.length; i++) { 5948 Intent intent = res.key.allIntents[i]; 5949 if (intent.getPackage() != null && intent.getComponent() != null) { 5950 return false; 5951 } 5952 } 5953 return true; 5954 } catch (ClassCastException e) { 5955 } 5956 return false; 5957 } 5958 5959 @Override 5960 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5961 if (!(pendingResult instanceof PendingIntentRecord)) { 5962 return false; 5963 } 5964 try { 5965 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5966 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5967 return true; 5968 } 5969 return false; 5970 } catch (ClassCastException e) { 5971 } 5972 return false; 5973 } 5974 5975 @Override 5976 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5977 if (!(pendingResult instanceof PendingIntentRecord)) { 5978 return null; 5979 } 5980 try { 5981 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5982 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5983 } catch (ClassCastException e) { 5984 } 5985 return null; 5986 } 5987 5988 @Override 5989 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5990 if (!(pendingResult instanceof PendingIntentRecord)) { 5991 return null; 5992 } 5993 try { 5994 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5995 Intent intent = res.key.requestIntent; 5996 if (intent != null) { 5997 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5998 || res.lastTagPrefix.equals(prefix))) { 5999 return res.lastTag; 6000 } 6001 res.lastTagPrefix = prefix; 6002 StringBuilder sb = new StringBuilder(128); 6003 if (prefix != null) { 6004 sb.append(prefix); 6005 } 6006 if (intent.getAction() != null) { 6007 sb.append(intent.getAction()); 6008 } else if (intent.getComponent() != null) { 6009 intent.getComponent().appendShortString(sb); 6010 } else { 6011 sb.append("?"); 6012 } 6013 return res.lastTag = sb.toString(); 6014 } 6015 } catch (ClassCastException e) { 6016 } 6017 return null; 6018 } 6019 6020 @Override 6021 public void setProcessLimit(int max) { 6022 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6023 "setProcessLimit()"); 6024 synchronized (this) { 6025 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 6026 mProcessLimitOverride = max; 6027 } 6028 trimApplications(); 6029 } 6030 6031 @Override 6032 public int getProcessLimit() { 6033 synchronized (this) { 6034 return mProcessLimitOverride; 6035 } 6036 } 6037 6038 void foregroundTokenDied(ForegroundToken token) { 6039 synchronized (ActivityManagerService.this) { 6040 synchronized (mPidsSelfLocked) { 6041 ForegroundToken cur 6042 = mForegroundProcesses.get(token.pid); 6043 if (cur != token) { 6044 return; 6045 } 6046 mForegroundProcesses.remove(token.pid); 6047 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 6048 if (pr == null) { 6049 return; 6050 } 6051 pr.forcingToForeground = null; 6052 updateProcessForegroundLocked(pr, false, false); 6053 } 6054 updateOomAdjLocked(); 6055 } 6056 } 6057 6058 @Override 6059 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 6060 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 6061 "setProcessForeground()"); 6062 synchronized(this) { 6063 boolean changed = false; 6064 6065 synchronized (mPidsSelfLocked) { 6066 ProcessRecord pr = mPidsSelfLocked.get(pid); 6067 if (pr == null && isForeground) { 6068 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 6069 return; 6070 } 6071 ForegroundToken oldToken = mForegroundProcesses.get(pid); 6072 if (oldToken != null) { 6073 oldToken.token.unlinkToDeath(oldToken, 0); 6074 mForegroundProcesses.remove(pid); 6075 if (pr != null) { 6076 pr.forcingToForeground = null; 6077 } 6078 changed = true; 6079 } 6080 if (isForeground && token != null) { 6081 ForegroundToken newToken = new ForegroundToken() { 6082 @Override 6083 public void binderDied() { 6084 foregroundTokenDied(this); 6085 } 6086 }; 6087 newToken.pid = pid; 6088 newToken.token = token; 6089 try { 6090 token.linkToDeath(newToken, 0); 6091 mForegroundProcesses.put(pid, newToken); 6092 pr.forcingToForeground = token; 6093 changed = true; 6094 } catch (RemoteException e) { 6095 // If the process died while doing this, we will later 6096 // do the cleanup with the process death link. 6097 } 6098 } 6099 } 6100 6101 if (changed) { 6102 updateOomAdjLocked(); 6103 } 6104 } 6105 } 6106 6107 // ========================================================= 6108 // PERMISSIONS 6109 // ========================================================= 6110 6111 static class PermissionController extends IPermissionController.Stub { 6112 ActivityManagerService mActivityManagerService; 6113 PermissionController(ActivityManagerService activityManagerService) { 6114 mActivityManagerService = activityManagerService; 6115 } 6116 6117 @Override 6118 public boolean checkPermission(String permission, int pid, int uid) { 6119 return mActivityManagerService.checkPermission(permission, pid, 6120 uid) == PackageManager.PERMISSION_GRANTED; 6121 } 6122 } 6123 6124 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 6125 @Override 6126 public int checkComponentPermission(String permission, int pid, int uid, 6127 int owningUid, boolean exported) { 6128 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 6129 owningUid, exported); 6130 } 6131 6132 @Override 6133 public Object getAMSLock() { 6134 return ActivityManagerService.this; 6135 } 6136 } 6137 6138 /** 6139 * This can be called with or without the global lock held. 6140 */ 6141 int checkComponentPermission(String permission, int pid, int uid, 6142 int owningUid, boolean exported) { 6143 // We might be performing an operation on behalf of an indirect binder 6144 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 6145 // client identity accordingly before proceeding. 6146 Identity tlsIdentity = sCallerIdentity.get(); 6147 if (tlsIdentity != null) { 6148 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 6149 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 6150 uid = tlsIdentity.uid; 6151 pid = tlsIdentity.pid; 6152 } 6153 6154 if (pid == MY_PID) { 6155 return PackageManager.PERMISSION_GRANTED; 6156 } 6157 6158 return ActivityManager.checkComponentPermission(permission, uid, 6159 owningUid, exported); 6160 } 6161 6162 /** 6163 * As the only public entry point for permissions checking, this method 6164 * can enforce the semantic that requesting a check on a null global 6165 * permission is automatically denied. (Internally a null permission 6166 * string is used when calling {@link #checkComponentPermission} in cases 6167 * when only uid-based security is needed.) 6168 * 6169 * This can be called with or without the global lock held. 6170 */ 6171 @Override 6172 public int checkPermission(String permission, int pid, int uid) { 6173 if (permission == null) { 6174 return PackageManager.PERMISSION_DENIED; 6175 } 6176 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 6177 } 6178 6179 /** 6180 * Binder IPC calls go through the public entry point. 6181 * This can be called with or without the global lock held. 6182 */ 6183 int checkCallingPermission(String permission) { 6184 return checkPermission(permission, 6185 Binder.getCallingPid(), 6186 UserHandle.getAppId(Binder.getCallingUid())); 6187 } 6188 6189 /** 6190 * This can be called with or without the global lock held. 6191 */ 6192 void enforceCallingPermission(String permission, String func) { 6193 if (checkCallingPermission(permission) 6194 == PackageManager.PERMISSION_GRANTED) { 6195 return; 6196 } 6197 6198 String msg = "Permission Denial: " + func + " from pid=" 6199 + Binder.getCallingPid() 6200 + ", uid=" + Binder.getCallingUid() 6201 + " requires " + permission; 6202 Slog.w(TAG, msg); 6203 throw new SecurityException(msg); 6204 } 6205 6206 /** 6207 * Determine if UID is holding permissions required to access {@link Uri} in 6208 * the given {@link ProviderInfo}. Final permission checking is always done 6209 * in {@link ContentProvider}. 6210 */ 6211 private final boolean checkHoldingPermissionsLocked( 6212 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6213 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6214 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6215 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) { 6216 return false; 6217 } 6218 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true); 6219 } 6220 6221 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi, 6222 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) { 6223 if (pi.applicationInfo.uid == uid) { 6224 return true; 6225 } else if (!pi.exported) { 6226 return false; 6227 } 6228 6229 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6230 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6231 try { 6232 // check if target holds top-level <provider> permissions 6233 if (!readMet && pi.readPermission != null && considerUidPermissions 6234 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6235 readMet = true; 6236 } 6237 if (!writeMet && pi.writePermission != null && considerUidPermissions 6238 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6239 writeMet = true; 6240 } 6241 6242 // track if unprotected read/write is allowed; any denied 6243 // <path-permission> below removes this ability 6244 boolean allowDefaultRead = pi.readPermission == null; 6245 boolean allowDefaultWrite = pi.writePermission == null; 6246 6247 // check if target holds any <path-permission> that match uri 6248 final PathPermission[] pps = pi.pathPermissions; 6249 if (pps != null) { 6250 final String path = grantUri.uri.getPath(); 6251 int i = pps.length; 6252 while (i > 0 && (!readMet || !writeMet)) { 6253 i--; 6254 PathPermission pp = pps[i]; 6255 if (pp.match(path)) { 6256 if (!readMet) { 6257 final String pprperm = pp.getReadPermission(); 6258 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6259 + pprperm + " for " + pp.getPath() 6260 + ": match=" + pp.match(path) 6261 + " check=" + pm.checkUidPermission(pprperm, uid)); 6262 if (pprperm != null) { 6263 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid) 6264 == PERMISSION_GRANTED) { 6265 readMet = true; 6266 } else { 6267 allowDefaultRead = false; 6268 } 6269 } 6270 } 6271 if (!writeMet) { 6272 final String ppwperm = pp.getWritePermission(); 6273 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6274 + ppwperm + " for " + pp.getPath() 6275 + ": match=" + pp.match(path) 6276 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6277 if (ppwperm != null) { 6278 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid) 6279 == PERMISSION_GRANTED) { 6280 writeMet = true; 6281 } else { 6282 allowDefaultWrite = false; 6283 } 6284 } 6285 } 6286 } 6287 } 6288 } 6289 6290 // grant unprotected <provider> read/write, if not blocked by 6291 // <path-permission> above 6292 if (allowDefaultRead) readMet = true; 6293 if (allowDefaultWrite) writeMet = true; 6294 6295 } catch (RemoteException e) { 6296 return false; 6297 } 6298 6299 return readMet && writeMet; 6300 } 6301 6302 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6303 ProviderInfo pi = null; 6304 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6305 if (cpr != null) { 6306 pi = cpr.info; 6307 } else { 6308 try { 6309 pi = AppGlobals.getPackageManager().resolveContentProvider( 6310 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6311 } catch (RemoteException ex) { 6312 } 6313 } 6314 return pi; 6315 } 6316 6317 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6318 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6319 if (targetUris != null) { 6320 return targetUris.get(grantUri); 6321 } 6322 return null; 6323 } 6324 6325 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6326 String targetPkg, int targetUid, GrantUri grantUri) { 6327 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6328 if (targetUris == null) { 6329 targetUris = Maps.newArrayMap(); 6330 mGrantedUriPermissions.put(targetUid, targetUris); 6331 } 6332 6333 UriPermission perm = targetUris.get(grantUri); 6334 if (perm == null) { 6335 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6336 targetUris.put(grantUri, perm); 6337 } 6338 6339 return perm; 6340 } 6341 6342 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6343 final int modeFlags) { 6344 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6345 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6346 : UriPermission.STRENGTH_OWNED; 6347 6348 // Root gets to do everything. 6349 if (uid == 0) { 6350 return true; 6351 } 6352 6353 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6354 if (perms == null) return false; 6355 6356 // First look for exact match 6357 final UriPermission exactPerm = perms.get(grantUri); 6358 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6359 return true; 6360 } 6361 6362 // No exact match, look for prefixes 6363 final int N = perms.size(); 6364 for (int i = 0; i < N; i++) { 6365 final UriPermission perm = perms.valueAt(i); 6366 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6367 && perm.getStrength(modeFlags) >= minStrength) { 6368 return true; 6369 } 6370 } 6371 6372 return false; 6373 } 6374 6375 @Override 6376 public int checkUriPermission(Uri uri, int pid, int uid, 6377 final int modeFlags, int userId) { 6378 enforceNotIsolatedCaller("checkUriPermission"); 6379 6380 // Another redirected-binder-call permissions check as in 6381 // {@link checkComponentPermission}. 6382 Identity tlsIdentity = sCallerIdentity.get(); 6383 if (tlsIdentity != null) { 6384 uid = tlsIdentity.uid; 6385 pid = tlsIdentity.pid; 6386 } 6387 6388 // Our own process gets to do everything. 6389 if (pid == MY_PID) { 6390 return PackageManager.PERMISSION_GRANTED; 6391 } 6392 synchronized (this) { 6393 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6394 ? PackageManager.PERMISSION_GRANTED 6395 : PackageManager.PERMISSION_DENIED; 6396 } 6397 } 6398 6399 /** 6400 * Check if the targetPkg can be granted permission to access uri by 6401 * the callingUid using the given modeFlags. Throws a security exception 6402 * if callingUid is not allowed to do this. Returns the uid of the target 6403 * if the URI permission grant should be performed; returns -1 if it is not 6404 * needed (for example targetPkg already has permission to access the URI). 6405 * If you already know the uid of the target, you can supply it in 6406 * lastTargetUid else set that to -1. 6407 */ 6408 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6409 final int modeFlags, int lastTargetUid) { 6410 if (!Intent.isAccessUriMode(modeFlags)) { 6411 return -1; 6412 } 6413 6414 if (targetPkg != null) { 6415 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6416 "Checking grant " + targetPkg + " permission to " + grantUri); 6417 } 6418 6419 final IPackageManager pm = AppGlobals.getPackageManager(); 6420 6421 // If this is not a content: uri, we can't do anything with it. 6422 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6423 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6424 "Can't grant URI permission for non-content URI: " + grantUri); 6425 return -1; 6426 } 6427 6428 final String authority = grantUri.uri.getAuthority(); 6429 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6430 if (pi == null) { 6431 Slog.w(TAG, "No content provider found for permission check: " + 6432 grantUri.uri.toSafeString()); 6433 return -1; 6434 } 6435 6436 int targetUid = lastTargetUid; 6437 if (targetUid < 0 && targetPkg != null) { 6438 try { 6439 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6440 if (targetUid < 0) { 6441 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6442 "Can't grant URI permission no uid for: " + targetPkg); 6443 return -1; 6444 } 6445 } catch (RemoteException ex) { 6446 return -1; 6447 } 6448 } 6449 6450 if (targetUid >= 0) { 6451 // First... does the target actually need this permission? 6452 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6453 // No need to grant the target this permission. 6454 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6455 "Target " + targetPkg + " already has full permission to " + grantUri); 6456 return -1; 6457 } 6458 } else { 6459 // First... there is no target package, so can anyone access it? 6460 boolean allowed = pi.exported; 6461 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6462 if (pi.readPermission != null) { 6463 allowed = false; 6464 } 6465 } 6466 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6467 if (pi.writePermission != null) { 6468 allowed = false; 6469 } 6470 } 6471 if (allowed) { 6472 return -1; 6473 } 6474 } 6475 6476 /* There is a special cross user grant if: 6477 * - The target is on another user. 6478 * - Apps on the current user can access the uri without any uid permissions. 6479 * In this case, we grant a uri permission, even if the ContentProvider does not normally 6480 * grant uri permissions. 6481 */ 6482 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId 6483 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid, 6484 modeFlags, false /*without considering the uid permissions*/); 6485 6486 // Second... is the provider allowing granting of URI permissions? 6487 if (!specialCrossUserGrant) { 6488 if (!pi.grantUriPermissions) { 6489 throw new SecurityException("Provider " + pi.packageName 6490 + "/" + pi.name 6491 + " does not allow granting of Uri permissions (uri " 6492 + grantUri + ")"); 6493 } 6494 if (pi.uriPermissionPatterns != null) { 6495 final int N = pi.uriPermissionPatterns.length; 6496 boolean allowed = false; 6497 for (int i=0; i<N; i++) { 6498 if (pi.uriPermissionPatterns[i] != null 6499 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6500 allowed = true; 6501 break; 6502 } 6503 } 6504 if (!allowed) { 6505 throw new SecurityException("Provider " + pi.packageName 6506 + "/" + pi.name 6507 + " does not allow granting of permission to path of Uri " 6508 + grantUri); 6509 } 6510 } 6511 } 6512 6513 // Third... does the caller itself have permission to access 6514 // this uri? 6515 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6516 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6517 // Require they hold a strong enough Uri permission 6518 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6519 throw new SecurityException("Uid " + callingUid 6520 + " does not have permission to uri " + grantUri); 6521 } 6522 } 6523 } 6524 return targetUid; 6525 } 6526 6527 @Override 6528 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6529 final int modeFlags, int userId) { 6530 enforceNotIsolatedCaller("checkGrantUriPermission"); 6531 synchronized(this) { 6532 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6533 new GrantUri(userId, uri, false), modeFlags, -1); 6534 } 6535 } 6536 6537 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6538 final int modeFlags, UriPermissionOwner owner) { 6539 if (!Intent.isAccessUriMode(modeFlags)) { 6540 return; 6541 } 6542 6543 // So here we are: the caller has the assumed permission 6544 // to the uri, and the target doesn't. Let's now give this to 6545 // the target. 6546 6547 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6548 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6549 6550 final String authority = grantUri.uri.getAuthority(); 6551 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6552 if (pi == null) { 6553 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6554 return; 6555 } 6556 6557 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6558 grantUri.prefix = true; 6559 } 6560 final UriPermission perm = findOrCreateUriPermissionLocked( 6561 pi.packageName, targetPkg, targetUid, grantUri); 6562 perm.grantModes(modeFlags, owner); 6563 } 6564 6565 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6566 final int modeFlags, UriPermissionOwner owner, int targetUserId) { 6567 if (targetPkg == null) { 6568 throw new NullPointerException("targetPkg"); 6569 } 6570 int targetUid; 6571 final IPackageManager pm = AppGlobals.getPackageManager(); 6572 try { 6573 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6574 } catch (RemoteException ex) { 6575 return; 6576 } 6577 6578 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6579 targetUid); 6580 if (targetUid < 0) { 6581 return; 6582 } 6583 6584 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6585 owner); 6586 } 6587 6588 static class NeededUriGrants extends ArrayList<GrantUri> { 6589 final String targetPkg; 6590 final int targetUid; 6591 final int flags; 6592 6593 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6594 this.targetPkg = targetPkg; 6595 this.targetUid = targetUid; 6596 this.flags = flags; 6597 } 6598 } 6599 6600 /** 6601 * Like checkGrantUriPermissionLocked, but takes an Intent. 6602 */ 6603 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6604 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) { 6605 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6606 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6607 + " clip=" + (intent != null ? intent.getClipData() : null) 6608 + " from " + intent + "; flags=0x" 6609 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6610 6611 if (targetPkg == null) { 6612 throw new NullPointerException("targetPkg"); 6613 } 6614 6615 if (intent == null) { 6616 return null; 6617 } 6618 Uri data = intent.getData(); 6619 ClipData clip = intent.getClipData(); 6620 if (data == null && clip == null) { 6621 return null; 6622 } 6623 final IPackageManager pm = AppGlobals.getPackageManager(); 6624 int targetUid; 6625 if (needed != null) { 6626 targetUid = needed.targetUid; 6627 } else { 6628 try { 6629 targetUid = pm.getPackageUid(targetPkg, targetUserId); 6630 } catch (RemoteException ex) { 6631 return null; 6632 } 6633 if (targetUid < 0) { 6634 if (DEBUG_URI_PERMISSION) { 6635 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg 6636 + " on user " + targetUserId); 6637 } 6638 return null; 6639 } 6640 } 6641 if (data != null) { 6642 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6643 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6644 targetUid); 6645 if (targetUid > 0) { 6646 if (needed == null) { 6647 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6648 } 6649 needed.add(grantUri); 6650 } 6651 } 6652 if (clip != null) { 6653 for (int i=0; i<clip.getItemCount(); i++) { 6654 Uri uri = clip.getItemAt(i).getUri(); 6655 if (uri != null) { 6656 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6657 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6658 targetUid); 6659 if (targetUid > 0) { 6660 if (needed == null) { 6661 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6662 } 6663 needed.add(grantUri); 6664 } 6665 } else { 6666 Intent clipIntent = clip.getItemAt(i).getIntent(); 6667 if (clipIntent != null) { 6668 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6669 callingUid, targetPkg, clipIntent, mode, needed, targetUserId); 6670 if (newNeeded != null) { 6671 needed = newNeeded; 6672 } 6673 } 6674 } 6675 } 6676 } 6677 6678 return needed; 6679 } 6680 6681 /** 6682 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6683 */ 6684 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6685 UriPermissionOwner owner) { 6686 if (needed != null) { 6687 for (int i=0; i<needed.size(); i++) { 6688 GrantUri grantUri = needed.get(i); 6689 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6690 grantUri, needed.flags, owner); 6691 } 6692 } 6693 } 6694 6695 void grantUriPermissionFromIntentLocked(int callingUid, 6696 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) { 6697 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6698 intent, intent != null ? intent.getFlags() : 0, null, targetUserId); 6699 if (needed == null) { 6700 return; 6701 } 6702 6703 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6704 } 6705 6706 @Override 6707 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6708 final int modeFlags, int userId) { 6709 enforceNotIsolatedCaller("grantUriPermission"); 6710 GrantUri grantUri = new GrantUri(userId, uri, false); 6711 synchronized(this) { 6712 final ProcessRecord r = getRecordForAppLocked(caller); 6713 if (r == null) { 6714 throw new SecurityException("Unable to find app for caller " 6715 + caller 6716 + " when granting permission to uri " + grantUri); 6717 } 6718 if (targetPkg == null) { 6719 throw new IllegalArgumentException("null target"); 6720 } 6721 if (grantUri == null) { 6722 throw new IllegalArgumentException("null uri"); 6723 } 6724 6725 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6726 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6727 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6728 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6729 6730 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null, 6731 UserHandle.getUserId(r.uid)); 6732 } 6733 } 6734 6735 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6736 if (perm.modeFlags == 0) { 6737 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6738 perm.targetUid); 6739 if (perms != null) { 6740 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6741 "Removing " + perm.targetUid + " permission to " + perm.uri); 6742 6743 perms.remove(perm.uri); 6744 if (perms.isEmpty()) { 6745 mGrantedUriPermissions.remove(perm.targetUid); 6746 } 6747 } 6748 } 6749 } 6750 6751 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6752 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6753 6754 final IPackageManager pm = AppGlobals.getPackageManager(); 6755 final String authority = grantUri.uri.getAuthority(); 6756 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6757 if (pi == null) { 6758 Slog.w(TAG, "No content provider found for permission revoke: " 6759 + grantUri.toSafeString()); 6760 return; 6761 } 6762 6763 // Does the caller have this permission on the URI? 6764 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6765 // Right now, if you are not the original owner of the permission, 6766 // you are not allowed to revoke it. 6767 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6768 throw new SecurityException("Uid " + callingUid 6769 + " does not have permission to uri " + grantUri); 6770 //} 6771 } 6772 6773 boolean persistChanged = false; 6774 6775 // Go through all of the permissions and remove any that match. 6776 int N = mGrantedUriPermissions.size(); 6777 for (int i = 0; i < N; i++) { 6778 final int targetUid = mGrantedUriPermissions.keyAt(i); 6779 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6780 6781 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6782 final UriPermission perm = it.next(); 6783 if (perm.uri.sourceUserId == grantUri.sourceUserId 6784 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6785 if (DEBUG_URI_PERMISSION) 6786 Slog.v(TAG, 6787 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6788 persistChanged |= perm.revokeModes( 6789 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6790 if (perm.modeFlags == 0) { 6791 it.remove(); 6792 } 6793 } 6794 } 6795 6796 if (perms.isEmpty()) { 6797 mGrantedUriPermissions.remove(targetUid); 6798 N--; 6799 i--; 6800 } 6801 } 6802 6803 if (persistChanged) { 6804 schedulePersistUriGrants(); 6805 } 6806 } 6807 6808 @Override 6809 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6810 int userId) { 6811 enforceNotIsolatedCaller("revokeUriPermission"); 6812 synchronized(this) { 6813 final ProcessRecord r = getRecordForAppLocked(caller); 6814 if (r == null) { 6815 throw new SecurityException("Unable to find app for caller " 6816 + caller 6817 + " when revoking permission to uri " + uri); 6818 } 6819 if (uri == null) { 6820 Slog.w(TAG, "revokeUriPermission: null uri"); 6821 return; 6822 } 6823 6824 if (!Intent.isAccessUriMode(modeFlags)) { 6825 return; 6826 } 6827 6828 final IPackageManager pm = AppGlobals.getPackageManager(); 6829 final String authority = uri.getAuthority(); 6830 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6831 if (pi == null) { 6832 Slog.w(TAG, "No content provider found for permission revoke: " 6833 + uri.toSafeString()); 6834 return; 6835 } 6836 6837 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6838 } 6839 } 6840 6841 /** 6842 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6843 * given package. 6844 * 6845 * @param packageName Package name to match, or {@code null} to apply to all 6846 * packages. 6847 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6848 * to all users. 6849 * @param persistable If persistable grants should be removed. 6850 */ 6851 private void removeUriPermissionsForPackageLocked( 6852 String packageName, int userHandle, boolean persistable) { 6853 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6854 throw new IllegalArgumentException("Must narrow by either package or user"); 6855 } 6856 6857 boolean persistChanged = false; 6858 6859 int N = mGrantedUriPermissions.size(); 6860 for (int i = 0; i < N; i++) { 6861 final int targetUid = mGrantedUriPermissions.keyAt(i); 6862 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6863 6864 // Only inspect grants matching user 6865 if (userHandle == UserHandle.USER_ALL 6866 || userHandle == UserHandle.getUserId(targetUid)) { 6867 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6868 final UriPermission perm = it.next(); 6869 6870 // Only inspect grants matching package 6871 if (packageName == null || perm.sourcePkg.equals(packageName) 6872 || perm.targetPkg.equals(packageName)) { 6873 persistChanged |= perm.revokeModes( 6874 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6875 6876 // Only remove when no modes remain; any persisted grants 6877 // will keep this alive. 6878 if (perm.modeFlags == 0) { 6879 it.remove(); 6880 } 6881 } 6882 } 6883 6884 if (perms.isEmpty()) { 6885 mGrantedUriPermissions.remove(targetUid); 6886 N--; 6887 i--; 6888 } 6889 } 6890 } 6891 6892 if (persistChanged) { 6893 schedulePersistUriGrants(); 6894 } 6895 } 6896 6897 @Override 6898 public IBinder newUriPermissionOwner(String name) { 6899 enforceNotIsolatedCaller("newUriPermissionOwner"); 6900 synchronized(this) { 6901 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6902 return owner.getExternalTokenLocked(); 6903 } 6904 } 6905 6906 @Override 6907 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6908 final int modeFlags, int sourceUserId, int targetUserId) { 6909 synchronized(this) { 6910 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6911 if (owner == null) { 6912 throw new IllegalArgumentException("Unknown owner: " + token); 6913 } 6914 if (fromUid != Binder.getCallingUid()) { 6915 if (Binder.getCallingUid() != Process.myUid()) { 6916 // Only system code can grant URI permissions on behalf 6917 // of other users. 6918 throw new SecurityException("nice try"); 6919 } 6920 } 6921 if (targetPkg == null) { 6922 throw new IllegalArgumentException("null target"); 6923 } 6924 if (uri == null) { 6925 throw new IllegalArgumentException("null uri"); 6926 } 6927 6928 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false), 6929 modeFlags, owner, targetUserId); 6930 } 6931 } 6932 6933 @Override 6934 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6935 synchronized(this) { 6936 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6937 if (owner == null) { 6938 throw new IllegalArgumentException("Unknown owner: " + token); 6939 } 6940 6941 if (uri == null) { 6942 owner.removeUriPermissionsLocked(mode); 6943 } else { 6944 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6945 } 6946 } 6947 } 6948 6949 private void schedulePersistUriGrants() { 6950 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6951 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6952 10 * DateUtils.SECOND_IN_MILLIS); 6953 } 6954 } 6955 6956 private void writeGrantedUriPermissions() { 6957 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6958 6959 // Snapshot permissions so we can persist without lock 6960 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6961 synchronized (this) { 6962 final int size = mGrantedUriPermissions.size(); 6963 for (int i = 0; i < size; i++) { 6964 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6965 for (UriPermission perm : perms.values()) { 6966 if (perm.persistedModeFlags != 0) { 6967 persist.add(perm.snapshot()); 6968 } 6969 } 6970 } 6971 } 6972 6973 FileOutputStream fos = null; 6974 try { 6975 fos = mGrantFile.startWrite(); 6976 6977 XmlSerializer out = new FastXmlSerializer(); 6978 out.setOutput(fos, "utf-8"); 6979 out.startDocument(null, true); 6980 out.startTag(null, TAG_URI_GRANTS); 6981 for (UriPermission.Snapshot perm : persist) { 6982 out.startTag(null, TAG_URI_GRANT); 6983 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6984 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6985 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6986 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6987 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6988 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6989 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6990 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6991 out.endTag(null, TAG_URI_GRANT); 6992 } 6993 out.endTag(null, TAG_URI_GRANTS); 6994 out.endDocument(); 6995 6996 mGrantFile.finishWrite(fos); 6997 } catch (IOException e) { 6998 if (fos != null) { 6999 mGrantFile.failWrite(fos); 7000 } 7001 } 7002 } 7003 7004 private void readGrantedUriPermissionsLocked() { 7005 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 7006 7007 final long now = System.currentTimeMillis(); 7008 7009 FileInputStream fis = null; 7010 try { 7011 fis = mGrantFile.openRead(); 7012 final XmlPullParser in = Xml.newPullParser(); 7013 in.setInput(fis, null); 7014 7015 int type; 7016 while ((type = in.next()) != END_DOCUMENT) { 7017 final String tag = in.getName(); 7018 if (type == START_TAG) { 7019 if (TAG_URI_GRANT.equals(tag)) { 7020 final int sourceUserId; 7021 final int targetUserId; 7022 final int userHandle = readIntAttribute(in, 7023 ATTR_USER_HANDLE, UserHandle.USER_NULL); 7024 if (userHandle != UserHandle.USER_NULL) { 7025 // For backwards compatibility. 7026 sourceUserId = userHandle; 7027 targetUserId = userHandle; 7028 } else { 7029 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 7030 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 7031 } 7032 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 7033 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 7034 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 7035 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 7036 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 7037 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 7038 7039 // Sanity check that provider still belongs to source package 7040 final ProviderInfo pi = getProviderInfoLocked( 7041 uri.getAuthority(), sourceUserId); 7042 if (pi != null && sourcePkg.equals(pi.packageName)) { 7043 int targetUid = -1; 7044 try { 7045 targetUid = AppGlobals.getPackageManager() 7046 .getPackageUid(targetPkg, targetUserId); 7047 } catch (RemoteException e) { 7048 } 7049 if (targetUid != -1) { 7050 final UriPermission perm = findOrCreateUriPermissionLocked( 7051 sourcePkg, targetPkg, targetUid, 7052 new GrantUri(sourceUserId, uri, prefix)); 7053 perm.initPersistedModes(modeFlags, createdTime); 7054 } 7055 } else { 7056 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 7057 + " but instead found " + pi); 7058 } 7059 } 7060 } 7061 } 7062 } catch (FileNotFoundException e) { 7063 // Missing grants is okay 7064 } catch (IOException e) { 7065 Log.wtf(TAG, "Failed reading Uri grants", e); 7066 } catch (XmlPullParserException e) { 7067 Log.wtf(TAG, "Failed reading Uri grants", e); 7068 } finally { 7069 IoUtils.closeQuietly(fis); 7070 } 7071 } 7072 7073 @Override 7074 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7075 enforceNotIsolatedCaller("takePersistableUriPermission"); 7076 7077 Preconditions.checkFlagsArgument(modeFlags, 7078 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7079 7080 synchronized (this) { 7081 final int callingUid = Binder.getCallingUid(); 7082 boolean persistChanged = false; 7083 GrantUri grantUri = new GrantUri(userId, uri, false); 7084 7085 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7086 new GrantUri(userId, uri, false)); 7087 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7088 new GrantUri(userId, uri, true)); 7089 7090 final boolean exactValid = (exactPerm != null) 7091 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 7092 final boolean prefixValid = (prefixPerm != null) 7093 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 7094 7095 if (!(exactValid || prefixValid)) { 7096 throw new SecurityException("No persistable permission grants found for UID " 7097 + callingUid + " and Uri " + grantUri.toSafeString()); 7098 } 7099 7100 if (exactValid) { 7101 persistChanged |= exactPerm.takePersistableModes(modeFlags); 7102 } 7103 if (prefixValid) { 7104 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 7105 } 7106 7107 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 7108 7109 if (persistChanged) { 7110 schedulePersistUriGrants(); 7111 } 7112 } 7113 } 7114 7115 @Override 7116 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 7117 enforceNotIsolatedCaller("releasePersistableUriPermission"); 7118 7119 Preconditions.checkFlagsArgument(modeFlags, 7120 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 7121 7122 synchronized (this) { 7123 final int callingUid = Binder.getCallingUid(); 7124 boolean persistChanged = false; 7125 7126 UriPermission exactPerm = findUriPermissionLocked(callingUid, 7127 new GrantUri(userId, uri, false)); 7128 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 7129 new GrantUri(userId, uri, true)); 7130 if (exactPerm == null && prefixPerm == null) { 7131 throw new SecurityException("No permission grants found for UID " + callingUid 7132 + " and Uri " + uri.toSafeString()); 7133 } 7134 7135 if (exactPerm != null) { 7136 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 7137 removeUriPermissionIfNeededLocked(exactPerm); 7138 } 7139 if (prefixPerm != null) { 7140 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 7141 removeUriPermissionIfNeededLocked(prefixPerm); 7142 } 7143 7144 if (persistChanged) { 7145 schedulePersistUriGrants(); 7146 } 7147 } 7148 } 7149 7150 /** 7151 * Prune any older {@link UriPermission} for the given UID until outstanding 7152 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 7153 * 7154 * @return if any mutations occured that require persisting. 7155 */ 7156 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 7157 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 7158 if (perms == null) return false; 7159 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 7160 7161 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 7162 for (UriPermission perm : perms.values()) { 7163 if (perm.persistedModeFlags != 0) { 7164 persisted.add(perm); 7165 } 7166 } 7167 7168 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 7169 if (trimCount <= 0) return false; 7170 7171 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 7172 for (int i = 0; i < trimCount; i++) { 7173 final UriPermission perm = persisted.get(i); 7174 7175 if (DEBUG_URI_PERMISSION) { 7176 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 7177 } 7178 7179 perm.releasePersistableModes(~0); 7180 removeUriPermissionIfNeededLocked(perm); 7181 } 7182 7183 return true; 7184 } 7185 7186 @Override 7187 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 7188 String packageName, boolean incoming) { 7189 enforceNotIsolatedCaller("getPersistedUriPermissions"); 7190 Preconditions.checkNotNull(packageName, "packageName"); 7191 7192 final int callingUid = Binder.getCallingUid(); 7193 final IPackageManager pm = AppGlobals.getPackageManager(); 7194 try { 7195 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 7196 if (packageUid != callingUid) { 7197 throw new SecurityException( 7198 "Package " + packageName + " does not belong to calling UID " + callingUid); 7199 } 7200 } catch (RemoteException e) { 7201 throw new SecurityException("Failed to verify package name ownership"); 7202 } 7203 7204 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 7205 synchronized (this) { 7206 if (incoming) { 7207 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 7208 callingUid); 7209 if (perms == null) { 7210 Slog.w(TAG, "No permission grants found for " + packageName); 7211 } else { 7212 for (UriPermission perm : perms.values()) { 7213 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 7214 result.add(perm.buildPersistedPublicApiObject()); 7215 } 7216 } 7217 } 7218 } else { 7219 final int size = mGrantedUriPermissions.size(); 7220 for (int i = 0; i < size; i++) { 7221 final ArrayMap<GrantUri, UriPermission> perms = 7222 mGrantedUriPermissions.valueAt(i); 7223 for (UriPermission perm : perms.values()) { 7224 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 7225 result.add(perm.buildPersistedPublicApiObject()); 7226 } 7227 } 7228 } 7229 } 7230 } 7231 return new ParceledListSlice<android.content.UriPermission>(result); 7232 } 7233 7234 @Override 7235 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 7236 synchronized (this) { 7237 ProcessRecord app = 7238 who != null ? getRecordForAppLocked(who) : null; 7239 if (app == null) return; 7240 7241 Message msg = Message.obtain(); 7242 msg.what = WAIT_FOR_DEBUGGER_MSG; 7243 msg.obj = app; 7244 msg.arg1 = waiting ? 1 : 0; 7245 mHandler.sendMessage(msg); 7246 } 7247 } 7248 7249 @Override 7250 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7251 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7252 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7253 outInfo.availMem = Process.getFreeMemory(); 7254 outInfo.totalMem = Process.getTotalMemory(); 7255 outInfo.threshold = homeAppMem; 7256 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7257 outInfo.hiddenAppThreshold = cachedAppMem; 7258 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7259 ProcessList.SERVICE_ADJ); 7260 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7261 ProcessList.VISIBLE_APP_ADJ); 7262 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7263 ProcessList.FOREGROUND_APP_ADJ); 7264 } 7265 7266 // ========================================================= 7267 // TASK MANAGEMENT 7268 // ========================================================= 7269 7270 @Override 7271 public List<IAppTask> getAppTasks() { 7272 final PackageManager pm = mContext.getPackageManager(); 7273 int callingUid = Binder.getCallingUid(); 7274 long ident = Binder.clearCallingIdentity(); 7275 7276 // Compose the list of packages for this id to test against 7277 HashSet<String> packages = new HashSet<String>(); 7278 String[] uidPackages = pm.getPackagesForUid(callingUid); 7279 for (int i = 0; i < uidPackages.length; i++) { 7280 packages.add(uidPackages[i]); 7281 } 7282 7283 synchronized(this) { 7284 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7285 try { 7286 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7287 7288 final int N = mRecentTasks.size(); 7289 for (int i = 0; i < N; i++) { 7290 TaskRecord tr = mRecentTasks.get(i); 7291 // Skip tasks that are not created by the caller 7292 if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) { 7293 ActivityManager.RecentTaskInfo taskInfo = 7294 createRecentTaskInfoFromTaskRecord(tr); 7295 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7296 list.add(taskImpl); 7297 } 7298 } 7299 } finally { 7300 Binder.restoreCallingIdentity(ident); 7301 } 7302 return list; 7303 } 7304 } 7305 7306 @Override 7307 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7308 final int callingUid = Binder.getCallingUid(); 7309 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7310 7311 synchronized(this) { 7312 if (localLOGV) Slog.v( 7313 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7314 7315 final boolean allowed = checkCallingPermission( 7316 android.Manifest.permission.GET_TASKS) 7317 == PackageManager.PERMISSION_GRANTED; 7318 if (!allowed) { 7319 Slog.w(TAG, "getTasks: caller " + callingUid 7320 + " does not hold GET_TASKS; limiting output"); 7321 } 7322 7323 // TODO: Improve with MRU list from all ActivityStacks. 7324 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7325 } 7326 7327 return list; 7328 } 7329 7330 TaskRecord getMostRecentTask() { 7331 return mRecentTasks.get(0); 7332 } 7333 7334 /** 7335 * Creates a new RecentTaskInfo from a TaskRecord. 7336 */ 7337 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7338 // Update the task description to reflect any changes in the task stack 7339 tr.updateTaskDescription(); 7340 7341 // Compose the recent task info 7342 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo(); 7343 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId; 7344 rti.persistentId = tr.taskId; 7345 rti.baseIntent = new Intent(tr.getBaseIntent()); 7346 rti.origActivity = tr.origActivity; 7347 rti.description = tr.lastDescription; 7348 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1; 7349 rti.userId = tr.userId; 7350 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7351 rti.firstActiveTime = tr.firstActiveTime; 7352 rti.lastActiveTime = tr.lastActiveTime; 7353 rti.affiliatedTaskId = tr.mAffiliatedTaskId; 7354 return rti; 7355 } 7356 7357 @Override 7358 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) { 7359 final int callingUid = Binder.getCallingUid(); 7360 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7361 false, ALLOW_FULL_ONLY, "getRecentTasks", null); 7362 7363 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0; 7364 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0; 7365 synchronized (this) { 7366 final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS) 7367 == PackageManager.PERMISSION_GRANTED; 7368 if (!allowed) { 7369 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7370 + " does not hold GET_TASKS; limiting output"); 7371 } 7372 final boolean detailed = checkCallingPermission( 7373 android.Manifest.permission.GET_DETAILED_TASKS) 7374 == PackageManager.PERMISSION_GRANTED; 7375 7376 IPackageManager pm = AppGlobals.getPackageManager(); 7377 7378 final int N = mRecentTasks.size(); 7379 ArrayList<ActivityManager.RecentTaskInfo> res 7380 = new ArrayList<ActivityManager.RecentTaskInfo>( 7381 maxNum < N ? maxNum : N); 7382 7383 final Set<Integer> includedUsers; 7384 if (includeProfiles) { 7385 includedUsers = getProfileIdsLocked(userId); 7386 } else { 7387 includedUsers = new HashSet<Integer>(); 7388 } 7389 includedUsers.add(Integer.valueOf(userId)); 7390 7391 // Regroup affiliated tasks together. 7392 for (int i = 0; i < N; ) { 7393 TaskRecord task = mRecentTasks.remove(i); 7394 if (mTmpRecents.contains(task)) { 7395 continue; 7396 } 7397 int affiliatedTaskId = task.mAffiliatedTaskId; 7398 while (true) { 7399 TaskRecord next = task.mNextAffiliate; 7400 if (next == null) { 7401 break; 7402 } 7403 if (next.mAffiliatedTaskId != affiliatedTaskId) { 7404 Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" + 7405 next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId); 7406 task.setNextAffiliate(null); 7407 if (next.mPrevAffiliate == task) { 7408 next.setPrevAffiliate(null); 7409 } 7410 break; 7411 } 7412 if (next.mPrevAffiliate != task) { 7413 Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" + 7414 next.mPrevAffiliate + " task=" + task); 7415 next.setPrevAffiliate(null); 7416 break; 7417 } 7418 if (!mRecentTasks.contains(next)) { 7419 Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks"); 7420 task.setNextAffiliate(null); 7421 if (next.mPrevAffiliate == task) { 7422 next.setPrevAffiliate(null); 7423 } 7424 break; 7425 } 7426 task = next; 7427 } 7428 // task is now the end of the list 7429 do { 7430 mRecentTasks.remove(task); 7431 mRecentTasks.add(i++, task); 7432 mTmpRecents.add(task); 7433 } while ((task = task.mPrevAffiliate) != null); 7434 } 7435 mTmpRecents.clear(); 7436 // mRecentTasks is now in sorted, affiliated order. 7437 7438 for (int i=0; i<N && maxNum > 0; i++) { 7439 TaskRecord tr = mRecentTasks.get(i); 7440 // Only add calling user or related users recent tasks 7441 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7442 7443 // Return the entry if desired by the caller. We always return 7444 // the first entry, because callers always expect this to be the 7445 // foreground app. We may filter others if the caller has 7446 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7447 // we should exclude the entry. 7448 7449 if (i == 0 7450 || withExcluded 7451 || (tr.intent == null) 7452 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) 7453 == 0)) { 7454 if (!allowed) { 7455 // If the caller doesn't have the GET_TASKS permission, then only 7456 // allow them to see a small subset of tasks -- their own and home. 7457 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7458 continue; 7459 } 7460 } 7461 if (tr.autoRemoveRecents && tr.getTopActivity() == null) { 7462 // Don't include auto remove tasks that are finished or finishing. 7463 continue; 7464 } 7465 7466 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7467 if (!detailed) { 7468 rti.baseIntent.replaceExtras((Bundle)null); 7469 } 7470 7471 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7472 // Check whether this activity is currently available. 7473 try { 7474 if (rti.origActivity != null) { 7475 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7476 == null) { 7477 continue; 7478 } 7479 } else if (rti.baseIntent != null) { 7480 if (pm.queryIntentActivities(rti.baseIntent, 7481 null, 0, userId) == null) { 7482 continue; 7483 } 7484 } 7485 } catch (RemoteException e) { 7486 // Will never happen. 7487 } 7488 } 7489 7490 res.add(rti); 7491 maxNum--; 7492 } 7493 } 7494 return res; 7495 } 7496 } 7497 7498 private TaskRecord recentTaskForIdLocked(int id) { 7499 final int N = mRecentTasks.size(); 7500 for (int i=0; i<N; i++) { 7501 TaskRecord tr = mRecentTasks.get(i); 7502 if (tr.taskId == id) { 7503 return tr; 7504 } 7505 } 7506 return null; 7507 } 7508 7509 @Override 7510 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) { 7511 synchronized (this) { 7512 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7513 "getTaskThumbnail()"); 7514 TaskRecord tr = recentTaskForIdLocked(id); 7515 if (tr != null) { 7516 return tr.getTaskThumbnailLocked(); 7517 } 7518 } 7519 return null; 7520 } 7521 7522 @Override 7523 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7524 synchronized (this) { 7525 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7526 if (r != null) { 7527 r.taskDescription = td; 7528 r.task.updateTaskDescription(); 7529 } 7530 } 7531 } 7532 7533 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7534 if (!pr.killedByAm) { 7535 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7536 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7537 pr.processName, pr.setAdj, reason); 7538 pr.killedByAm = true; 7539 Process.killProcessQuiet(pr.pid); 7540 Process.killProcessGroup(pr.info.uid, pr.pid); 7541 } 7542 } 7543 7544 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7545 tr.disposeThumbnail(); 7546 mRecentTasks.remove(tr); 7547 tr.closeRecentsChain(); 7548 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7549 Intent baseIntent = new Intent( 7550 tr.intent != null ? tr.intent : tr.affinityIntent); 7551 ComponentName component = baseIntent.getComponent(); 7552 if (component == null) { 7553 Slog.w(TAG, "Now component for base intent of task: " + tr); 7554 return; 7555 } 7556 7557 // Find any running services associated with this app. 7558 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7559 7560 if (killProcesses) { 7561 // Find any running processes associated with this app. 7562 final String pkg = component.getPackageName(); 7563 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7564 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7565 for (int i=0; i<pmap.size(); i++) { 7566 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7567 for (int j=0; j<uids.size(); j++) { 7568 ProcessRecord proc = uids.valueAt(j); 7569 if (proc.userId != tr.userId) { 7570 continue; 7571 } 7572 if (!proc.pkgList.containsKey(pkg)) { 7573 continue; 7574 } 7575 procs.add(proc); 7576 } 7577 } 7578 7579 // Kill the running processes. 7580 for (int i=0; i<procs.size(); i++) { 7581 ProcessRecord pr = procs.get(i); 7582 if (pr == mHomeProcess) { 7583 // Don't kill the home process along with tasks from the same package. 7584 continue; 7585 } 7586 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7587 killUnneededProcessLocked(pr, "remove task"); 7588 } else { 7589 pr.waitingToKill = "remove task"; 7590 } 7591 } 7592 } 7593 } 7594 7595 /** 7596 * Removes the task with the specified task id. 7597 * 7598 * @param taskId Identifier of the task to be removed. 7599 * @param flags Additional operational flags. May be 0 or 7600 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7601 * @return Returns true if the given task was found and removed. 7602 */ 7603 private boolean removeTaskByIdLocked(int taskId, int flags) { 7604 TaskRecord tr = recentTaskForIdLocked(taskId); 7605 if (tr != null) { 7606 tr.removeTaskActivitiesLocked(); 7607 cleanUpRemovedTaskLocked(tr, flags); 7608 if (tr.isPersistable) { 7609 notifyTaskPersisterLocked(tr, true); 7610 } 7611 return true; 7612 } 7613 return false; 7614 } 7615 7616 @Override 7617 public boolean removeTask(int taskId, int flags) { 7618 synchronized (this) { 7619 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7620 "removeTask()"); 7621 long ident = Binder.clearCallingIdentity(); 7622 try { 7623 return removeTaskByIdLocked(taskId, flags); 7624 } finally { 7625 Binder.restoreCallingIdentity(ident); 7626 } 7627 } 7628 } 7629 7630 /** 7631 * TODO: Add mController hook 7632 */ 7633 @Override 7634 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7635 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7636 "moveTaskToFront()"); 7637 7638 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7639 synchronized(this) { 7640 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7641 Binder.getCallingUid(), "Task to front")) { 7642 ActivityOptions.abort(options); 7643 return; 7644 } 7645 final long origId = Binder.clearCallingIdentity(); 7646 try { 7647 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7648 if (task == null) { 7649 return; 7650 } 7651 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7652 mStackSupervisor.showLockTaskToast(); 7653 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7654 return; 7655 } 7656 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked(); 7657 if (prev != null && prev.isRecentsActivity()) { 7658 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE); 7659 } 7660 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7661 } finally { 7662 Binder.restoreCallingIdentity(origId); 7663 } 7664 ActivityOptions.abort(options); 7665 } 7666 } 7667 7668 @Override 7669 public void moveTaskToBack(int taskId) { 7670 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7671 "moveTaskToBack()"); 7672 7673 synchronized(this) { 7674 TaskRecord tr = recentTaskForIdLocked(taskId); 7675 if (tr != null) { 7676 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7677 ActivityStack stack = tr.stack; 7678 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7679 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7680 Binder.getCallingUid(), "Task to back")) { 7681 return; 7682 } 7683 } 7684 final long origId = Binder.clearCallingIdentity(); 7685 try { 7686 stack.moveTaskToBackLocked(taskId, null); 7687 } finally { 7688 Binder.restoreCallingIdentity(origId); 7689 } 7690 } 7691 } 7692 } 7693 7694 /** 7695 * Moves an activity, and all of the other activities within the same task, to the bottom 7696 * of the history stack. The activity's order within the task is unchanged. 7697 * 7698 * @param token A reference to the activity we wish to move 7699 * @param nonRoot If false then this only works if the activity is the root 7700 * of a task; if true it will work for any activity in a task. 7701 * @return Returns true if the move completed, false if not. 7702 */ 7703 @Override 7704 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7705 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7706 synchronized(this) { 7707 final long origId = Binder.clearCallingIdentity(); 7708 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7709 if (taskId >= 0) { 7710 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7711 } 7712 Binder.restoreCallingIdentity(origId); 7713 } 7714 return false; 7715 } 7716 7717 @Override 7718 public void moveTaskBackwards(int task) { 7719 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7720 "moveTaskBackwards()"); 7721 7722 synchronized(this) { 7723 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7724 Binder.getCallingUid(), "Task backwards")) { 7725 return; 7726 } 7727 final long origId = Binder.clearCallingIdentity(); 7728 moveTaskBackwardsLocked(task); 7729 Binder.restoreCallingIdentity(origId); 7730 } 7731 } 7732 7733 private final void moveTaskBackwardsLocked(int task) { 7734 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7735 } 7736 7737 @Override 7738 public IBinder getHomeActivityToken() throws RemoteException { 7739 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7740 "getHomeActivityToken()"); 7741 synchronized (this) { 7742 return mStackSupervisor.getHomeActivityToken(); 7743 } 7744 } 7745 7746 @Override 7747 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7748 IActivityContainerCallback callback) throws RemoteException { 7749 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7750 "createActivityContainer()"); 7751 synchronized (this) { 7752 if (parentActivityToken == null) { 7753 throw new IllegalArgumentException("parent token must not be null"); 7754 } 7755 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7756 if (r == null) { 7757 return null; 7758 } 7759 if (callback == null) { 7760 throw new IllegalArgumentException("callback must not be null"); 7761 } 7762 return mStackSupervisor.createActivityContainer(r, callback); 7763 } 7764 } 7765 7766 @Override 7767 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7768 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7769 "deleteActivityContainer()"); 7770 synchronized (this) { 7771 mStackSupervisor.deleteActivityContainer(container); 7772 } 7773 } 7774 7775 @Override 7776 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7777 throws RemoteException { 7778 synchronized (this) { 7779 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7780 if (stack != null) { 7781 return stack.mActivityContainer; 7782 } 7783 return null; 7784 } 7785 } 7786 7787 @Override 7788 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7789 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7790 "moveTaskToStack()"); 7791 if (stackId == HOME_STACK_ID) { 7792 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7793 new RuntimeException("here").fillInStackTrace()); 7794 } 7795 synchronized (this) { 7796 long ident = Binder.clearCallingIdentity(); 7797 try { 7798 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7799 + stackId + " toTop=" + toTop); 7800 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7801 } finally { 7802 Binder.restoreCallingIdentity(ident); 7803 } 7804 } 7805 } 7806 7807 @Override 7808 public void resizeStack(int stackBoxId, Rect bounds) { 7809 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7810 "resizeStackBox()"); 7811 long ident = Binder.clearCallingIdentity(); 7812 try { 7813 mWindowManager.resizeStack(stackBoxId, bounds); 7814 } finally { 7815 Binder.restoreCallingIdentity(ident); 7816 } 7817 } 7818 7819 @Override 7820 public List<StackInfo> getAllStackInfos() { 7821 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7822 "getAllStackInfos()"); 7823 long ident = Binder.clearCallingIdentity(); 7824 try { 7825 synchronized (this) { 7826 return mStackSupervisor.getAllStackInfosLocked(); 7827 } 7828 } finally { 7829 Binder.restoreCallingIdentity(ident); 7830 } 7831 } 7832 7833 @Override 7834 public StackInfo getStackInfo(int stackId) { 7835 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7836 "getStackInfo()"); 7837 long ident = Binder.clearCallingIdentity(); 7838 try { 7839 synchronized (this) { 7840 return mStackSupervisor.getStackInfoLocked(stackId); 7841 } 7842 } finally { 7843 Binder.restoreCallingIdentity(ident); 7844 } 7845 } 7846 7847 @Override 7848 public boolean isInHomeStack(int taskId) { 7849 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7850 "getStackInfo()"); 7851 long ident = Binder.clearCallingIdentity(); 7852 try { 7853 synchronized (this) { 7854 TaskRecord tr = recentTaskForIdLocked(taskId); 7855 return tr != null && tr.stack != null && tr.stack.isHomeStack(); 7856 } 7857 } finally { 7858 Binder.restoreCallingIdentity(ident); 7859 } 7860 } 7861 7862 @Override 7863 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7864 synchronized(this) { 7865 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7866 } 7867 } 7868 7869 private boolean isLockTaskAuthorized(String pkg) { 7870 final DevicePolicyManager dpm = (DevicePolicyManager) 7871 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7872 try { 7873 int uid = mContext.getPackageManager().getPackageUid(pkg, 7874 Binder.getCallingUserHandle().getIdentifier()); 7875 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg); 7876 } catch (NameNotFoundException e) { 7877 return false; 7878 } 7879 } 7880 7881 void startLockTaskMode(TaskRecord task) { 7882 final String pkg; 7883 synchronized (this) { 7884 pkg = task.intent.getComponent().getPackageName(); 7885 } 7886 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID; 7887 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) { 7888 final TaskRecord taskRecord = task; 7889 mHandler.post(new Runnable() { 7890 @Override 7891 public void run() { 7892 mLockToAppRequest.showLockTaskPrompt(taskRecord); 7893 } 7894 }); 7895 return; 7896 } 7897 long ident = Binder.clearCallingIdentity(); 7898 try { 7899 synchronized (this) { 7900 // Since we lost lock on task, make sure it is still there. 7901 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7902 if (task != null) { 7903 if (!isSystemInitiated 7904 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { 7905 throw new IllegalArgumentException("Invalid task, not in foreground"); 7906 } 7907 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); 7908 } 7909 } 7910 } finally { 7911 Binder.restoreCallingIdentity(ident); 7912 } 7913 } 7914 7915 @Override 7916 public void startLockTaskMode(int taskId) { 7917 final TaskRecord task; 7918 long ident = Binder.clearCallingIdentity(); 7919 try { 7920 synchronized (this) { 7921 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7922 } 7923 } finally { 7924 Binder.restoreCallingIdentity(ident); 7925 } 7926 if (task != null) { 7927 startLockTaskMode(task); 7928 } 7929 } 7930 7931 @Override 7932 public void startLockTaskMode(IBinder token) { 7933 final TaskRecord task; 7934 long ident = Binder.clearCallingIdentity(); 7935 try { 7936 synchronized (this) { 7937 final ActivityRecord r = ActivityRecord.forToken(token); 7938 if (r == null) { 7939 return; 7940 } 7941 task = r.task; 7942 } 7943 } finally { 7944 Binder.restoreCallingIdentity(ident); 7945 } 7946 if (task != null) { 7947 startLockTaskMode(task); 7948 } 7949 } 7950 7951 @Override 7952 public void startLockTaskModeOnCurrent() throws RemoteException { 7953 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7954 ActivityRecord r = null; 7955 synchronized (this) { 7956 r = mStackSupervisor.topRunningActivityLocked(); 7957 } 7958 startLockTaskMode(r.task); 7959 } 7960 7961 @Override 7962 public void stopLockTaskMode() { 7963 // Verify that the user matches the package of the intent for the TaskRecord 7964 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode 7965 // and stopLockTaskMode. 7966 final int callingUid = Binder.getCallingUid(); 7967 if (callingUid != Process.SYSTEM_UID) { 7968 try { 7969 String pkg = 7970 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName(); 7971 int uid = mContext.getPackageManager().getPackageUid(pkg, 7972 Binder.getCallingUserHandle().getIdentifier()); 7973 if (uid != callingUid) { 7974 throw new SecurityException("Invalid uid, expected " + uid); 7975 } 7976 } catch (NameNotFoundException e) { 7977 Log.d(TAG, "stopLockTaskMode " + e); 7978 return; 7979 } 7980 } 7981 long ident = Binder.clearCallingIdentity(); 7982 try { 7983 Log.d(TAG, "stopLockTaskMode"); 7984 // Stop lock task 7985 synchronized (this) { 7986 mStackSupervisor.setLockTaskModeLocked(null, false); 7987 } 7988 } finally { 7989 Binder.restoreCallingIdentity(ident); 7990 } 7991 } 7992 7993 @Override 7994 public void stopLockTaskModeOnCurrent() throws RemoteException { 7995 checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS); 7996 long ident = Binder.clearCallingIdentity(); 7997 try { 7998 stopLockTaskMode(); 7999 } finally { 8000 Binder.restoreCallingIdentity(ident); 8001 } 8002 } 8003 8004 @Override 8005 public boolean isInLockTaskMode() { 8006 synchronized (this) { 8007 return mStackSupervisor.isInLockTaskMode(); 8008 } 8009 } 8010 8011 // ========================================================= 8012 // CONTENT PROVIDERS 8013 // ========================================================= 8014 8015 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 8016 List<ProviderInfo> providers = null; 8017 try { 8018 providers = AppGlobals.getPackageManager(). 8019 queryContentProviders(app.processName, app.uid, 8020 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 8021 } catch (RemoteException ex) { 8022 } 8023 if (DEBUG_MU) 8024 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 8025 int userId = app.userId; 8026 if (providers != null) { 8027 int N = providers.size(); 8028 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 8029 for (int i=0; i<N; i++) { 8030 ProviderInfo cpi = 8031 (ProviderInfo)providers.get(i); 8032 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8033 cpi.name, cpi.flags); 8034 if (singleton && UserHandle.getUserId(app.uid) != 0) { 8035 // This is a singleton provider, but a user besides the 8036 // default user is asking to initialize a process it runs 8037 // in... well, no, it doesn't actually run in this process, 8038 // it runs in the process of the default user. Get rid of it. 8039 providers.remove(i); 8040 N--; 8041 i--; 8042 continue; 8043 } 8044 8045 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8046 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 8047 if (cpr == null) { 8048 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 8049 mProviderMap.putProviderByClass(comp, cpr); 8050 } 8051 if (DEBUG_MU) 8052 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 8053 app.pubProviders.put(cpi.name, cpr); 8054 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 8055 // Don't add this if it is a platform component that is marked 8056 // to run in multiple processes, because this is actually 8057 // part of the framework so doesn't make sense to track as a 8058 // separate apk in the process. 8059 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode, 8060 mProcessStats); 8061 } 8062 ensurePackageDexOpt(cpi.applicationInfo.packageName); 8063 } 8064 } 8065 return providers; 8066 } 8067 8068 /** 8069 * Check if {@link ProcessRecord} has a possible chance at accessing the 8070 * given {@link ProviderInfo}. Final permission checking is always done 8071 * in {@link ContentProvider}. 8072 */ 8073 private final String checkContentProviderPermissionLocked( 8074 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) { 8075 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 8076 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 8077 boolean checkedGrants = false; 8078 if (checkUser) { 8079 // Looking for cross-user grants before enforcing the typical cross-users permissions 8080 int tmpTargetUserId = unsafeConvertIncomingUser(userId); 8081 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) { 8082 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) { 8083 return null; 8084 } 8085 checkedGrants = true; 8086 } 8087 userId = handleIncomingUser(callingPid, callingUid, userId, 8088 false, ALLOW_NON_FULL, 8089 "checkContentProviderPermissionLocked " + cpi.authority, null); 8090 if (userId != tmpTargetUserId) { 8091 // When we actually went to determine the final targer user ID, this ended 8092 // up different than our initial check for the authority. This is because 8093 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to 8094 // SELF. So we need to re-check the grants again. 8095 checkedGrants = false; 8096 } 8097 } 8098 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 8099 cpi.applicationInfo.uid, cpi.exported) 8100 == PackageManager.PERMISSION_GRANTED) { 8101 return null; 8102 } 8103 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 8104 cpi.applicationInfo.uid, cpi.exported) 8105 == PackageManager.PERMISSION_GRANTED) { 8106 return null; 8107 } 8108 8109 PathPermission[] pps = cpi.pathPermissions; 8110 if (pps != null) { 8111 int i = pps.length; 8112 while (i > 0) { 8113 i--; 8114 PathPermission pp = pps[i]; 8115 String pprperm = pp.getReadPermission(); 8116 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid, 8117 cpi.applicationInfo.uid, cpi.exported) 8118 == PackageManager.PERMISSION_GRANTED) { 8119 return null; 8120 } 8121 String ppwperm = pp.getWritePermission(); 8122 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid, 8123 cpi.applicationInfo.uid, cpi.exported) 8124 == PackageManager.PERMISSION_GRANTED) { 8125 return null; 8126 } 8127 } 8128 } 8129 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) { 8130 return null; 8131 } 8132 8133 String msg; 8134 if (!cpi.exported) { 8135 msg = "Permission Denial: opening provider " + cpi.name 8136 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8137 + ", uid=" + callingUid + ") that is not exported from uid " 8138 + cpi.applicationInfo.uid; 8139 } else { 8140 msg = "Permission Denial: opening provider " + cpi.name 8141 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 8142 + ", uid=" + callingUid + ") requires " 8143 + cpi.readPermission + " or " + cpi.writePermission; 8144 } 8145 Slog.w(TAG, msg); 8146 return msg; 8147 } 8148 8149 /** 8150 * Returns if the ContentProvider has granted a uri to callingUid 8151 */ 8152 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) { 8153 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 8154 if (perms != null) { 8155 for (int i=perms.size()-1; i>=0; i--) { 8156 GrantUri grantUri = perms.keyAt(i); 8157 if (grantUri.sourceUserId == userId || !checkUser) { 8158 if (matchesProvider(grantUri.uri, cpi)) { 8159 return true; 8160 } 8161 } 8162 } 8163 } 8164 return false; 8165 } 8166 8167 /** 8168 * Returns true if the uri authority is one of the authorities specified in the provider. 8169 */ 8170 boolean matchesProvider(Uri uri, ProviderInfo cpi) { 8171 String uriAuth = uri.getAuthority(); 8172 String cpiAuth = cpi.authority; 8173 if (cpiAuth.indexOf(';') == -1) { 8174 return cpiAuth.equals(uriAuth); 8175 } 8176 String[] cpiAuths = cpiAuth.split(";"); 8177 int length = cpiAuths.length; 8178 for (int i = 0; i < length; i++) { 8179 if (cpiAuths[i].equals(uriAuth)) return true; 8180 } 8181 return false; 8182 } 8183 8184 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 8185 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8186 if (r != null) { 8187 for (int i=0; i<r.conProviders.size(); i++) { 8188 ContentProviderConnection conn = r.conProviders.get(i); 8189 if (conn.provider == cpr) { 8190 if (DEBUG_PROVIDER) Slog.v(TAG, 8191 "Adding provider requested by " 8192 + r.processName + " from process " 8193 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8194 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8195 if (stable) { 8196 conn.stableCount++; 8197 conn.numStableIncs++; 8198 } else { 8199 conn.unstableCount++; 8200 conn.numUnstableIncs++; 8201 } 8202 return conn; 8203 } 8204 } 8205 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 8206 if (stable) { 8207 conn.stableCount = 1; 8208 conn.numStableIncs = 1; 8209 } else { 8210 conn.unstableCount = 1; 8211 conn.numUnstableIncs = 1; 8212 } 8213 cpr.connections.add(conn); 8214 r.conProviders.add(conn); 8215 return conn; 8216 } 8217 cpr.addExternalProcessHandleLocked(externalProcessToken); 8218 return null; 8219 } 8220 8221 boolean decProviderCountLocked(ContentProviderConnection conn, 8222 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 8223 if (conn != null) { 8224 cpr = conn.provider; 8225 if (DEBUG_PROVIDER) Slog.v(TAG, 8226 "Removing provider requested by " 8227 + conn.client.processName + " from process " 8228 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 8229 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 8230 if (stable) { 8231 conn.stableCount--; 8232 } else { 8233 conn.unstableCount--; 8234 } 8235 if (conn.stableCount == 0 && conn.unstableCount == 0) { 8236 cpr.connections.remove(conn); 8237 conn.client.conProviders.remove(conn); 8238 return true; 8239 } 8240 return false; 8241 } 8242 cpr.removeExternalProcessHandleLocked(externalProcessToken); 8243 return false; 8244 } 8245 8246 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 8247 String name, IBinder token, boolean stable, int userId) { 8248 ContentProviderRecord cpr; 8249 ContentProviderConnection conn = null; 8250 ProviderInfo cpi = null; 8251 8252 synchronized(this) { 8253 ProcessRecord r = null; 8254 if (caller != null) { 8255 r = getRecordForAppLocked(caller); 8256 if (r == null) { 8257 throw new SecurityException( 8258 "Unable to find app for caller " + caller 8259 + " (pid=" + Binder.getCallingPid() 8260 + ") when getting content provider " + name); 8261 } 8262 } 8263 8264 boolean checkCrossUser = true; 8265 8266 // First check if this content provider has been published... 8267 cpr = mProviderMap.getProviderByName(name, userId); 8268 // If that didn't work, check if it exists for user 0 and then 8269 // verify that it's a singleton provider before using it. 8270 if (cpr == null && userId != UserHandle.USER_OWNER) { 8271 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER); 8272 if (cpr != null) { 8273 cpi = cpr.info; 8274 if (isSingleton(cpi.processName, cpi.applicationInfo, 8275 cpi.name, cpi.flags) 8276 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) { 8277 userId = UserHandle.USER_OWNER; 8278 checkCrossUser = false; 8279 } else { 8280 cpr = null; 8281 cpi = null; 8282 } 8283 } 8284 } 8285 8286 boolean providerRunning = cpr != null; 8287 if (providerRunning) { 8288 cpi = cpr.info; 8289 String msg; 8290 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser)) 8291 != null) { 8292 throw new SecurityException(msg); 8293 } 8294 8295 if (r != null && cpr.canRunHere(r)) { 8296 // This provider has been published or is in the process 8297 // of being published... but it is also allowed to run 8298 // in the caller's process, so don't make a connection 8299 // and just let the caller instantiate its own instance. 8300 ContentProviderHolder holder = cpr.newHolder(null); 8301 // don't give caller the provider object, it needs 8302 // to make its own. 8303 holder.provider = null; 8304 return holder; 8305 } 8306 8307 final long origId = Binder.clearCallingIdentity(); 8308 8309 // In this case the provider instance already exists, so we can 8310 // return it right away. 8311 conn = incProviderCountLocked(r, cpr, token, stable); 8312 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 8313 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 8314 // If this is a perceptible app accessing the provider, 8315 // make sure to count it as being accessed and thus 8316 // back up on the LRU list. This is good because 8317 // content providers are often expensive to start. 8318 updateLruProcessLocked(cpr.proc, false, null); 8319 } 8320 } 8321 8322 if (cpr.proc != null) { 8323 if (false) { 8324 if (cpr.name.flattenToShortString().equals( 8325 "com.android.providers.calendar/.CalendarProvider2")) { 8326 Slog.v(TAG, "****************** KILLING " 8327 + cpr.name.flattenToShortString()); 8328 Process.killProcess(cpr.proc.pid); 8329 } 8330 } 8331 boolean success = updateOomAdjLocked(cpr.proc); 8332 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 8333 // NOTE: there is still a race here where a signal could be 8334 // pending on the process even though we managed to update its 8335 // adj level. Not sure what to do about this, but at least 8336 // the race is now smaller. 8337 if (!success) { 8338 // Uh oh... it looks like the provider's process 8339 // has been killed on us. We need to wait for a new 8340 // process to be started, and make sure its death 8341 // doesn't kill our process. 8342 Slog.i(TAG, 8343 "Existing provider " + cpr.name.flattenToShortString() 8344 + " is crashing; detaching " + r); 8345 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 8346 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 8347 if (!lastRef) { 8348 // This wasn't the last ref our process had on 8349 // the provider... we have now been killed, bail. 8350 return null; 8351 } 8352 providerRunning = false; 8353 conn = null; 8354 } 8355 } 8356 8357 Binder.restoreCallingIdentity(origId); 8358 } 8359 8360 boolean singleton; 8361 if (!providerRunning) { 8362 try { 8363 cpi = AppGlobals.getPackageManager(). 8364 resolveContentProvider(name, 8365 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 8366 } catch (RemoteException ex) { 8367 } 8368 if (cpi == null) { 8369 return null; 8370 } 8371 // If the provider is a singleton AND 8372 // (it's a call within the same user || the provider is a 8373 // privileged app) 8374 // Then allow connecting to the singleton provider 8375 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8376 cpi.name, cpi.flags) 8377 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid); 8378 if (singleton) { 8379 userId = UserHandle.USER_OWNER; 8380 } 8381 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8382 8383 String msg; 8384 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton)) 8385 != null) { 8386 throw new SecurityException(msg); 8387 } 8388 8389 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8390 && !cpi.processName.equals("system")) { 8391 // If this content provider does not run in the system 8392 // process, and the system is not yet ready to run other 8393 // processes, then fail fast instead of hanging. 8394 throw new IllegalArgumentException( 8395 "Attempt to launch content provider before system ready"); 8396 } 8397 8398 // Make sure that the user who owns this provider is started. If not, 8399 // we don't want to allow it to run. 8400 if (mStartedUsers.get(userId) == null) { 8401 Slog.w(TAG, "Unable to launch app " 8402 + cpi.applicationInfo.packageName + "/" 8403 + cpi.applicationInfo.uid + " for provider " 8404 + name + ": user " + userId + " is stopped"); 8405 return null; 8406 } 8407 8408 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8409 cpr = mProviderMap.getProviderByClass(comp, userId); 8410 final boolean firstClass = cpr == null; 8411 if (firstClass) { 8412 try { 8413 ApplicationInfo ai = 8414 AppGlobals.getPackageManager(). 8415 getApplicationInfo( 8416 cpi.applicationInfo.packageName, 8417 STOCK_PM_FLAGS, userId); 8418 if (ai == null) { 8419 Slog.w(TAG, "No package info for content provider " 8420 + cpi.name); 8421 return null; 8422 } 8423 ai = getAppInfoForUser(ai, userId); 8424 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8425 } catch (RemoteException ex) { 8426 // pm is in same process, this will never happen. 8427 } 8428 } 8429 8430 if (r != null && cpr.canRunHere(r)) { 8431 // If this is a multiprocess provider, then just return its 8432 // info and allow the caller to instantiate it. Only do 8433 // this if the provider is the same user as the caller's 8434 // process, or can run as root (so can be in any process). 8435 return cpr.newHolder(null); 8436 } 8437 8438 if (DEBUG_PROVIDER) { 8439 RuntimeException e = new RuntimeException("here"); 8440 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8441 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8442 } 8443 8444 // This is single process, and our app is now connecting to it. 8445 // See if we are already in the process of launching this 8446 // provider. 8447 final int N = mLaunchingProviders.size(); 8448 int i; 8449 for (i=0; i<N; i++) { 8450 if (mLaunchingProviders.get(i) == cpr) { 8451 break; 8452 } 8453 } 8454 8455 // If the provider is not already being launched, then get it 8456 // started. 8457 if (i >= N) { 8458 final long origId = Binder.clearCallingIdentity(); 8459 8460 try { 8461 // Content provider is now in use, its package can't be stopped. 8462 try { 8463 AppGlobals.getPackageManager().setPackageStoppedState( 8464 cpr.appInfo.packageName, false, userId); 8465 } catch (RemoteException e) { 8466 } catch (IllegalArgumentException e) { 8467 Slog.w(TAG, "Failed trying to unstop package " 8468 + cpr.appInfo.packageName + ": " + e); 8469 } 8470 8471 // Use existing process if already started 8472 ProcessRecord proc = getProcessRecordLocked( 8473 cpi.processName, cpr.appInfo.uid, false); 8474 if (proc != null && proc.thread != null) { 8475 if (DEBUG_PROVIDER) { 8476 Slog.d(TAG, "Installing in existing process " + proc); 8477 } 8478 proc.pubProviders.put(cpi.name, cpr); 8479 try { 8480 proc.thread.scheduleInstallProvider(cpi); 8481 } catch (RemoteException e) { 8482 } 8483 } else { 8484 proc = startProcessLocked(cpi.processName, 8485 cpr.appInfo, false, 0, "content provider", 8486 new ComponentName(cpi.applicationInfo.packageName, 8487 cpi.name), false, false, false); 8488 if (proc == null) { 8489 Slog.w(TAG, "Unable to launch app " 8490 + cpi.applicationInfo.packageName + "/" 8491 + cpi.applicationInfo.uid + " for provider " 8492 + name + ": process is bad"); 8493 return null; 8494 } 8495 } 8496 cpr.launchingApp = proc; 8497 mLaunchingProviders.add(cpr); 8498 } finally { 8499 Binder.restoreCallingIdentity(origId); 8500 } 8501 } 8502 8503 // Make sure the provider is published (the same provider class 8504 // may be published under multiple names). 8505 if (firstClass) { 8506 mProviderMap.putProviderByClass(comp, cpr); 8507 } 8508 8509 mProviderMap.putProviderByName(name, cpr); 8510 conn = incProviderCountLocked(r, cpr, token, stable); 8511 if (conn != null) { 8512 conn.waiting = true; 8513 } 8514 } 8515 } 8516 8517 // Wait for the provider to be published... 8518 synchronized (cpr) { 8519 while (cpr.provider == null) { 8520 if (cpr.launchingApp == null) { 8521 Slog.w(TAG, "Unable to launch app " 8522 + cpi.applicationInfo.packageName + "/" 8523 + cpi.applicationInfo.uid + " for provider " 8524 + name + ": launching app became null"); 8525 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8526 UserHandle.getUserId(cpi.applicationInfo.uid), 8527 cpi.applicationInfo.packageName, 8528 cpi.applicationInfo.uid, name); 8529 return null; 8530 } 8531 try { 8532 if (DEBUG_MU) { 8533 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8534 + cpr.launchingApp); 8535 } 8536 if (conn != null) { 8537 conn.waiting = true; 8538 } 8539 cpr.wait(); 8540 } catch (InterruptedException ex) { 8541 } finally { 8542 if (conn != null) { 8543 conn.waiting = false; 8544 } 8545 } 8546 } 8547 } 8548 return cpr != null ? cpr.newHolder(conn) : null; 8549 } 8550 8551 @Override 8552 public final ContentProviderHolder getContentProvider( 8553 IApplicationThread caller, String name, int userId, boolean stable) { 8554 enforceNotIsolatedCaller("getContentProvider"); 8555 if (caller == null) { 8556 String msg = "null IApplicationThread when getting content provider " 8557 + name; 8558 Slog.w(TAG, msg); 8559 throw new SecurityException(msg); 8560 } 8561 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8562 // with cross-user grant. 8563 return getContentProviderImpl(caller, name, null, stable, userId); 8564 } 8565 8566 public ContentProviderHolder getContentProviderExternal( 8567 String name, int userId, IBinder token) { 8568 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8569 "Do not have permission in call getContentProviderExternal()"); 8570 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8571 false, ALLOW_FULL_ONLY, "getContentProvider", null); 8572 return getContentProviderExternalUnchecked(name, token, userId); 8573 } 8574 8575 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8576 IBinder token, int userId) { 8577 return getContentProviderImpl(null, name, token, true, userId); 8578 } 8579 8580 /** 8581 * Drop a content provider from a ProcessRecord's bookkeeping 8582 */ 8583 public void removeContentProvider(IBinder connection, boolean stable) { 8584 enforceNotIsolatedCaller("removeContentProvider"); 8585 long ident = Binder.clearCallingIdentity(); 8586 try { 8587 synchronized (this) { 8588 ContentProviderConnection conn; 8589 try { 8590 conn = (ContentProviderConnection)connection; 8591 } catch (ClassCastException e) { 8592 String msg ="removeContentProvider: " + connection 8593 + " not a ContentProviderConnection"; 8594 Slog.w(TAG, msg); 8595 throw new IllegalArgumentException(msg); 8596 } 8597 if (conn == null) { 8598 throw new NullPointerException("connection is null"); 8599 } 8600 if (decProviderCountLocked(conn, null, null, stable)) { 8601 updateOomAdjLocked(); 8602 } 8603 } 8604 } finally { 8605 Binder.restoreCallingIdentity(ident); 8606 } 8607 } 8608 8609 public void removeContentProviderExternal(String name, IBinder token) { 8610 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8611 "Do not have permission in call removeContentProviderExternal()"); 8612 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8613 } 8614 8615 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8616 synchronized (this) { 8617 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8618 if(cpr == null) { 8619 //remove from mProvidersByClass 8620 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8621 return; 8622 } 8623 8624 //update content provider record entry info 8625 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8626 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8627 if (localCpr.hasExternalProcessHandles()) { 8628 if (localCpr.removeExternalProcessHandleLocked(token)) { 8629 updateOomAdjLocked(); 8630 } else { 8631 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8632 + " with no external reference for token: " 8633 + token + "."); 8634 } 8635 } else { 8636 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8637 + " with no external references."); 8638 } 8639 } 8640 } 8641 8642 public final void publishContentProviders(IApplicationThread caller, 8643 List<ContentProviderHolder> providers) { 8644 if (providers == null) { 8645 return; 8646 } 8647 8648 enforceNotIsolatedCaller("publishContentProviders"); 8649 synchronized (this) { 8650 final ProcessRecord r = getRecordForAppLocked(caller); 8651 if (DEBUG_MU) 8652 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8653 if (r == null) { 8654 throw new SecurityException( 8655 "Unable to find app for caller " + caller 8656 + " (pid=" + Binder.getCallingPid() 8657 + ") when publishing content providers"); 8658 } 8659 8660 final long origId = Binder.clearCallingIdentity(); 8661 8662 final int N = providers.size(); 8663 for (int i=0; i<N; i++) { 8664 ContentProviderHolder src = providers.get(i); 8665 if (src == null || src.info == null || src.provider == null) { 8666 continue; 8667 } 8668 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8669 if (DEBUG_MU) 8670 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8671 if (dst != null) { 8672 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8673 mProviderMap.putProviderByClass(comp, dst); 8674 String names[] = dst.info.authority.split(";"); 8675 for (int j = 0; j < names.length; j++) { 8676 mProviderMap.putProviderByName(names[j], dst); 8677 } 8678 8679 int NL = mLaunchingProviders.size(); 8680 int j; 8681 for (j=0; j<NL; j++) { 8682 if (mLaunchingProviders.get(j) == dst) { 8683 mLaunchingProviders.remove(j); 8684 j--; 8685 NL--; 8686 } 8687 } 8688 synchronized (dst) { 8689 dst.provider = src.provider; 8690 dst.proc = r; 8691 dst.notifyAll(); 8692 } 8693 updateOomAdjLocked(r); 8694 } 8695 } 8696 8697 Binder.restoreCallingIdentity(origId); 8698 } 8699 } 8700 8701 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8702 ContentProviderConnection conn; 8703 try { 8704 conn = (ContentProviderConnection)connection; 8705 } catch (ClassCastException e) { 8706 String msg ="refContentProvider: " + connection 8707 + " not a ContentProviderConnection"; 8708 Slog.w(TAG, msg); 8709 throw new IllegalArgumentException(msg); 8710 } 8711 if (conn == null) { 8712 throw new NullPointerException("connection is null"); 8713 } 8714 8715 synchronized (this) { 8716 if (stable > 0) { 8717 conn.numStableIncs += stable; 8718 } 8719 stable = conn.stableCount + stable; 8720 if (stable < 0) { 8721 throw new IllegalStateException("stableCount < 0: " + stable); 8722 } 8723 8724 if (unstable > 0) { 8725 conn.numUnstableIncs += unstable; 8726 } 8727 unstable = conn.unstableCount + unstable; 8728 if (unstable < 0) { 8729 throw new IllegalStateException("unstableCount < 0: " + unstable); 8730 } 8731 8732 if ((stable+unstable) <= 0) { 8733 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8734 + stable + " unstable=" + unstable); 8735 } 8736 conn.stableCount = stable; 8737 conn.unstableCount = unstable; 8738 return !conn.dead; 8739 } 8740 } 8741 8742 public void unstableProviderDied(IBinder connection) { 8743 ContentProviderConnection conn; 8744 try { 8745 conn = (ContentProviderConnection)connection; 8746 } catch (ClassCastException e) { 8747 String msg ="refContentProvider: " + connection 8748 + " not a ContentProviderConnection"; 8749 Slog.w(TAG, msg); 8750 throw new IllegalArgumentException(msg); 8751 } 8752 if (conn == null) { 8753 throw new NullPointerException("connection is null"); 8754 } 8755 8756 // Safely retrieve the content provider associated with the connection. 8757 IContentProvider provider; 8758 synchronized (this) { 8759 provider = conn.provider.provider; 8760 } 8761 8762 if (provider == null) { 8763 // Um, yeah, we're way ahead of you. 8764 return; 8765 } 8766 8767 // Make sure the caller is being honest with us. 8768 if (provider.asBinder().pingBinder()) { 8769 // Er, no, still looks good to us. 8770 synchronized (this) { 8771 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8772 + " says " + conn + " died, but we don't agree"); 8773 return; 8774 } 8775 } 8776 8777 // Well look at that! It's dead! 8778 synchronized (this) { 8779 if (conn.provider.provider != provider) { 8780 // But something changed... good enough. 8781 return; 8782 } 8783 8784 ProcessRecord proc = conn.provider.proc; 8785 if (proc == null || proc.thread == null) { 8786 // Seems like the process is already cleaned up. 8787 return; 8788 } 8789 8790 // As far as we're concerned, this is just like receiving a 8791 // death notification... just a bit prematurely. 8792 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8793 + ") early provider death"); 8794 final long ident = Binder.clearCallingIdentity(); 8795 try { 8796 appDiedLocked(proc, proc.pid, proc.thread); 8797 } finally { 8798 Binder.restoreCallingIdentity(ident); 8799 } 8800 } 8801 } 8802 8803 @Override 8804 public void appNotRespondingViaProvider(IBinder connection) { 8805 enforceCallingPermission( 8806 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8807 8808 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8809 if (conn == null) { 8810 Slog.w(TAG, "ContentProviderConnection is null"); 8811 return; 8812 } 8813 8814 final ProcessRecord host = conn.provider.proc; 8815 if (host == null) { 8816 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8817 return; 8818 } 8819 8820 final long token = Binder.clearCallingIdentity(); 8821 try { 8822 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8823 } finally { 8824 Binder.restoreCallingIdentity(token); 8825 } 8826 } 8827 8828 public final void installSystemProviders() { 8829 List<ProviderInfo> providers; 8830 synchronized (this) { 8831 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8832 providers = generateApplicationProvidersLocked(app); 8833 if (providers != null) { 8834 for (int i=providers.size()-1; i>=0; i--) { 8835 ProviderInfo pi = (ProviderInfo)providers.get(i); 8836 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8837 Slog.w(TAG, "Not installing system proc provider " + pi.name 8838 + ": not system .apk"); 8839 providers.remove(i); 8840 } 8841 } 8842 } 8843 } 8844 if (providers != null) { 8845 mSystemThread.installSystemProviders(providers); 8846 } 8847 8848 mCoreSettingsObserver = new CoreSettingsObserver(this); 8849 8850 //mUsageStatsService.monitorPackages(); 8851 } 8852 8853 /** 8854 * Allows app to retrieve the MIME type of a URI without having permission 8855 * to access its content provider. 8856 * 8857 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8858 * 8859 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8860 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8861 */ 8862 public String getProviderMimeType(Uri uri, int userId) { 8863 enforceNotIsolatedCaller("getProviderMimeType"); 8864 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8865 userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null); 8866 final String name = uri.getAuthority(); 8867 final long ident = Binder.clearCallingIdentity(); 8868 ContentProviderHolder holder = null; 8869 8870 try { 8871 holder = getContentProviderExternalUnchecked(name, null, userId); 8872 if (holder != null) { 8873 return holder.provider.getType(uri); 8874 } 8875 } catch (RemoteException e) { 8876 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8877 return null; 8878 } finally { 8879 if (holder != null) { 8880 removeContentProviderExternalUnchecked(name, null, userId); 8881 } 8882 Binder.restoreCallingIdentity(ident); 8883 } 8884 8885 return null; 8886 } 8887 8888 // ========================================================= 8889 // GLOBAL MANAGEMENT 8890 // ========================================================= 8891 8892 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8893 boolean isolated) { 8894 String proc = customProcess != null ? customProcess : info.processName; 8895 BatteryStatsImpl.Uid.Proc ps = null; 8896 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8897 int uid = info.uid; 8898 if (isolated) { 8899 int userId = UserHandle.getUserId(uid); 8900 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8901 while (true) { 8902 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8903 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8904 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8905 } 8906 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8907 mNextIsolatedProcessUid++; 8908 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8909 // No process for this uid, use it. 8910 break; 8911 } 8912 stepsLeft--; 8913 if (stepsLeft <= 0) { 8914 return null; 8915 } 8916 } 8917 } 8918 return new ProcessRecord(stats, info, proc, uid); 8919 } 8920 8921 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated, 8922 String abiOverride) { 8923 ProcessRecord app; 8924 if (!isolated) { 8925 app = getProcessRecordLocked(info.processName, info.uid, true); 8926 } else { 8927 app = null; 8928 } 8929 8930 if (app == null) { 8931 app = newProcessRecordLocked(info, null, isolated); 8932 mProcessNames.put(info.processName, app.uid, app); 8933 if (isolated) { 8934 mIsolatedProcesses.put(app.uid, app); 8935 } 8936 updateLruProcessLocked(app, false, null); 8937 updateOomAdjLocked(); 8938 } 8939 8940 // This package really, really can not be stopped. 8941 try { 8942 AppGlobals.getPackageManager().setPackageStoppedState( 8943 info.packageName, false, UserHandle.getUserId(app.uid)); 8944 } catch (RemoteException e) { 8945 } catch (IllegalArgumentException e) { 8946 Slog.w(TAG, "Failed trying to unstop package " 8947 + info.packageName + ": " + e); 8948 } 8949 8950 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8951 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8952 app.persistent = true; 8953 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8954 } 8955 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8956 mPersistentStartingProcesses.add(app); 8957 startProcessLocked(app, "added application", app.processName, 8958 abiOverride); 8959 } 8960 8961 return app; 8962 } 8963 8964 public void unhandledBack() { 8965 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8966 "unhandledBack()"); 8967 8968 synchronized(this) { 8969 final long origId = Binder.clearCallingIdentity(); 8970 try { 8971 getFocusedStack().unhandledBackLocked(); 8972 } finally { 8973 Binder.restoreCallingIdentity(origId); 8974 } 8975 } 8976 } 8977 8978 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8979 enforceNotIsolatedCaller("openContentUri"); 8980 final int userId = UserHandle.getCallingUserId(); 8981 String name = uri.getAuthority(); 8982 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8983 ParcelFileDescriptor pfd = null; 8984 if (cph != null) { 8985 // We record the binder invoker's uid in thread-local storage before 8986 // going to the content provider to open the file. Later, in the code 8987 // that handles all permissions checks, we look for this uid and use 8988 // that rather than the Activity Manager's own uid. The effect is that 8989 // we do the check against the caller's permissions even though it looks 8990 // to the content provider like the Activity Manager itself is making 8991 // the request. 8992 sCallerIdentity.set(new Identity( 8993 Binder.getCallingPid(), Binder.getCallingUid())); 8994 try { 8995 pfd = cph.provider.openFile(null, uri, "r", null); 8996 } catch (FileNotFoundException e) { 8997 // do nothing; pfd will be returned null 8998 } finally { 8999 // Ensure that whatever happens, we clean up the identity state 9000 sCallerIdentity.remove(); 9001 } 9002 9003 // We've got the fd now, so we're done with the provider. 9004 removeContentProviderExternalUnchecked(name, null, userId); 9005 } else { 9006 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 9007 } 9008 return pfd; 9009 } 9010 9011 // Actually is sleeping or shutting down or whatever else in the future 9012 // is an inactive state. 9013 public boolean isSleepingOrShuttingDown() { 9014 return mSleeping || mShuttingDown; 9015 } 9016 9017 public boolean isSleeping() { 9018 return mSleeping; 9019 } 9020 9021 void goingToSleep() { 9022 synchronized(this) { 9023 mWentToSleep = true; 9024 updateEventDispatchingLocked(); 9025 goToSleepIfNeededLocked(); 9026 } 9027 } 9028 9029 void finishRunningVoiceLocked() { 9030 if (mRunningVoice) { 9031 mRunningVoice = false; 9032 goToSleepIfNeededLocked(); 9033 } 9034 } 9035 9036 void goToSleepIfNeededLocked() { 9037 if (mWentToSleep && !mRunningVoice) { 9038 if (!mSleeping) { 9039 mSleeping = true; 9040 mStackSupervisor.goingToSleepLocked(); 9041 9042 // Initialize the wake times of all processes. 9043 checkExcessivePowerUsageLocked(false); 9044 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9045 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 9046 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 9047 } 9048 } 9049 } 9050 9051 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) { 9052 mTaskPersister.notify(task, flush); 9053 } 9054 9055 @Override 9056 public boolean shutdown(int timeout) { 9057 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 9058 != PackageManager.PERMISSION_GRANTED) { 9059 throw new SecurityException("Requires permission " 9060 + android.Manifest.permission.SHUTDOWN); 9061 } 9062 9063 boolean timedout = false; 9064 9065 synchronized(this) { 9066 mShuttingDown = true; 9067 updateEventDispatchingLocked(); 9068 timedout = mStackSupervisor.shutdownLocked(timeout); 9069 } 9070 9071 mAppOpsService.shutdown(); 9072 if (mUsageStatsService != null) { 9073 mUsageStatsService.prepareShutdown(); 9074 } 9075 mBatteryStatsService.shutdown(); 9076 synchronized (this) { 9077 mProcessStats.shutdownLocked(); 9078 } 9079 notifyTaskPersisterLocked(null, true); 9080 9081 return timedout; 9082 } 9083 9084 public final void activitySlept(IBinder token) { 9085 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 9086 9087 final long origId = Binder.clearCallingIdentity(); 9088 9089 synchronized (this) { 9090 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9091 if (r != null) { 9092 mStackSupervisor.activitySleptLocked(r); 9093 } 9094 } 9095 9096 Binder.restoreCallingIdentity(origId); 9097 } 9098 9099 void logLockScreen(String msg) { 9100 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 9101 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 9102 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 9103 mStackSupervisor.mDismissKeyguardOnNextActivity); 9104 } 9105 9106 private void comeOutOfSleepIfNeededLocked() { 9107 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 9108 if (mSleeping) { 9109 mSleeping = false; 9110 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 9111 } 9112 } 9113 } 9114 9115 void wakingUp() { 9116 synchronized(this) { 9117 mWentToSleep = false; 9118 updateEventDispatchingLocked(); 9119 comeOutOfSleepIfNeededLocked(); 9120 } 9121 } 9122 9123 void startRunningVoiceLocked() { 9124 if (!mRunningVoice) { 9125 mRunningVoice = true; 9126 comeOutOfSleepIfNeededLocked(); 9127 } 9128 } 9129 9130 private void updateEventDispatchingLocked() { 9131 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 9132 } 9133 9134 public void setLockScreenShown(boolean shown) { 9135 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 9136 != PackageManager.PERMISSION_GRANTED) { 9137 throw new SecurityException("Requires permission " 9138 + android.Manifest.permission.DEVICE_POWER); 9139 } 9140 9141 synchronized(this) { 9142 long ident = Binder.clearCallingIdentity(); 9143 try { 9144 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 9145 mLockScreenShown = shown; 9146 comeOutOfSleepIfNeededLocked(); 9147 } finally { 9148 Binder.restoreCallingIdentity(ident); 9149 } 9150 } 9151 } 9152 9153 @Override 9154 public void stopAppSwitches() { 9155 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9156 != PackageManager.PERMISSION_GRANTED) { 9157 throw new SecurityException("Requires permission " 9158 + android.Manifest.permission.STOP_APP_SWITCHES); 9159 } 9160 9161 synchronized(this) { 9162 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 9163 + APP_SWITCH_DELAY_TIME; 9164 mDidAppSwitch = false; 9165 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9166 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 9167 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 9168 } 9169 } 9170 9171 public void resumeAppSwitches() { 9172 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 9173 != PackageManager.PERMISSION_GRANTED) { 9174 throw new SecurityException("Requires permission " 9175 + android.Manifest.permission.STOP_APP_SWITCHES); 9176 } 9177 9178 synchronized(this) { 9179 // Note that we don't execute any pending app switches... we will 9180 // let those wait until either the timeout, or the next start 9181 // activity request. 9182 mAppSwitchesAllowedTime = 0; 9183 } 9184 } 9185 9186 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 9187 String name) { 9188 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 9189 return true; 9190 } 9191 9192 final int perm = checkComponentPermission( 9193 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 9194 callingUid, -1, true); 9195 if (perm == PackageManager.PERMISSION_GRANTED) { 9196 return true; 9197 } 9198 9199 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 9200 return false; 9201 } 9202 9203 public void setDebugApp(String packageName, boolean waitForDebugger, 9204 boolean persistent) { 9205 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 9206 "setDebugApp()"); 9207 9208 long ident = Binder.clearCallingIdentity(); 9209 try { 9210 // Note that this is not really thread safe if there are multiple 9211 // callers into it at the same time, but that's not a situation we 9212 // care about. 9213 if (persistent) { 9214 final ContentResolver resolver = mContext.getContentResolver(); 9215 Settings.Global.putString( 9216 resolver, Settings.Global.DEBUG_APP, 9217 packageName); 9218 Settings.Global.putInt( 9219 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 9220 waitForDebugger ? 1 : 0); 9221 } 9222 9223 synchronized (this) { 9224 if (!persistent) { 9225 mOrigDebugApp = mDebugApp; 9226 mOrigWaitForDebugger = mWaitForDebugger; 9227 } 9228 mDebugApp = packageName; 9229 mWaitForDebugger = waitForDebugger; 9230 mDebugTransient = !persistent; 9231 if (packageName != null) { 9232 forceStopPackageLocked(packageName, -1, false, false, true, true, 9233 false, UserHandle.USER_ALL, "set debug app"); 9234 } 9235 } 9236 } finally { 9237 Binder.restoreCallingIdentity(ident); 9238 } 9239 } 9240 9241 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 9242 synchronized (this) { 9243 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9244 if (!isDebuggable) { 9245 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9246 throw new SecurityException("Process not debuggable: " + app.packageName); 9247 } 9248 } 9249 9250 mOpenGlTraceApp = processName; 9251 } 9252 } 9253 9254 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 9255 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 9256 synchronized (this) { 9257 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 9258 if (!isDebuggable) { 9259 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 9260 throw new SecurityException("Process not debuggable: " + app.packageName); 9261 } 9262 } 9263 mProfileApp = processName; 9264 mProfileFile = profileFile; 9265 if (mProfileFd != null) { 9266 try { 9267 mProfileFd.close(); 9268 } catch (IOException e) { 9269 } 9270 mProfileFd = null; 9271 } 9272 mProfileFd = profileFd; 9273 mProfileType = 0; 9274 mAutoStopProfiler = autoStopProfiler; 9275 } 9276 } 9277 9278 @Override 9279 public void setAlwaysFinish(boolean enabled) { 9280 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 9281 "setAlwaysFinish()"); 9282 9283 Settings.Global.putInt( 9284 mContext.getContentResolver(), 9285 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 9286 9287 synchronized (this) { 9288 mAlwaysFinishActivities = enabled; 9289 } 9290 } 9291 9292 @Override 9293 public void setActivityController(IActivityController controller) { 9294 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9295 "setActivityController()"); 9296 synchronized (this) { 9297 mController = controller; 9298 Watchdog.getInstance().setActivityController(controller); 9299 } 9300 } 9301 9302 @Override 9303 public void setUserIsMonkey(boolean userIsMonkey) { 9304 synchronized (this) { 9305 synchronized (mPidsSelfLocked) { 9306 final int callingPid = Binder.getCallingPid(); 9307 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 9308 if (precessRecord == null) { 9309 throw new SecurityException("Unknown process: " + callingPid); 9310 } 9311 if (precessRecord.instrumentationUiAutomationConnection == null) { 9312 throw new SecurityException("Only an instrumentation process " 9313 + "with a UiAutomation can call setUserIsMonkey"); 9314 } 9315 } 9316 mUserIsMonkey = userIsMonkey; 9317 } 9318 } 9319 9320 @Override 9321 public boolean isUserAMonkey() { 9322 synchronized (this) { 9323 // If there is a controller also implies the user is a monkey. 9324 return (mUserIsMonkey || mController != null); 9325 } 9326 } 9327 9328 public void requestBugReport() { 9329 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 9330 SystemProperties.set("ctl.start", "bugreport"); 9331 } 9332 9333 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 9334 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 9335 } 9336 9337 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 9338 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 9339 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 9340 } 9341 return KEY_DISPATCHING_TIMEOUT; 9342 } 9343 9344 @Override 9345 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 9346 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9347 != PackageManager.PERMISSION_GRANTED) { 9348 throw new SecurityException("Requires permission " 9349 + android.Manifest.permission.FILTER_EVENTS); 9350 } 9351 ProcessRecord proc; 9352 long timeout; 9353 synchronized (this) { 9354 synchronized (mPidsSelfLocked) { 9355 proc = mPidsSelfLocked.get(pid); 9356 } 9357 timeout = getInputDispatchingTimeoutLocked(proc); 9358 } 9359 9360 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 9361 return -1; 9362 } 9363 9364 return timeout; 9365 } 9366 9367 /** 9368 * Handle input dispatching timeouts. 9369 * Returns whether input dispatching should be aborted or not. 9370 */ 9371 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 9372 final ActivityRecord activity, final ActivityRecord parent, 9373 final boolean aboveSystem, String reason) { 9374 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 9375 != PackageManager.PERMISSION_GRANTED) { 9376 throw new SecurityException("Requires permission " 9377 + android.Manifest.permission.FILTER_EVENTS); 9378 } 9379 9380 final String annotation; 9381 if (reason == null) { 9382 annotation = "Input dispatching timed out"; 9383 } else { 9384 annotation = "Input dispatching timed out (" + reason + ")"; 9385 } 9386 9387 if (proc != null) { 9388 synchronized (this) { 9389 if (proc.debugging) { 9390 return false; 9391 } 9392 9393 if (mDidDexOpt) { 9394 // Give more time since we were dexopting. 9395 mDidDexOpt = false; 9396 return false; 9397 } 9398 9399 if (proc.instrumentationClass != null) { 9400 Bundle info = new Bundle(); 9401 info.putString("shortMsg", "keyDispatchingTimedOut"); 9402 info.putString("longMsg", annotation); 9403 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9404 return true; 9405 } 9406 } 9407 mHandler.post(new Runnable() { 9408 @Override 9409 public void run() { 9410 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9411 } 9412 }); 9413 } 9414 9415 return true; 9416 } 9417 9418 public Bundle getAssistContextExtras(int requestType) { 9419 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9420 "getAssistContextExtras()"); 9421 PendingAssistExtras pae; 9422 Bundle extras = new Bundle(); 9423 synchronized (this) { 9424 ActivityRecord activity = getFocusedStack().mResumedActivity; 9425 if (activity == null) { 9426 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9427 return null; 9428 } 9429 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9430 if (activity.app == null || activity.app.thread == null) { 9431 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9432 return extras; 9433 } 9434 if (activity.app.pid == Binder.getCallingPid()) { 9435 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9436 return extras; 9437 } 9438 pae = new PendingAssistExtras(activity); 9439 try { 9440 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9441 requestType); 9442 mPendingAssistExtras.add(pae); 9443 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9444 } catch (RemoteException e) { 9445 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9446 return extras; 9447 } 9448 } 9449 synchronized (pae) { 9450 while (!pae.haveResult) { 9451 try { 9452 pae.wait(); 9453 } catch (InterruptedException e) { 9454 } 9455 } 9456 if (pae.result != null) { 9457 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9458 } 9459 } 9460 synchronized (this) { 9461 mPendingAssistExtras.remove(pae); 9462 mHandler.removeCallbacks(pae); 9463 } 9464 return extras; 9465 } 9466 9467 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9468 PendingAssistExtras pae = (PendingAssistExtras)token; 9469 synchronized (pae) { 9470 pae.result = extras; 9471 pae.haveResult = true; 9472 pae.notifyAll(); 9473 } 9474 } 9475 9476 public void registerProcessObserver(IProcessObserver observer) { 9477 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9478 "registerProcessObserver()"); 9479 synchronized (this) { 9480 mProcessObservers.register(observer); 9481 } 9482 } 9483 9484 @Override 9485 public void unregisterProcessObserver(IProcessObserver observer) { 9486 synchronized (this) { 9487 mProcessObservers.unregister(observer); 9488 } 9489 } 9490 9491 @Override 9492 public boolean convertFromTranslucent(IBinder token) { 9493 final long origId = Binder.clearCallingIdentity(); 9494 try { 9495 synchronized (this) { 9496 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9497 if (r == null) { 9498 return false; 9499 } 9500 if (r.changeWindowTranslucency(true)) { 9501 mWindowManager.setAppFullscreen(token, true); 9502 r.task.stack.releaseMediaResources(); 9503 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9504 return true; 9505 } 9506 return false; 9507 } 9508 } finally { 9509 Binder.restoreCallingIdentity(origId); 9510 } 9511 } 9512 9513 @Override 9514 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9515 final long origId = Binder.clearCallingIdentity(); 9516 try { 9517 synchronized (this) { 9518 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9519 if (r == null) { 9520 return false; 9521 } 9522 if (r.changeWindowTranslucency(false)) { 9523 r.task.stack.convertToTranslucent(r, options); 9524 mWindowManager.setAppFullscreen(token, false); 9525 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9526 return true; 9527 } else { 9528 r.task.stack.mReturningActivityOptions = options; 9529 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9530 return false; 9531 } 9532 } 9533 } finally { 9534 Binder.restoreCallingIdentity(origId); 9535 } 9536 } 9537 9538 @Override 9539 public boolean setMediaPlaying(IBinder token, boolean playing) { 9540 final long origId = Binder.clearCallingIdentity(); 9541 try { 9542 synchronized (this) { 9543 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9544 if (r != null) { 9545 return mStackSupervisor.setMediaPlayingLocked(r, playing); 9546 } 9547 } 9548 return false; 9549 } finally { 9550 Binder.restoreCallingIdentity(origId); 9551 } 9552 } 9553 9554 @Override 9555 public boolean isBackgroundMediaPlaying(IBinder token) { 9556 final long origId = Binder.clearCallingIdentity(); 9557 try { 9558 synchronized (this) { 9559 final ActivityStack stack = ActivityRecord.getStackLocked(token); 9560 final boolean playing = stack == null ? false : stack.isMediaPlaying(); 9561 if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG, 9562 "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing); 9563 return playing; 9564 } 9565 } finally { 9566 Binder.restoreCallingIdentity(origId); 9567 } 9568 } 9569 9570 @Override 9571 public ActivityOptions getActivityOptions(IBinder token) { 9572 final long origId = Binder.clearCallingIdentity(); 9573 try { 9574 synchronized (this) { 9575 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9576 if (r != null) { 9577 final ActivityOptions activityOptions = r.pendingOptions; 9578 r.pendingOptions = null; 9579 return activityOptions; 9580 } 9581 return null; 9582 } 9583 } finally { 9584 Binder.restoreCallingIdentity(origId); 9585 } 9586 } 9587 9588 @Override 9589 public void setImmersive(IBinder token, boolean immersive) { 9590 synchronized(this) { 9591 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9592 if (r == null) { 9593 throw new IllegalArgumentException(); 9594 } 9595 r.immersive = immersive; 9596 9597 // update associated state if we're frontmost 9598 if (r == mFocusedActivity) { 9599 if (DEBUG_IMMERSIVE) { 9600 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9601 } 9602 applyUpdateLockStateLocked(r); 9603 } 9604 } 9605 } 9606 9607 @Override 9608 public boolean isImmersive(IBinder token) { 9609 synchronized (this) { 9610 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9611 if (r == null) { 9612 throw new IllegalArgumentException(); 9613 } 9614 return r.immersive; 9615 } 9616 } 9617 9618 public boolean isTopActivityImmersive() { 9619 enforceNotIsolatedCaller("startActivity"); 9620 synchronized (this) { 9621 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9622 return (r != null) ? r.immersive : false; 9623 } 9624 } 9625 9626 @Override 9627 public boolean isTopOfTask(IBinder token) { 9628 synchronized (this) { 9629 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9630 if (r == null) { 9631 throw new IllegalArgumentException(); 9632 } 9633 return r.task.getTopActivity() == r; 9634 } 9635 } 9636 9637 public final void enterSafeMode() { 9638 synchronized(this) { 9639 // It only makes sense to do this before the system is ready 9640 // and started launching other packages. 9641 if (!mSystemReady) { 9642 try { 9643 AppGlobals.getPackageManager().enterSafeMode(); 9644 } catch (RemoteException e) { 9645 } 9646 } 9647 9648 mSafeMode = true; 9649 } 9650 } 9651 9652 public final void showSafeModeOverlay() { 9653 View v = LayoutInflater.from(mContext).inflate( 9654 com.android.internal.R.layout.safe_mode, null); 9655 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9656 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9657 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9658 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9659 lp.gravity = Gravity.BOTTOM | Gravity.START; 9660 lp.format = v.getBackground().getOpacity(); 9661 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9662 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9663 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9664 ((WindowManager)mContext.getSystemService( 9665 Context.WINDOW_SERVICE)).addView(v, lp); 9666 } 9667 9668 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9669 if (!(sender instanceof PendingIntentRecord)) { 9670 return; 9671 } 9672 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9673 synchronized (stats) { 9674 if (mBatteryStatsService.isOnBattery()) { 9675 mBatteryStatsService.enforceCallingPermission(); 9676 PendingIntentRecord rec = (PendingIntentRecord)sender; 9677 int MY_UID = Binder.getCallingUid(); 9678 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9679 BatteryStatsImpl.Uid.Pkg pkg = 9680 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9681 sourcePkg != null ? sourcePkg : rec.key.packageName); 9682 pkg.incWakeupsLocked(); 9683 } 9684 } 9685 } 9686 9687 public boolean killPids(int[] pids, String pReason, boolean secure) { 9688 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9689 throw new SecurityException("killPids only available to the system"); 9690 } 9691 String reason = (pReason == null) ? "Unknown" : pReason; 9692 // XXX Note: don't acquire main activity lock here, because the window 9693 // manager calls in with its locks held. 9694 9695 boolean killed = false; 9696 synchronized (mPidsSelfLocked) { 9697 int[] types = new int[pids.length]; 9698 int worstType = 0; 9699 for (int i=0; i<pids.length; i++) { 9700 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9701 if (proc != null) { 9702 int type = proc.setAdj; 9703 types[i] = type; 9704 if (type > worstType) { 9705 worstType = type; 9706 } 9707 } 9708 } 9709 9710 // If the worst oom_adj is somewhere in the cached proc LRU range, 9711 // then constrain it so we will kill all cached procs. 9712 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9713 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9714 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9715 } 9716 9717 // If this is not a secure call, don't let it kill processes that 9718 // are important. 9719 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9720 worstType = ProcessList.SERVICE_ADJ; 9721 } 9722 9723 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9724 for (int i=0; i<pids.length; i++) { 9725 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9726 if (proc == null) { 9727 continue; 9728 } 9729 int adj = proc.setAdj; 9730 if (adj >= worstType && !proc.killedByAm) { 9731 killUnneededProcessLocked(proc, reason); 9732 killed = true; 9733 } 9734 } 9735 } 9736 return killed; 9737 } 9738 9739 @Override 9740 public void killUid(int uid, String reason) { 9741 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9742 throw new SecurityException("killUid only available to the system"); 9743 } 9744 synchronized (this) { 9745 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9746 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9747 reason != null ? reason : "kill uid"); 9748 } 9749 } 9750 9751 @Override 9752 public boolean killProcessesBelowForeground(String reason) { 9753 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9754 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9755 } 9756 9757 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9758 } 9759 9760 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9761 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9762 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9763 } 9764 9765 boolean killed = false; 9766 synchronized (mPidsSelfLocked) { 9767 final int size = mPidsSelfLocked.size(); 9768 for (int i = 0; i < size; i++) { 9769 final int pid = mPidsSelfLocked.keyAt(i); 9770 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9771 if (proc == null) continue; 9772 9773 final int adj = proc.setAdj; 9774 if (adj > belowAdj && !proc.killedByAm) { 9775 killUnneededProcessLocked(proc, reason); 9776 killed = true; 9777 } 9778 } 9779 } 9780 return killed; 9781 } 9782 9783 @Override 9784 public void hang(final IBinder who, boolean allowRestart) { 9785 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9786 != PackageManager.PERMISSION_GRANTED) { 9787 throw new SecurityException("Requires permission " 9788 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9789 } 9790 9791 final IBinder.DeathRecipient death = new DeathRecipient() { 9792 @Override 9793 public void binderDied() { 9794 synchronized (this) { 9795 notifyAll(); 9796 } 9797 } 9798 }; 9799 9800 try { 9801 who.linkToDeath(death, 0); 9802 } catch (RemoteException e) { 9803 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9804 return; 9805 } 9806 9807 synchronized (this) { 9808 Watchdog.getInstance().setAllowRestart(allowRestart); 9809 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9810 synchronized (death) { 9811 while (who.isBinderAlive()) { 9812 try { 9813 death.wait(); 9814 } catch (InterruptedException e) { 9815 } 9816 } 9817 } 9818 Watchdog.getInstance().setAllowRestart(true); 9819 } 9820 } 9821 9822 @Override 9823 public void restart() { 9824 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9825 != PackageManager.PERMISSION_GRANTED) { 9826 throw new SecurityException("Requires permission " 9827 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9828 } 9829 9830 Log.i(TAG, "Sending shutdown broadcast..."); 9831 9832 BroadcastReceiver br = new BroadcastReceiver() { 9833 @Override public void onReceive(Context context, Intent intent) { 9834 // Now the broadcast is done, finish up the low-level shutdown. 9835 Log.i(TAG, "Shutting down activity manager..."); 9836 shutdown(10000); 9837 Log.i(TAG, "Shutdown complete, restarting!"); 9838 Process.killProcess(Process.myPid()); 9839 System.exit(10); 9840 } 9841 }; 9842 9843 // First send the high-level shut down broadcast. 9844 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9845 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9846 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9847 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9848 mContext.sendOrderedBroadcastAsUser(intent, 9849 UserHandle.ALL, null, br, mHandler, 0, null, null); 9850 */ 9851 br.onReceive(mContext, intent); 9852 } 9853 9854 private long getLowRamTimeSinceIdle(long now) { 9855 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9856 } 9857 9858 @Override 9859 public void performIdleMaintenance() { 9860 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9861 != PackageManager.PERMISSION_GRANTED) { 9862 throw new SecurityException("Requires permission " 9863 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9864 } 9865 9866 synchronized (this) { 9867 final long now = SystemClock.uptimeMillis(); 9868 final long timeSinceLastIdle = now - mLastIdleTime; 9869 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9870 mLastIdleTime = now; 9871 mLowRamTimeSinceLastIdle = 0; 9872 if (mLowRamStartTime != 0) { 9873 mLowRamStartTime = now; 9874 } 9875 9876 StringBuilder sb = new StringBuilder(128); 9877 sb.append("Idle maintenance over "); 9878 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9879 sb.append(" low RAM for "); 9880 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9881 Slog.i(TAG, sb.toString()); 9882 9883 // If at least 1/3 of our time since the last idle period has been spent 9884 // with RAM low, then we want to kill processes. 9885 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9886 9887 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9888 ProcessRecord proc = mLruProcesses.get(i); 9889 if (proc.notCachedSinceIdle) { 9890 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9891 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9892 if (doKilling && proc.initialIdlePss != 0 9893 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9894 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9895 + " from " + proc.initialIdlePss + ")"); 9896 } 9897 } 9898 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9899 proc.notCachedSinceIdle = true; 9900 proc.initialIdlePss = 0; 9901 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9902 isSleeping(), now); 9903 } 9904 } 9905 9906 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9907 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9908 } 9909 } 9910 9911 private void retrieveSettings() { 9912 final ContentResolver resolver = mContext.getContentResolver(); 9913 String debugApp = Settings.Global.getString( 9914 resolver, Settings.Global.DEBUG_APP); 9915 boolean waitForDebugger = Settings.Global.getInt( 9916 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9917 boolean alwaysFinishActivities = Settings.Global.getInt( 9918 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9919 boolean forceRtl = Settings.Global.getInt( 9920 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9921 // Transfer any global setting for forcing RTL layout, into a System Property 9922 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9923 9924 Configuration configuration = new Configuration(); 9925 Settings.System.getConfiguration(resolver, configuration); 9926 if (forceRtl) { 9927 // This will take care of setting the correct layout direction flags 9928 configuration.setLayoutDirection(configuration.locale); 9929 } 9930 9931 synchronized (this) { 9932 mDebugApp = mOrigDebugApp = debugApp; 9933 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9934 mAlwaysFinishActivities = alwaysFinishActivities; 9935 // This happens before any activities are started, so we can 9936 // change mConfiguration in-place. 9937 updateConfigurationLocked(configuration, null, false, true); 9938 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9939 } 9940 } 9941 9942 public boolean testIsSystemReady() { 9943 // no need to synchronize(this) just to read & return the value 9944 return mSystemReady; 9945 } 9946 9947 private static File getCalledPreBootReceiversFile() { 9948 File dataDir = Environment.getDataDirectory(); 9949 File systemDir = new File(dataDir, "system"); 9950 File fname = new File(systemDir, "called_pre_boots.dat"); 9951 return fname; 9952 } 9953 9954 static final int LAST_DONE_VERSION = 10000; 9955 9956 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9957 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9958 File file = getCalledPreBootReceiversFile(); 9959 FileInputStream fis = null; 9960 try { 9961 fis = new FileInputStream(file); 9962 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9963 int fvers = dis.readInt(); 9964 if (fvers == LAST_DONE_VERSION) { 9965 String vers = dis.readUTF(); 9966 String codename = dis.readUTF(); 9967 String build = dis.readUTF(); 9968 if (android.os.Build.VERSION.RELEASE.equals(vers) 9969 && android.os.Build.VERSION.CODENAME.equals(codename) 9970 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9971 int num = dis.readInt(); 9972 while (num > 0) { 9973 num--; 9974 String pkg = dis.readUTF(); 9975 String cls = dis.readUTF(); 9976 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9977 } 9978 } 9979 } 9980 } catch (FileNotFoundException e) { 9981 } catch (IOException e) { 9982 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9983 } finally { 9984 if (fis != null) { 9985 try { 9986 fis.close(); 9987 } catch (IOException e) { 9988 } 9989 } 9990 } 9991 return lastDoneReceivers; 9992 } 9993 9994 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9995 File file = getCalledPreBootReceiversFile(); 9996 FileOutputStream fos = null; 9997 DataOutputStream dos = null; 9998 try { 9999 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 10000 fos = new FileOutputStream(file); 10001 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 10002 dos.writeInt(LAST_DONE_VERSION); 10003 dos.writeUTF(android.os.Build.VERSION.RELEASE); 10004 dos.writeUTF(android.os.Build.VERSION.CODENAME); 10005 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 10006 dos.writeInt(list.size()); 10007 for (int i=0; i<list.size(); i++) { 10008 dos.writeUTF(list.get(i).getPackageName()); 10009 dos.writeUTF(list.get(i).getClassName()); 10010 } 10011 } catch (IOException e) { 10012 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 10013 file.delete(); 10014 } finally { 10015 FileUtils.sync(fos); 10016 if (dos != null) { 10017 try { 10018 dos.close(); 10019 } catch (IOException e) { 10020 // TODO Auto-generated catch block 10021 e.printStackTrace(); 10022 } 10023 } 10024 } 10025 } 10026 10027 public void systemReady(final Runnable goingCallback) { 10028 synchronized(this) { 10029 if (mSystemReady) { 10030 if (goingCallback != null) goingCallback.run(); 10031 return; 10032 } 10033 10034 // Make sure we have the current profile info, since it is needed for 10035 // security checks. 10036 updateCurrentProfileIdsLocked(); 10037 10038 if (mRecentTasks == null) { 10039 mRecentTasks = mTaskPersister.restoreTasksLocked(); 10040 if (!mRecentTasks.isEmpty()) { 10041 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks); 10042 } 10043 mTaskPersister.startPersisting(); 10044 } 10045 10046 // Check to see if there are any update receivers to run. 10047 if (!mDidUpdate) { 10048 if (mWaitingUpdate) { 10049 return; 10050 } 10051 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 10052 List<ResolveInfo> ris = null; 10053 try { 10054 ris = AppGlobals.getPackageManager().queryIntentReceivers( 10055 intent, null, 0, 0); 10056 } catch (RemoteException e) { 10057 } 10058 if (ris != null) { 10059 for (int i=ris.size()-1; i>=0; i--) { 10060 if ((ris.get(i).activityInfo.applicationInfo.flags 10061 &ApplicationInfo.FLAG_SYSTEM) == 0) { 10062 ris.remove(i); 10063 } 10064 } 10065 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 10066 10067 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 10068 10069 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 10070 for (int i=0; i<ris.size(); i++) { 10071 ActivityInfo ai = ris.get(i).activityInfo; 10072 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10073 if (lastDoneReceivers.contains(comp)) { 10074 // We already did the pre boot receiver for this app with the current 10075 // platform version, so don't do it again... 10076 ris.remove(i); 10077 i--; 10078 // ...however, do keep it as one that has been done, so we don't 10079 // forget about it when rewriting the file of last done receivers. 10080 doneReceivers.add(comp); 10081 } 10082 } 10083 10084 final int[] users = getUsersLocked(); 10085 for (int i=0; i<ris.size(); i++) { 10086 ActivityInfo ai = ris.get(i).activityInfo; 10087 ComponentName comp = new ComponentName(ai.packageName, ai.name); 10088 doneReceivers.add(comp); 10089 intent.setComponent(comp); 10090 for (int j=0; j<users.length; j++) { 10091 IIntentReceiver finisher = null; 10092 if (i == ris.size()-1 && j == users.length-1) { 10093 finisher = new IIntentReceiver.Stub() { 10094 public void performReceive(Intent intent, int resultCode, 10095 String data, Bundle extras, boolean ordered, 10096 boolean sticky, int sendingUser) { 10097 // The raw IIntentReceiver interface is called 10098 // with the AM lock held, so redispatch to 10099 // execute our code without the lock. 10100 mHandler.post(new Runnable() { 10101 public void run() { 10102 synchronized (ActivityManagerService.this) { 10103 mDidUpdate = true; 10104 } 10105 writeLastDonePreBootReceivers(doneReceivers); 10106 showBootMessage(mContext.getText( 10107 R.string.android_upgrading_complete), 10108 false); 10109 systemReady(goingCallback); 10110 } 10111 }); 10112 } 10113 }; 10114 } 10115 Slog.i(TAG, "Sending system update to " + intent.getComponent() 10116 + " for user " + users[j]); 10117 broadcastIntentLocked(null, null, intent, null, finisher, 10118 0, null, null, null, AppOpsManager.OP_NONE, 10119 true, false, MY_PID, Process.SYSTEM_UID, 10120 users[j]); 10121 if (finisher != null) { 10122 mWaitingUpdate = true; 10123 } 10124 } 10125 } 10126 } 10127 if (mWaitingUpdate) { 10128 return; 10129 } 10130 mDidUpdate = true; 10131 } 10132 10133 mAppOpsService.systemReady(); 10134 mSystemReady = true; 10135 } 10136 10137 ArrayList<ProcessRecord> procsToKill = null; 10138 synchronized(mPidsSelfLocked) { 10139 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 10140 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 10141 if (!isAllowedWhileBooting(proc.info)){ 10142 if (procsToKill == null) { 10143 procsToKill = new ArrayList<ProcessRecord>(); 10144 } 10145 procsToKill.add(proc); 10146 } 10147 } 10148 } 10149 10150 synchronized(this) { 10151 if (procsToKill != null) { 10152 for (int i=procsToKill.size()-1; i>=0; i--) { 10153 ProcessRecord proc = procsToKill.get(i); 10154 Slog.i(TAG, "Removing system update proc: " + proc); 10155 removeProcessLocked(proc, true, false, "system update done"); 10156 } 10157 } 10158 10159 // Now that we have cleaned up any update processes, we 10160 // are ready to start launching real processes and know that 10161 // we won't trample on them any more. 10162 mProcessesReady = true; 10163 } 10164 10165 Slog.i(TAG, "System now ready"); 10166 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 10167 SystemClock.uptimeMillis()); 10168 10169 synchronized(this) { 10170 // Make sure we have no pre-ready processes sitting around. 10171 10172 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10173 ResolveInfo ri = mContext.getPackageManager() 10174 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 10175 STOCK_PM_FLAGS); 10176 CharSequence errorMsg = null; 10177 if (ri != null) { 10178 ActivityInfo ai = ri.activityInfo; 10179 ApplicationInfo app = ai.applicationInfo; 10180 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 10181 mTopAction = Intent.ACTION_FACTORY_TEST; 10182 mTopData = null; 10183 mTopComponent = new ComponentName(app.packageName, 10184 ai.name); 10185 } else { 10186 errorMsg = mContext.getResources().getText( 10187 com.android.internal.R.string.factorytest_not_system); 10188 } 10189 } else { 10190 errorMsg = mContext.getResources().getText( 10191 com.android.internal.R.string.factorytest_no_action); 10192 } 10193 if (errorMsg != null) { 10194 mTopAction = null; 10195 mTopData = null; 10196 mTopComponent = null; 10197 Message msg = Message.obtain(); 10198 msg.what = SHOW_FACTORY_ERROR_MSG; 10199 msg.getData().putCharSequence("msg", errorMsg); 10200 mHandler.sendMessage(msg); 10201 } 10202 } 10203 } 10204 10205 retrieveSettings(); 10206 10207 synchronized (this) { 10208 readGrantedUriPermissionsLocked(); 10209 } 10210 10211 if (goingCallback != null) goingCallback.run(); 10212 10213 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START, 10214 Integer.toString(mCurrentUserId), mCurrentUserId); 10215 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START, 10216 Integer.toString(mCurrentUserId), mCurrentUserId); 10217 mSystemServiceManager.startUser(mCurrentUserId); 10218 10219 synchronized (this) { 10220 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 10221 try { 10222 List apps = AppGlobals.getPackageManager(). 10223 getPersistentApplications(STOCK_PM_FLAGS); 10224 if (apps != null) { 10225 int N = apps.size(); 10226 int i; 10227 for (i=0; i<N; i++) { 10228 ApplicationInfo info 10229 = (ApplicationInfo)apps.get(i); 10230 if (info != null && 10231 !info.packageName.equals("android")) { 10232 addAppLocked(info, false, null /* ABI override */); 10233 } 10234 } 10235 } 10236 } catch (RemoteException ex) { 10237 // pm is in same process, this will never happen. 10238 } 10239 } 10240 10241 // Start up initial activity. 10242 mBooting = true; 10243 10244 try { 10245 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 10246 Message msg = Message.obtain(); 10247 msg.what = SHOW_UID_ERROR_MSG; 10248 mHandler.sendMessage(msg); 10249 } 10250 } catch (RemoteException e) { 10251 } 10252 10253 long ident = Binder.clearCallingIdentity(); 10254 try { 10255 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 10256 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 10257 | Intent.FLAG_RECEIVER_FOREGROUND); 10258 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10259 broadcastIntentLocked(null, null, intent, 10260 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 10261 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 10262 intent = new Intent(Intent.ACTION_USER_STARTING); 10263 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 10264 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 10265 broadcastIntentLocked(null, null, intent, 10266 null, new IIntentReceiver.Stub() { 10267 @Override 10268 public void performReceive(Intent intent, int resultCode, String data, 10269 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 10270 throws RemoteException { 10271 } 10272 }, 0, null, null, 10273 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 10274 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 10275 } catch (Throwable t) { 10276 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 10277 } finally { 10278 Binder.restoreCallingIdentity(ident); 10279 } 10280 mStackSupervisor.resumeTopActivitiesLocked(); 10281 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 10282 } 10283 } 10284 10285 private boolean makeAppCrashingLocked(ProcessRecord app, 10286 String shortMsg, String longMsg, String stackTrace) { 10287 app.crashing = true; 10288 app.crashingReport = generateProcessError(app, 10289 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 10290 startAppProblemLocked(app); 10291 app.stopFreezingAllLocked(); 10292 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 10293 } 10294 10295 private void makeAppNotRespondingLocked(ProcessRecord app, 10296 String activity, String shortMsg, String longMsg) { 10297 app.notResponding = true; 10298 app.notRespondingReport = generateProcessError(app, 10299 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 10300 activity, shortMsg, longMsg, null); 10301 startAppProblemLocked(app); 10302 app.stopFreezingAllLocked(); 10303 } 10304 10305 /** 10306 * Generate a process error record, suitable for attachment to a ProcessRecord. 10307 * 10308 * @param app The ProcessRecord in which the error occurred. 10309 * @param condition Crashing, Application Not Responding, etc. Values are defined in 10310 * ActivityManager.AppErrorStateInfo 10311 * @param activity The activity associated with the crash, if known. 10312 * @param shortMsg Short message describing the crash. 10313 * @param longMsg Long message describing the crash. 10314 * @param stackTrace Full crash stack trace, may be null. 10315 * 10316 * @return Returns a fully-formed AppErrorStateInfo record. 10317 */ 10318 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 10319 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 10320 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 10321 10322 report.condition = condition; 10323 report.processName = app.processName; 10324 report.pid = app.pid; 10325 report.uid = app.info.uid; 10326 report.tag = activity; 10327 report.shortMsg = shortMsg; 10328 report.longMsg = longMsg; 10329 report.stackTrace = stackTrace; 10330 10331 return report; 10332 } 10333 10334 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 10335 synchronized (this) { 10336 app.crashing = false; 10337 app.crashingReport = null; 10338 app.notResponding = false; 10339 app.notRespondingReport = null; 10340 if (app.anrDialog == fromDialog) { 10341 app.anrDialog = null; 10342 } 10343 if (app.waitDialog == fromDialog) { 10344 app.waitDialog = null; 10345 } 10346 if (app.pid > 0 && app.pid != MY_PID) { 10347 handleAppCrashLocked(app, null, null, null); 10348 killUnneededProcessLocked(app, "user request after error"); 10349 } 10350 } 10351 } 10352 10353 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 10354 String stackTrace) { 10355 long now = SystemClock.uptimeMillis(); 10356 10357 Long crashTime; 10358 if (!app.isolated) { 10359 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 10360 } else { 10361 crashTime = null; 10362 } 10363 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 10364 // This process loses! 10365 Slog.w(TAG, "Process " + app.info.processName 10366 + " has crashed too many times: killing!"); 10367 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 10368 app.userId, app.info.processName, app.uid); 10369 mStackSupervisor.handleAppCrashLocked(app); 10370 if (!app.persistent) { 10371 // We don't want to start this process again until the user 10372 // explicitly does so... but for persistent process, we really 10373 // need to keep it running. If a persistent process is actually 10374 // repeatedly crashing, then badness for everyone. 10375 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 10376 app.info.processName); 10377 if (!app.isolated) { 10378 // XXX We don't have a way to mark isolated processes 10379 // as bad, since they don't have a peristent identity. 10380 mBadProcesses.put(app.info.processName, app.uid, 10381 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 10382 mProcessCrashTimes.remove(app.info.processName, app.uid); 10383 } 10384 app.bad = true; 10385 app.removed = true; 10386 // Don't let services in this process be restarted and potentially 10387 // annoy the user repeatedly. Unless it is persistent, since those 10388 // processes run critical code. 10389 removeProcessLocked(app, false, false, "crash"); 10390 mStackSupervisor.resumeTopActivitiesLocked(); 10391 return false; 10392 } 10393 mStackSupervisor.resumeTopActivitiesLocked(); 10394 } else { 10395 mStackSupervisor.finishTopRunningActivityLocked(app); 10396 } 10397 10398 // Bump up the crash count of any services currently running in the proc. 10399 for (int i=app.services.size()-1; i>=0; i--) { 10400 // Any services running in the application need to be placed 10401 // back in the pending list. 10402 ServiceRecord sr = app.services.valueAt(i); 10403 sr.crashCount++; 10404 } 10405 10406 // If the crashing process is what we consider to be the "home process" and it has been 10407 // replaced by a third-party app, clear the package preferred activities from packages 10408 // with a home activity running in the process to prevent a repeatedly crashing app 10409 // from blocking the user to manually clear the list. 10410 final ArrayList<ActivityRecord> activities = app.activities; 10411 if (app == mHomeProcess && activities.size() > 0 10412 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 10413 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 10414 final ActivityRecord r = activities.get(activityNdx); 10415 if (r.isHomeActivity()) { 10416 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 10417 try { 10418 ActivityThread.getPackageManager() 10419 .clearPackagePreferredActivities(r.packageName); 10420 } catch (RemoteException c) { 10421 // pm is in same process, this will never happen. 10422 } 10423 } 10424 } 10425 } 10426 10427 if (!app.isolated) { 10428 // XXX Can't keep track of crash times for isolated processes, 10429 // because they don't have a perisistent identity. 10430 mProcessCrashTimes.put(app.info.processName, app.uid, now); 10431 } 10432 10433 return true; 10434 } 10435 10436 void startAppProblemLocked(ProcessRecord app) { 10437 if (app.userId == mCurrentUserId) { 10438 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 10439 mContext, app.info.packageName, app.info.flags); 10440 } else { 10441 // If this app is not running under the current user, then we 10442 // can't give it a report button because that would require 10443 // launching the report UI under a different user. 10444 app.errorReportReceiver = null; 10445 } 10446 skipCurrentReceiverLocked(app); 10447 } 10448 10449 void skipCurrentReceiverLocked(ProcessRecord app) { 10450 for (BroadcastQueue queue : mBroadcastQueues) { 10451 queue.skipCurrentReceiverLocked(app); 10452 } 10453 } 10454 10455 /** 10456 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 10457 * The application process will exit immediately after this call returns. 10458 * @param app object of the crashing app, null for the system server 10459 * @param crashInfo describing the exception 10460 */ 10461 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 10462 ProcessRecord r = findAppProcess(app, "Crash"); 10463 final String processName = app == null ? "system_server" 10464 : (r == null ? "unknown" : r.processName); 10465 10466 handleApplicationCrashInner("crash", r, processName, crashInfo); 10467 } 10468 10469 /* Native crash reporting uses this inner version because it needs to be somewhat 10470 * decoupled from the AM-managed cleanup lifecycle 10471 */ 10472 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10473 ApplicationErrorReport.CrashInfo crashInfo) { 10474 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10475 UserHandle.getUserId(Binder.getCallingUid()), processName, 10476 r == null ? -1 : r.info.flags, 10477 crashInfo.exceptionClassName, 10478 crashInfo.exceptionMessage, 10479 crashInfo.throwFileName, 10480 crashInfo.throwLineNumber); 10481 10482 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10483 10484 crashApplication(r, crashInfo); 10485 } 10486 10487 public void handleApplicationStrictModeViolation( 10488 IBinder app, 10489 int violationMask, 10490 StrictMode.ViolationInfo info) { 10491 ProcessRecord r = findAppProcess(app, "StrictMode"); 10492 if (r == null) { 10493 return; 10494 } 10495 10496 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10497 Integer stackFingerprint = info.hashCode(); 10498 boolean logIt = true; 10499 synchronized (mAlreadyLoggedViolatedStacks) { 10500 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10501 logIt = false; 10502 // TODO: sub-sample into EventLog for these, with 10503 // the info.durationMillis? Then we'd get 10504 // the relative pain numbers, without logging all 10505 // the stack traces repeatedly. We'd want to do 10506 // likewise in the client code, which also does 10507 // dup suppression, before the Binder call. 10508 } else { 10509 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10510 mAlreadyLoggedViolatedStacks.clear(); 10511 } 10512 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10513 } 10514 } 10515 if (logIt) { 10516 logStrictModeViolationToDropBox(r, info); 10517 } 10518 } 10519 10520 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10521 AppErrorResult result = new AppErrorResult(); 10522 synchronized (this) { 10523 final long origId = Binder.clearCallingIdentity(); 10524 10525 Message msg = Message.obtain(); 10526 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10527 HashMap<String, Object> data = new HashMap<String, Object>(); 10528 data.put("result", result); 10529 data.put("app", r); 10530 data.put("violationMask", violationMask); 10531 data.put("info", info); 10532 msg.obj = data; 10533 mHandler.sendMessage(msg); 10534 10535 Binder.restoreCallingIdentity(origId); 10536 } 10537 int res = result.get(); 10538 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10539 } 10540 } 10541 10542 // Depending on the policy in effect, there could be a bunch of 10543 // these in quick succession so we try to batch these together to 10544 // minimize disk writes, number of dropbox entries, and maximize 10545 // compression, by having more fewer, larger records. 10546 private void logStrictModeViolationToDropBox( 10547 ProcessRecord process, 10548 StrictMode.ViolationInfo info) { 10549 if (info == null) { 10550 return; 10551 } 10552 final boolean isSystemApp = process == null || 10553 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10554 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10555 final String processName = process == null ? "unknown" : process.processName; 10556 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10557 final DropBoxManager dbox = (DropBoxManager) 10558 mContext.getSystemService(Context.DROPBOX_SERVICE); 10559 10560 // Exit early if the dropbox isn't configured to accept this report type. 10561 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10562 10563 boolean bufferWasEmpty; 10564 boolean needsFlush; 10565 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10566 synchronized (sb) { 10567 bufferWasEmpty = sb.length() == 0; 10568 appendDropBoxProcessHeaders(process, processName, sb); 10569 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10570 sb.append("System-App: ").append(isSystemApp).append("\n"); 10571 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10572 if (info.violationNumThisLoop != 0) { 10573 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10574 } 10575 if (info.numAnimationsRunning != 0) { 10576 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10577 } 10578 if (info.broadcastIntentAction != null) { 10579 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10580 } 10581 if (info.durationMillis != -1) { 10582 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10583 } 10584 if (info.numInstances != -1) { 10585 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10586 } 10587 if (info.tags != null) { 10588 for (String tag : info.tags) { 10589 sb.append("Span-Tag: ").append(tag).append("\n"); 10590 } 10591 } 10592 sb.append("\n"); 10593 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10594 sb.append(info.crashInfo.stackTrace); 10595 } 10596 sb.append("\n"); 10597 10598 // Only buffer up to ~64k. Various logging bits truncate 10599 // things at 128k. 10600 needsFlush = (sb.length() > 64 * 1024); 10601 } 10602 10603 // Flush immediately if the buffer's grown too large, or this 10604 // is a non-system app. Non-system apps are isolated with a 10605 // different tag & policy and not batched. 10606 // 10607 // Batching is useful during internal testing with 10608 // StrictMode settings turned up high. Without batching, 10609 // thousands of separate files could be created on boot. 10610 if (!isSystemApp || needsFlush) { 10611 new Thread("Error dump: " + dropboxTag) { 10612 @Override 10613 public void run() { 10614 String report; 10615 synchronized (sb) { 10616 report = sb.toString(); 10617 sb.delete(0, sb.length()); 10618 sb.trimToSize(); 10619 } 10620 if (report.length() != 0) { 10621 dbox.addText(dropboxTag, report); 10622 } 10623 } 10624 }.start(); 10625 return; 10626 } 10627 10628 // System app batching: 10629 if (!bufferWasEmpty) { 10630 // An existing dropbox-writing thread is outstanding, so 10631 // we don't need to start it up. The existing thread will 10632 // catch the buffer appends we just did. 10633 return; 10634 } 10635 10636 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10637 // (After this point, we shouldn't access AMS internal data structures.) 10638 new Thread("Error dump: " + dropboxTag) { 10639 @Override 10640 public void run() { 10641 // 5 second sleep to let stacks arrive and be batched together 10642 try { 10643 Thread.sleep(5000); // 5 seconds 10644 } catch (InterruptedException e) {} 10645 10646 String errorReport; 10647 synchronized (mStrictModeBuffer) { 10648 errorReport = mStrictModeBuffer.toString(); 10649 if (errorReport.length() == 0) { 10650 return; 10651 } 10652 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10653 mStrictModeBuffer.trimToSize(); 10654 } 10655 dbox.addText(dropboxTag, errorReport); 10656 } 10657 }.start(); 10658 } 10659 10660 /** 10661 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10662 * @param app object of the crashing app, null for the system server 10663 * @param tag reported by the caller 10664 * @param crashInfo describing the context of the error 10665 * @return true if the process should exit immediately (WTF is fatal) 10666 */ 10667 public boolean handleApplicationWtf(IBinder app, String tag, 10668 ApplicationErrorReport.CrashInfo crashInfo) { 10669 ProcessRecord r = findAppProcess(app, "WTF"); 10670 final String processName = app == null ? "system_server" 10671 : (r == null ? "unknown" : r.processName); 10672 10673 EventLog.writeEvent(EventLogTags.AM_WTF, 10674 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10675 processName, 10676 r == null ? -1 : r.info.flags, 10677 tag, crashInfo.exceptionMessage); 10678 10679 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10680 10681 if (r != null && r.pid != Process.myPid() && 10682 Settings.Global.getInt(mContext.getContentResolver(), 10683 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10684 crashApplication(r, crashInfo); 10685 return true; 10686 } else { 10687 return false; 10688 } 10689 } 10690 10691 /** 10692 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10693 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10694 */ 10695 private ProcessRecord findAppProcess(IBinder app, String reason) { 10696 if (app == null) { 10697 return null; 10698 } 10699 10700 synchronized (this) { 10701 final int NP = mProcessNames.getMap().size(); 10702 for (int ip=0; ip<NP; ip++) { 10703 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10704 final int NA = apps.size(); 10705 for (int ia=0; ia<NA; ia++) { 10706 ProcessRecord p = apps.valueAt(ia); 10707 if (p.thread != null && p.thread.asBinder() == app) { 10708 return p; 10709 } 10710 } 10711 } 10712 10713 Slog.w(TAG, "Can't find mystery application for " + reason 10714 + " from pid=" + Binder.getCallingPid() 10715 + " uid=" + Binder.getCallingUid() + ": " + app); 10716 return null; 10717 } 10718 } 10719 10720 /** 10721 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10722 * to append various headers to the dropbox log text. 10723 */ 10724 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10725 StringBuilder sb) { 10726 // Watchdog thread ends up invoking this function (with 10727 // a null ProcessRecord) to add the stack file to dropbox. 10728 // Do not acquire a lock on this (am) in such cases, as it 10729 // could cause a potential deadlock, if and when watchdog 10730 // is invoked due to unavailability of lock on am and it 10731 // would prevent watchdog from killing system_server. 10732 if (process == null) { 10733 sb.append("Process: ").append(processName).append("\n"); 10734 return; 10735 } 10736 // Note: ProcessRecord 'process' is guarded by the service 10737 // instance. (notably process.pkgList, which could otherwise change 10738 // concurrently during execution of this method) 10739 synchronized (this) { 10740 sb.append("Process: ").append(processName).append("\n"); 10741 int flags = process.info.flags; 10742 IPackageManager pm = AppGlobals.getPackageManager(); 10743 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10744 for (int ip=0; ip<process.pkgList.size(); ip++) { 10745 String pkg = process.pkgList.keyAt(ip); 10746 sb.append("Package: ").append(pkg); 10747 try { 10748 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10749 if (pi != null) { 10750 sb.append(" v").append(pi.versionCode); 10751 if (pi.versionName != null) { 10752 sb.append(" (").append(pi.versionName).append(")"); 10753 } 10754 } 10755 } catch (RemoteException e) { 10756 Slog.e(TAG, "Error getting package info: " + pkg, e); 10757 } 10758 sb.append("\n"); 10759 } 10760 } 10761 } 10762 10763 private static String processClass(ProcessRecord process) { 10764 if (process == null || process.pid == MY_PID) { 10765 return "system_server"; 10766 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10767 return "system_app"; 10768 } else { 10769 return "data_app"; 10770 } 10771 } 10772 10773 /** 10774 * Write a description of an error (crash, WTF, ANR) to the drop box. 10775 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10776 * @param process which caused the error, null means the system server 10777 * @param activity which triggered the error, null if unknown 10778 * @param parent activity related to the error, null if unknown 10779 * @param subject line related to the error, null if absent 10780 * @param report in long form describing the error, null if absent 10781 * @param logFile to include in the report, null if none 10782 * @param crashInfo giving an application stack trace, null if absent 10783 */ 10784 public void addErrorToDropBox(String eventType, 10785 ProcessRecord process, String processName, ActivityRecord activity, 10786 ActivityRecord parent, String subject, 10787 final String report, final File logFile, 10788 final ApplicationErrorReport.CrashInfo crashInfo) { 10789 // NOTE -- this must never acquire the ActivityManagerService lock, 10790 // otherwise the watchdog may be prevented from resetting the system. 10791 10792 final String dropboxTag = processClass(process) + "_" + eventType; 10793 final DropBoxManager dbox = (DropBoxManager) 10794 mContext.getSystemService(Context.DROPBOX_SERVICE); 10795 10796 // Exit early if the dropbox isn't configured to accept this report type. 10797 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10798 10799 final StringBuilder sb = new StringBuilder(1024); 10800 appendDropBoxProcessHeaders(process, processName, sb); 10801 if (activity != null) { 10802 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10803 } 10804 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10805 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10806 } 10807 if (parent != null && parent != activity) { 10808 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10809 } 10810 if (subject != null) { 10811 sb.append("Subject: ").append(subject).append("\n"); 10812 } 10813 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10814 if (Debug.isDebuggerConnected()) { 10815 sb.append("Debugger: Connected\n"); 10816 } 10817 sb.append("\n"); 10818 10819 // Do the rest in a worker thread to avoid blocking the caller on I/O 10820 // (After this point, we shouldn't access AMS internal data structures.) 10821 Thread worker = new Thread("Error dump: " + dropboxTag) { 10822 @Override 10823 public void run() { 10824 if (report != null) { 10825 sb.append(report); 10826 } 10827 if (logFile != null) { 10828 try { 10829 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10830 "\n\n[[TRUNCATED]]")); 10831 } catch (IOException e) { 10832 Slog.e(TAG, "Error reading " + logFile, e); 10833 } 10834 } 10835 if (crashInfo != null && crashInfo.stackTrace != null) { 10836 sb.append(crashInfo.stackTrace); 10837 } 10838 10839 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10840 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10841 if (lines > 0) { 10842 sb.append("\n"); 10843 10844 // Merge several logcat streams, and take the last N lines 10845 InputStreamReader input = null; 10846 try { 10847 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10848 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10849 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10850 10851 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10852 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10853 input = new InputStreamReader(logcat.getInputStream()); 10854 10855 int num; 10856 char[] buf = new char[8192]; 10857 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10858 } catch (IOException e) { 10859 Slog.e(TAG, "Error running logcat", e); 10860 } finally { 10861 if (input != null) try { input.close(); } catch (IOException e) {} 10862 } 10863 } 10864 10865 dbox.addText(dropboxTag, sb.toString()); 10866 } 10867 }; 10868 10869 if (process == null) { 10870 // If process is null, we are being called from some internal code 10871 // and may be about to die -- run this synchronously. 10872 worker.run(); 10873 } else { 10874 worker.start(); 10875 } 10876 } 10877 10878 /** 10879 * Bring up the "unexpected error" dialog box for a crashing app. 10880 * Deal with edge cases (intercepts from instrumented applications, 10881 * ActivityController, error intent receivers, that sort of thing). 10882 * @param r the application crashing 10883 * @param crashInfo describing the failure 10884 */ 10885 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10886 long timeMillis = System.currentTimeMillis(); 10887 String shortMsg = crashInfo.exceptionClassName; 10888 String longMsg = crashInfo.exceptionMessage; 10889 String stackTrace = crashInfo.stackTrace; 10890 if (shortMsg != null && longMsg != null) { 10891 longMsg = shortMsg + ": " + longMsg; 10892 } else if (shortMsg != null) { 10893 longMsg = shortMsg; 10894 } 10895 10896 AppErrorResult result = new AppErrorResult(); 10897 synchronized (this) { 10898 if (mController != null) { 10899 try { 10900 String name = r != null ? r.processName : null; 10901 int pid = r != null ? r.pid : Binder.getCallingPid(); 10902 int uid = r != null ? r.info.uid : Binder.getCallingUid(); 10903 if (!mController.appCrashed(name, pid, 10904 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10905 Slog.w(TAG, "Force-killing crashed app " + name 10906 + " at watcher's request"); 10907 Process.killProcess(pid); 10908 if (r != null) { 10909 Process.killProcessGroup(uid, pid); 10910 } 10911 return; 10912 } 10913 } catch (RemoteException e) { 10914 mController = null; 10915 Watchdog.getInstance().setActivityController(null); 10916 } 10917 } 10918 10919 final long origId = Binder.clearCallingIdentity(); 10920 10921 // If this process is running instrumentation, finish it. 10922 if (r != null && r.instrumentationClass != null) { 10923 Slog.w(TAG, "Error in app " + r.processName 10924 + " running instrumentation " + r.instrumentationClass + ":"); 10925 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10926 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10927 Bundle info = new Bundle(); 10928 info.putString("shortMsg", shortMsg); 10929 info.putString("longMsg", longMsg); 10930 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10931 Binder.restoreCallingIdentity(origId); 10932 return; 10933 } 10934 10935 // If we can't identify the process or it's already exceeded its crash quota, 10936 // quit right away without showing a crash dialog. 10937 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10938 Binder.restoreCallingIdentity(origId); 10939 return; 10940 } 10941 10942 Message msg = Message.obtain(); 10943 msg.what = SHOW_ERROR_MSG; 10944 HashMap data = new HashMap(); 10945 data.put("result", result); 10946 data.put("app", r); 10947 msg.obj = data; 10948 mHandler.sendMessage(msg); 10949 10950 Binder.restoreCallingIdentity(origId); 10951 } 10952 10953 int res = result.get(); 10954 10955 Intent appErrorIntent = null; 10956 synchronized (this) { 10957 if (r != null && !r.isolated) { 10958 // XXX Can't keep track of crash time for isolated processes, 10959 // since they don't have a persistent identity. 10960 mProcessCrashTimes.put(r.info.processName, r.uid, 10961 SystemClock.uptimeMillis()); 10962 } 10963 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10964 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10965 } 10966 } 10967 10968 if (appErrorIntent != null) { 10969 try { 10970 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10971 } catch (ActivityNotFoundException e) { 10972 Slog.w(TAG, "bug report receiver dissappeared", e); 10973 } 10974 } 10975 } 10976 10977 Intent createAppErrorIntentLocked(ProcessRecord r, 10978 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10979 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10980 if (report == null) { 10981 return null; 10982 } 10983 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10984 result.setComponent(r.errorReportReceiver); 10985 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10986 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10987 return result; 10988 } 10989 10990 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10991 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10992 if (r.errorReportReceiver == null) { 10993 return null; 10994 } 10995 10996 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10997 return null; 10998 } 10999 11000 ApplicationErrorReport report = new ApplicationErrorReport(); 11001 report.packageName = r.info.packageName; 11002 report.installerPackageName = r.errorReportReceiver.getPackageName(); 11003 report.processName = r.processName; 11004 report.time = timeMillis; 11005 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 11006 11007 if (r.crashing || r.forceCrashReport) { 11008 report.type = ApplicationErrorReport.TYPE_CRASH; 11009 report.crashInfo = crashInfo; 11010 } else if (r.notResponding) { 11011 report.type = ApplicationErrorReport.TYPE_ANR; 11012 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 11013 11014 report.anrInfo.activity = r.notRespondingReport.tag; 11015 report.anrInfo.cause = r.notRespondingReport.shortMsg; 11016 report.anrInfo.info = r.notRespondingReport.longMsg; 11017 } 11018 11019 return report; 11020 } 11021 11022 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 11023 enforceNotIsolatedCaller("getProcessesInErrorState"); 11024 // assume our apps are happy - lazy create the list 11025 List<ActivityManager.ProcessErrorStateInfo> errList = null; 11026 11027 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11028 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11029 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11030 11031 synchronized (this) { 11032 11033 // iterate across all processes 11034 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11035 ProcessRecord app = mLruProcesses.get(i); 11036 if (!allUsers && app.userId != userId) { 11037 continue; 11038 } 11039 if ((app.thread != null) && (app.crashing || app.notResponding)) { 11040 // This one's in trouble, so we'll generate a report for it 11041 // crashes are higher priority (in case there's a crash *and* an anr) 11042 ActivityManager.ProcessErrorStateInfo report = null; 11043 if (app.crashing) { 11044 report = app.crashingReport; 11045 } else if (app.notResponding) { 11046 report = app.notRespondingReport; 11047 } 11048 11049 if (report != null) { 11050 if (errList == null) { 11051 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 11052 } 11053 errList.add(report); 11054 } else { 11055 Slog.w(TAG, "Missing app error report, app = " + app.processName + 11056 " crashing = " + app.crashing + 11057 " notResponding = " + app.notResponding); 11058 } 11059 } 11060 } 11061 } 11062 11063 return errList; 11064 } 11065 11066 static int procStateToImportance(int procState, int memAdj, 11067 ActivityManager.RunningAppProcessInfo currApp) { 11068 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState); 11069 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 11070 currApp.lru = memAdj; 11071 } else { 11072 currApp.lru = 0; 11073 } 11074 return imp; 11075 } 11076 11077 private void fillInProcMemInfo(ProcessRecord app, 11078 ActivityManager.RunningAppProcessInfo outInfo) { 11079 outInfo.pid = app.pid; 11080 outInfo.uid = app.info.uid; 11081 if (mHeavyWeightProcess == app) { 11082 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 11083 } 11084 if (app.persistent) { 11085 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 11086 } 11087 if (app.activities.size() > 0) { 11088 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 11089 } 11090 outInfo.lastTrimLevel = app.trimMemoryLevel; 11091 int adj = app.curAdj; 11092 int procState = app.curProcState; 11093 outInfo.importance = procStateToImportance(procState, adj, outInfo); 11094 outInfo.importanceReasonCode = app.adjTypeCode; 11095 outInfo.processState = app.curProcState; 11096 } 11097 11098 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 11099 enforceNotIsolatedCaller("getRunningAppProcesses"); 11100 // Lazy instantiation of list 11101 List<ActivityManager.RunningAppProcessInfo> runList = null; 11102 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, 11103 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 11104 int userId = UserHandle.getUserId(Binder.getCallingUid()); 11105 synchronized (this) { 11106 // Iterate across all processes 11107 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11108 ProcessRecord app = mLruProcesses.get(i); 11109 if (!allUsers && app.userId != userId) { 11110 continue; 11111 } 11112 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 11113 // Generate process state info for running application 11114 ActivityManager.RunningAppProcessInfo currApp = 11115 new ActivityManager.RunningAppProcessInfo(app.processName, 11116 app.pid, app.getPackageList()); 11117 fillInProcMemInfo(app, currApp); 11118 if (app.adjSource instanceof ProcessRecord) { 11119 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 11120 currApp.importanceReasonImportance = 11121 ActivityManager.RunningAppProcessInfo.procStateToImportance( 11122 app.adjSourceProcState); 11123 } else if (app.adjSource instanceof ActivityRecord) { 11124 ActivityRecord r = (ActivityRecord)app.adjSource; 11125 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 11126 } 11127 if (app.adjTarget instanceof ComponentName) { 11128 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 11129 } 11130 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 11131 // + " lru=" + currApp.lru); 11132 if (runList == null) { 11133 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 11134 } 11135 runList.add(currApp); 11136 } 11137 } 11138 } 11139 return runList; 11140 } 11141 11142 public List<ApplicationInfo> getRunningExternalApplications() { 11143 enforceNotIsolatedCaller("getRunningExternalApplications"); 11144 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 11145 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 11146 if (runningApps != null && runningApps.size() > 0) { 11147 Set<String> extList = new HashSet<String>(); 11148 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 11149 if (app.pkgList != null) { 11150 for (String pkg : app.pkgList) { 11151 extList.add(pkg); 11152 } 11153 } 11154 } 11155 IPackageManager pm = AppGlobals.getPackageManager(); 11156 for (String pkg : extList) { 11157 try { 11158 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 11159 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 11160 retList.add(info); 11161 } 11162 } catch (RemoteException e) { 11163 } 11164 } 11165 } 11166 return retList; 11167 } 11168 11169 @Override 11170 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 11171 enforceNotIsolatedCaller("getMyMemoryState"); 11172 synchronized (this) { 11173 ProcessRecord proc; 11174 synchronized (mPidsSelfLocked) { 11175 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 11176 } 11177 fillInProcMemInfo(proc, outInfo); 11178 } 11179 } 11180 11181 @Override 11182 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 11183 if (checkCallingPermission(android.Manifest.permission.DUMP) 11184 != PackageManager.PERMISSION_GRANTED) { 11185 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 11186 + Binder.getCallingPid() 11187 + ", uid=" + Binder.getCallingUid() 11188 + " without permission " 11189 + android.Manifest.permission.DUMP); 11190 return; 11191 } 11192 11193 boolean dumpAll = false; 11194 boolean dumpClient = false; 11195 String dumpPackage = null; 11196 11197 int opti = 0; 11198 while (opti < args.length) { 11199 String opt = args[opti]; 11200 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 11201 break; 11202 } 11203 opti++; 11204 if ("-a".equals(opt)) { 11205 dumpAll = true; 11206 } else if ("-c".equals(opt)) { 11207 dumpClient = true; 11208 } else if ("-h".equals(opt)) { 11209 pw.println("Activity manager dump options:"); 11210 pw.println(" [-a] [-c] [-h] [cmd] ..."); 11211 pw.println(" cmd may be one of:"); 11212 pw.println(" a[ctivities]: activity stack state"); 11213 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 11214 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 11215 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 11216 pw.println(" o[om]: out of memory management"); 11217 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 11218 pw.println(" provider [COMP_SPEC]: provider client-side state"); 11219 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 11220 pw.println(" service [COMP_SPEC]: service client-side state"); 11221 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 11222 pw.println(" all: dump all activities"); 11223 pw.println(" top: dump the top activity"); 11224 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 11225 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 11226 pw.println(" a partial substring in a component name, a"); 11227 pw.println(" hex object identifier."); 11228 pw.println(" -a: include all available server state."); 11229 pw.println(" -c: include client state."); 11230 return; 11231 } else { 11232 pw.println("Unknown argument: " + opt + "; use -h for help"); 11233 } 11234 } 11235 11236 long origId = Binder.clearCallingIdentity(); 11237 boolean more = false; 11238 // Is the caller requesting to dump a particular piece of data? 11239 if (opti < args.length) { 11240 String cmd = args[opti]; 11241 opti++; 11242 if ("activities".equals(cmd) || "a".equals(cmd)) { 11243 synchronized (this) { 11244 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 11245 } 11246 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 11247 String[] newArgs; 11248 String name; 11249 if (opti >= args.length) { 11250 name = null; 11251 newArgs = EMPTY_STRING_ARRAY; 11252 } else { 11253 name = args[opti]; 11254 opti++; 11255 newArgs = new String[args.length - opti]; 11256 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11257 args.length - opti); 11258 } 11259 synchronized (this) { 11260 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 11261 } 11262 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 11263 String[] newArgs; 11264 String name; 11265 if (opti >= args.length) { 11266 name = null; 11267 newArgs = EMPTY_STRING_ARRAY; 11268 } else { 11269 name = args[opti]; 11270 opti++; 11271 newArgs = new String[args.length - opti]; 11272 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11273 args.length - opti); 11274 } 11275 synchronized (this) { 11276 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 11277 } 11278 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 11279 String[] newArgs; 11280 String name; 11281 if (opti >= args.length) { 11282 name = null; 11283 newArgs = EMPTY_STRING_ARRAY; 11284 } else { 11285 name = args[opti]; 11286 opti++; 11287 newArgs = new String[args.length - opti]; 11288 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11289 args.length - opti); 11290 } 11291 synchronized (this) { 11292 dumpProcessesLocked(fd, pw, args, opti, true, name); 11293 } 11294 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 11295 synchronized (this) { 11296 dumpOomLocked(fd, pw, args, opti, true); 11297 } 11298 } else if ("provider".equals(cmd)) { 11299 String[] newArgs; 11300 String name; 11301 if (opti >= args.length) { 11302 name = null; 11303 newArgs = EMPTY_STRING_ARRAY; 11304 } else { 11305 name = args[opti]; 11306 opti++; 11307 newArgs = new String[args.length - opti]; 11308 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11309 } 11310 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 11311 pw.println("No providers match: " + name); 11312 pw.println("Use -h for help."); 11313 } 11314 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 11315 synchronized (this) { 11316 dumpProvidersLocked(fd, pw, args, opti, true, null); 11317 } 11318 } else if ("service".equals(cmd)) { 11319 String[] newArgs; 11320 String name; 11321 if (opti >= args.length) { 11322 name = null; 11323 newArgs = EMPTY_STRING_ARRAY; 11324 } else { 11325 name = args[opti]; 11326 opti++; 11327 newArgs = new String[args.length - opti]; 11328 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11329 args.length - opti); 11330 } 11331 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 11332 pw.println("No services match: " + name); 11333 pw.println("Use -h for help."); 11334 } 11335 } else if ("package".equals(cmd)) { 11336 String[] newArgs; 11337 if (opti >= args.length) { 11338 pw.println("package: no package name specified"); 11339 pw.println("Use -h for help."); 11340 } else { 11341 dumpPackage = args[opti]; 11342 opti++; 11343 newArgs = new String[args.length - opti]; 11344 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 11345 args.length - opti); 11346 args = newArgs; 11347 opti = 0; 11348 more = true; 11349 } 11350 } else if ("services".equals(cmd) || "s".equals(cmd)) { 11351 synchronized (this) { 11352 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 11353 } 11354 } else { 11355 // Dumping a single activity? 11356 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 11357 pw.println("Bad activity command, or no activities match: " + cmd); 11358 pw.println("Use -h for help."); 11359 } 11360 } 11361 if (!more) { 11362 Binder.restoreCallingIdentity(origId); 11363 return; 11364 } 11365 } 11366 11367 // No piece of data specified, dump everything. 11368 synchronized (this) { 11369 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11370 pw.println(); 11371 if (dumpAll) { 11372 pw.println("-------------------------------------------------------------------------------"); 11373 } 11374 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11375 pw.println(); 11376 if (dumpAll) { 11377 pw.println("-------------------------------------------------------------------------------"); 11378 } 11379 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11380 pw.println(); 11381 if (dumpAll) { 11382 pw.println("-------------------------------------------------------------------------------"); 11383 } 11384 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11385 pw.println(); 11386 if (dumpAll) { 11387 pw.println("-------------------------------------------------------------------------------"); 11388 } 11389 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 11390 pw.println(); 11391 if (dumpAll) { 11392 pw.println("-------------------------------------------------------------------------------"); 11393 } 11394 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 11395 } 11396 Binder.restoreCallingIdentity(origId); 11397 } 11398 11399 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11400 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 11401 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 11402 11403 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 11404 dumpPackage); 11405 boolean needSep = printedAnything; 11406 11407 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 11408 dumpPackage, needSep, " mFocusedActivity: "); 11409 if (printed) { 11410 printedAnything = true; 11411 needSep = false; 11412 } 11413 11414 if (dumpPackage == null) { 11415 if (needSep) { 11416 pw.println(); 11417 } 11418 needSep = true; 11419 printedAnything = true; 11420 mStackSupervisor.dump(pw, " "); 11421 } 11422 11423 if (mRecentTasks.size() > 0) { 11424 boolean printedHeader = false; 11425 11426 final int N = mRecentTasks.size(); 11427 for (int i=0; i<N; i++) { 11428 TaskRecord tr = mRecentTasks.get(i); 11429 if (dumpPackage != null) { 11430 if (tr.realActivity == null || 11431 !dumpPackage.equals(tr.realActivity)) { 11432 continue; 11433 } 11434 } 11435 if (!printedHeader) { 11436 if (needSep) { 11437 pw.println(); 11438 } 11439 pw.println(" Recent tasks:"); 11440 printedHeader = true; 11441 printedAnything = true; 11442 } 11443 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 11444 pw.println(tr); 11445 if (dumpAll) { 11446 mRecentTasks.get(i).dump(pw, " "); 11447 } 11448 } 11449 } 11450 11451 if (!printedAnything) { 11452 pw.println(" (nothing)"); 11453 } 11454 } 11455 11456 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11457 int opti, boolean dumpAll, String dumpPackage) { 11458 boolean needSep = false; 11459 boolean printedAnything = false; 11460 int numPers = 0; 11461 11462 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11463 11464 if (dumpAll) { 11465 final int NP = mProcessNames.getMap().size(); 11466 for (int ip=0; ip<NP; ip++) { 11467 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11468 final int NA = procs.size(); 11469 for (int ia=0; ia<NA; ia++) { 11470 ProcessRecord r = procs.valueAt(ia); 11471 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11472 continue; 11473 } 11474 if (!needSep) { 11475 pw.println(" All known processes:"); 11476 needSep = true; 11477 printedAnything = true; 11478 } 11479 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11480 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11481 pw.print(" "); pw.println(r); 11482 r.dump(pw, " "); 11483 if (r.persistent) { 11484 numPers++; 11485 } 11486 } 11487 } 11488 } 11489 11490 if (mIsolatedProcesses.size() > 0) { 11491 boolean printed = false; 11492 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11493 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11494 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11495 continue; 11496 } 11497 if (!printed) { 11498 if (needSep) { 11499 pw.println(); 11500 } 11501 pw.println(" Isolated process list (sorted by uid):"); 11502 printedAnything = true; 11503 printed = true; 11504 needSep = true; 11505 } 11506 pw.println(String.format("%sIsolated #%2d: %s", 11507 " ", i, r.toString())); 11508 } 11509 } 11510 11511 if (mLruProcesses.size() > 0) { 11512 if (needSep) { 11513 pw.println(); 11514 } 11515 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11516 pw.print(" total, non-act at "); 11517 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11518 pw.print(", non-svc at "); 11519 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11520 pw.println("):"); 11521 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11522 needSep = true; 11523 printedAnything = true; 11524 } 11525 11526 if (dumpAll || dumpPackage != null) { 11527 synchronized (mPidsSelfLocked) { 11528 boolean printed = false; 11529 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11530 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11531 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11532 continue; 11533 } 11534 if (!printed) { 11535 if (needSep) pw.println(); 11536 needSep = true; 11537 pw.println(" PID mappings:"); 11538 printed = true; 11539 printedAnything = true; 11540 } 11541 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11542 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11543 } 11544 } 11545 } 11546 11547 if (mForegroundProcesses.size() > 0) { 11548 synchronized (mPidsSelfLocked) { 11549 boolean printed = false; 11550 for (int i=0; i<mForegroundProcesses.size(); i++) { 11551 ProcessRecord r = mPidsSelfLocked.get( 11552 mForegroundProcesses.valueAt(i).pid); 11553 if (dumpPackage != null && (r == null 11554 || !r.pkgList.containsKey(dumpPackage))) { 11555 continue; 11556 } 11557 if (!printed) { 11558 if (needSep) pw.println(); 11559 needSep = true; 11560 pw.println(" Foreground Processes:"); 11561 printed = true; 11562 printedAnything = true; 11563 } 11564 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11565 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11566 } 11567 } 11568 } 11569 11570 if (mPersistentStartingProcesses.size() > 0) { 11571 if (needSep) pw.println(); 11572 needSep = true; 11573 printedAnything = true; 11574 pw.println(" Persisent processes that are starting:"); 11575 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11576 "Starting Norm", "Restarting PERS", dumpPackage); 11577 } 11578 11579 if (mRemovedProcesses.size() > 0) { 11580 if (needSep) pw.println(); 11581 needSep = true; 11582 printedAnything = true; 11583 pw.println(" Processes that are being removed:"); 11584 dumpProcessList(pw, this, mRemovedProcesses, " ", 11585 "Removed Norm", "Removed PERS", dumpPackage); 11586 } 11587 11588 if (mProcessesOnHold.size() > 0) { 11589 if (needSep) pw.println(); 11590 needSep = true; 11591 printedAnything = true; 11592 pw.println(" Processes that are on old until the system is ready:"); 11593 dumpProcessList(pw, this, mProcessesOnHold, " ", 11594 "OnHold Norm", "OnHold PERS", dumpPackage); 11595 } 11596 11597 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11598 11599 if (mProcessCrashTimes.getMap().size() > 0) { 11600 boolean printed = false; 11601 long now = SystemClock.uptimeMillis(); 11602 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11603 final int NP = pmap.size(); 11604 for (int ip=0; ip<NP; ip++) { 11605 String pname = pmap.keyAt(ip); 11606 SparseArray<Long> uids = pmap.valueAt(ip); 11607 final int N = uids.size(); 11608 for (int i=0; i<N; i++) { 11609 int puid = uids.keyAt(i); 11610 ProcessRecord r = mProcessNames.get(pname, puid); 11611 if (dumpPackage != null && (r == null 11612 || !r.pkgList.containsKey(dumpPackage))) { 11613 continue; 11614 } 11615 if (!printed) { 11616 if (needSep) pw.println(); 11617 needSep = true; 11618 pw.println(" Time since processes crashed:"); 11619 printed = true; 11620 printedAnything = true; 11621 } 11622 pw.print(" Process "); pw.print(pname); 11623 pw.print(" uid "); pw.print(puid); 11624 pw.print(": last crashed "); 11625 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11626 pw.println(" ago"); 11627 } 11628 } 11629 } 11630 11631 if (mBadProcesses.getMap().size() > 0) { 11632 boolean printed = false; 11633 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11634 final int NP = pmap.size(); 11635 for (int ip=0; ip<NP; ip++) { 11636 String pname = pmap.keyAt(ip); 11637 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11638 final int N = uids.size(); 11639 for (int i=0; i<N; i++) { 11640 int puid = uids.keyAt(i); 11641 ProcessRecord r = mProcessNames.get(pname, puid); 11642 if (dumpPackage != null && (r == null 11643 || !r.pkgList.containsKey(dumpPackage))) { 11644 continue; 11645 } 11646 if (!printed) { 11647 if (needSep) pw.println(); 11648 needSep = true; 11649 pw.println(" Bad processes:"); 11650 printedAnything = true; 11651 } 11652 BadProcessInfo info = uids.valueAt(i); 11653 pw.print(" Bad process "); pw.print(pname); 11654 pw.print(" uid "); pw.print(puid); 11655 pw.print(": crashed at time "); pw.println(info.time); 11656 if (info.shortMsg != null) { 11657 pw.print(" Short msg: "); pw.println(info.shortMsg); 11658 } 11659 if (info.longMsg != null) { 11660 pw.print(" Long msg: "); pw.println(info.longMsg); 11661 } 11662 if (info.stack != null) { 11663 pw.println(" Stack:"); 11664 int lastPos = 0; 11665 for (int pos=0; pos<info.stack.length(); pos++) { 11666 if (info.stack.charAt(pos) == '\n') { 11667 pw.print(" "); 11668 pw.write(info.stack, lastPos, pos-lastPos); 11669 pw.println(); 11670 lastPos = pos+1; 11671 } 11672 } 11673 if (lastPos < info.stack.length()) { 11674 pw.print(" "); 11675 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11676 pw.println(); 11677 } 11678 } 11679 } 11680 } 11681 } 11682 11683 if (dumpPackage == null) { 11684 pw.println(); 11685 needSep = false; 11686 pw.println(" mStartedUsers:"); 11687 for (int i=0; i<mStartedUsers.size(); i++) { 11688 UserStartedState uss = mStartedUsers.valueAt(i); 11689 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11690 pw.print(": "); uss.dump("", pw); 11691 } 11692 pw.print(" mStartedUserArray: ["); 11693 for (int i=0; i<mStartedUserArray.length; i++) { 11694 if (i > 0) pw.print(", "); 11695 pw.print(mStartedUserArray[i]); 11696 } 11697 pw.println("]"); 11698 pw.print(" mUserLru: ["); 11699 for (int i=0; i<mUserLru.size(); i++) { 11700 if (i > 0) pw.print(", "); 11701 pw.print(mUserLru.get(i)); 11702 } 11703 pw.println("]"); 11704 if (dumpAll) { 11705 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11706 } 11707 synchronized (mUserProfileGroupIdsSelfLocked) { 11708 if (mUserProfileGroupIdsSelfLocked.size() > 0) { 11709 pw.println(" mUserProfileGroupIds:"); 11710 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) { 11711 pw.print(" User #"); 11712 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i)); 11713 pw.print(" -> profile #"); 11714 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i)); 11715 } 11716 } 11717 } 11718 } 11719 if (mHomeProcess != null && (dumpPackage == null 11720 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11721 if (needSep) { 11722 pw.println(); 11723 needSep = false; 11724 } 11725 pw.println(" mHomeProcess: " + mHomeProcess); 11726 } 11727 if (mPreviousProcess != null && (dumpPackage == null 11728 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11729 if (needSep) { 11730 pw.println(); 11731 needSep = false; 11732 } 11733 pw.println(" mPreviousProcess: " + mPreviousProcess); 11734 } 11735 if (dumpAll) { 11736 StringBuilder sb = new StringBuilder(128); 11737 sb.append(" mPreviousProcessVisibleTime: "); 11738 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11739 pw.println(sb); 11740 } 11741 if (mHeavyWeightProcess != null && (dumpPackage == null 11742 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11743 if (needSep) { 11744 pw.println(); 11745 needSep = false; 11746 } 11747 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11748 } 11749 if (dumpPackage == null) { 11750 pw.println(" mConfiguration: " + mConfiguration); 11751 } 11752 if (dumpAll) { 11753 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11754 if (mCompatModePackages.getPackages().size() > 0) { 11755 boolean printed = false; 11756 for (Map.Entry<String, Integer> entry 11757 : mCompatModePackages.getPackages().entrySet()) { 11758 String pkg = entry.getKey(); 11759 int mode = entry.getValue(); 11760 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11761 continue; 11762 } 11763 if (!printed) { 11764 pw.println(" mScreenCompatPackages:"); 11765 printed = true; 11766 } 11767 pw.print(" "); pw.print(pkg); pw.print(": "); 11768 pw.print(mode); pw.println(); 11769 } 11770 } 11771 } 11772 if (dumpPackage == null) { 11773 if (mSleeping || mWentToSleep || mLockScreenShown) { 11774 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11775 + " mLockScreenShown " + mLockScreenShown); 11776 } 11777 if (mShuttingDown || mRunningVoice) { 11778 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11779 } 11780 } 11781 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11782 || mOrigWaitForDebugger) { 11783 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11784 || dumpPackage.equals(mOrigDebugApp)) { 11785 if (needSep) { 11786 pw.println(); 11787 needSep = false; 11788 } 11789 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11790 + " mDebugTransient=" + mDebugTransient 11791 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11792 } 11793 } 11794 if (mOpenGlTraceApp != null) { 11795 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11796 if (needSep) { 11797 pw.println(); 11798 needSep = false; 11799 } 11800 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11801 } 11802 } 11803 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11804 || mProfileFd != null) { 11805 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11806 if (needSep) { 11807 pw.println(); 11808 needSep = false; 11809 } 11810 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11811 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11812 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11813 + mAutoStopProfiler); 11814 } 11815 } 11816 if (dumpPackage == null) { 11817 if (mAlwaysFinishActivities || mController != null) { 11818 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11819 + " mController=" + mController); 11820 } 11821 if (dumpAll) { 11822 pw.println(" Total persistent processes: " + numPers); 11823 pw.println(" mProcessesReady=" + mProcessesReady 11824 + " mSystemReady=" + mSystemReady); 11825 pw.println(" mBooting=" + mBooting 11826 + " mBooted=" + mBooted 11827 + " mFactoryTest=" + mFactoryTest); 11828 pw.print(" mLastPowerCheckRealtime="); 11829 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11830 pw.println(""); 11831 pw.print(" mLastPowerCheckUptime="); 11832 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11833 pw.println(""); 11834 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11835 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11836 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11837 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11838 + " (" + mLruProcesses.size() + " total)" 11839 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11840 + " mNumServiceProcs=" + mNumServiceProcs 11841 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11842 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11843 + " mLastMemoryLevel" + mLastMemoryLevel 11844 + " mLastNumProcesses" + mLastNumProcesses); 11845 long now = SystemClock.uptimeMillis(); 11846 pw.print(" mLastIdleTime="); 11847 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11848 pw.print(" mLowRamSinceLastIdle="); 11849 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11850 pw.println(); 11851 } 11852 } 11853 11854 if (!printedAnything) { 11855 pw.println(" (nothing)"); 11856 } 11857 } 11858 11859 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11860 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11861 if (mProcessesToGc.size() > 0) { 11862 boolean printed = false; 11863 long now = SystemClock.uptimeMillis(); 11864 for (int i=0; i<mProcessesToGc.size(); i++) { 11865 ProcessRecord proc = mProcessesToGc.get(i); 11866 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11867 continue; 11868 } 11869 if (!printed) { 11870 if (needSep) pw.println(); 11871 needSep = true; 11872 pw.println(" Processes that are waiting to GC:"); 11873 printed = true; 11874 } 11875 pw.print(" Process "); pw.println(proc); 11876 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11877 pw.print(", last gced="); 11878 pw.print(now-proc.lastRequestedGc); 11879 pw.print(" ms ago, last lowMem="); 11880 pw.print(now-proc.lastLowMemory); 11881 pw.println(" ms ago"); 11882 11883 } 11884 } 11885 return needSep; 11886 } 11887 11888 void printOomLevel(PrintWriter pw, String name, int adj) { 11889 pw.print(" "); 11890 if (adj >= 0) { 11891 pw.print(' '); 11892 if (adj < 10) pw.print(' '); 11893 } else { 11894 if (adj > -10) pw.print(' '); 11895 } 11896 pw.print(adj); 11897 pw.print(": "); 11898 pw.print(name); 11899 pw.print(" ("); 11900 pw.print(mProcessList.getMemLevel(adj)/1024); 11901 pw.println(" kB)"); 11902 } 11903 11904 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11905 int opti, boolean dumpAll) { 11906 boolean needSep = false; 11907 11908 if (mLruProcesses.size() > 0) { 11909 if (needSep) pw.println(); 11910 needSep = true; 11911 pw.println(" OOM levels:"); 11912 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11913 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11914 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11915 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11916 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11917 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11918 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11919 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11920 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11921 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11922 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11923 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11924 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11925 11926 if (needSep) pw.println(); 11927 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11928 pw.print(" total, non-act at "); 11929 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11930 pw.print(", non-svc at "); 11931 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11932 pw.println("):"); 11933 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11934 needSep = true; 11935 } 11936 11937 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11938 11939 pw.println(); 11940 pw.println(" mHomeProcess: " + mHomeProcess); 11941 pw.println(" mPreviousProcess: " + mPreviousProcess); 11942 if (mHeavyWeightProcess != null) { 11943 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11944 } 11945 11946 return true; 11947 } 11948 11949 /** 11950 * There are three ways to call this: 11951 * - no provider specified: dump all the providers 11952 * - a flattened component name that matched an existing provider was specified as the 11953 * first arg: dump that one provider 11954 * - the first arg isn't the flattened component name of an existing provider: 11955 * dump all providers whose component contains the first arg as a substring 11956 */ 11957 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11958 int opti, boolean dumpAll) { 11959 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11960 } 11961 11962 static class ItemMatcher { 11963 ArrayList<ComponentName> components; 11964 ArrayList<String> strings; 11965 ArrayList<Integer> objects; 11966 boolean all; 11967 11968 ItemMatcher() { 11969 all = true; 11970 } 11971 11972 void build(String name) { 11973 ComponentName componentName = ComponentName.unflattenFromString(name); 11974 if (componentName != null) { 11975 if (components == null) { 11976 components = new ArrayList<ComponentName>(); 11977 } 11978 components.add(componentName); 11979 all = false; 11980 } else { 11981 int objectId = 0; 11982 // Not a '/' separated full component name; maybe an object ID? 11983 try { 11984 objectId = Integer.parseInt(name, 16); 11985 if (objects == null) { 11986 objects = new ArrayList<Integer>(); 11987 } 11988 objects.add(objectId); 11989 all = false; 11990 } catch (RuntimeException e) { 11991 // Not an integer; just do string match. 11992 if (strings == null) { 11993 strings = new ArrayList<String>(); 11994 } 11995 strings.add(name); 11996 all = false; 11997 } 11998 } 11999 } 12000 12001 int build(String[] args, int opti) { 12002 for (; opti<args.length; opti++) { 12003 String name = args[opti]; 12004 if ("--".equals(name)) { 12005 return opti+1; 12006 } 12007 build(name); 12008 } 12009 return opti; 12010 } 12011 12012 boolean match(Object object, ComponentName comp) { 12013 if (all) { 12014 return true; 12015 } 12016 if (components != null) { 12017 for (int i=0; i<components.size(); i++) { 12018 if (components.get(i).equals(comp)) { 12019 return true; 12020 } 12021 } 12022 } 12023 if (objects != null) { 12024 for (int i=0; i<objects.size(); i++) { 12025 if (System.identityHashCode(object) == objects.get(i)) { 12026 return true; 12027 } 12028 } 12029 } 12030 if (strings != null) { 12031 String flat = comp.flattenToString(); 12032 for (int i=0; i<strings.size(); i++) { 12033 if (flat.contains(strings.get(i))) { 12034 return true; 12035 } 12036 } 12037 } 12038 return false; 12039 } 12040 } 12041 12042 /** 12043 * There are three things that cmd can be: 12044 * - a flattened component name that matches an existing activity 12045 * - the cmd arg isn't the flattened component name of an existing activity: 12046 * dump all activity whose component contains the cmd as a substring 12047 * - A hex number of the ActivityRecord object instance. 12048 */ 12049 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 12050 int opti, boolean dumpAll) { 12051 ArrayList<ActivityRecord> activities; 12052 12053 synchronized (this) { 12054 activities = mStackSupervisor.getDumpActivitiesLocked(name); 12055 } 12056 12057 if (activities.size() <= 0) { 12058 return false; 12059 } 12060 12061 String[] newArgs = new String[args.length - opti]; 12062 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 12063 12064 TaskRecord lastTask = null; 12065 boolean needSep = false; 12066 for (int i=activities.size()-1; i>=0; i--) { 12067 ActivityRecord r = activities.get(i); 12068 if (needSep) { 12069 pw.println(); 12070 } 12071 needSep = true; 12072 synchronized (this) { 12073 if (lastTask != r.task) { 12074 lastTask = r.task; 12075 pw.print("TASK "); pw.print(lastTask.affinity); 12076 pw.print(" id="); pw.println(lastTask.taskId); 12077 if (dumpAll) { 12078 lastTask.dump(pw, " "); 12079 } 12080 } 12081 } 12082 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 12083 } 12084 return true; 12085 } 12086 12087 /** 12088 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 12089 * there is a thread associated with the activity. 12090 */ 12091 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 12092 final ActivityRecord r, String[] args, boolean dumpAll) { 12093 String innerPrefix = prefix + " "; 12094 synchronized (this) { 12095 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 12096 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 12097 pw.print(" pid="); 12098 if (r.app != null) pw.println(r.app.pid); 12099 else pw.println("(not running)"); 12100 if (dumpAll) { 12101 r.dump(pw, innerPrefix); 12102 } 12103 } 12104 if (r.app != null && r.app.thread != null) { 12105 // flush anything that is already in the PrintWriter since the thread is going 12106 // to write to the file descriptor directly 12107 pw.flush(); 12108 try { 12109 TransferPipe tp = new TransferPipe(); 12110 try { 12111 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 12112 r.appToken, innerPrefix, args); 12113 tp.go(fd); 12114 } finally { 12115 tp.kill(); 12116 } 12117 } catch (IOException e) { 12118 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 12119 } catch (RemoteException e) { 12120 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 12121 } 12122 } 12123 } 12124 12125 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12126 int opti, boolean dumpAll, String dumpPackage) { 12127 boolean needSep = false; 12128 boolean onlyHistory = false; 12129 boolean printedAnything = false; 12130 12131 if ("history".equals(dumpPackage)) { 12132 if (opti < args.length && "-s".equals(args[opti])) { 12133 dumpAll = false; 12134 } 12135 onlyHistory = true; 12136 dumpPackage = null; 12137 } 12138 12139 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 12140 if (!onlyHistory && dumpAll) { 12141 if (mRegisteredReceivers.size() > 0) { 12142 boolean printed = false; 12143 Iterator it = mRegisteredReceivers.values().iterator(); 12144 while (it.hasNext()) { 12145 ReceiverList r = (ReceiverList)it.next(); 12146 if (dumpPackage != null && (r.app == null || 12147 !dumpPackage.equals(r.app.info.packageName))) { 12148 continue; 12149 } 12150 if (!printed) { 12151 pw.println(" Registered Receivers:"); 12152 needSep = true; 12153 printed = true; 12154 printedAnything = true; 12155 } 12156 pw.print(" * "); pw.println(r); 12157 r.dump(pw, " "); 12158 } 12159 } 12160 12161 if (mReceiverResolver.dump(pw, needSep ? 12162 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 12163 " ", dumpPackage, false)) { 12164 needSep = true; 12165 printedAnything = true; 12166 } 12167 } 12168 12169 for (BroadcastQueue q : mBroadcastQueues) { 12170 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 12171 printedAnything |= needSep; 12172 } 12173 12174 needSep = true; 12175 12176 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 12177 for (int user=0; user<mStickyBroadcasts.size(); user++) { 12178 if (needSep) { 12179 pw.println(); 12180 } 12181 needSep = true; 12182 printedAnything = true; 12183 pw.print(" Sticky broadcasts for user "); 12184 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 12185 StringBuilder sb = new StringBuilder(128); 12186 for (Map.Entry<String, ArrayList<Intent>> ent 12187 : mStickyBroadcasts.valueAt(user).entrySet()) { 12188 pw.print(" * Sticky action "); pw.print(ent.getKey()); 12189 if (dumpAll) { 12190 pw.println(":"); 12191 ArrayList<Intent> intents = ent.getValue(); 12192 final int N = intents.size(); 12193 for (int i=0; i<N; i++) { 12194 sb.setLength(0); 12195 sb.append(" Intent: "); 12196 intents.get(i).toShortString(sb, false, true, false, false); 12197 pw.println(sb.toString()); 12198 Bundle bundle = intents.get(i).getExtras(); 12199 if (bundle != null) { 12200 pw.print(" "); 12201 pw.println(bundle.toString()); 12202 } 12203 } 12204 } else { 12205 pw.println(""); 12206 } 12207 } 12208 } 12209 } 12210 12211 if (!onlyHistory && dumpAll) { 12212 pw.println(); 12213 for (BroadcastQueue queue : mBroadcastQueues) { 12214 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 12215 + queue.mBroadcastsScheduled); 12216 } 12217 pw.println(" mHandler:"); 12218 mHandler.dump(new PrintWriterPrinter(pw), " "); 12219 needSep = true; 12220 printedAnything = true; 12221 } 12222 12223 if (!printedAnything) { 12224 pw.println(" (nothing)"); 12225 } 12226 } 12227 12228 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12229 int opti, boolean dumpAll, String dumpPackage) { 12230 boolean needSep; 12231 boolean printedAnything = false; 12232 12233 ItemMatcher matcher = new ItemMatcher(); 12234 matcher.build(args, opti); 12235 12236 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 12237 12238 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 12239 printedAnything |= needSep; 12240 12241 if (mLaunchingProviders.size() > 0) { 12242 boolean printed = false; 12243 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 12244 ContentProviderRecord r = mLaunchingProviders.get(i); 12245 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 12246 continue; 12247 } 12248 if (!printed) { 12249 if (needSep) pw.println(); 12250 needSep = true; 12251 pw.println(" Launching content providers:"); 12252 printed = true; 12253 printedAnything = true; 12254 } 12255 pw.print(" Launching #"); pw.print(i); pw.print(": "); 12256 pw.println(r); 12257 } 12258 } 12259 12260 if (mGrantedUriPermissions.size() > 0) { 12261 boolean printed = false; 12262 int dumpUid = -2; 12263 if (dumpPackage != null) { 12264 try { 12265 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 12266 } catch (NameNotFoundException e) { 12267 dumpUid = -1; 12268 } 12269 } 12270 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 12271 int uid = mGrantedUriPermissions.keyAt(i); 12272 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 12273 continue; 12274 } 12275 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 12276 if (!printed) { 12277 if (needSep) pw.println(); 12278 needSep = true; 12279 pw.println(" Granted Uri Permissions:"); 12280 printed = true; 12281 printedAnything = true; 12282 } 12283 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 12284 for (UriPermission perm : perms.values()) { 12285 pw.print(" "); pw.println(perm); 12286 if (dumpAll) { 12287 perm.dump(pw, " "); 12288 } 12289 } 12290 } 12291 } 12292 12293 if (!printedAnything) { 12294 pw.println(" (nothing)"); 12295 } 12296 } 12297 12298 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 12299 int opti, boolean dumpAll, String dumpPackage) { 12300 boolean printed = false; 12301 12302 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 12303 12304 if (mIntentSenderRecords.size() > 0) { 12305 Iterator<WeakReference<PendingIntentRecord>> it 12306 = mIntentSenderRecords.values().iterator(); 12307 while (it.hasNext()) { 12308 WeakReference<PendingIntentRecord> ref = it.next(); 12309 PendingIntentRecord rec = ref != null ? ref.get(): null; 12310 if (dumpPackage != null && (rec == null 12311 || !dumpPackage.equals(rec.key.packageName))) { 12312 continue; 12313 } 12314 printed = true; 12315 if (rec != null) { 12316 pw.print(" * "); pw.println(rec); 12317 if (dumpAll) { 12318 rec.dump(pw, " "); 12319 } 12320 } else { 12321 pw.print(" * "); pw.println(ref); 12322 } 12323 } 12324 } 12325 12326 if (!printed) { 12327 pw.println(" (nothing)"); 12328 } 12329 } 12330 12331 private static final int dumpProcessList(PrintWriter pw, 12332 ActivityManagerService service, List list, 12333 String prefix, String normalLabel, String persistentLabel, 12334 String dumpPackage) { 12335 int numPers = 0; 12336 final int N = list.size()-1; 12337 for (int i=N; i>=0; i--) { 12338 ProcessRecord r = (ProcessRecord)list.get(i); 12339 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 12340 continue; 12341 } 12342 pw.println(String.format("%s%s #%2d: %s", 12343 prefix, (r.persistent ? persistentLabel : normalLabel), 12344 i, r.toString())); 12345 if (r.persistent) { 12346 numPers++; 12347 } 12348 } 12349 return numPers; 12350 } 12351 12352 private static final boolean dumpProcessOomList(PrintWriter pw, 12353 ActivityManagerService service, List<ProcessRecord> origList, 12354 String prefix, String normalLabel, String persistentLabel, 12355 boolean inclDetails, String dumpPackage) { 12356 12357 ArrayList<Pair<ProcessRecord, Integer>> list 12358 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 12359 for (int i=0; i<origList.size(); i++) { 12360 ProcessRecord r = origList.get(i); 12361 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 12362 continue; 12363 } 12364 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 12365 } 12366 12367 if (list.size() <= 0) { 12368 return false; 12369 } 12370 12371 Comparator<Pair<ProcessRecord, Integer>> comparator 12372 = new Comparator<Pair<ProcessRecord, Integer>>() { 12373 @Override 12374 public int compare(Pair<ProcessRecord, Integer> object1, 12375 Pair<ProcessRecord, Integer> object2) { 12376 if (object1.first.setAdj != object2.first.setAdj) { 12377 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 12378 } 12379 if (object1.second.intValue() != object2.second.intValue()) { 12380 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 12381 } 12382 return 0; 12383 } 12384 }; 12385 12386 Collections.sort(list, comparator); 12387 12388 final long curRealtime = SystemClock.elapsedRealtime(); 12389 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 12390 final long curUptime = SystemClock.uptimeMillis(); 12391 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 12392 12393 for (int i=list.size()-1; i>=0; i--) { 12394 ProcessRecord r = list.get(i).first; 12395 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 12396 char schedGroup; 12397 switch (r.setSchedGroup) { 12398 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 12399 schedGroup = 'B'; 12400 break; 12401 case Process.THREAD_GROUP_DEFAULT: 12402 schedGroup = 'F'; 12403 break; 12404 default: 12405 schedGroup = '?'; 12406 break; 12407 } 12408 char foreground; 12409 if (r.foregroundActivities) { 12410 foreground = 'A'; 12411 } else if (r.foregroundServices) { 12412 foreground = 'S'; 12413 } else { 12414 foreground = ' '; 12415 } 12416 String procState = ProcessList.makeProcStateString(r.curProcState); 12417 pw.print(prefix); 12418 pw.print(r.persistent ? persistentLabel : normalLabel); 12419 pw.print(" #"); 12420 int num = (origList.size()-1)-list.get(i).second; 12421 if (num < 10) pw.print(' '); 12422 pw.print(num); 12423 pw.print(": "); 12424 pw.print(oomAdj); 12425 pw.print(' '); 12426 pw.print(schedGroup); 12427 pw.print('/'); 12428 pw.print(foreground); 12429 pw.print('/'); 12430 pw.print(procState); 12431 pw.print(" trm:"); 12432 if (r.trimMemoryLevel < 10) pw.print(' '); 12433 pw.print(r.trimMemoryLevel); 12434 pw.print(' '); 12435 pw.print(r.toShortString()); 12436 pw.print(" ("); 12437 pw.print(r.adjType); 12438 pw.println(')'); 12439 if (r.adjSource != null || r.adjTarget != null) { 12440 pw.print(prefix); 12441 pw.print(" "); 12442 if (r.adjTarget instanceof ComponentName) { 12443 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 12444 } else if (r.adjTarget != null) { 12445 pw.print(r.adjTarget.toString()); 12446 } else { 12447 pw.print("{null}"); 12448 } 12449 pw.print("<="); 12450 if (r.adjSource instanceof ProcessRecord) { 12451 pw.print("Proc{"); 12452 pw.print(((ProcessRecord)r.adjSource).toShortString()); 12453 pw.println("}"); 12454 } else if (r.adjSource != null) { 12455 pw.println(r.adjSource.toString()); 12456 } else { 12457 pw.println("{null}"); 12458 } 12459 } 12460 if (inclDetails) { 12461 pw.print(prefix); 12462 pw.print(" "); 12463 pw.print("oom: max="); pw.print(r.maxAdj); 12464 pw.print(" curRaw="); pw.print(r.curRawAdj); 12465 pw.print(" setRaw="); pw.print(r.setRawAdj); 12466 pw.print(" cur="); pw.print(r.curAdj); 12467 pw.print(" set="); pw.println(r.setAdj); 12468 pw.print(prefix); 12469 pw.print(" "); 12470 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12471 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12472 pw.print(" lastPss="); pw.print(r.lastPss); 12473 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12474 pw.print(prefix); 12475 pw.print(" "); 12476 pw.print("cached="); pw.print(r.cached); 12477 pw.print(" empty="); pw.print(r.empty); 12478 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12479 12480 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) { 12481 if (r.lastWakeTime != 0) { 12482 long wtime; 12483 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12484 synchronized (stats) { 12485 wtime = stats.getProcessWakeTime(r.info.uid, 12486 r.pid, curRealtime); 12487 } 12488 long timeUsed = wtime - r.lastWakeTime; 12489 pw.print(prefix); 12490 pw.print(" "); 12491 pw.print("keep awake over "); 12492 TimeUtils.formatDuration(realtimeSince, pw); 12493 pw.print(" used "); 12494 TimeUtils.formatDuration(timeUsed, pw); 12495 pw.print(" ("); 12496 pw.print((timeUsed*100)/realtimeSince); 12497 pw.println("%)"); 12498 } 12499 if (r.lastCpuTime != 0) { 12500 long timeUsed = r.curCpuTime - r.lastCpuTime; 12501 pw.print(prefix); 12502 pw.print(" "); 12503 pw.print("run cpu over "); 12504 TimeUtils.formatDuration(uptimeSince, pw); 12505 pw.print(" used "); 12506 TimeUtils.formatDuration(timeUsed, pw); 12507 pw.print(" ("); 12508 pw.print((timeUsed*100)/uptimeSince); 12509 pw.println("%)"); 12510 } 12511 } 12512 } 12513 } 12514 return true; 12515 } 12516 12517 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12518 ArrayList<ProcessRecord> procs; 12519 synchronized (this) { 12520 if (args != null && args.length > start 12521 && args[start].charAt(0) != '-') { 12522 procs = new ArrayList<ProcessRecord>(); 12523 int pid = -1; 12524 try { 12525 pid = Integer.parseInt(args[start]); 12526 } catch (NumberFormatException e) { 12527 } 12528 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12529 ProcessRecord proc = mLruProcesses.get(i); 12530 if (proc.pid == pid) { 12531 procs.add(proc); 12532 } else if (proc.processName.equals(args[start])) { 12533 procs.add(proc); 12534 } 12535 } 12536 if (procs.size() <= 0) { 12537 return null; 12538 } 12539 } else { 12540 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12541 } 12542 } 12543 return procs; 12544 } 12545 12546 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12547 PrintWriter pw, String[] args) { 12548 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12549 if (procs == null) { 12550 pw.println("No process found for: " + args[0]); 12551 return; 12552 } 12553 12554 long uptime = SystemClock.uptimeMillis(); 12555 long realtime = SystemClock.elapsedRealtime(); 12556 pw.println("Applications Graphics Acceleration Info:"); 12557 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12558 12559 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12560 ProcessRecord r = procs.get(i); 12561 if (r.thread != null) { 12562 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12563 pw.flush(); 12564 try { 12565 TransferPipe tp = new TransferPipe(); 12566 try { 12567 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12568 tp.go(fd); 12569 } finally { 12570 tp.kill(); 12571 } 12572 } catch (IOException e) { 12573 pw.println("Failure while dumping the app: " + r); 12574 pw.flush(); 12575 } catch (RemoteException e) { 12576 pw.println("Got a RemoteException while dumping the app " + r); 12577 pw.flush(); 12578 } 12579 } 12580 } 12581 } 12582 12583 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12584 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12585 if (procs == null) { 12586 pw.println("No process found for: " + args[0]); 12587 return; 12588 } 12589 12590 pw.println("Applications Database Info:"); 12591 12592 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12593 ProcessRecord r = procs.get(i); 12594 if (r.thread != null) { 12595 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12596 pw.flush(); 12597 try { 12598 TransferPipe tp = new TransferPipe(); 12599 try { 12600 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12601 tp.go(fd); 12602 } finally { 12603 tp.kill(); 12604 } 12605 } catch (IOException e) { 12606 pw.println("Failure while dumping the app: " + r); 12607 pw.flush(); 12608 } catch (RemoteException e) { 12609 pw.println("Got a RemoteException while dumping the app " + r); 12610 pw.flush(); 12611 } 12612 } 12613 } 12614 } 12615 12616 final static class MemItem { 12617 final boolean isProc; 12618 final String label; 12619 final String shortLabel; 12620 final long pss; 12621 final int id; 12622 final boolean hasActivities; 12623 ArrayList<MemItem> subitems; 12624 12625 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12626 boolean _hasActivities) { 12627 isProc = true; 12628 label = _label; 12629 shortLabel = _shortLabel; 12630 pss = _pss; 12631 id = _id; 12632 hasActivities = _hasActivities; 12633 } 12634 12635 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12636 isProc = false; 12637 label = _label; 12638 shortLabel = _shortLabel; 12639 pss = _pss; 12640 id = _id; 12641 hasActivities = false; 12642 } 12643 } 12644 12645 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12646 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12647 if (sort && !isCompact) { 12648 Collections.sort(items, new Comparator<MemItem>() { 12649 @Override 12650 public int compare(MemItem lhs, MemItem rhs) { 12651 if (lhs.pss < rhs.pss) { 12652 return 1; 12653 } else if (lhs.pss > rhs.pss) { 12654 return -1; 12655 } 12656 return 0; 12657 } 12658 }); 12659 } 12660 12661 for (int i=0; i<items.size(); i++) { 12662 MemItem mi = items.get(i); 12663 if (!isCompact) { 12664 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12665 } else if (mi.isProc) { 12666 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12667 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12668 pw.println(mi.hasActivities ? ",a" : ",e"); 12669 } else { 12670 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12671 pw.println(mi.pss); 12672 } 12673 if (mi.subitems != null) { 12674 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12675 true, isCompact); 12676 } 12677 } 12678 } 12679 12680 // These are in KB. 12681 static final long[] DUMP_MEM_BUCKETS = new long[] { 12682 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12683 120*1024, 160*1024, 200*1024, 12684 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12685 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12686 }; 12687 12688 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12689 boolean stackLike) { 12690 int start = label.lastIndexOf('.'); 12691 if (start >= 0) start++; 12692 else start = 0; 12693 int end = label.length(); 12694 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12695 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12696 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12697 out.append(bucket); 12698 out.append(stackLike ? "MB." : "MB "); 12699 out.append(label, start, end); 12700 return; 12701 } 12702 } 12703 out.append(memKB/1024); 12704 out.append(stackLike ? "MB." : "MB "); 12705 out.append(label, start, end); 12706 } 12707 12708 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12709 ProcessList.NATIVE_ADJ, 12710 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12711 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12712 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12713 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12714 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12715 }; 12716 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12717 "Native", 12718 "System", "Persistent", "Foreground", 12719 "Visible", "Perceptible", 12720 "Heavy Weight", "Backup", 12721 "A Services", "Home", 12722 "Previous", "B Services", "Cached" 12723 }; 12724 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12725 "native", 12726 "sys", "pers", "fore", 12727 "vis", "percept", 12728 "heavy", "backup", 12729 "servicea", "home", 12730 "prev", "serviceb", "cached" 12731 }; 12732 12733 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12734 long realtime, boolean isCheckinRequest, boolean isCompact) { 12735 if (isCheckinRequest || isCompact) { 12736 // short checkin version 12737 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12738 } else { 12739 pw.println("Applications Memory Usage (kB):"); 12740 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12741 } 12742 } 12743 12744 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12745 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12746 boolean dumpDetails = false; 12747 boolean dumpFullDetails = false; 12748 boolean dumpDalvik = false; 12749 boolean oomOnly = false; 12750 boolean isCompact = false; 12751 boolean localOnly = false; 12752 12753 int opti = 0; 12754 while (opti < args.length) { 12755 String opt = args[opti]; 12756 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12757 break; 12758 } 12759 opti++; 12760 if ("-a".equals(opt)) { 12761 dumpDetails = true; 12762 dumpFullDetails = true; 12763 dumpDalvik = true; 12764 } else if ("-d".equals(opt)) { 12765 dumpDalvik = true; 12766 } else if ("-c".equals(opt)) { 12767 isCompact = true; 12768 } else if ("--oom".equals(opt)) { 12769 oomOnly = true; 12770 } else if ("--local".equals(opt)) { 12771 localOnly = true; 12772 } else if ("-h".equals(opt)) { 12773 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12774 pw.println(" -a: include all available information for each process."); 12775 pw.println(" -d: include dalvik details when dumping process details."); 12776 pw.println(" -c: dump in a compact machine-parseable representation."); 12777 pw.println(" --oom: only show processes organized by oom adj."); 12778 pw.println(" --local: only collect details locally, don't call process."); 12779 pw.println("If [process] is specified it can be the name or "); 12780 pw.println("pid of a specific process to dump."); 12781 return; 12782 } else { 12783 pw.println("Unknown argument: " + opt + "; use -h for help"); 12784 } 12785 } 12786 12787 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12788 long uptime = SystemClock.uptimeMillis(); 12789 long realtime = SystemClock.elapsedRealtime(); 12790 final long[] tmpLong = new long[1]; 12791 12792 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12793 if (procs == null) { 12794 // No Java processes. Maybe they want to print a native process. 12795 if (args != null && args.length > opti 12796 && args[opti].charAt(0) != '-') { 12797 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12798 = new ArrayList<ProcessCpuTracker.Stats>(); 12799 updateCpuStatsNow(); 12800 int findPid = -1; 12801 try { 12802 findPid = Integer.parseInt(args[opti]); 12803 } catch (NumberFormatException e) { 12804 } 12805 synchronized (mProcessCpuThread) { 12806 final int N = mProcessCpuTracker.countStats(); 12807 for (int i=0; i<N; i++) { 12808 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12809 if (st.pid == findPid || (st.baseName != null 12810 && st.baseName.equals(args[opti]))) { 12811 nativeProcs.add(st); 12812 } 12813 } 12814 } 12815 if (nativeProcs.size() > 0) { 12816 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12817 isCompact); 12818 Debug.MemoryInfo mi = null; 12819 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12820 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12821 final int pid = r.pid; 12822 if (!isCheckinRequest && dumpDetails) { 12823 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12824 } 12825 if (mi == null) { 12826 mi = new Debug.MemoryInfo(); 12827 } 12828 if (dumpDetails || (!brief && !oomOnly)) { 12829 Debug.getMemoryInfo(pid, mi); 12830 } else { 12831 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12832 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12833 } 12834 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12835 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12836 if (isCheckinRequest) { 12837 pw.println(); 12838 } 12839 } 12840 return; 12841 } 12842 } 12843 pw.println("No process found for: " + args[opti]); 12844 return; 12845 } 12846 12847 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12848 dumpDetails = true; 12849 } 12850 12851 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12852 12853 String[] innerArgs = new String[args.length-opti]; 12854 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12855 12856 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12857 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12858 long nativePss=0, dalvikPss=0, otherPss=0; 12859 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12860 12861 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12862 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12863 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12864 12865 long totalPss = 0; 12866 long cachedPss = 0; 12867 12868 Debug.MemoryInfo mi = null; 12869 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12870 final ProcessRecord r = procs.get(i); 12871 final IApplicationThread thread; 12872 final int pid; 12873 final int oomAdj; 12874 final boolean hasActivities; 12875 synchronized (this) { 12876 thread = r.thread; 12877 pid = r.pid; 12878 oomAdj = r.getSetAdjWithServices(); 12879 hasActivities = r.activities.size() > 0; 12880 } 12881 if (thread != null) { 12882 if (!isCheckinRequest && dumpDetails) { 12883 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12884 } 12885 if (mi == null) { 12886 mi = new Debug.MemoryInfo(); 12887 } 12888 if (dumpDetails || (!brief && !oomOnly)) { 12889 Debug.getMemoryInfo(pid, mi); 12890 } else { 12891 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12892 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12893 } 12894 if (dumpDetails) { 12895 if (localOnly) { 12896 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12897 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12898 if (isCheckinRequest) { 12899 pw.println(); 12900 } 12901 } else { 12902 try { 12903 pw.flush(); 12904 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12905 dumpDalvik, innerArgs); 12906 } catch (RemoteException e) { 12907 if (!isCheckinRequest) { 12908 pw.println("Got RemoteException!"); 12909 pw.flush(); 12910 } 12911 } 12912 } 12913 } 12914 12915 final long myTotalPss = mi.getTotalPss(); 12916 final long myTotalUss = mi.getTotalUss(); 12917 12918 synchronized (this) { 12919 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12920 // Record this for posterity if the process has been stable. 12921 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12922 } 12923 } 12924 12925 if (!isCheckinRequest && mi != null) { 12926 totalPss += myTotalPss; 12927 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12928 (hasActivities ? " / activities)" : ")"), 12929 r.processName, myTotalPss, pid, hasActivities); 12930 procMems.add(pssItem); 12931 procMemsMap.put(pid, pssItem); 12932 12933 nativePss += mi.nativePss; 12934 dalvikPss += mi.dalvikPss; 12935 otherPss += mi.otherPss; 12936 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12937 long mem = mi.getOtherPss(j); 12938 miscPss[j] += mem; 12939 otherPss -= mem; 12940 } 12941 12942 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12943 cachedPss += myTotalPss; 12944 } 12945 12946 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12947 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12948 || oomIndex == (oomPss.length-1)) { 12949 oomPss[oomIndex] += myTotalPss; 12950 if (oomProcs[oomIndex] == null) { 12951 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12952 } 12953 oomProcs[oomIndex].add(pssItem); 12954 break; 12955 } 12956 } 12957 } 12958 } 12959 } 12960 12961 long nativeProcTotalPss = 0; 12962 12963 if (!isCheckinRequest && procs.size() > 1) { 12964 // If we are showing aggregations, also look for native processes to 12965 // include so that our aggregations are more accurate. 12966 updateCpuStatsNow(); 12967 synchronized (mProcessCpuThread) { 12968 final int N = mProcessCpuTracker.countStats(); 12969 for (int i=0; i<N; i++) { 12970 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12971 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12972 if (mi == null) { 12973 mi = new Debug.MemoryInfo(); 12974 } 12975 if (!brief && !oomOnly) { 12976 Debug.getMemoryInfo(st.pid, mi); 12977 } else { 12978 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12979 mi.nativePrivateDirty = (int)tmpLong[0]; 12980 } 12981 12982 final long myTotalPss = mi.getTotalPss(); 12983 totalPss += myTotalPss; 12984 nativeProcTotalPss += myTotalPss; 12985 12986 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12987 st.name, myTotalPss, st.pid, false); 12988 procMems.add(pssItem); 12989 12990 nativePss += mi.nativePss; 12991 dalvikPss += mi.dalvikPss; 12992 otherPss += mi.otherPss; 12993 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12994 long mem = mi.getOtherPss(j); 12995 miscPss[j] += mem; 12996 otherPss -= mem; 12997 } 12998 oomPss[0] += myTotalPss; 12999 if (oomProcs[0] == null) { 13000 oomProcs[0] = new ArrayList<MemItem>(); 13001 } 13002 oomProcs[0].add(pssItem); 13003 } 13004 } 13005 } 13006 13007 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 13008 13009 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 13010 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 13011 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 13012 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 13013 String label = Debug.MemoryInfo.getOtherLabel(j); 13014 catMems.add(new MemItem(label, label, miscPss[j], j)); 13015 } 13016 13017 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 13018 for (int j=0; j<oomPss.length; j++) { 13019 if (oomPss[j] != 0) { 13020 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 13021 : DUMP_MEM_OOM_LABEL[j]; 13022 MemItem item = new MemItem(label, label, oomPss[j], 13023 DUMP_MEM_OOM_ADJ[j]); 13024 item.subitems = oomProcs[j]; 13025 oomMems.add(item); 13026 } 13027 } 13028 13029 if (!brief && !oomOnly && !isCompact) { 13030 pw.println(); 13031 pw.println("Total PSS by process:"); 13032 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 13033 pw.println(); 13034 } 13035 if (!isCompact) { 13036 pw.println("Total PSS by OOM adjustment:"); 13037 } 13038 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 13039 if (!brief && !oomOnly) { 13040 PrintWriter out = categoryPw != null ? categoryPw : pw; 13041 if (!isCompact) { 13042 out.println(); 13043 out.println("Total PSS by category:"); 13044 } 13045 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 13046 } 13047 if (!isCompact) { 13048 pw.println(); 13049 } 13050 MemInfoReader memInfo = new MemInfoReader(); 13051 memInfo.readMemInfo(); 13052 if (nativeProcTotalPss > 0) { 13053 synchronized (this) { 13054 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(), 13055 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(), 13056 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(), 13057 nativeProcTotalPss); 13058 } 13059 } 13060 if (!brief) { 13061 if (!isCompact) { 13062 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 13063 pw.print(" kB (status "); 13064 switch (mLastMemoryLevel) { 13065 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 13066 pw.println("normal)"); 13067 break; 13068 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 13069 pw.println("moderate)"); 13070 break; 13071 case ProcessStats.ADJ_MEM_FACTOR_LOW: 13072 pw.println("low)"); 13073 break; 13074 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 13075 pw.println("critical)"); 13076 break; 13077 default: 13078 pw.print(mLastMemoryLevel); 13079 pw.println(")"); 13080 break; 13081 } 13082 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 13083 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 13084 pw.print(cachedPss); pw.print(" cached pss + "); 13085 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 13086 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 13087 } else { 13088 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 13089 pw.print(cachedPss + memInfo.getCachedSizeKb() 13090 + memInfo.getFreeSizeKb()); pw.print(","); 13091 pw.println(totalPss - cachedPss); 13092 } 13093 } 13094 if (!isCompact) { 13095 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 13096 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 13097 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 13098 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 13099 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 13100 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 13101 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 13102 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 13103 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 13104 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 13105 - memInfo.getSlabSizeKb()); pw.println(" kB"); 13106 } 13107 if (!brief) { 13108 if (memInfo.getZramTotalSizeKb() != 0) { 13109 if (!isCompact) { 13110 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 13111 pw.print(" kB physical used for "); 13112 pw.print(memInfo.getSwapTotalSizeKb() 13113 - memInfo.getSwapFreeSizeKb()); 13114 pw.print(" kB in swap ("); 13115 pw.print(memInfo.getSwapTotalSizeKb()); 13116 pw.println(" kB total swap)"); 13117 } else { 13118 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 13119 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 13120 pw.println(memInfo.getSwapFreeSizeKb()); 13121 } 13122 } 13123 final int[] SINGLE_LONG_FORMAT = new int[] { 13124 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 13125 }; 13126 long[] longOut = new long[1]; 13127 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 13128 SINGLE_LONG_FORMAT, null, longOut, null); 13129 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13130 longOut[0] = 0; 13131 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 13132 SINGLE_LONG_FORMAT, null, longOut, null); 13133 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13134 longOut[0] = 0; 13135 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 13136 SINGLE_LONG_FORMAT, null, longOut, null); 13137 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13138 longOut[0] = 0; 13139 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 13140 SINGLE_LONG_FORMAT, null, longOut, null); 13141 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 13142 if (!isCompact) { 13143 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 13144 pw.print(" KSM: "); pw.print(sharing); 13145 pw.print(" kB saved from shared "); 13146 pw.print(shared); pw.println(" kB"); 13147 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 13148 pw.print(voltile); pw.println(" kB volatile"); 13149 } 13150 pw.print(" Tuning: "); 13151 pw.print(ActivityManager.staticGetMemoryClass()); 13152 pw.print(" (large "); 13153 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13154 pw.print("), oom "); 13155 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13156 pw.print(" kB"); 13157 pw.print(", restore limit "); 13158 pw.print(mProcessList.getCachedRestoreThresholdKb()); 13159 pw.print(" kB"); 13160 if (ActivityManager.isLowRamDeviceStatic()) { 13161 pw.print(" (low-ram)"); 13162 } 13163 if (ActivityManager.isHighEndGfx()) { 13164 pw.print(" (high-end-gfx)"); 13165 } 13166 pw.println(); 13167 } else { 13168 pw.print("ksm,"); pw.print(sharing); pw.print(","); 13169 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 13170 pw.println(voltile); 13171 pw.print("tuning,"); 13172 pw.print(ActivityManager.staticGetMemoryClass()); 13173 pw.print(','); 13174 pw.print(ActivityManager.staticGetLargeMemoryClass()); 13175 pw.print(','); 13176 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 13177 if (ActivityManager.isLowRamDeviceStatic()) { 13178 pw.print(",low-ram"); 13179 } 13180 if (ActivityManager.isHighEndGfx()) { 13181 pw.print(",high-end-gfx"); 13182 } 13183 pw.println(); 13184 } 13185 } 13186 } 13187 } 13188 13189 /** 13190 * Searches array of arguments for the specified string 13191 * @param args array of argument strings 13192 * @param value value to search for 13193 * @return true if the value is contained in the array 13194 */ 13195 private static boolean scanArgs(String[] args, String value) { 13196 if (args != null) { 13197 for (String arg : args) { 13198 if (value.equals(arg)) { 13199 return true; 13200 } 13201 } 13202 } 13203 return false; 13204 } 13205 13206 private final boolean removeDyingProviderLocked(ProcessRecord proc, 13207 ContentProviderRecord cpr, boolean always) { 13208 final boolean inLaunching = mLaunchingProviders.contains(cpr); 13209 13210 if (!inLaunching || always) { 13211 synchronized (cpr) { 13212 cpr.launchingApp = null; 13213 cpr.notifyAll(); 13214 } 13215 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 13216 String names[] = cpr.info.authority.split(";"); 13217 for (int j = 0; j < names.length; j++) { 13218 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 13219 } 13220 } 13221 13222 for (int i=0; i<cpr.connections.size(); i++) { 13223 ContentProviderConnection conn = cpr.connections.get(i); 13224 if (conn.waiting) { 13225 // If this connection is waiting for the provider, then we don't 13226 // need to mess with its process unless we are always removing 13227 // or for some reason the provider is not currently launching. 13228 if (inLaunching && !always) { 13229 continue; 13230 } 13231 } 13232 ProcessRecord capp = conn.client; 13233 conn.dead = true; 13234 if (conn.stableCount > 0) { 13235 if (!capp.persistent && capp.thread != null 13236 && capp.pid != 0 13237 && capp.pid != MY_PID) { 13238 killUnneededProcessLocked(capp, "depends on provider " 13239 + cpr.name.flattenToShortString() 13240 + " in dying proc " + (proc != null ? proc.processName : "??")); 13241 } 13242 } else if (capp.thread != null && conn.provider.provider != null) { 13243 try { 13244 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 13245 } catch (RemoteException e) { 13246 } 13247 // In the protocol here, we don't expect the client to correctly 13248 // clean up this connection, we'll just remove it. 13249 cpr.connections.remove(i); 13250 conn.client.conProviders.remove(conn); 13251 } 13252 } 13253 13254 if (inLaunching && always) { 13255 mLaunchingProviders.remove(cpr); 13256 } 13257 return inLaunching; 13258 } 13259 13260 /** 13261 * Main code for cleaning up a process when it has gone away. This is 13262 * called both as a result of the process dying, or directly when stopping 13263 * a process when running in single process mode. 13264 */ 13265 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 13266 boolean restarting, boolean allowRestart, int index) { 13267 if (index >= 0) { 13268 removeLruProcessLocked(app); 13269 ProcessList.remove(app.pid); 13270 } 13271 13272 mProcessesToGc.remove(app); 13273 mPendingPssProcesses.remove(app); 13274 13275 // Dismiss any open dialogs. 13276 if (app.crashDialog != null && !app.forceCrashReport) { 13277 app.crashDialog.dismiss(); 13278 app.crashDialog = null; 13279 } 13280 if (app.anrDialog != null) { 13281 app.anrDialog.dismiss(); 13282 app.anrDialog = null; 13283 } 13284 if (app.waitDialog != null) { 13285 app.waitDialog.dismiss(); 13286 app.waitDialog = null; 13287 } 13288 13289 app.crashing = false; 13290 app.notResponding = false; 13291 13292 app.resetPackageList(mProcessStats); 13293 app.unlinkDeathRecipient(); 13294 app.makeInactive(mProcessStats); 13295 app.waitingToKill = null; 13296 app.forcingToForeground = null; 13297 updateProcessForegroundLocked(app, false, false); 13298 app.foregroundActivities = false; 13299 app.hasShownUi = false; 13300 app.treatLikeActivity = false; 13301 app.hasAboveClient = false; 13302 app.hasClientActivities = false; 13303 13304 mServices.killServicesLocked(app, allowRestart); 13305 13306 boolean restart = false; 13307 13308 // Remove published content providers. 13309 for (int i=app.pubProviders.size()-1; i>=0; i--) { 13310 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 13311 final boolean always = app.bad || !allowRestart; 13312 if (removeDyingProviderLocked(app, cpr, always) || always) { 13313 // We left the provider in the launching list, need to 13314 // restart it. 13315 restart = true; 13316 } 13317 13318 cpr.provider = null; 13319 cpr.proc = null; 13320 } 13321 app.pubProviders.clear(); 13322 13323 // Take care of any launching providers waiting for this process. 13324 if (checkAppInLaunchingProvidersLocked(app, false)) { 13325 restart = true; 13326 } 13327 13328 // Unregister from connected content providers. 13329 if (!app.conProviders.isEmpty()) { 13330 for (int i=0; i<app.conProviders.size(); i++) { 13331 ContentProviderConnection conn = app.conProviders.get(i); 13332 conn.provider.connections.remove(conn); 13333 } 13334 app.conProviders.clear(); 13335 } 13336 13337 // At this point there may be remaining entries in mLaunchingProviders 13338 // where we were the only one waiting, so they are no longer of use. 13339 // Look for these and clean up if found. 13340 // XXX Commented out for now. Trying to figure out a way to reproduce 13341 // the actual situation to identify what is actually going on. 13342 if (false) { 13343 for (int i=0; i<mLaunchingProviders.size(); i++) { 13344 ContentProviderRecord cpr = (ContentProviderRecord) 13345 mLaunchingProviders.get(i); 13346 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 13347 synchronized (cpr) { 13348 cpr.launchingApp = null; 13349 cpr.notifyAll(); 13350 } 13351 } 13352 } 13353 } 13354 13355 skipCurrentReceiverLocked(app); 13356 13357 // Unregister any receivers. 13358 for (int i=app.receivers.size()-1; i>=0; i--) { 13359 removeReceiverLocked(app.receivers.valueAt(i)); 13360 } 13361 app.receivers.clear(); 13362 13363 // If the app is undergoing backup, tell the backup manager about it 13364 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 13365 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 13366 + mBackupTarget.appInfo + " died during backup"); 13367 try { 13368 IBackupManager bm = IBackupManager.Stub.asInterface( 13369 ServiceManager.getService(Context.BACKUP_SERVICE)); 13370 bm.agentDisconnected(app.info.packageName); 13371 } catch (RemoteException e) { 13372 // can't happen; backup manager is local 13373 } 13374 } 13375 13376 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 13377 ProcessChangeItem item = mPendingProcessChanges.get(i); 13378 if (item.pid == app.pid) { 13379 mPendingProcessChanges.remove(i); 13380 mAvailProcessChanges.add(item); 13381 } 13382 } 13383 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 13384 13385 // If the caller is restarting this app, then leave it in its 13386 // current lists and let the caller take care of it. 13387 if (restarting) { 13388 return; 13389 } 13390 13391 if (!app.persistent || app.isolated) { 13392 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 13393 "Removing non-persistent process during cleanup: " + app); 13394 mProcessNames.remove(app.processName, app.uid); 13395 mIsolatedProcesses.remove(app.uid); 13396 if (mHeavyWeightProcess == app) { 13397 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 13398 mHeavyWeightProcess.userId, 0)); 13399 mHeavyWeightProcess = null; 13400 } 13401 } else if (!app.removed) { 13402 // This app is persistent, so we need to keep its record around. 13403 // If it is not already on the pending app list, add it there 13404 // and start a new process for it. 13405 if (mPersistentStartingProcesses.indexOf(app) < 0) { 13406 mPersistentStartingProcesses.add(app); 13407 restart = true; 13408 } 13409 } 13410 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 13411 "Clean-up removing on hold: " + app); 13412 mProcessesOnHold.remove(app); 13413 13414 if (app == mHomeProcess) { 13415 mHomeProcess = null; 13416 } 13417 if (app == mPreviousProcess) { 13418 mPreviousProcess = null; 13419 } 13420 13421 if (restart && !app.isolated) { 13422 // We have components that still need to be running in the 13423 // process, so re-launch it. 13424 mProcessNames.put(app.processName, app.uid, app); 13425 startProcessLocked(app, "restart", app.processName, null /* ABI override */); 13426 } else if (app.pid > 0 && app.pid != MY_PID) { 13427 // Goodbye! 13428 boolean removed; 13429 synchronized (mPidsSelfLocked) { 13430 mPidsSelfLocked.remove(app.pid); 13431 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 13432 } 13433 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 13434 if (app.isolated) { 13435 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 13436 } 13437 app.setPid(0); 13438 } 13439 } 13440 13441 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 13442 // Look through the content providers we are waiting to have launched, 13443 // and if any run in this process then either schedule a restart of 13444 // the process or kill the client waiting for it if this process has 13445 // gone bad. 13446 int NL = mLaunchingProviders.size(); 13447 boolean restart = false; 13448 for (int i=0; i<NL; i++) { 13449 ContentProviderRecord cpr = mLaunchingProviders.get(i); 13450 if (cpr.launchingApp == app) { 13451 if (!alwaysBad && !app.bad) { 13452 restart = true; 13453 } else { 13454 removeDyingProviderLocked(app, cpr, true); 13455 // cpr should have been removed from mLaunchingProviders 13456 NL = mLaunchingProviders.size(); 13457 i--; 13458 } 13459 } 13460 } 13461 return restart; 13462 } 13463 13464 // ========================================================= 13465 // SERVICES 13466 // ========================================================= 13467 13468 @Override 13469 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 13470 int flags) { 13471 enforceNotIsolatedCaller("getServices"); 13472 synchronized (this) { 13473 return mServices.getRunningServiceInfoLocked(maxNum, flags); 13474 } 13475 } 13476 13477 @Override 13478 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 13479 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 13480 synchronized (this) { 13481 return mServices.getRunningServiceControlPanelLocked(name); 13482 } 13483 } 13484 13485 @Override 13486 public ComponentName startService(IApplicationThread caller, Intent service, 13487 String resolvedType, int userId) { 13488 enforceNotIsolatedCaller("startService"); 13489 // Refuse possible leaked file descriptors 13490 if (service != null && service.hasFileDescriptors() == true) { 13491 throw new IllegalArgumentException("File descriptors passed in Intent"); 13492 } 13493 13494 if (DEBUG_SERVICE) 13495 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13496 synchronized(this) { 13497 final int callingPid = Binder.getCallingPid(); 13498 final int callingUid = Binder.getCallingUid(); 13499 final long origId = Binder.clearCallingIdentity(); 13500 ComponentName res = mServices.startServiceLocked(caller, service, 13501 resolvedType, callingPid, callingUid, userId); 13502 Binder.restoreCallingIdentity(origId); 13503 return res; 13504 } 13505 } 13506 13507 ComponentName startServiceInPackage(int uid, 13508 Intent service, String resolvedType, int userId) { 13509 synchronized(this) { 13510 if (DEBUG_SERVICE) 13511 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13512 final long origId = Binder.clearCallingIdentity(); 13513 ComponentName res = mServices.startServiceLocked(null, service, 13514 resolvedType, -1, uid, userId); 13515 Binder.restoreCallingIdentity(origId); 13516 return res; 13517 } 13518 } 13519 13520 @Override 13521 public int stopService(IApplicationThread caller, Intent service, 13522 String resolvedType, int userId) { 13523 enforceNotIsolatedCaller("stopService"); 13524 // Refuse possible leaked file descriptors 13525 if (service != null && service.hasFileDescriptors() == true) { 13526 throw new IllegalArgumentException("File descriptors passed in Intent"); 13527 } 13528 13529 synchronized(this) { 13530 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13531 } 13532 } 13533 13534 @Override 13535 public IBinder peekService(Intent service, String resolvedType) { 13536 enforceNotIsolatedCaller("peekService"); 13537 // Refuse possible leaked file descriptors 13538 if (service != null && service.hasFileDescriptors() == true) { 13539 throw new IllegalArgumentException("File descriptors passed in Intent"); 13540 } 13541 synchronized(this) { 13542 return mServices.peekServiceLocked(service, resolvedType); 13543 } 13544 } 13545 13546 @Override 13547 public boolean stopServiceToken(ComponentName className, IBinder token, 13548 int startId) { 13549 synchronized(this) { 13550 return mServices.stopServiceTokenLocked(className, token, startId); 13551 } 13552 } 13553 13554 @Override 13555 public void setServiceForeground(ComponentName className, IBinder token, 13556 int id, Notification notification, boolean removeNotification) { 13557 synchronized(this) { 13558 mServices.setServiceForegroundLocked(className, token, id, notification, 13559 removeNotification); 13560 } 13561 } 13562 13563 @Override 13564 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13565 boolean requireFull, String name, String callerPackage) { 13566 return handleIncomingUser(callingPid, callingUid, userId, allowAll, 13567 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage); 13568 } 13569 13570 int unsafeConvertIncomingUser(int userId) { 13571 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF) 13572 ? mCurrentUserId : userId; 13573 } 13574 13575 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13576 int allowMode, String name, String callerPackage) { 13577 final int callingUserId = UserHandle.getUserId(callingUid); 13578 if (callingUserId == userId) { 13579 return userId; 13580 } 13581 13582 // Note that we may be accessing mCurrentUserId outside of a lock... 13583 // shouldn't be a big deal, if this is being called outside 13584 // of a locked context there is intrinsically a race with 13585 // the value the caller will receive and someone else changing it. 13586 // We assume that USER_CURRENT_OR_SELF will use the current user; later 13587 // we will switch to the calling user if access to the current user fails. 13588 int targetUserId = unsafeConvertIncomingUser(userId); 13589 13590 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13591 final boolean allow; 13592 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, 13593 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { 13594 // If the caller has this permission, they always pass go. And collect $200. 13595 allow = true; 13596 } else if (allowMode == ALLOW_FULL_ONLY) { 13597 // We require full access, sucks to be you. 13598 allow = false; 13599 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid, 13600 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { 13601 // If the caller does not have either permission, they are always doomed. 13602 allow = false; 13603 } else if (allowMode == ALLOW_NON_FULL) { 13604 // We are blanket allowing non-full access, you lucky caller! 13605 allow = true; 13606 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) { 13607 // We may or may not allow this depending on whether the two users are 13608 // in the same profile. 13609 synchronized (mUserProfileGroupIdsSelfLocked) { 13610 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId, 13611 UserInfo.NO_PROFILE_GROUP_ID); 13612 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId, 13613 UserInfo.NO_PROFILE_GROUP_ID); 13614 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID 13615 && callingProfile == targetProfile; 13616 } 13617 } else { 13618 throw new IllegalArgumentException("Unknown mode: " + allowMode); 13619 } 13620 if (!allow) { 13621 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13622 // In this case, they would like to just execute as their 13623 // owner user instead of failing. 13624 targetUserId = callingUserId; 13625 } else { 13626 StringBuilder builder = new StringBuilder(128); 13627 builder.append("Permission Denial: "); 13628 builder.append(name); 13629 if (callerPackage != null) { 13630 builder.append(" from "); 13631 builder.append(callerPackage); 13632 } 13633 builder.append(" asks to run as user "); 13634 builder.append(userId); 13635 builder.append(" but is calling from user "); 13636 builder.append(UserHandle.getUserId(callingUid)); 13637 builder.append("; this requires "); 13638 builder.append(INTERACT_ACROSS_USERS_FULL); 13639 if (allowMode != ALLOW_FULL_ONLY) { 13640 builder.append(" or "); 13641 builder.append(INTERACT_ACROSS_USERS); 13642 } 13643 String msg = builder.toString(); 13644 Slog.w(TAG, msg); 13645 throw new SecurityException(msg); 13646 } 13647 } 13648 } 13649 if (!allowAll && targetUserId < 0) { 13650 throw new IllegalArgumentException( 13651 "Call does not support special user #" + targetUserId); 13652 } 13653 return targetUserId; 13654 } 13655 13656 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13657 String className, int flags) { 13658 boolean result = false; 13659 // For apps that don't have pre-defined UIDs, check for permission 13660 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13661 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) { 13662 if (ActivityManager.checkUidPermission( 13663 INTERACT_ACROSS_USERS, 13664 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13665 ComponentName comp = new ComponentName(aInfo.packageName, className); 13666 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13667 + " requests FLAG_SINGLE_USER, but app does not hold " 13668 + INTERACT_ACROSS_USERS; 13669 Slog.w(TAG, msg); 13670 throw new SecurityException(msg); 13671 } 13672 // Permission passed 13673 result = true; 13674 } 13675 } else if ("system".equals(componentProcessName)) { 13676 result = true; 13677 } else { 13678 // App with pre-defined UID, check if it's a persistent app 13679 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13680 } 13681 if (DEBUG_MU) { 13682 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13683 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13684 } 13685 return result; 13686 } 13687 13688 /** 13689 * Checks to see if the caller is in the same app as the singleton 13690 * component, or the component is in a special app. It allows special apps 13691 * to export singleton components but prevents exporting singleton 13692 * components for regular apps. 13693 */ 13694 boolean isValidSingletonCall(int callingUid, int componentUid) { 13695 int componentAppId = UserHandle.getAppId(componentUid); 13696 return UserHandle.isSameApp(callingUid, componentUid) 13697 || componentAppId == Process.SYSTEM_UID 13698 || componentAppId == Process.PHONE_UID 13699 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid) 13700 == PackageManager.PERMISSION_GRANTED; 13701 } 13702 13703 public int bindService(IApplicationThread caller, IBinder token, 13704 Intent service, String resolvedType, 13705 IServiceConnection connection, int flags, int userId) { 13706 enforceNotIsolatedCaller("bindService"); 13707 // Refuse possible leaked file descriptors 13708 if (service != null && service.hasFileDescriptors() == true) { 13709 throw new IllegalArgumentException("File descriptors passed in Intent"); 13710 } 13711 13712 synchronized(this) { 13713 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13714 connection, flags, userId); 13715 } 13716 } 13717 13718 public boolean unbindService(IServiceConnection connection) { 13719 synchronized (this) { 13720 return mServices.unbindServiceLocked(connection); 13721 } 13722 } 13723 13724 public void publishService(IBinder token, Intent intent, IBinder service) { 13725 // Refuse possible leaked file descriptors 13726 if (intent != null && intent.hasFileDescriptors() == true) { 13727 throw new IllegalArgumentException("File descriptors passed in Intent"); 13728 } 13729 13730 synchronized(this) { 13731 if (!(token instanceof ServiceRecord)) { 13732 throw new IllegalArgumentException("Invalid service token"); 13733 } 13734 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13735 } 13736 } 13737 13738 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13739 // Refuse possible leaked file descriptors 13740 if (intent != null && intent.hasFileDescriptors() == true) { 13741 throw new IllegalArgumentException("File descriptors passed in Intent"); 13742 } 13743 13744 synchronized(this) { 13745 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13746 } 13747 } 13748 13749 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13750 synchronized(this) { 13751 if (!(token instanceof ServiceRecord)) { 13752 throw new IllegalArgumentException("Invalid service token"); 13753 } 13754 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13755 } 13756 } 13757 13758 // ========================================================= 13759 // BACKUP AND RESTORE 13760 // ========================================================= 13761 13762 // Cause the target app to be launched if necessary and its backup agent 13763 // instantiated. The backup agent will invoke backupAgentCreated() on the 13764 // activity manager to announce its creation. 13765 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13766 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13767 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent"); 13768 13769 synchronized(this) { 13770 // !!! TODO: currently no check here that we're already bound 13771 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13772 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13773 synchronized (stats) { 13774 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13775 } 13776 13777 // Backup agent is now in use, its package can't be stopped. 13778 try { 13779 AppGlobals.getPackageManager().setPackageStoppedState( 13780 app.packageName, false, UserHandle.getUserId(app.uid)); 13781 } catch (RemoteException e) { 13782 } catch (IllegalArgumentException e) { 13783 Slog.w(TAG, "Failed trying to unstop package " 13784 + app.packageName + ": " + e); 13785 } 13786 13787 BackupRecord r = new BackupRecord(ss, app, backupMode); 13788 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13789 ? new ComponentName(app.packageName, app.backupAgentName) 13790 : new ComponentName("android", "FullBackupAgent"); 13791 // startProcessLocked() returns existing proc's record if it's already running 13792 ProcessRecord proc = startProcessLocked(app.processName, app, 13793 false, 0, "backup", hostingName, false, false, false); 13794 if (proc == null) { 13795 Slog.e(TAG, "Unable to start backup agent process " + r); 13796 return false; 13797 } 13798 13799 r.app = proc; 13800 mBackupTarget = r; 13801 mBackupAppName = app.packageName; 13802 13803 // Try not to kill the process during backup 13804 updateOomAdjLocked(proc); 13805 13806 // If the process is already attached, schedule the creation of the backup agent now. 13807 // If it is not yet live, this will be done when it attaches to the framework. 13808 if (proc.thread != null) { 13809 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13810 try { 13811 proc.thread.scheduleCreateBackupAgent(app, 13812 compatibilityInfoForPackageLocked(app), backupMode); 13813 } catch (RemoteException e) { 13814 // Will time out on the backup manager side 13815 } 13816 } else { 13817 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13818 } 13819 // Invariants: at this point, the target app process exists and the application 13820 // is either already running or in the process of coming up. mBackupTarget and 13821 // mBackupAppName describe the app, so that when it binds back to the AM we 13822 // know that it's scheduled for a backup-agent operation. 13823 } 13824 13825 return true; 13826 } 13827 13828 @Override 13829 public void clearPendingBackup() { 13830 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13831 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13832 13833 synchronized (this) { 13834 mBackupTarget = null; 13835 mBackupAppName = null; 13836 } 13837 } 13838 13839 // A backup agent has just come up 13840 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13841 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13842 + " = " + agent); 13843 13844 synchronized(this) { 13845 if (!agentPackageName.equals(mBackupAppName)) { 13846 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13847 return; 13848 } 13849 } 13850 13851 long oldIdent = Binder.clearCallingIdentity(); 13852 try { 13853 IBackupManager bm = IBackupManager.Stub.asInterface( 13854 ServiceManager.getService(Context.BACKUP_SERVICE)); 13855 bm.agentConnected(agentPackageName, agent); 13856 } catch (RemoteException e) { 13857 // can't happen; the backup manager service is local 13858 } catch (Exception e) { 13859 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13860 e.printStackTrace(); 13861 } finally { 13862 Binder.restoreCallingIdentity(oldIdent); 13863 } 13864 } 13865 13866 // done with this agent 13867 public void unbindBackupAgent(ApplicationInfo appInfo) { 13868 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13869 if (appInfo == null) { 13870 Slog.w(TAG, "unbind backup agent for null app"); 13871 return; 13872 } 13873 13874 synchronized(this) { 13875 try { 13876 if (mBackupAppName == null) { 13877 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13878 return; 13879 } 13880 13881 if (!mBackupAppName.equals(appInfo.packageName)) { 13882 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13883 return; 13884 } 13885 13886 // Not backing this app up any more; reset its OOM adjustment 13887 final ProcessRecord proc = mBackupTarget.app; 13888 updateOomAdjLocked(proc); 13889 13890 // If the app crashed during backup, 'thread' will be null here 13891 if (proc.thread != null) { 13892 try { 13893 proc.thread.scheduleDestroyBackupAgent(appInfo, 13894 compatibilityInfoForPackageLocked(appInfo)); 13895 } catch (Exception e) { 13896 Slog.e(TAG, "Exception when unbinding backup agent:"); 13897 e.printStackTrace(); 13898 } 13899 } 13900 } finally { 13901 mBackupTarget = null; 13902 mBackupAppName = null; 13903 } 13904 } 13905 } 13906 // ========================================================= 13907 // BROADCASTS 13908 // ========================================================= 13909 13910 private final List getStickiesLocked(String action, IntentFilter filter, 13911 List cur, int userId) { 13912 final ContentResolver resolver = mContext.getContentResolver(); 13913 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13914 if (stickies == null) { 13915 return cur; 13916 } 13917 final ArrayList<Intent> list = stickies.get(action); 13918 if (list == null) { 13919 return cur; 13920 } 13921 int N = list.size(); 13922 for (int i=0; i<N; i++) { 13923 Intent intent = list.get(i); 13924 if (filter.match(resolver, intent, true, TAG) >= 0) { 13925 if (cur == null) { 13926 cur = new ArrayList<Intent>(); 13927 } 13928 cur.add(intent); 13929 } 13930 } 13931 return cur; 13932 } 13933 13934 boolean isPendingBroadcastProcessLocked(int pid) { 13935 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13936 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13937 } 13938 13939 void skipPendingBroadcastLocked(int pid) { 13940 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13941 for (BroadcastQueue queue : mBroadcastQueues) { 13942 queue.skipPendingBroadcastLocked(pid); 13943 } 13944 } 13945 13946 // The app just attached; send any pending broadcasts that it should receive 13947 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13948 boolean didSomething = false; 13949 for (BroadcastQueue queue : mBroadcastQueues) { 13950 didSomething |= queue.sendPendingBroadcastsLocked(app); 13951 } 13952 return didSomething; 13953 } 13954 13955 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13956 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13957 enforceNotIsolatedCaller("registerReceiver"); 13958 int callingUid; 13959 int callingPid; 13960 synchronized(this) { 13961 ProcessRecord callerApp = null; 13962 if (caller != null) { 13963 callerApp = getRecordForAppLocked(caller); 13964 if (callerApp == null) { 13965 throw new SecurityException( 13966 "Unable to find app for caller " + caller 13967 + " (pid=" + Binder.getCallingPid() 13968 + ") when registering receiver " + receiver); 13969 } 13970 if (callerApp.info.uid != Process.SYSTEM_UID && 13971 !callerApp.pkgList.containsKey(callerPackage) && 13972 !"android".equals(callerPackage)) { 13973 throw new SecurityException("Given caller package " + callerPackage 13974 + " is not running in process " + callerApp); 13975 } 13976 callingUid = callerApp.info.uid; 13977 callingPid = callerApp.pid; 13978 } else { 13979 callerPackage = null; 13980 callingUid = Binder.getCallingUid(); 13981 callingPid = Binder.getCallingPid(); 13982 } 13983 13984 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13985 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage); 13986 13987 List allSticky = null; 13988 13989 // Look for any matching sticky broadcasts... 13990 Iterator actions = filter.actionsIterator(); 13991 if (actions != null) { 13992 while (actions.hasNext()) { 13993 String action = (String)actions.next(); 13994 allSticky = getStickiesLocked(action, filter, allSticky, 13995 UserHandle.USER_ALL); 13996 allSticky = getStickiesLocked(action, filter, allSticky, 13997 UserHandle.getUserId(callingUid)); 13998 } 13999 } else { 14000 allSticky = getStickiesLocked(null, filter, allSticky, 14001 UserHandle.USER_ALL); 14002 allSticky = getStickiesLocked(null, filter, allSticky, 14003 UserHandle.getUserId(callingUid)); 14004 } 14005 14006 // The first sticky in the list is returned directly back to 14007 // the client. 14008 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 14009 14010 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 14011 + ": " + sticky); 14012 14013 if (receiver == null) { 14014 return sticky; 14015 } 14016 14017 ReceiverList rl 14018 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 14019 if (rl == null) { 14020 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 14021 userId, receiver); 14022 if (rl.app != null) { 14023 rl.app.receivers.add(rl); 14024 } else { 14025 try { 14026 receiver.asBinder().linkToDeath(rl, 0); 14027 } catch (RemoteException e) { 14028 return sticky; 14029 } 14030 rl.linkedToDeath = true; 14031 } 14032 mRegisteredReceivers.put(receiver.asBinder(), rl); 14033 } else if (rl.uid != callingUid) { 14034 throw new IllegalArgumentException( 14035 "Receiver requested to register for uid " + callingUid 14036 + " was previously registered for uid " + rl.uid); 14037 } else if (rl.pid != callingPid) { 14038 throw new IllegalArgumentException( 14039 "Receiver requested to register for pid " + callingPid 14040 + " was previously registered for pid " + rl.pid); 14041 } else if (rl.userId != userId) { 14042 throw new IllegalArgumentException( 14043 "Receiver requested to register for user " + userId 14044 + " was previously registered for user " + rl.userId); 14045 } 14046 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 14047 permission, callingUid, userId); 14048 rl.add(bf); 14049 if (!bf.debugCheck()) { 14050 Slog.w(TAG, "==> For Dynamic broadast"); 14051 } 14052 mReceiverResolver.addFilter(bf); 14053 14054 // Enqueue broadcasts for all existing stickies that match 14055 // this filter. 14056 if (allSticky != null) { 14057 ArrayList receivers = new ArrayList(); 14058 receivers.add(bf); 14059 14060 int N = allSticky.size(); 14061 for (int i=0; i<N; i++) { 14062 Intent intent = (Intent)allSticky.get(i); 14063 BroadcastQueue queue = broadcastQueueForIntent(intent); 14064 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 14065 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 14066 null, null, false, true, true, -1); 14067 queue.enqueueParallelBroadcastLocked(r); 14068 queue.scheduleBroadcastsLocked(); 14069 } 14070 } 14071 14072 return sticky; 14073 } 14074 } 14075 14076 public void unregisterReceiver(IIntentReceiver receiver) { 14077 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 14078 14079 final long origId = Binder.clearCallingIdentity(); 14080 try { 14081 boolean doTrim = false; 14082 14083 synchronized(this) { 14084 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 14085 if (rl != null) { 14086 if (rl.curBroadcast != null) { 14087 BroadcastRecord r = rl.curBroadcast; 14088 final boolean doNext = finishReceiverLocked( 14089 receiver.asBinder(), r.resultCode, r.resultData, 14090 r.resultExtras, r.resultAbort); 14091 if (doNext) { 14092 doTrim = true; 14093 r.queue.processNextBroadcast(false); 14094 } 14095 } 14096 14097 if (rl.app != null) { 14098 rl.app.receivers.remove(rl); 14099 } 14100 removeReceiverLocked(rl); 14101 if (rl.linkedToDeath) { 14102 rl.linkedToDeath = false; 14103 rl.receiver.asBinder().unlinkToDeath(rl, 0); 14104 } 14105 } 14106 } 14107 14108 // If we actually concluded any broadcasts, we might now be able 14109 // to trim the recipients' apps from our working set 14110 if (doTrim) { 14111 trimApplications(); 14112 return; 14113 } 14114 14115 } finally { 14116 Binder.restoreCallingIdentity(origId); 14117 } 14118 } 14119 14120 void removeReceiverLocked(ReceiverList rl) { 14121 mRegisteredReceivers.remove(rl.receiver.asBinder()); 14122 int N = rl.size(); 14123 for (int i=0; i<N; i++) { 14124 mReceiverResolver.removeFilter(rl.get(i)); 14125 } 14126 } 14127 14128 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 14129 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 14130 ProcessRecord r = mLruProcesses.get(i); 14131 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 14132 try { 14133 r.thread.dispatchPackageBroadcast(cmd, packages); 14134 } catch (RemoteException ex) { 14135 } 14136 } 14137 } 14138 } 14139 14140 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 14141 int[] users) { 14142 List<ResolveInfo> receivers = null; 14143 try { 14144 HashSet<ComponentName> singleUserReceivers = null; 14145 boolean scannedFirstReceivers = false; 14146 for (int user : users) { 14147 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 14148 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 14149 if (user != 0 && newReceivers != null) { 14150 // If this is not the primary user, we need to check for 14151 // any receivers that should be filtered out. 14152 for (int i=0; i<newReceivers.size(); i++) { 14153 ResolveInfo ri = newReceivers.get(i); 14154 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 14155 newReceivers.remove(i); 14156 i--; 14157 } 14158 } 14159 } 14160 if (newReceivers != null && newReceivers.size() == 0) { 14161 newReceivers = null; 14162 } 14163 if (receivers == null) { 14164 receivers = newReceivers; 14165 } else if (newReceivers != null) { 14166 // We need to concatenate the additional receivers 14167 // found with what we have do far. This would be easy, 14168 // but we also need to de-dup any receivers that are 14169 // singleUser. 14170 if (!scannedFirstReceivers) { 14171 // Collect any single user receivers we had already retrieved. 14172 scannedFirstReceivers = true; 14173 for (int i=0; i<receivers.size(); i++) { 14174 ResolveInfo ri = receivers.get(i); 14175 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14176 ComponentName cn = new ComponentName( 14177 ri.activityInfo.packageName, ri.activityInfo.name); 14178 if (singleUserReceivers == null) { 14179 singleUserReceivers = new HashSet<ComponentName>(); 14180 } 14181 singleUserReceivers.add(cn); 14182 } 14183 } 14184 } 14185 // Add the new results to the existing results, tracking 14186 // and de-dupping single user receivers. 14187 for (int i=0; i<newReceivers.size(); i++) { 14188 ResolveInfo ri = newReceivers.get(i); 14189 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 14190 ComponentName cn = new ComponentName( 14191 ri.activityInfo.packageName, ri.activityInfo.name); 14192 if (singleUserReceivers == null) { 14193 singleUserReceivers = new HashSet<ComponentName>(); 14194 } 14195 if (!singleUserReceivers.contains(cn)) { 14196 singleUserReceivers.add(cn); 14197 receivers.add(ri); 14198 } 14199 } else { 14200 receivers.add(ri); 14201 } 14202 } 14203 } 14204 } 14205 } catch (RemoteException ex) { 14206 // pm is in same process, this will never happen. 14207 } 14208 return receivers; 14209 } 14210 14211 private final int broadcastIntentLocked(ProcessRecord callerApp, 14212 String callerPackage, Intent intent, String resolvedType, 14213 IIntentReceiver resultTo, int resultCode, String resultData, 14214 Bundle map, String requiredPermission, int appOp, 14215 boolean ordered, boolean sticky, int callingPid, int callingUid, 14216 int userId) { 14217 intent = new Intent(intent); 14218 14219 // By default broadcasts do not go to stopped apps. 14220 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 14221 14222 if (DEBUG_BROADCAST_LIGHT) Slog.v( 14223 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 14224 + " ordered=" + ordered + " userid=" + userId); 14225 if ((resultTo != null) && !ordered) { 14226 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 14227 } 14228 14229 userId = handleIncomingUser(callingPid, callingUid, userId, 14230 true, ALLOW_NON_FULL, "broadcast", callerPackage); 14231 14232 // Make sure that the user who is receiving this broadcast is started. 14233 // If not, we will just skip it. 14234 14235 14236 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 14237 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 14238 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 14239 Slog.w(TAG, "Skipping broadcast of " + intent 14240 + ": user " + userId + " is stopped"); 14241 return ActivityManager.BROADCAST_SUCCESS; 14242 } 14243 } 14244 14245 /* 14246 * Prevent non-system code (defined here to be non-persistent 14247 * processes) from sending protected broadcasts. 14248 */ 14249 int callingAppId = UserHandle.getAppId(callingUid); 14250 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 14251 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID 14252 || callingAppId == Process.NFC_UID || callingUid == 0) { 14253 // Always okay. 14254 } else if (callerApp == null || !callerApp.persistent) { 14255 try { 14256 if (AppGlobals.getPackageManager().isProtectedBroadcast( 14257 intent.getAction())) { 14258 String msg = "Permission Denial: not allowed to send broadcast " 14259 + intent.getAction() + " from pid=" 14260 + callingPid + ", uid=" + callingUid; 14261 Slog.w(TAG, msg); 14262 throw new SecurityException(msg); 14263 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 14264 // Special case for compatibility: we don't want apps to send this, 14265 // but historically it has not been protected and apps may be using it 14266 // to poke their own app widget. So, instead of making it protected, 14267 // just limit it to the caller. 14268 if (callerApp == null) { 14269 String msg = "Permission Denial: not allowed to send broadcast " 14270 + intent.getAction() + " from unknown caller."; 14271 Slog.w(TAG, msg); 14272 throw new SecurityException(msg); 14273 } else if (intent.getComponent() != null) { 14274 // They are good enough to send to an explicit component... verify 14275 // it is being sent to the calling app. 14276 if (!intent.getComponent().getPackageName().equals( 14277 callerApp.info.packageName)) { 14278 String msg = "Permission Denial: not allowed to send broadcast " 14279 + intent.getAction() + " to " 14280 + intent.getComponent().getPackageName() + " from " 14281 + callerApp.info.packageName; 14282 Slog.w(TAG, msg); 14283 throw new SecurityException(msg); 14284 } 14285 } else { 14286 // Limit broadcast to their own package. 14287 intent.setPackage(callerApp.info.packageName); 14288 } 14289 } 14290 } catch (RemoteException e) { 14291 Slog.w(TAG, "Remote exception", e); 14292 return ActivityManager.BROADCAST_SUCCESS; 14293 } 14294 } 14295 14296 // Handle special intents: if this broadcast is from the package 14297 // manager about a package being removed, we need to remove all of 14298 // its activities from the history stack. 14299 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 14300 intent.getAction()); 14301 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 14302 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 14303 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 14304 || uidRemoved) { 14305 if (checkComponentPermission( 14306 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 14307 callingPid, callingUid, -1, true) 14308 == PackageManager.PERMISSION_GRANTED) { 14309 if (uidRemoved) { 14310 final Bundle intentExtras = intent.getExtras(); 14311 final int uid = intentExtras != null 14312 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 14313 if (uid >= 0) { 14314 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 14315 synchronized (bs) { 14316 bs.removeUidStatsLocked(uid); 14317 } 14318 mAppOpsService.uidRemoved(uid); 14319 } 14320 } else { 14321 // If resources are unavailable just force stop all 14322 // those packages and flush the attribute cache as well. 14323 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 14324 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14325 if (list != null && (list.length > 0)) { 14326 for (String pkg : list) { 14327 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 14328 "storage unmount"); 14329 } 14330 sendPackageBroadcastLocked( 14331 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 14332 } 14333 } else { 14334 Uri data = intent.getData(); 14335 String ssp; 14336 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14337 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 14338 intent.getAction()); 14339 boolean fullUninstall = removed && 14340 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 14341 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 14342 forceStopPackageLocked(ssp, UserHandle.getAppId( 14343 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 14344 false, fullUninstall, userId, 14345 removed ? "pkg removed" : "pkg changed"); 14346 } 14347 if (removed) { 14348 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 14349 new String[] {ssp}, userId); 14350 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 14351 mAppOpsService.packageRemoved( 14352 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 14353 14354 // Remove all permissions granted from/to this package 14355 removeUriPermissionsForPackageLocked(ssp, userId, true); 14356 } 14357 } 14358 } 14359 } 14360 } 14361 } else { 14362 String msg = "Permission Denial: " + intent.getAction() 14363 + " broadcast from " + callerPackage + " (pid=" + callingPid 14364 + ", uid=" + callingUid + ")" 14365 + " requires " 14366 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 14367 Slog.w(TAG, msg); 14368 throw new SecurityException(msg); 14369 } 14370 14371 // Special case for adding a package: by default turn on compatibility 14372 // mode. 14373 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 14374 Uri data = intent.getData(); 14375 String ssp; 14376 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 14377 mCompatModePackages.handlePackageAddedLocked(ssp, 14378 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 14379 } 14380 } 14381 14382 /* 14383 * If this is the time zone changed action, queue up a message that will reset the timezone 14384 * of all currently running processes. This message will get queued up before the broadcast 14385 * happens. 14386 */ 14387 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 14388 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 14389 } 14390 14391 /* 14392 * If the user set the time, let all running processes know. 14393 */ 14394 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 14395 final int is24Hour = intent.getBooleanExtra( 14396 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 14397 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 14398 } 14399 14400 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 14401 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 14402 } 14403 14404 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 14405 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO); 14406 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 14407 } 14408 14409 // Add to the sticky list if requested. 14410 if (sticky) { 14411 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 14412 callingPid, callingUid) 14413 != PackageManager.PERMISSION_GRANTED) { 14414 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 14415 + callingPid + ", uid=" + callingUid 14416 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14417 Slog.w(TAG, msg); 14418 throw new SecurityException(msg); 14419 } 14420 if (requiredPermission != null) { 14421 Slog.w(TAG, "Can't broadcast sticky intent " + intent 14422 + " and enforce permission " + requiredPermission); 14423 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 14424 } 14425 if (intent.getComponent() != null) { 14426 throw new SecurityException( 14427 "Sticky broadcasts can't target a specific component"); 14428 } 14429 // We use userId directly here, since the "all" target is maintained 14430 // as a separate set of sticky broadcasts. 14431 if (userId != UserHandle.USER_ALL) { 14432 // But first, if this is not a broadcast to all users, then 14433 // make sure it doesn't conflict with an existing broadcast to 14434 // all users. 14435 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 14436 UserHandle.USER_ALL); 14437 if (stickies != null) { 14438 ArrayList<Intent> list = stickies.get(intent.getAction()); 14439 if (list != null) { 14440 int N = list.size(); 14441 int i; 14442 for (i=0; i<N; i++) { 14443 if (intent.filterEquals(list.get(i))) { 14444 throw new IllegalArgumentException( 14445 "Sticky broadcast " + intent + " for user " 14446 + userId + " conflicts with existing global broadcast"); 14447 } 14448 } 14449 } 14450 } 14451 } 14452 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14453 if (stickies == null) { 14454 stickies = new ArrayMap<String, ArrayList<Intent>>(); 14455 mStickyBroadcasts.put(userId, stickies); 14456 } 14457 ArrayList<Intent> list = stickies.get(intent.getAction()); 14458 if (list == null) { 14459 list = new ArrayList<Intent>(); 14460 stickies.put(intent.getAction(), list); 14461 } 14462 int N = list.size(); 14463 int i; 14464 for (i=0; i<N; i++) { 14465 if (intent.filterEquals(list.get(i))) { 14466 // This sticky already exists, replace it. 14467 list.set(i, new Intent(intent)); 14468 break; 14469 } 14470 } 14471 if (i >= N) { 14472 list.add(new Intent(intent)); 14473 } 14474 } 14475 14476 int[] users; 14477 if (userId == UserHandle.USER_ALL) { 14478 // Caller wants broadcast to go to all started users. 14479 users = mStartedUserArray; 14480 } else { 14481 // Caller wants broadcast to go to one specific user. 14482 users = new int[] {userId}; 14483 } 14484 14485 // Figure out who all will receive this broadcast. 14486 List receivers = null; 14487 List<BroadcastFilter> registeredReceivers = null; 14488 // Need to resolve the intent to interested receivers... 14489 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 14490 == 0) { 14491 receivers = collectReceiverComponents(intent, resolvedType, users); 14492 } 14493 if (intent.getComponent() == null) { 14494 registeredReceivers = mReceiverResolver.queryIntent(intent, 14495 resolvedType, false, userId); 14496 } 14497 14498 final boolean replacePending = 14499 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 14500 14501 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 14502 + " replacePending=" + replacePending); 14503 14504 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 14505 if (!ordered && NR > 0) { 14506 // If we are not serializing this broadcast, then send the 14507 // registered receivers separately so they don't wait for the 14508 // components to be launched. 14509 final BroadcastQueue queue = broadcastQueueForIntent(intent); 14510 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14511 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 14512 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 14513 ordered, sticky, false, userId); 14514 if (DEBUG_BROADCAST) Slog.v( 14515 TAG, "Enqueueing parallel broadcast " + r); 14516 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 14517 if (!replaced) { 14518 queue.enqueueParallelBroadcastLocked(r); 14519 queue.scheduleBroadcastsLocked(); 14520 } 14521 registeredReceivers = null; 14522 NR = 0; 14523 } 14524 14525 // Merge into one list. 14526 int ir = 0; 14527 if (receivers != null) { 14528 // A special case for PACKAGE_ADDED: do not allow the package 14529 // being added to see this broadcast. This prevents them from 14530 // using this as a back door to get run as soon as they are 14531 // installed. Maybe in the future we want to have a special install 14532 // broadcast or such for apps, but we'd like to deliberately make 14533 // this decision. 14534 String skipPackages[] = null; 14535 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 14536 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 14537 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 14538 Uri data = intent.getData(); 14539 if (data != null) { 14540 String pkgName = data.getSchemeSpecificPart(); 14541 if (pkgName != null) { 14542 skipPackages = new String[] { pkgName }; 14543 } 14544 } 14545 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14546 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14547 } 14548 if (skipPackages != null && (skipPackages.length > 0)) { 14549 for (String skipPackage : skipPackages) { 14550 if (skipPackage != null) { 14551 int NT = receivers.size(); 14552 for (int it=0; it<NT; it++) { 14553 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14554 if (curt.activityInfo.packageName.equals(skipPackage)) { 14555 receivers.remove(it); 14556 it--; 14557 NT--; 14558 } 14559 } 14560 } 14561 } 14562 } 14563 14564 int NT = receivers != null ? receivers.size() : 0; 14565 int it = 0; 14566 ResolveInfo curt = null; 14567 BroadcastFilter curr = null; 14568 while (it < NT && ir < NR) { 14569 if (curt == null) { 14570 curt = (ResolveInfo)receivers.get(it); 14571 } 14572 if (curr == null) { 14573 curr = registeredReceivers.get(ir); 14574 } 14575 if (curr.getPriority() >= curt.priority) { 14576 // Insert this broadcast record into the final list. 14577 receivers.add(it, curr); 14578 ir++; 14579 curr = null; 14580 it++; 14581 NT++; 14582 } else { 14583 // Skip to the next ResolveInfo in the final list. 14584 it++; 14585 curt = null; 14586 } 14587 } 14588 } 14589 while (ir < NR) { 14590 if (receivers == null) { 14591 receivers = new ArrayList(); 14592 } 14593 receivers.add(registeredReceivers.get(ir)); 14594 ir++; 14595 } 14596 14597 if ((receivers != null && receivers.size() > 0) 14598 || resultTo != null) { 14599 BroadcastQueue queue = broadcastQueueForIntent(intent); 14600 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14601 callerPackage, callingPid, callingUid, resolvedType, 14602 requiredPermission, appOp, receivers, resultTo, resultCode, 14603 resultData, map, ordered, sticky, false, userId); 14604 if (DEBUG_BROADCAST) Slog.v( 14605 TAG, "Enqueueing ordered broadcast " + r 14606 + ": prev had " + queue.mOrderedBroadcasts.size()); 14607 if (DEBUG_BROADCAST) { 14608 int seq = r.intent.getIntExtra("seq", -1); 14609 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14610 } 14611 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14612 if (!replaced) { 14613 queue.enqueueOrderedBroadcastLocked(r); 14614 queue.scheduleBroadcastsLocked(); 14615 } 14616 } 14617 14618 return ActivityManager.BROADCAST_SUCCESS; 14619 } 14620 14621 final Intent verifyBroadcastLocked(Intent intent) { 14622 // Refuse possible leaked file descriptors 14623 if (intent != null && intent.hasFileDescriptors() == true) { 14624 throw new IllegalArgumentException("File descriptors passed in Intent"); 14625 } 14626 14627 int flags = intent.getFlags(); 14628 14629 if (!mProcessesReady) { 14630 // if the caller really truly claims to know what they're doing, go 14631 // ahead and allow the broadcast without launching any receivers 14632 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14633 intent = new Intent(intent); 14634 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14635 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14636 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14637 + " before boot completion"); 14638 throw new IllegalStateException("Cannot broadcast before boot completed"); 14639 } 14640 } 14641 14642 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14643 throw new IllegalArgumentException( 14644 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14645 } 14646 14647 return intent; 14648 } 14649 14650 public final int broadcastIntent(IApplicationThread caller, 14651 Intent intent, String resolvedType, IIntentReceiver resultTo, 14652 int resultCode, String resultData, Bundle map, 14653 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14654 enforceNotIsolatedCaller("broadcastIntent"); 14655 synchronized(this) { 14656 intent = verifyBroadcastLocked(intent); 14657 14658 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14659 final int callingPid = Binder.getCallingPid(); 14660 final int callingUid = Binder.getCallingUid(); 14661 final long origId = Binder.clearCallingIdentity(); 14662 int res = broadcastIntentLocked(callerApp, 14663 callerApp != null ? callerApp.info.packageName : null, 14664 intent, resolvedType, resultTo, 14665 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14666 callingPid, callingUid, userId); 14667 Binder.restoreCallingIdentity(origId); 14668 return res; 14669 } 14670 } 14671 14672 int broadcastIntentInPackage(String packageName, int uid, 14673 Intent intent, String resolvedType, IIntentReceiver resultTo, 14674 int resultCode, String resultData, Bundle map, 14675 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14676 synchronized(this) { 14677 intent = verifyBroadcastLocked(intent); 14678 14679 final long origId = Binder.clearCallingIdentity(); 14680 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14681 resultTo, resultCode, resultData, map, requiredPermission, 14682 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14683 Binder.restoreCallingIdentity(origId); 14684 return res; 14685 } 14686 } 14687 14688 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14689 // Refuse possible leaked file descriptors 14690 if (intent != null && intent.hasFileDescriptors() == true) { 14691 throw new IllegalArgumentException("File descriptors passed in Intent"); 14692 } 14693 14694 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14695 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null); 14696 14697 synchronized(this) { 14698 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14699 != PackageManager.PERMISSION_GRANTED) { 14700 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14701 + Binder.getCallingPid() 14702 + ", uid=" + Binder.getCallingUid() 14703 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14704 Slog.w(TAG, msg); 14705 throw new SecurityException(msg); 14706 } 14707 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14708 if (stickies != null) { 14709 ArrayList<Intent> list = stickies.get(intent.getAction()); 14710 if (list != null) { 14711 int N = list.size(); 14712 int i; 14713 for (i=0; i<N; i++) { 14714 if (intent.filterEquals(list.get(i))) { 14715 list.remove(i); 14716 break; 14717 } 14718 } 14719 if (list.size() <= 0) { 14720 stickies.remove(intent.getAction()); 14721 } 14722 } 14723 if (stickies.size() <= 0) { 14724 mStickyBroadcasts.remove(userId); 14725 } 14726 } 14727 } 14728 } 14729 14730 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14731 String resultData, Bundle resultExtras, boolean resultAbort) { 14732 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14733 if (r == null) { 14734 Slog.w(TAG, "finishReceiver called but not found on queue"); 14735 return false; 14736 } 14737 14738 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14739 } 14740 14741 void backgroundServicesFinishedLocked(int userId) { 14742 for (BroadcastQueue queue : mBroadcastQueues) { 14743 queue.backgroundServicesFinishedLocked(userId); 14744 } 14745 } 14746 14747 public void finishReceiver(IBinder who, int resultCode, String resultData, 14748 Bundle resultExtras, boolean resultAbort) { 14749 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14750 14751 // Refuse possible leaked file descriptors 14752 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14753 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14754 } 14755 14756 final long origId = Binder.clearCallingIdentity(); 14757 try { 14758 boolean doNext = false; 14759 BroadcastRecord r; 14760 14761 synchronized(this) { 14762 r = broadcastRecordForReceiverLocked(who); 14763 if (r != null) { 14764 doNext = r.queue.finishReceiverLocked(r, resultCode, 14765 resultData, resultExtras, resultAbort, true); 14766 } 14767 } 14768 14769 if (doNext) { 14770 r.queue.processNextBroadcast(false); 14771 } 14772 trimApplications(); 14773 } finally { 14774 Binder.restoreCallingIdentity(origId); 14775 } 14776 } 14777 14778 // ========================================================= 14779 // INSTRUMENTATION 14780 // ========================================================= 14781 14782 public boolean startInstrumentation(ComponentName className, 14783 String profileFile, int flags, Bundle arguments, 14784 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14785 int userId, String abiOverride) { 14786 enforceNotIsolatedCaller("startInstrumentation"); 14787 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14788 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null); 14789 // Refuse possible leaked file descriptors 14790 if (arguments != null && arguments.hasFileDescriptors()) { 14791 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14792 } 14793 14794 synchronized(this) { 14795 InstrumentationInfo ii = null; 14796 ApplicationInfo ai = null; 14797 try { 14798 ii = mContext.getPackageManager().getInstrumentationInfo( 14799 className, STOCK_PM_FLAGS); 14800 ai = AppGlobals.getPackageManager().getApplicationInfo( 14801 ii.targetPackage, STOCK_PM_FLAGS, userId); 14802 } catch (PackageManager.NameNotFoundException e) { 14803 } catch (RemoteException e) { 14804 } 14805 if (ii == null) { 14806 reportStartInstrumentationFailure(watcher, className, 14807 "Unable to find instrumentation info for: " + className); 14808 return false; 14809 } 14810 if (ai == null) { 14811 reportStartInstrumentationFailure(watcher, className, 14812 "Unable to find instrumentation target package: " + ii.targetPackage); 14813 return false; 14814 } 14815 14816 int match = mContext.getPackageManager().checkSignatures( 14817 ii.targetPackage, ii.packageName); 14818 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14819 String msg = "Permission Denial: starting instrumentation " 14820 + className + " from pid=" 14821 + Binder.getCallingPid() 14822 + ", uid=" + Binder.getCallingPid() 14823 + " not allowed because package " + ii.packageName 14824 + " does not have a signature matching the target " 14825 + ii.targetPackage; 14826 reportStartInstrumentationFailure(watcher, className, msg); 14827 throw new SecurityException(msg); 14828 } 14829 14830 final long origId = Binder.clearCallingIdentity(); 14831 // Instrumentation can kill and relaunch even persistent processes 14832 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14833 "start instr"); 14834 ProcessRecord app = addAppLocked(ai, false, abiOverride); 14835 app.instrumentationClass = className; 14836 app.instrumentationInfo = ai; 14837 app.instrumentationProfileFile = profileFile; 14838 app.instrumentationArguments = arguments; 14839 app.instrumentationWatcher = watcher; 14840 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14841 app.instrumentationResultClass = className; 14842 Binder.restoreCallingIdentity(origId); 14843 } 14844 14845 return true; 14846 } 14847 14848 /** 14849 * Report errors that occur while attempting to start Instrumentation. Always writes the 14850 * error to the logs, but if somebody is watching, send the report there too. This enables 14851 * the "am" command to report errors with more information. 14852 * 14853 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14854 * @param cn The component name of the instrumentation. 14855 * @param report The error report. 14856 */ 14857 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14858 ComponentName cn, String report) { 14859 Slog.w(TAG, report); 14860 try { 14861 if (watcher != null) { 14862 Bundle results = new Bundle(); 14863 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14864 results.putString("Error", report); 14865 watcher.instrumentationStatus(cn, -1, results); 14866 } 14867 } catch (RemoteException e) { 14868 Slog.w(TAG, e); 14869 } 14870 } 14871 14872 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14873 if (app.instrumentationWatcher != null) { 14874 try { 14875 // NOTE: IInstrumentationWatcher *must* be oneway here 14876 app.instrumentationWatcher.instrumentationFinished( 14877 app.instrumentationClass, 14878 resultCode, 14879 results); 14880 } catch (RemoteException e) { 14881 } 14882 } 14883 if (app.instrumentationUiAutomationConnection != null) { 14884 try { 14885 app.instrumentationUiAutomationConnection.shutdown(); 14886 } catch (RemoteException re) { 14887 /* ignore */ 14888 } 14889 // Only a UiAutomation can set this flag and now that 14890 // it is finished we make sure it is reset to its default. 14891 mUserIsMonkey = false; 14892 } 14893 app.instrumentationWatcher = null; 14894 app.instrumentationUiAutomationConnection = null; 14895 app.instrumentationClass = null; 14896 app.instrumentationInfo = null; 14897 app.instrumentationProfileFile = null; 14898 app.instrumentationArguments = null; 14899 14900 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14901 "finished inst"); 14902 } 14903 14904 public void finishInstrumentation(IApplicationThread target, 14905 int resultCode, Bundle results) { 14906 int userId = UserHandle.getCallingUserId(); 14907 // Refuse possible leaked file descriptors 14908 if (results != null && results.hasFileDescriptors()) { 14909 throw new IllegalArgumentException("File descriptors passed in Intent"); 14910 } 14911 14912 synchronized(this) { 14913 ProcessRecord app = getRecordForAppLocked(target); 14914 if (app == null) { 14915 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14916 return; 14917 } 14918 final long origId = Binder.clearCallingIdentity(); 14919 finishInstrumentationLocked(app, resultCode, results); 14920 Binder.restoreCallingIdentity(origId); 14921 } 14922 } 14923 14924 // ========================================================= 14925 // CONFIGURATION 14926 // ========================================================= 14927 14928 public ConfigurationInfo getDeviceConfigurationInfo() { 14929 ConfigurationInfo config = new ConfigurationInfo(); 14930 synchronized (this) { 14931 config.reqTouchScreen = mConfiguration.touchscreen; 14932 config.reqKeyboardType = mConfiguration.keyboard; 14933 config.reqNavigation = mConfiguration.navigation; 14934 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14935 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14936 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14937 } 14938 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14939 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14940 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14941 } 14942 config.reqGlEsVersion = GL_ES_VERSION; 14943 } 14944 return config; 14945 } 14946 14947 ActivityStack getFocusedStack() { 14948 return mStackSupervisor.getFocusedStack(); 14949 } 14950 14951 public Configuration getConfiguration() { 14952 Configuration ci; 14953 synchronized(this) { 14954 ci = new Configuration(mConfiguration); 14955 } 14956 return ci; 14957 } 14958 14959 public void updatePersistentConfiguration(Configuration values) { 14960 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14961 "updateConfiguration()"); 14962 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14963 "updateConfiguration()"); 14964 if (values == null) { 14965 throw new NullPointerException("Configuration must not be null"); 14966 } 14967 14968 synchronized(this) { 14969 final long origId = Binder.clearCallingIdentity(); 14970 updateConfigurationLocked(values, null, true, false); 14971 Binder.restoreCallingIdentity(origId); 14972 } 14973 } 14974 14975 public void updateConfiguration(Configuration values) { 14976 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14977 "updateConfiguration()"); 14978 14979 synchronized(this) { 14980 if (values == null && mWindowManager != null) { 14981 // sentinel: fetch the current configuration from the window manager 14982 values = mWindowManager.computeNewConfiguration(); 14983 } 14984 14985 if (mWindowManager != null) { 14986 mProcessList.applyDisplaySize(mWindowManager); 14987 } 14988 14989 final long origId = Binder.clearCallingIdentity(); 14990 if (values != null) { 14991 Settings.System.clearConfiguration(values); 14992 } 14993 updateConfigurationLocked(values, null, false, false); 14994 Binder.restoreCallingIdentity(origId); 14995 } 14996 } 14997 14998 /** 14999 * Do either or both things: (1) change the current configuration, and (2) 15000 * make sure the given activity is running with the (now) current 15001 * configuration. Returns true if the activity has been left running, or 15002 * false if <var>starting</var> is being destroyed to match the new 15003 * configuration. 15004 * @param persistent TODO 15005 */ 15006 boolean updateConfigurationLocked(Configuration values, 15007 ActivityRecord starting, boolean persistent, boolean initLocale) { 15008 int changes = 0; 15009 15010 if (values != null) { 15011 Configuration newConfig = new Configuration(mConfiguration); 15012 changes = newConfig.updateFrom(values); 15013 if (changes != 0) { 15014 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 15015 Slog.i(TAG, "Updating configuration to: " + values); 15016 } 15017 15018 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 15019 15020 if (values.locale != null && !initLocale) { 15021 saveLocaleLocked(values.locale, 15022 !values.locale.equals(mConfiguration.locale), 15023 values.userSetLocale); 15024 } 15025 15026 mConfigurationSeq++; 15027 if (mConfigurationSeq <= 0) { 15028 mConfigurationSeq = 1; 15029 } 15030 newConfig.seq = mConfigurationSeq; 15031 mConfiguration = newConfig; 15032 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 15033 //mUsageStatsService.noteStartConfig(newConfig); 15034 15035 final Configuration configCopy = new Configuration(mConfiguration); 15036 15037 // TODO: If our config changes, should we auto dismiss any currently 15038 // showing dialogs? 15039 mShowDialogs = shouldShowDialogs(newConfig); 15040 15041 AttributeCache ac = AttributeCache.instance(); 15042 if (ac != null) { 15043 ac.updateConfiguration(configCopy); 15044 } 15045 15046 // Make sure all resources in our process are updated 15047 // right now, so that anyone who is going to retrieve 15048 // resource values after we return will be sure to get 15049 // the new ones. This is especially important during 15050 // boot, where the first config change needs to guarantee 15051 // all resources have that config before following boot 15052 // code is executed. 15053 mSystemThread.applyConfigurationToResources(configCopy); 15054 15055 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 15056 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 15057 msg.obj = new Configuration(configCopy); 15058 mHandler.sendMessage(msg); 15059 } 15060 15061 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15062 ProcessRecord app = mLruProcesses.get(i); 15063 try { 15064 if (app.thread != null) { 15065 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 15066 + app.processName + " new config " + mConfiguration); 15067 app.thread.scheduleConfigurationChanged(configCopy); 15068 } 15069 } catch (Exception e) { 15070 } 15071 } 15072 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 15073 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 15074 | Intent.FLAG_RECEIVER_REPLACE_PENDING 15075 | Intent.FLAG_RECEIVER_FOREGROUND); 15076 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 15077 null, AppOpsManager.OP_NONE, false, false, MY_PID, 15078 Process.SYSTEM_UID, UserHandle.USER_ALL); 15079 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 15080 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 15081 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 15082 broadcastIntentLocked(null, null, intent, 15083 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 15084 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 15085 } 15086 } 15087 } 15088 15089 boolean kept = true; 15090 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 15091 // mainStack is null during startup. 15092 if (mainStack != null) { 15093 if (changes != 0 && starting == null) { 15094 // If the configuration changed, and the caller is not already 15095 // in the process of starting an activity, then find the top 15096 // activity to check if its configuration needs to change. 15097 starting = mainStack.topRunningActivityLocked(null); 15098 } 15099 15100 if (starting != null) { 15101 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 15102 // And we need to make sure at this point that all other activities 15103 // are made visible with the correct configuration. 15104 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 15105 } 15106 } 15107 15108 if (values != null && mWindowManager != null) { 15109 mWindowManager.setNewConfiguration(mConfiguration); 15110 } 15111 15112 return kept; 15113 } 15114 15115 /** 15116 * Decide based on the configuration whether we should shouw the ANR, 15117 * crash, etc dialogs. The idea is that if there is no affordnace to 15118 * press the on-screen buttons, we shouldn't show the dialog. 15119 * 15120 * A thought: SystemUI might also want to get told about this, the Power 15121 * dialog / global actions also might want different behaviors. 15122 */ 15123 private static final boolean shouldShowDialogs(Configuration config) { 15124 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 15125 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 15126 } 15127 15128 /** 15129 * Save the locale. You must be inside a synchronized (this) block. 15130 */ 15131 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 15132 if(isDiff) { 15133 SystemProperties.set("user.language", l.getLanguage()); 15134 SystemProperties.set("user.region", l.getCountry()); 15135 } 15136 15137 if(isPersist) { 15138 SystemProperties.set("persist.sys.language", l.getLanguage()); 15139 SystemProperties.set("persist.sys.country", l.getCountry()); 15140 SystemProperties.set("persist.sys.localevar", l.getVariant()); 15141 } 15142 } 15143 15144 @Override 15145 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 15146 ActivityRecord srec = ActivityRecord.forToken(token); 15147 return srec != null && srec.task.affinity != null && 15148 srec.task.affinity.equals(destAffinity); 15149 } 15150 15151 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 15152 Intent resultData) { 15153 15154 synchronized (this) { 15155 final ActivityStack stack = ActivityRecord.getStackLocked(token); 15156 if (stack != null) { 15157 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 15158 } 15159 return false; 15160 } 15161 } 15162 15163 public int getLaunchedFromUid(IBinder activityToken) { 15164 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15165 if (srec == null) { 15166 return -1; 15167 } 15168 return srec.launchedFromUid; 15169 } 15170 15171 public String getLaunchedFromPackage(IBinder activityToken) { 15172 ActivityRecord srec = ActivityRecord.forToken(activityToken); 15173 if (srec == null) { 15174 return null; 15175 } 15176 return srec.launchedFromPackage; 15177 } 15178 15179 // ========================================================= 15180 // LIFETIME MANAGEMENT 15181 // ========================================================= 15182 15183 // Returns which broadcast queue the app is the current [or imminent] receiver 15184 // on, or 'null' if the app is not an active broadcast recipient. 15185 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 15186 BroadcastRecord r = app.curReceiver; 15187 if (r != null) { 15188 return r.queue; 15189 } 15190 15191 // It's not the current receiver, but it might be starting up to become one 15192 synchronized (this) { 15193 for (BroadcastQueue queue : mBroadcastQueues) { 15194 r = queue.mPendingBroadcast; 15195 if (r != null && r.curApp == app) { 15196 // found it; report which queue it's in 15197 return queue; 15198 } 15199 } 15200 } 15201 15202 return null; 15203 } 15204 15205 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 15206 boolean doingAll, long now) { 15207 if (mAdjSeq == app.adjSeq) { 15208 // This adjustment has already been computed. 15209 return app.curRawAdj; 15210 } 15211 15212 if (app.thread == null) { 15213 app.adjSeq = mAdjSeq; 15214 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15215 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15216 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 15217 } 15218 15219 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 15220 app.adjSource = null; 15221 app.adjTarget = null; 15222 app.empty = false; 15223 app.cached = false; 15224 15225 final int activitiesSize = app.activities.size(); 15226 15227 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 15228 // The max adjustment doesn't allow this app to be anything 15229 // below foreground, so it is not worth doing work for it. 15230 app.adjType = "fixed"; 15231 app.adjSeq = mAdjSeq; 15232 app.curRawAdj = app.maxAdj; 15233 app.foregroundActivities = false; 15234 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 15235 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 15236 // System processes can do UI, and when they do we want to have 15237 // them trim their memory after the user leaves the UI. To 15238 // facilitate this, here we need to determine whether or not it 15239 // is currently showing UI. 15240 app.systemNoUi = true; 15241 if (app == TOP_APP) { 15242 app.systemNoUi = false; 15243 } else if (activitiesSize > 0) { 15244 for (int j = 0; j < activitiesSize; j++) { 15245 final ActivityRecord r = app.activities.get(j); 15246 if (r.visible) { 15247 app.systemNoUi = false; 15248 } 15249 } 15250 } 15251 if (!app.systemNoUi) { 15252 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 15253 } 15254 return (app.curAdj=app.maxAdj); 15255 } 15256 15257 app.systemNoUi = false; 15258 15259 // Determine the importance of the process, starting with most 15260 // important to least, and assign an appropriate OOM adjustment. 15261 int adj; 15262 int schedGroup; 15263 int procState; 15264 boolean foregroundActivities = false; 15265 BroadcastQueue queue; 15266 if (app == TOP_APP) { 15267 // The last app on the list is the foreground app. 15268 adj = ProcessList.FOREGROUND_APP_ADJ; 15269 schedGroup = Process.THREAD_GROUP_DEFAULT; 15270 app.adjType = "top-activity"; 15271 foregroundActivities = true; 15272 procState = ActivityManager.PROCESS_STATE_TOP; 15273 } else if (app.instrumentationClass != null) { 15274 // Don't want to kill running instrumentation. 15275 adj = ProcessList.FOREGROUND_APP_ADJ; 15276 schedGroup = Process.THREAD_GROUP_DEFAULT; 15277 app.adjType = "instrumentation"; 15278 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15279 } else if ((queue = isReceivingBroadcast(app)) != null) { 15280 // An app that is currently receiving a broadcast also 15281 // counts as being in the foreground for OOM killer purposes. 15282 // It's placed in a sched group based on the nature of the 15283 // broadcast as reflected by which queue it's active in. 15284 adj = ProcessList.FOREGROUND_APP_ADJ; 15285 schedGroup = (queue == mFgBroadcastQueue) 15286 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15287 app.adjType = "broadcast"; 15288 procState = ActivityManager.PROCESS_STATE_RECEIVER; 15289 } else if (app.executingServices.size() > 0) { 15290 // An app that is currently executing a service callback also 15291 // counts as being in the foreground. 15292 adj = ProcessList.FOREGROUND_APP_ADJ; 15293 schedGroup = app.execServicesFg ? 15294 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 15295 app.adjType = "exec-service"; 15296 procState = ActivityManager.PROCESS_STATE_SERVICE; 15297 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 15298 } else { 15299 // As far as we know the process is empty. We may change our mind later. 15300 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15301 // At this point we don't actually know the adjustment. Use the cached adj 15302 // value that the caller wants us to. 15303 adj = cachedAdj; 15304 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15305 app.cached = true; 15306 app.empty = true; 15307 app.adjType = "cch-empty"; 15308 } 15309 15310 // Examine all activities if not already foreground. 15311 if (!foregroundActivities && activitiesSize > 0) { 15312 for (int j = 0; j < activitiesSize; j++) { 15313 final ActivityRecord r = app.activities.get(j); 15314 if (r.app != app) { 15315 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 15316 + app + "?!?"); 15317 continue; 15318 } 15319 if (r.visible) { 15320 // App has a visible activity; only upgrade adjustment. 15321 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15322 adj = ProcessList.VISIBLE_APP_ADJ; 15323 app.adjType = "visible"; 15324 } 15325 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15326 procState = ActivityManager.PROCESS_STATE_TOP; 15327 } 15328 schedGroup = Process.THREAD_GROUP_DEFAULT; 15329 app.cached = false; 15330 app.empty = false; 15331 foregroundActivities = true; 15332 break; 15333 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 15334 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15335 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15336 app.adjType = "pausing"; 15337 } 15338 if (procState > ActivityManager.PROCESS_STATE_TOP) { 15339 procState = ActivityManager.PROCESS_STATE_TOP; 15340 } 15341 schedGroup = Process.THREAD_GROUP_DEFAULT; 15342 app.cached = false; 15343 app.empty = false; 15344 foregroundActivities = true; 15345 } else if (r.state == ActivityState.STOPPING) { 15346 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15347 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15348 app.adjType = "stopping"; 15349 } 15350 // For the process state, we will at this point consider the 15351 // process to be cached. It will be cached either as an activity 15352 // or empty depending on whether the activity is finishing. We do 15353 // this so that we can treat the process as cached for purposes of 15354 // memory trimming (determing current memory level, trim command to 15355 // send to process) since there can be an arbitrary number of stopping 15356 // processes and they should soon all go into the cached state. 15357 if (!r.finishing) { 15358 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15359 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15360 } 15361 } 15362 app.cached = false; 15363 app.empty = false; 15364 foregroundActivities = true; 15365 } else { 15366 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15367 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15368 app.adjType = "cch-act"; 15369 } 15370 } 15371 } 15372 } 15373 15374 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15375 if (app.foregroundServices) { 15376 // The user is aware of this app, so make it visible. 15377 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15378 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15379 app.cached = false; 15380 app.adjType = "fg-service"; 15381 schedGroup = Process.THREAD_GROUP_DEFAULT; 15382 } else if (app.forcingToForeground != null) { 15383 // The user is aware of this app, so make it visible. 15384 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15385 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15386 app.cached = false; 15387 app.adjType = "force-fg"; 15388 app.adjSource = app.forcingToForeground; 15389 schedGroup = Process.THREAD_GROUP_DEFAULT; 15390 } 15391 } 15392 15393 if (app == mHeavyWeightProcess) { 15394 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15395 // We don't want to kill the current heavy-weight process. 15396 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 15397 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15398 app.cached = false; 15399 app.adjType = "heavy"; 15400 } 15401 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15402 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 15403 } 15404 } 15405 15406 if (app == mHomeProcess) { 15407 if (adj > ProcessList.HOME_APP_ADJ) { 15408 // This process is hosting what we currently consider to be the 15409 // home app, so we don't want to let it go into the background. 15410 adj = ProcessList.HOME_APP_ADJ; 15411 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15412 app.cached = false; 15413 app.adjType = "home"; 15414 } 15415 if (procState > ActivityManager.PROCESS_STATE_HOME) { 15416 procState = ActivityManager.PROCESS_STATE_HOME; 15417 } 15418 } 15419 15420 if (app == mPreviousProcess && app.activities.size() > 0) { 15421 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 15422 // This was the previous process that showed UI to the user. 15423 // We want to try to keep it around more aggressively, to give 15424 // a good experience around switching between two apps. 15425 adj = ProcessList.PREVIOUS_APP_ADJ; 15426 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 15427 app.cached = false; 15428 app.adjType = "previous"; 15429 } 15430 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 15431 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 15432 } 15433 } 15434 15435 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 15436 + " reason=" + app.adjType); 15437 15438 // By default, we use the computed adjustment. It may be changed if 15439 // there are applications dependent on our services or providers, but 15440 // this gives us a baseline and makes sure we don't get into an 15441 // infinite recursion. 15442 app.adjSeq = mAdjSeq; 15443 app.curRawAdj = adj; 15444 app.hasStartedServices = false; 15445 15446 if (mBackupTarget != null && app == mBackupTarget.app) { 15447 // If possible we want to avoid killing apps while they're being backed up 15448 if (adj > ProcessList.BACKUP_APP_ADJ) { 15449 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 15450 adj = ProcessList.BACKUP_APP_ADJ; 15451 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15452 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15453 } 15454 app.adjType = "backup"; 15455 app.cached = false; 15456 } 15457 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 15458 procState = ActivityManager.PROCESS_STATE_BACKUP; 15459 } 15460 } 15461 15462 boolean mayBeTop = false; 15463 15464 for (int is = app.services.size()-1; 15465 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15466 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15467 || procState > ActivityManager.PROCESS_STATE_TOP); 15468 is--) { 15469 ServiceRecord s = app.services.valueAt(is); 15470 if (s.startRequested) { 15471 app.hasStartedServices = true; 15472 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 15473 procState = ActivityManager.PROCESS_STATE_SERVICE; 15474 } 15475 if (app.hasShownUi && app != mHomeProcess) { 15476 // If this process has shown some UI, let it immediately 15477 // go to the LRU list because it may be pretty heavy with 15478 // UI stuff. We'll tag it with a label just to help 15479 // debug and understand what is going on. 15480 if (adj > ProcessList.SERVICE_ADJ) { 15481 app.adjType = "cch-started-ui-services"; 15482 } 15483 } else { 15484 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15485 // This service has seen some activity within 15486 // recent memory, so we will keep its process ahead 15487 // of the background processes. 15488 if (adj > ProcessList.SERVICE_ADJ) { 15489 adj = ProcessList.SERVICE_ADJ; 15490 app.adjType = "started-services"; 15491 app.cached = false; 15492 } 15493 } 15494 // If we have let the service slide into the background 15495 // state, still have some text describing what it is doing 15496 // even though the service no longer has an impact. 15497 if (adj > ProcessList.SERVICE_ADJ) { 15498 app.adjType = "cch-started-services"; 15499 } 15500 } 15501 } 15502 for (int conni = s.connections.size()-1; 15503 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15504 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15505 || procState > ActivityManager.PROCESS_STATE_TOP); 15506 conni--) { 15507 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 15508 for (int i = 0; 15509 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 15510 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15511 || procState > ActivityManager.PROCESS_STATE_TOP); 15512 i++) { 15513 // XXX should compute this based on the max of 15514 // all connected clients. 15515 ConnectionRecord cr = clist.get(i); 15516 if (cr.binding.client == app) { 15517 // Binding to ourself is not interesting. 15518 continue; 15519 } 15520 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 15521 ProcessRecord client = cr.binding.client; 15522 int clientAdj = computeOomAdjLocked(client, cachedAdj, 15523 TOP_APP, doingAll, now); 15524 int clientProcState = client.curProcState; 15525 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15526 // If the other app is cached for any reason, for purposes here 15527 // we are going to consider it empty. The specific cached state 15528 // doesn't propagate except under certain conditions. 15529 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15530 } 15531 String adjType = null; 15532 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15533 // Not doing bind OOM management, so treat 15534 // this guy more like a started service. 15535 if (app.hasShownUi && app != mHomeProcess) { 15536 // If this process has shown some UI, let it immediately 15537 // go to the LRU list because it may be pretty heavy with 15538 // UI stuff. We'll tag it with a label just to help 15539 // debug and understand what is going on. 15540 if (adj > clientAdj) { 15541 adjType = "cch-bound-ui-services"; 15542 } 15543 app.cached = false; 15544 clientAdj = adj; 15545 clientProcState = procState; 15546 } else { 15547 if (now >= (s.lastActivity 15548 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15549 // This service has not seen activity within 15550 // recent memory, so allow it to drop to the 15551 // LRU list if there is no other reason to keep 15552 // it around. We'll also tag it with a label just 15553 // to help debug and undertand what is going on. 15554 if (adj > clientAdj) { 15555 adjType = "cch-bound-services"; 15556 } 15557 clientAdj = adj; 15558 } 15559 } 15560 } 15561 if (adj > clientAdj) { 15562 // If this process has recently shown UI, and 15563 // the process that is binding to it is less 15564 // important than being visible, then we don't 15565 // care about the binding as much as we care 15566 // about letting this process get into the LRU 15567 // list to be killed and restarted if needed for 15568 // memory. 15569 if (app.hasShownUi && app != mHomeProcess 15570 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15571 adjType = "cch-bound-ui-services"; 15572 } else { 15573 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15574 |Context.BIND_IMPORTANT)) != 0) { 15575 adj = clientAdj; 15576 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15577 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15578 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15579 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15580 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15581 adj = clientAdj; 15582 } else { 15583 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15584 adj = ProcessList.VISIBLE_APP_ADJ; 15585 } 15586 } 15587 if (!client.cached) { 15588 app.cached = false; 15589 } 15590 adjType = "service"; 15591 } 15592 } 15593 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15594 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15595 schedGroup = Process.THREAD_GROUP_DEFAULT; 15596 } 15597 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15598 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15599 // Special handling of clients who are in the top state. 15600 // We *may* want to consider this process to be in the 15601 // top state as well, but only if there is not another 15602 // reason for it to be running. Being on the top is a 15603 // special state, meaning you are specifically running 15604 // for the current top app. If the process is already 15605 // running in the background for some other reason, it 15606 // is more important to continue considering it to be 15607 // in the background state. 15608 mayBeTop = true; 15609 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15610 } else { 15611 // Special handling for above-top states (persistent 15612 // processes). These should not bring the current process 15613 // into the top state, since they are not on top. Instead 15614 // give them the best state after that. 15615 clientProcState = 15616 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15617 } 15618 } 15619 } else { 15620 if (clientProcState < 15621 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15622 clientProcState = 15623 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15624 } 15625 } 15626 if (procState > clientProcState) { 15627 procState = clientProcState; 15628 } 15629 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15630 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15631 app.pendingUiClean = true; 15632 } 15633 if (adjType != null) { 15634 app.adjType = adjType; 15635 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15636 .REASON_SERVICE_IN_USE; 15637 app.adjSource = cr.binding.client; 15638 app.adjSourceProcState = clientProcState; 15639 app.adjTarget = s.name; 15640 } 15641 } 15642 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15643 app.treatLikeActivity = true; 15644 } 15645 final ActivityRecord a = cr.activity; 15646 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15647 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15648 (a.visible || a.state == ActivityState.RESUMED 15649 || a.state == ActivityState.PAUSING)) { 15650 adj = ProcessList.FOREGROUND_APP_ADJ; 15651 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15652 schedGroup = Process.THREAD_GROUP_DEFAULT; 15653 } 15654 app.cached = false; 15655 app.adjType = "service"; 15656 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15657 .REASON_SERVICE_IN_USE; 15658 app.adjSource = a; 15659 app.adjSourceProcState = procState; 15660 app.adjTarget = s.name; 15661 } 15662 } 15663 } 15664 } 15665 } 15666 15667 for (int provi = app.pubProviders.size()-1; 15668 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15669 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15670 || procState > ActivityManager.PROCESS_STATE_TOP); 15671 provi--) { 15672 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15673 for (int i = cpr.connections.size()-1; 15674 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15675 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15676 || procState > ActivityManager.PROCESS_STATE_TOP); 15677 i--) { 15678 ContentProviderConnection conn = cpr.connections.get(i); 15679 ProcessRecord client = conn.client; 15680 if (client == app) { 15681 // Being our own client is not interesting. 15682 continue; 15683 } 15684 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15685 int clientProcState = client.curProcState; 15686 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15687 // If the other app is cached for any reason, for purposes here 15688 // we are going to consider it empty. 15689 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15690 } 15691 if (adj > clientAdj) { 15692 if (app.hasShownUi && app != mHomeProcess 15693 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15694 app.adjType = "cch-ui-provider"; 15695 } else { 15696 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15697 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15698 app.adjType = "provider"; 15699 } 15700 app.cached &= client.cached; 15701 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15702 .REASON_PROVIDER_IN_USE; 15703 app.adjSource = client; 15704 app.adjSourceProcState = clientProcState; 15705 app.adjTarget = cpr.name; 15706 } 15707 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15708 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15709 // Special handling of clients who are in the top state. 15710 // We *may* want to consider this process to be in the 15711 // top state as well, but only if there is not another 15712 // reason for it to be running. Being on the top is a 15713 // special state, meaning you are specifically running 15714 // for the current top app. If the process is already 15715 // running in the background for some other reason, it 15716 // is more important to continue considering it to be 15717 // in the background state. 15718 mayBeTop = true; 15719 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15720 } else { 15721 // Special handling for above-top states (persistent 15722 // processes). These should not bring the current process 15723 // into the top state, since they are not on top. Instead 15724 // give them the best state after that. 15725 clientProcState = 15726 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15727 } 15728 } 15729 if (procState > clientProcState) { 15730 procState = clientProcState; 15731 } 15732 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15733 schedGroup = Process.THREAD_GROUP_DEFAULT; 15734 } 15735 } 15736 // If the provider has external (non-framework) process 15737 // dependencies, ensure that its adjustment is at least 15738 // FOREGROUND_APP_ADJ. 15739 if (cpr.hasExternalProcessHandles()) { 15740 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15741 adj = ProcessList.FOREGROUND_APP_ADJ; 15742 schedGroup = Process.THREAD_GROUP_DEFAULT; 15743 app.cached = false; 15744 app.adjType = "provider"; 15745 app.adjTarget = cpr.name; 15746 } 15747 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15748 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15749 } 15750 } 15751 } 15752 15753 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15754 // A client of one of our services or providers is in the top state. We 15755 // *may* want to be in the top state, but not if we are already running in 15756 // the background for some other reason. For the decision here, we are going 15757 // to pick out a few specific states that we want to remain in when a client 15758 // is top (states that tend to be longer-term) and otherwise allow it to go 15759 // to the top state. 15760 switch (procState) { 15761 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15762 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15763 case ActivityManager.PROCESS_STATE_SERVICE: 15764 // These all are longer-term states, so pull them up to the top 15765 // of the background states, but not all the way to the top state. 15766 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15767 break; 15768 default: 15769 // Otherwise, top is a better choice, so take it. 15770 procState = ActivityManager.PROCESS_STATE_TOP; 15771 break; 15772 } 15773 } 15774 15775 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15776 if (app.hasClientActivities) { 15777 // This is a cached process, but with client activities. Mark it so. 15778 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15779 app.adjType = "cch-client-act"; 15780 } else if (app.treatLikeActivity) { 15781 // This is a cached process, but somebody wants us to treat it like it has 15782 // an activity, okay! 15783 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15784 app.adjType = "cch-as-act"; 15785 } 15786 } 15787 15788 if (adj == ProcessList.SERVICE_ADJ) { 15789 if (doingAll) { 15790 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15791 mNewNumServiceProcs++; 15792 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15793 if (!app.serviceb) { 15794 // This service isn't far enough down on the LRU list to 15795 // normally be a B service, but if we are low on RAM and it 15796 // is large we want to force it down since we would prefer to 15797 // keep launcher over it. 15798 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15799 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15800 app.serviceHighRam = true; 15801 app.serviceb = true; 15802 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15803 } else { 15804 mNewNumAServiceProcs++; 15805 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15806 } 15807 } else { 15808 app.serviceHighRam = false; 15809 } 15810 } 15811 if (app.serviceb) { 15812 adj = ProcessList.SERVICE_B_ADJ; 15813 } 15814 } 15815 15816 app.curRawAdj = adj; 15817 15818 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15819 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15820 if (adj > app.maxAdj) { 15821 adj = app.maxAdj; 15822 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15823 schedGroup = Process.THREAD_GROUP_DEFAULT; 15824 } 15825 } 15826 15827 // Do final modification to adj. Everything we do between here and applying 15828 // the final setAdj must be done in this function, because we will also use 15829 // it when computing the final cached adj later. Note that we don't need to 15830 // worry about this for max adj above, since max adj will always be used to 15831 // keep it out of the cached vaues. 15832 app.curAdj = app.modifyRawOomAdj(adj); 15833 app.curSchedGroup = schedGroup; 15834 app.curProcState = procState; 15835 app.foregroundActivities = foregroundActivities; 15836 15837 return app.curRawAdj; 15838 } 15839 15840 /** 15841 * Schedule PSS collection of a process. 15842 */ 15843 void requestPssLocked(ProcessRecord proc, int procState) { 15844 if (mPendingPssProcesses.contains(proc)) { 15845 return; 15846 } 15847 if (mPendingPssProcesses.size() == 0) { 15848 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15849 } 15850 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15851 proc.pssProcState = procState; 15852 mPendingPssProcesses.add(proc); 15853 } 15854 15855 /** 15856 * Schedule PSS collection of all processes. 15857 */ 15858 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15859 if (!always) { 15860 if (now < (mLastFullPssTime + 15861 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15862 return; 15863 } 15864 } 15865 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15866 mLastFullPssTime = now; 15867 mFullPssPending = true; 15868 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15869 mPendingPssProcesses.clear(); 15870 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15871 ProcessRecord app = mLruProcesses.get(i); 15872 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15873 app.pssProcState = app.setProcState; 15874 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15875 isSleeping(), now); 15876 mPendingPssProcesses.add(app); 15877 } 15878 } 15879 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15880 } 15881 15882 /** 15883 * Ask a given process to GC right now. 15884 */ 15885 final void performAppGcLocked(ProcessRecord app) { 15886 try { 15887 app.lastRequestedGc = SystemClock.uptimeMillis(); 15888 if (app.thread != null) { 15889 if (app.reportLowMemory) { 15890 app.reportLowMemory = false; 15891 app.thread.scheduleLowMemory(); 15892 } else { 15893 app.thread.processInBackground(); 15894 } 15895 } 15896 } catch (Exception e) { 15897 // whatever. 15898 } 15899 } 15900 15901 /** 15902 * Returns true if things are idle enough to perform GCs. 15903 */ 15904 private final boolean canGcNowLocked() { 15905 boolean processingBroadcasts = false; 15906 for (BroadcastQueue q : mBroadcastQueues) { 15907 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15908 processingBroadcasts = true; 15909 } 15910 } 15911 return !processingBroadcasts 15912 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15913 } 15914 15915 /** 15916 * Perform GCs on all processes that are waiting for it, but only 15917 * if things are idle. 15918 */ 15919 final void performAppGcsLocked() { 15920 final int N = mProcessesToGc.size(); 15921 if (N <= 0) { 15922 return; 15923 } 15924 if (canGcNowLocked()) { 15925 while (mProcessesToGc.size() > 0) { 15926 ProcessRecord proc = mProcessesToGc.remove(0); 15927 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15928 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15929 <= SystemClock.uptimeMillis()) { 15930 // To avoid spamming the system, we will GC processes one 15931 // at a time, waiting a few seconds between each. 15932 performAppGcLocked(proc); 15933 scheduleAppGcsLocked(); 15934 return; 15935 } else { 15936 // It hasn't been long enough since we last GCed this 15937 // process... put it in the list to wait for its time. 15938 addProcessToGcListLocked(proc); 15939 break; 15940 } 15941 } 15942 } 15943 15944 scheduleAppGcsLocked(); 15945 } 15946 } 15947 15948 /** 15949 * If all looks good, perform GCs on all processes waiting for them. 15950 */ 15951 final void performAppGcsIfAppropriateLocked() { 15952 if (canGcNowLocked()) { 15953 performAppGcsLocked(); 15954 return; 15955 } 15956 // Still not idle, wait some more. 15957 scheduleAppGcsLocked(); 15958 } 15959 15960 /** 15961 * Schedule the execution of all pending app GCs. 15962 */ 15963 final void scheduleAppGcsLocked() { 15964 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15965 15966 if (mProcessesToGc.size() > 0) { 15967 // Schedule a GC for the time to the next process. 15968 ProcessRecord proc = mProcessesToGc.get(0); 15969 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15970 15971 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15972 long now = SystemClock.uptimeMillis(); 15973 if (when < (now+GC_TIMEOUT)) { 15974 when = now + GC_TIMEOUT; 15975 } 15976 mHandler.sendMessageAtTime(msg, when); 15977 } 15978 } 15979 15980 /** 15981 * Add a process to the array of processes waiting to be GCed. Keeps the 15982 * list in sorted order by the last GC time. The process can't already be 15983 * on the list. 15984 */ 15985 final void addProcessToGcListLocked(ProcessRecord proc) { 15986 boolean added = false; 15987 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15988 if (mProcessesToGc.get(i).lastRequestedGc < 15989 proc.lastRequestedGc) { 15990 added = true; 15991 mProcessesToGc.add(i+1, proc); 15992 break; 15993 } 15994 } 15995 if (!added) { 15996 mProcessesToGc.add(0, proc); 15997 } 15998 } 15999 16000 /** 16001 * Set up to ask a process to GC itself. This will either do it 16002 * immediately, or put it on the list of processes to gc the next 16003 * time things are idle. 16004 */ 16005 final void scheduleAppGcLocked(ProcessRecord app) { 16006 long now = SystemClock.uptimeMillis(); 16007 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 16008 return; 16009 } 16010 if (!mProcessesToGc.contains(app)) { 16011 addProcessToGcListLocked(app); 16012 scheduleAppGcsLocked(); 16013 } 16014 } 16015 16016 final void checkExcessivePowerUsageLocked(boolean doKills) { 16017 updateCpuStatsNow(); 16018 16019 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16020 boolean doWakeKills = doKills; 16021 boolean doCpuKills = doKills; 16022 if (mLastPowerCheckRealtime == 0) { 16023 doWakeKills = false; 16024 } 16025 if (mLastPowerCheckUptime == 0) { 16026 doCpuKills = false; 16027 } 16028 if (stats.isScreenOn()) { 16029 doWakeKills = false; 16030 } 16031 final long curRealtime = SystemClock.elapsedRealtime(); 16032 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 16033 final long curUptime = SystemClock.uptimeMillis(); 16034 final long uptimeSince = curUptime - mLastPowerCheckUptime; 16035 mLastPowerCheckRealtime = curRealtime; 16036 mLastPowerCheckUptime = curUptime; 16037 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 16038 doWakeKills = false; 16039 } 16040 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 16041 doCpuKills = false; 16042 } 16043 int i = mLruProcesses.size(); 16044 while (i > 0) { 16045 i--; 16046 ProcessRecord app = mLruProcesses.get(i); 16047 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16048 long wtime; 16049 synchronized (stats) { 16050 wtime = stats.getProcessWakeTime(app.info.uid, 16051 app.pid, curRealtime); 16052 } 16053 long wtimeUsed = wtime - app.lastWakeTime; 16054 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 16055 if (DEBUG_POWER) { 16056 StringBuilder sb = new StringBuilder(128); 16057 sb.append("Wake for "); 16058 app.toShortString(sb); 16059 sb.append(": over "); 16060 TimeUtils.formatDuration(realtimeSince, sb); 16061 sb.append(" used "); 16062 TimeUtils.formatDuration(wtimeUsed, sb); 16063 sb.append(" ("); 16064 sb.append((wtimeUsed*100)/realtimeSince); 16065 sb.append("%)"); 16066 Slog.i(TAG, sb.toString()); 16067 sb.setLength(0); 16068 sb.append("CPU for "); 16069 app.toShortString(sb); 16070 sb.append(": over "); 16071 TimeUtils.formatDuration(uptimeSince, sb); 16072 sb.append(" used "); 16073 TimeUtils.formatDuration(cputimeUsed, sb); 16074 sb.append(" ("); 16075 sb.append((cputimeUsed*100)/uptimeSince); 16076 sb.append("%)"); 16077 Slog.i(TAG, sb.toString()); 16078 } 16079 // If a process has held a wake lock for more 16080 // than 50% of the time during this period, 16081 // that sounds bad. Kill! 16082 if (doWakeKills && realtimeSince > 0 16083 && ((wtimeUsed*100)/realtimeSince) >= 50) { 16084 synchronized (stats) { 16085 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 16086 realtimeSince, wtimeUsed); 16087 } 16088 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 16089 + " during " + realtimeSince); 16090 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 16091 } else if (doCpuKills && uptimeSince > 0 16092 && ((cputimeUsed*100)/uptimeSince) >= 25) { 16093 synchronized (stats) { 16094 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 16095 uptimeSince, cputimeUsed); 16096 } 16097 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 16098 + " during " + uptimeSince); 16099 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 16100 } else { 16101 app.lastWakeTime = wtime; 16102 app.lastCpuTime = app.curCpuTime; 16103 } 16104 } 16105 } 16106 } 16107 16108 private final boolean applyOomAdjLocked(ProcessRecord app, 16109 ProcessRecord TOP_APP, boolean doingAll, long now) { 16110 boolean success = true; 16111 16112 if (app.curRawAdj != app.setRawAdj) { 16113 app.setRawAdj = app.curRawAdj; 16114 } 16115 16116 int changes = 0; 16117 16118 if (app.curAdj != app.setAdj) { 16119 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj); 16120 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 16121 TAG, "Set " + app.pid + " " + app.processName + 16122 " adj " + app.curAdj + ": " + app.adjType); 16123 app.setAdj = app.curAdj; 16124 } 16125 16126 if (app.setSchedGroup != app.curSchedGroup) { 16127 app.setSchedGroup = app.curSchedGroup; 16128 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16129 "Setting process group of " + app.processName 16130 + " to " + app.curSchedGroup); 16131 if (app.waitingToKill != null && 16132 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 16133 killUnneededProcessLocked(app, app.waitingToKill); 16134 success = false; 16135 } else { 16136 if (true) { 16137 long oldId = Binder.clearCallingIdentity(); 16138 try { 16139 Process.setProcessGroup(app.pid, app.curSchedGroup); 16140 } catch (Exception e) { 16141 Slog.w(TAG, "Failed setting process group of " + app.pid 16142 + " to " + app.curSchedGroup); 16143 e.printStackTrace(); 16144 } finally { 16145 Binder.restoreCallingIdentity(oldId); 16146 } 16147 } else { 16148 if (app.thread != null) { 16149 try { 16150 app.thread.setSchedulingGroup(app.curSchedGroup); 16151 } catch (RemoteException e) { 16152 } 16153 } 16154 } 16155 Process.setSwappiness(app.pid, 16156 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 16157 } 16158 } 16159 if (app.repForegroundActivities != app.foregroundActivities) { 16160 app.repForegroundActivities = app.foregroundActivities; 16161 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 16162 } 16163 if (app.repProcState != app.curProcState) { 16164 app.repProcState = app.curProcState; 16165 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 16166 if (app.thread != null) { 16167 try { 16168 if (false) { 16169 //RuntimeException h = new RuntimeException("here"); 16170 Slog.i(TAG, "Sending new process state " + app.repProcState 16171 + " to " + app /*, h*/); 16172 } 16173 app.thread.setProcessState(app.repProcState); 16174 } catch (RemoteException e) { 16175 } 16176 } 16177 } 16178 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 16179 app.setProcState)) { 16180 app.lastStateTime = now; 16181 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 16182 isSleeping(), now); 16183 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 16184 + ProcessList.makeProcStateString(app.setProcState) + " to " 16185 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 16186 + (app.nextPssTime-now) + ": " + app); 16187 } else { 16188 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 16189 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 16190 requestPssLocked(app, app.setProcState); 16191 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 16192 isSleeping(), now); 16193 } else if (false && DEBUG_PSS) { 16194 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 16195 } 16196 } 16197 if (app.setProcState != app.curProcState) { 16198 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16199 "Proc state change of " + app.processName 16200 + " to " + app.curProcState); 16201 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE; 16202 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE; 16203 if (setImportant && !curImportant) { 16204 // This app is no longer something we consider important enough to allow to 16205 // use arbitrary amounts of battery power. Note 16206 // its current wake lock time to later know to kill it if 16207 // it is not behaving well. 16208 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 16209 synchronized (stats) { 16210 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 16211 app.pid, SystemClock.elapsedRealtime()); 16212 } 16213 app.lastCpuTime = app.curCpuTime; 16214 16215 } 16216 app.setProcState = app.curProcState; 16217 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 16218 app.notCachedSinceIdle = false; 16219 } 16220 if (!doingAll) { 16221 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now); 16222 } else { 16223 app.procStateChanged = true; 16224 } 16225 } 16226 16227 if (changes != 0) { 16228 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 16229 int i = mPendingProcessChanges.size()-1; 16230 ProcessChangeItem item = null; 16231 while (i >= 0) { 16232 item = mPendingProcessChanges.get(i); 16233 if (item.pid == app.pid) { 16234 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 16235 break; 16236 } 16237 i--; 16238 } 16239 if (i < 0) { 16240 // No existing item in pending changes; need a new one. 16241 final int NA = mAvailProcessChanges.size(); 16242 if (NA > 0) { 16243 item = mAvailProcessChanges.remove(NA-1); 16244 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 16245 } else { 16246 item = new ProcessChangeItem(); 16247 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 16248 } 16249 item.changes = 0; 16250 item.pid = app.pid; 16251 item.uid = app.info.uid; 16252 if (mPendingProcessChanges.size() == 0) { 16253 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 16254 "*** Enqueueing dispatch processes changed!"); 16255 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 16256 } 16257 mPendingProcessChanges.add(item); 16258 } 16259 item.changes |= changes; 16260 item.processState = app.repProcState; 16261 item.foregroundActivities = app.repForegroundActivities; 16262 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 16263 + Integer.toHexString(System.identityHashCode(item)) 16264 + " " + app.toShortString() + ": changes=" + item.changes 16265 + " procState=" + item.processState 16266 + " foreground=" + item.foregroundActivities 16267 + " type=" + app.adjType + " source=" + app.adjSource 16268 + " target=" + app.adjTarget); 16269 } 16270 16271 return success; 16272 } 16273 16274 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { 16275 if (proc.thread != null) { 16276 if (proc.baseProcessTracker != null) { 16277 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 16278 } 16279 if (proc.repProcState >= 0) { 16280 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid, 16281 proc.repProcState); 16282 } 16283 } 16284 } 16285 16286 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 16287 ProcessRecord TOP_APP, boolean doingAll, long now) { 16288 if (app.thread == null) { 16289 return false; 16290 } 16291 16292 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 16293 16294 return applyOomAdjLocked(app, TOP_APP, doingAll, now); 16295 } 16296 16297 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 16298 boolean oomAdj) { 16299 if (isForeground != proc.foregroundServices) { 16300 proc.foregroundServices = isForeground; 16301 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 16302 proc.info.uid); 16303 if (isForeground) { 16304 if (curProcs == null) { 16305 curProcs = new ArrayList<ProcessRecord>(); 16306 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 16307 } 16308 if (!curProcs.contains(proc)) { 16309 curProcs.add(proc); 16310 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 16311 proc.info.packageName, proc.info.uid); 16312 } 16313 } else { 16314 if (curProcs != null) { 16315 if (curProcs.remove(proc)) { 16316 mBatteryStatsService.noteEvent( 16317 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 16318 proc.info.packageName, proc.info.uid); 16319 if (curProcs.size() <= 0) { 16320 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 16321 } 16322 } 16323 } 16324 } 16325 if (oomAdj) { 16326 updateOomAdjLocked(); 16327 } 16328 } 16329 } 16330 16331 private final ActivityRecord resumedAppLocked() { 16332 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 16333 String pkg; 16334 int uid; 16335 if (act != null) { 16336 pkg = act.packageName; 16337 uid = act.info.applicationInfo.uid; 16338 } else { 16339 pkg = null; 16340 uid = -1; 16341 } 16342 // Has the UID or resumed package name changed? 16343 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 16344 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 16345 if (mCurResumedPackage != null) { 16346 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 16347 mCurResumedPackage, mCurResumedUid); 16348 } 16349 mCurResumedPackage = pkg; 16350 mCurResumedUid = uid; 16351 if (mCurResumedPackage != null) { 16352 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 16353 mCurResumedPackage, mCurResumedUid); 16354 } 16355 } 16356 return act; 16357 } 16358 16359 final boolean updateOomAdjLocked(ProcessRecord app) { 16360 final ActivityRecord TOP_ACT = resumedAppLocked(); 16361 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16362 final boolean wasCached = app.cached; 16363 16364 mAdjSeq++; 16365 16366 // This is the desired cached adjusment we want to tell it to use. 16367 // If our app is currently cached, we know it, and that is it. Otherwise, 16368 // we don't know it yet, and it needs to now be cached we will then 16369 // need to do a complete oom adj. 16370 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 16371 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 16372 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 16373 SystemClock.uptimeMillis()); 16374 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 16375 // Changed to/from cached state, so apps after it in the LRU 16376 // list may also be changed. 16377 updateOomAdjLocked(); 16378 } 16379 return success; 16380 } 16381 16382 final void updateOomAdjLocked() { 16383 final ActivityRecord TOP_ACT = resumedAppLocked(); 16384 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 16385 final long now = SystemClock.uptimeMillis(); 16386 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 16387 final int N = mLruProcesses.size(); 16388 16389 if (false) { 16390 RuntimeException e = new RuntimeException(); 16391 e.fillInStackTrace(); 16392 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 16393 } 16394 16395 mAdjSeq++; 16396 mNewNumServiceProcs = 0; 16397 mNewNumAServiceProcs = 0; 16398 16399 final int emptyProcessLimit; 16400 final int cachedProcessLimit; 16401 if (mProcessLimit <= 0) { 16402 emptyProcessLimit = cachedProcessLimit = 0; 16403 } else if (mProcessLimit == 1) { 16404 emptyProcessLimit = 1; 16405 cachedProcessLimit = 0; 16406 } else { 16407 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 16408 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 16409 } 16410 16411 // Let's determine how many processes we have running vs. 16412 // how many slots we have for background processes; we may want 16413 // to put multiple processes in a slot of there are enough of 16414 // them. 16415 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 16416 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 16417 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 16418 if (numEmptyProcs > cachedProcessLimit) { 16419 // If there are more empty processes than our limit on cached 16420 // processes, then use the cached process limit for the factor. 16421 // This ensures that the really old empty processes get pushed 16422 // down to the bottom, so if we are running low on memory we will 16423 // have a better chance at keeping around more cached processes 16424 // instead of a gazillion empty processes. 16425 numEmptyProcs = cachedProcessLimit; 16426 } 16427 int emptyFactor = numEmptyProcs/numSlots; 16428 if (emptyFactor < 1) emptyFactor = 1; 16429 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 16430 if (cachedFactor < 1) cachedFactor = 1; 16431 int stepCached = 0; 16432 int stepEmpty = 0; 16433 int numCached = 0; 16434 int numEmpty = 0; 16435 int numTrimming = 0; 16436 16437 mNumNonCachedProcs = 0; 16438 mNumCachedHiddenProcs = 0; 16439 16440 // First update the OOM adjustment for each of the 16441 // application processes based on their current state. 16442 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 16443 int nextCachedAdj = curCachedAdj+1; 16444 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 16445 int nextEmptyAdj = curEmptyAdj+2; 16446 for (int i=N-1; i>=0; i--) { 16447 ProcessRecord app = mLruProcesses.get(i); 16448 if (!app.killedByAm && app.thread != null) { 16449 app.procStateChanged = false; 16450 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 16451 16452 // If we haven't yet assigned the final cached adj 16453 // to the process, do that now. 16454 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 16455 switch (app.curProcState) { 16456 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16457 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16458 // This process is a cached process holding activities... 16459 // assign it the next cached value for that type, and then 16460 // step that cached level. 16461 app.curRawAdj = curCachedAdj; 16462 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 16463 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 16464 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 16465 + ")"); 16466 if (curCachedAdj != nextCachedAdj) { 16467 stepCached++; 16468 if (stepCached >= cachedFactor) { 16469 stepCached = 0; 16470 curCachedAdj = nextCachedAdj; 16471 nextCachedAdj += 2; 16472 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16473 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 16474 } 16475 } 16476 } 16477 break; 16478 default: 16479 // For everything else, assign next empty cached process 16480 // level and bump that up. Note that this means that 16481 // long-running services that have dropped down to the 16482 // cached level will be treated as empty (since their process 16483 // state is still as a service), which is what we want. 16484 app.curRawAdj = curEmptyAdj; 16485 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 16486 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 16487 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 16488 + ")"); 16489 if (curEmptyAdj != nextEmptyAdj) { 16490 stepEmpty++; 16491 if (stepEmpty >= emptyFactor) { 16492 stepEmpty = 0; 16493 curEmptyAdj = nextEmptyAdj; 16494 nextEmptyAdj += 2; 16495 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 16496 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 16497 } 16498 } 16499 } 16500 break; 16501 } 16502 } 16503 16504 applyOomAdjLocked(app, TOP_APP, true, now); 16505 16506 // Count the number of process types. 16507 switch (app.curProcState) { 16508 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 16509 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 16510 mNumCachedHiddenProcs++; 16511 numCached++; 16512 if (numCached > cachedProcessLimit) { 16513 killUnneededProcessLocked(app, "cached #" + numCached); 16514 } 16515 break; 16516 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 16517 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 16518 && app.lastActivityTime < oldTime) { 16519 killUnneededProcessLocked(app, "empty for " 16520 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 16521 / 1000) + "s"); 16522 } else { 16523 numEmpty++; 16524 if (numEmpty > emptyProcessLimit) { 16525 killUnneededProcessLocked(app, "empty #" + numEmpty); 16526 } 16527 } 16528 break; 16529 default: 16530 mNumNonCachedProcs++; 16531 break; 16532 } 16533 16534 if (app.isolated && app.services.size() <= 0) { 16535 // If this is an isolated process, and there are no 16536 // services running in it, then the process is no longer 16537 // needed. We agressively kill these because we can by 16538 // definition not re-use the same process again, and it is 16539 // good to avoid having whatever code was running in them 16540 // left sitting around after no longer needed. 16541 killUnneededProcessLocked(app, "isolated not needed"); 16542 } 16543 16544 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16545 && !app.killedByAm) { 16546 numTrimming++; 16547 } 16548 } 16549 } 16550 16551 mNumServiceProcs = mNewNumServiceProcs; 16552 16553 // Now determine the memory trimming level of background processes. 16554 // Unfortunately we need to start at the back of the list to do this 16555 // properly. We only do this if the number of background apps we 16556 // are managing to keep around is less than half the maximum we desire; 16557 // if we are keeping a good number around, we'll let them use whatever 16558 // memory they want. 16559 final int numCachedAndEmpty = numCached + numEmpty; 16560 int memFactor; 16561 if (numCached <= ProcessList.TRIM_CACHED_APPS 16562 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16563 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16564 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16565 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16566 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16567 } else { 16568 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16569 } 16570 } else { 16571 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16572 } 16573 // We always allow the memory level to go up (better). We only allow it to go 16574 // down if we are in a state where that is allowed, *and* the total number of processes 16575 // has gone down since last time. 16576 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16577 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16578 + " last=" + mLastNumProcesses); 16579 if (memFactor > mLastMemoryLevel) { 16580 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16581 memFactor = mLastMemoryLevel; 16582 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16583 } 16584 } 16585 mLastMemoryLevel = memFactor; 16586 mLastNumProcesses = mLruProcesses.size(); 16587 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16588 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16589 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16590 if (mLowRamStartTime == 0) { 16591 mLowRamStartTime = now; 16592 } 16593 int step = 0; 16594 int fgTrimLevel; 16595 switch (memFactor) { 16596 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16597 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16598 break; 16599 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16600 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16601 break; 16602 default: 16603 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16604 break; 16605 } 16606 int factor = numTrimming/3; 16607 int minFactor = 2; 16608 if (mHomeProcess != null) minFactor++; 16609 if (mPreviousProcess != null) minFactor++; 16610 if (factor < minFactor) factor = minFactor; 16611 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16612 for (int i=N-1; i>=0; i--) { 16613 ProcessRecord app = mLruProcesses.get(i); 16614 if (allChanged || app.procStateChanged) { 16615 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16616 app.procStateChanged = false; 16617 } 16618 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16619 && !app.killedByAm) { 16620 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16621 try { 16622 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16623 "Trimming memory of " + app.processName 16624 + " to " + curLevel); 16625 app.thread.scheduleTrimMemory(curLevel); 16626 } catch (RemoteException e) { 16627 } 16628 if (false) { 16629 // For now we won't do this; our memory trimming seems 16630 // to be good enough at this point that destroying 16631 // activities causes more harm than good. 16632 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16633 && app != mHomeProcess && app != mPreviousProcess) { 16634 // Need to do this on its own message because the stack may not 16635 // be in a consistent state at this point. 16636 // For these apps we will also finish their activities 16637 // to help them free memory. 16638 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16639 } 16640 } 16641 } 16642 app.trimMemoryLevel = curLevel; 16643 step++; 16644 if (step >= factor) { 16645 step = 0; 16646 switch (curLevel) { 16647 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16648 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16649 break; 16650 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16651 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16652 break; 16653 } 16654 } 16655 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16656 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16657 && app.thread != null) { 16658 try { 16659 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16660 "Trimming memory of heavy-weight " + app.processName 16661 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16662 app.thread.scheduleTrimMemory( 16663 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16664 } catch (RemoteException e) { 16665 } 16666 } 16667 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16668 } else { 16669 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16670 || app.systemNoUi) && app.pendingUiClean) { 16671 // If this application is now in the background and it 16672 // had done UI, then give it the special trim level to 16673 // have it free UI resources. 16674 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16675 if (app.trimMemoryLevel < level && app.thread != null) { 16676 try { 16677 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16678 "Trimming memory of bg-ui " + app.processName 16679 + " to " + level); 16680 app.thread.scheduleTrimMemory(level); 16681 } catch (RemoteException e) { 16682 } 16683 } 16684 app.pendingUiClean = false; 16685 } 16686 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16687 try { 16688 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16689 "Trimming memory of fg " + app.processName 16690 + " to " + fgTrimLevel); 16691 app.thread.scheduleTrimMemory(fgTrimLevel); 16692 } catch (RemoteException e) { 16693 } 16694 } 16695 app.trimMemoryLevel = fgTrimLevel; 16696 } 16697 } 16698 } else { 16699 if (mLowRamStartTime != 0) { 16700 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16701 mLowRamStartTime = 0; 16702 } 16703 for (int i=N-1; i>=0; i--) { 16704 ProcessRecord app = mLruProcesses.get(i); 16705 if (allChanged || app.procStateChanged) { 16706 setProcessTrackerStateLocked(app, trackerMemFactor, now); 16707 app.procStateChanged = false; 16708 } 16709 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16710 || app.systemNoUi) && app.pendingUiClean) { 16711 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16712 && app.thread != null) { 16713 try { 16714 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16715 "Trimming memory of ui hidden " + app.processName 16716 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16717 app.thread.scheduleTrimMemory( 16718 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16719 } catch (RemoteException e) { 16720 } 16721 } 16722 app.pendingUiClean = false; 16723 } 16724 app.trimMemoryLevel = 0; 16725 } 16726 } 16727 16728 if (mAlwaysFinishActivities) { 16729 // Need to do this on its own message because the stack may not 16730 // be in a consistent state at this point. 16731 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16732 } 16733 16734 if (allChanged) { 16735 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16736 } 16737 16738 if (mProcessStats.shouldWriteNowLocked(now)) { 16739 mHandler.post(new Runnable() { 16740 @Override public void run() { 16741 synchronized (ActivityManagerService.this) { 16742 mProcessStats.writeStateAsyncLocked(); 16743 } 16744 } 16745 }); 16746 } 16747 16748 if (DEBUG_OOM_ADJ) { 16749 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16750 } 16751 } 16752 16753 final void trimApplications() { 16754 synchronized (this) { 16755 int i; 16756 16757 // First remove any unused application processes whose package 16758 // has been removed. 16759 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16760 final ProcessRecord app = mRemovedProcesses.get(i); 16761 if (app.activities.size() == 0 16762 && app.curReceiver == null && app.services.size() == 0) { 16763 Slog.i( 16764 TAG, "Exiting empty application process " 16765 + app.processName + " (" 16766 + (app.thread != null ? app.thread.asBinder() : null) 16767 + ")\n"); 16768 if (app.pid > 0 && app.pid != MY_PID) { 16769 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16770 app.processName, app.setAdj, "empty"); 16771 app.killedByAm = true; 16772 Process.killProcessQuiet(app.pid); 16773 Process.killProcessGroup(app.info.uid, app.pid); 16774 } else { 16775 try { 16776 app.thread.scheduleExit(); 16777 } catch (Exception e) { 16778 // Ignore exceptions. 16779 } 16780 } 16781 cleanUpApplicationRecordLocked(app, false, true, -1); 16782 mRemovedProcesses.remove(i); 16783 16784 if (app.persistent) { 16785 addAppLocked(app.info, false, null /* ABI override */); 16786 } 16787 } 16788 } 16789 16790 // Now update the oom adj for all processes. 16791 updateOomAdjLocked(); 16792 } 16793 } 16794 16795 /** This method sends the specified signal to each of the persistent apps */ 16796 public void signalPersistentProcesses(int sig) throws RemoteException { 16797 if (sig != Process.SIGNAL_USR1) { 16798 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16799 } 16800 16801 synchronized (this) { 16802 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16803 != PackageManager.PERMISSION_GRANTED) { 16804 throw new SecurityException("Requires permission " 16805 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16806 } 16807 16808 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16809 ProcessRecord r = mLruProcesses.get(i); 16810 if (r.thread != null && r.persistent) { 16811 Process.sendSignal(r.pid, sig); 16812 } 16813 } 16814 } 16815 } 16816 16817 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16818 if (proc == null || proc == mProfileProc) { 16819 proc = mProfileProc; 16820 path = mProfileFile; 16821 profileType = mProfileType; 16822 clearProfilerLocked(); 16823 } 16824 if (proc == null) { 16825 return; 16826 } 16827 try { 16828 proc.thread.profilerControl(false, path, null, profileType); 16829 } catch (RemoteException e) { 16830 throw new IllegalStateException("Process disappeared"); 16831 } 16832 } 16833 16834 private void clearProfilerLocked() { 16835 if (mProfileFd != null) { 16836 try { 16837 mProfileFd.close(); 16838 } catch (IOException e) { 16839 } 16840 } 16841 mProfileApp = null; 16842 mProfileProc = null; 16843 mProfileFile = null; 16844 mProfileType = 0; 16845 mAutoStopProfiler = false; 16846 } 16847 16848 public boolean profileControl(String process, int userId, boolean start, 16849 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16850 16851 try { 16852 synchronized (this) { 16853 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16854 // its own permission. 16855 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16856 != PackageManager.PERMISSION_GRANTED) { 16857 throw new SecurityException("Requires permission " 16858 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16859 } 16860 16861 if (start && fd == null) { 16862 throw new IllegalArgumentException("null fd"); 16863 } 16864 16865 ProcessRecord proc = null; 16866 if (process != null) { 16867 proc = findProcessLocked(process, userId, "profileControl"); 16868 } 16869 16870 if (start && (proc == null || proc.thread == null)) { 16871 throw new IllegalArgumentException("Unknown process: " + process); 16872 } 16873 16874 if (start) { 16875 stopProfilerLocked(null, null, 0); 16876 setProfileApp(proc.info, proc.processName, path, fd, false); 16877 mProfileProc = proc; 16878 mProfileType = profileType; 16879 try { 16880 fd = fd.dup(); 16881 } catch (IOException e) { 16882 fd = null; 16883 } 16884 proc.thread.profilerControl(start, path, fd, profileType); 16885 fd = null; 16886 mProfileFd = null; 16887 } else { 16888 stopProfilerLocked(proc, path, profileType); 16889 if (fd != null) { 16890 try { 16891 fd.close(); 16892 } catch (IOException e) { 16893 } 16894 } 16895 } 16896 16897 return true; 16898 } 16899 } catch (RemoteException e) { 16900 throw new IllegalStateException("Process disappeared"); 16901 } finally { 16902 if (fd != null) { 16903 try { 16904 fd.close(); 16905 } catch (IOException e) { 16906 } 16907 } 16908 } 16909 } 16910 16911 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16912 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16913 userId, true, ALLOW_FULL_ONLY, callName, null); 16914 ProcessRecord proc = null; 16915 try { 16916 int pid = Integer.parseInt(process); 16917 synchronized (mPidsSelfLocked) { 16918 proc = mPidsSelfLocked.get(pid); 16919 } 16920 } catch (NumberFormatException e) { 16921 } 16922 16923 if (proc == null) { 16924 ArrayMap<String, SparseArray<ProcessRecord>> all 16925 = mProcessNames.getMap(); 16926 SparseArray<ProcessRecord> procs = all.get(process); 16927 if (procs != null && procs.size() > 0) { 16928 proc = procs.valueAt(0); 16929 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16930 for (int i=1; i<procs.size(); i++) { 16931 ProcessRecord thisProc = procs.valueAt(i); 16932 if (thisProc.userId == userId) { 16933 proc = thisProc; 16934 break; 16935 } 16936 } 16937 } 16938 } 16939 } 16940 16941 return proc; 16942 } 16943 16944 public boolean dumpHeap(String process, int userId, boolean managed, 16945 String path, ParcelFileDescriptor fd) throws RemoteException { 16946 16947 try { 16948 synchronized (this) { 16949 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16950 // its own permission (same as profileControl). 16951 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16952 != PackageManager.PERMISSION_GRANTED) { 16953 throw new SecurityException("Requires permission " 16954 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16955 } 16956 16957 if (fd == null) { 16958 throw new IllegalArgumentException("null fd"); 16959 } 16960 16961 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16962 if (proc == null || proc.thread == null) { 16963 throw new IllegalArgumentException("Unknown process: " + process); 16964 } 16965 16966 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16967 if (!isDebuggable) { 16968 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16969 throw new SecurityException("Process not debuggable: " + proc); 16970 } 16971 } 16972 16973 proc.thread.dumpHeap(managed, path, fd); 16974 fd = null; 16975 return true; 16976 } 16977 } catch (RemoteException e) { 16978 throw new IllegalStateException("Process disappeared"); 16979 } finally { 16980 if (fd != null) { 16981 try { 16982 fd.close(); 16983 } catch (IOException e) { 16984 } 16985 } 16986 } 16987 } 16988 16989 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16990 public void monitor() { 16991 synchronized (this) { } 16992 } 16993 16994 void onCoreSettingsChange(Bundle settings) { 16995 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16996 ProcessRecord processRecord = mLruProcesses.get(i); 16997 try { 16998 if (processRecord.thread != null) { 16999 processRecord.thread.setCoreSettings(settings); 17000 } 17001 } catch (RemoteException re) { 17002 /* ignore */ 17003 } 17004 } 17005 } 17006 17007 // Multi-user methods 17008 17009 /** 17010 * Start user, if its not already running, but don't bring it to foreground. 17011 */ 17012 @Override 17013 public boolean startUserInBackground(final int userId) { 17014 return startUser(userId, /* foreground */ false); 17015 } 17016 17017 /** 17018 * Refreshes the list of users related to the current user when either a 17019 * user switch happens or when a new related user is started in the 17020 * background. 17021 */ 17022 private void updateCurrentProfileIdsLocked() { 17023 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17024 mCurrentUserId, false /* enabledOnly */); 17025 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 17026 for (int i = 0; i < currentProfileIds.length; i++) { 17027 currentProfileIds[i] = profiles.get(i).id; 17028 } 17029 mCurrentProfileIds = currentProfileIds; 17030 17031 synchronized (mUserProfileGroupIdsSelfLocked) { 17032 mUserProfileGroupIdsSelfLocked.clear(); 17033 final List<UserInfo> users = getUserManagerLocked().getUsers(false); 17034 for (int i = 0; i < users.size(); i++) { 17035 UserInfo user = users.get(i); 17036 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) { 17037 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId); 17038 } 17039 } 17040 } 17041 } 17042 17043 private Set getProfileIdsLocked(int userId) { 17044 Set userIds = new HashSet<Integer>(); 17045 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17046 userId, false /* enabledOnly */); 17047 for (UserInfo user : profiles) { 17048 userIds.add(Integer.valueOf(user.id)); 17049 } 17050 return userIds; 17051 } 17052 17053 @Override 17054 public boolean switchUser(final int userId) { 17055 return startUser(userId, /* foregound */ true); 17056 } 17057 17058 private boolean startUser(final int userId, boolean foreground) { 17059 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17060 != PackageManager.PERMISSION_GRANTED) { 17061 String msg = "Permission Denial: switchUser() from pid=" 17062 + Binder.getCallingPid() 17063 + ", uid=" + Binder.getCallingUid() 17064 + " requires " + INTERACT_ACROSS_USERS_FULL; 17065 Slog.w(TAG, msg); 17066 throw new SecurityException(msg); 17067 } 17068 17069 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 17070 17071 final long ident = Binder.clearCallingIdentity(); 17072 try { 17073 synchronized (this) { 17074 final int oldUserId = mCurrentUserId; 17075 if (oldUserId == userId) { 17076 return true; 17077 } 17078 17079 mStackSupervisor.setLockTaskModeLocked(null, false); 17080 17081 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 17082 if (userInfo == null) { 17083 Slog.w(TAG, "No user info for user #" + userId); 17084 return false; 17085 } 17086 17087 if (foreground) { 17088 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 17089 R.anim.screen_user_enter); 17090 } 17091 17092 boolean needStart = false; 17093 17094 // If the user we are switching to is not currently started, then 17095 // we need to start it now. 17096 if (mStartedUsers.get(userId) == null) { 17097 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 17098 updateStartedUserArrayLocked(); 17099 needStart = true; 17100 } 17101 17102 final Integer userIdInt = Integer.valueOf(userId); 17103 mUserLru.remove(userIdInt); 17104 mUserLru.add(userIdInt); 17105 17106 if (foreground) { 17107 mCurrentUserId = userId; 17108 updateCurrentProfileIdsLocked(); 17109 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 17110 // Once the internal notion of the active user has switched, we lock the device 17111 // with the option to show the user switcher on the keyguard. 17112 mWindowManager.lockNow(null); 17113 } else { 17114 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 17115 updateCurrentProfileIdsLocked(); 17116 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 17117 mUserLru.remove(currentUserIdInt); 17118 mUserLru.add(currentUserIdInt); 17119 } 17120 17121 final UserStartedState uss = mStartedUsers.get(userId); 17122 17123 // Make sure user is in the started state. If it is currently 17124 // stopping, we need to knock that off. 17125 if (uss.mState == UserStartedState.STATE_STOPPING) { 17126 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 17127 // so we can just fairly silently bring the user back from 17128 // the almost-dead. 17129 uss.mState = UserStartedState.STATE_RUNNING; 17130 updateStartedUserArrayLocked(); 17131 needStart = true; 17132 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 17133 // This means ACTION_SHUTDOWN has been sent, so we will 17134 // need to treat this as a new boot of the user. 17135 uss.mState = UserStartedState.STATE_BOOTING; 17136 updateStartedUserArrayLocked(); 17137 needStart = true; 17138 } 17139 17140 if (uss.mState == UserStartedState.STATE_BOOTING) { 17141 // Booting up a new user, need to tell system services about it. 17142 // Note that this is on the same handler as scheduling of broadcasts, 17143 // which is important because it needs to go first. 17144 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 17145 } 17146 17147 if (foreground) { 17148 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId, 17149 oldUserId)); 17150 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 17151 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17152 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 17153 oldUserId, userId, uss)); 17154 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 17155 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 17156 } 17157 17158 if (needStart) { 17159 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 17160 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17161 | Intent.FLAG_RECEIVER_FOREGROUND); 17162 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17163 broadcastIntentLocked(null, null, intent, 17164 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17165 false, false, MY_PID, Process.SYSTEM_UID, userId); 17166 } 17167 17168 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 17169 if (userId != UserHandle.USER_OWNER) { 17170 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 17171 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 17172 broadcastIntentLocked(null, null, intent, null, 17173 new IIntentReceiver.Stub() { 17174 public void performReceive(Intent intent, int resultCode, 17175 String data, Bundle extras, boolean ordered, 17176 boolean sticky, int sendingUser) { 17177 userInitialized(uss, userId); 17178 } 17179 }, 0, null, null, null, AppOpsManager.OP_NONE, 17180 true, false, MY_PID, Process.SYSTEM_UID, 17181 userId); 17182 uss.initializing = true; 17183 } else { 17184 getUserManagerLocked().makeInitialized(userInfo.id); 17185 } 17186 } 17187 17188 if (foreground) { 17189 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 17190 if (homeInFront) { 17191 startHomeActivityLocked(userId); 17192 } else { 17193 mStackSupervisor.resumeTopActivitiesLocked(); 17194 } 17195 EventLogTags.writeAmSwitchUser(userId); 17196 getUserManagerLocked().userForeground(userId); 17197 sendUserSwitchBroadcastsLocked(oldUserId, userId); 17198 } else { 17199 mStackSupervisor.startBackgroundUserLocked(userId, uss); 17200 } 17201 17202 if (needStart) { 17203 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 17204 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17205 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17206 broadcastIntentLocked(null, null, intent, 17207 null, new IIntentReceiver.Stub() { 17208 @Override 17209 public void performReceive(Intent intent, int resultCode, String data, 17210 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 17211 throws RemoteException { 17212 } 17213 }, 0, null, null, 17214 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17215 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17216 } 17217 } 17218 } finally { 17219 Binder.restoreCallingIdentity(ident); 17220 } 17221 17222 return true; 17223 } 17224 17225 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 17226 long ident = Binder.clearCallingIdentity(); 17227 try { 17228 Intent intent; 17229 if (oldUserId >= 0) { 17230 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user 17231 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false); 17232 int count = profiles.size(); 17233 for (int i = 0; i < count; i++) { 17234 int profileUserId = profiles.get(i).id; 17235 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 17236 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17237 | Intent.FLAG_RECEIVER_FOREGROUND); 17238 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17239 broadcastIntentLocked(null, null, intent, 17240 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17241 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17242 } 17243 } 17244 if (newUserId >= 0) { 17245 // Send USER_FOREGROUND broadcast to all profiles of the incoming user 17246 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false); 17247 int count = profiles.size(); 17248 for (int i = 0; i < count; i++) { 17249 int profileUserId = profiles.get(i).id; 17250 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 17251 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17252 | Intent.FLAG_RECEIVER_FOREGROUND); 17253 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId); 17254 broadcastIntentLocked(null, null, intent, 17255 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 17256 false, false, MY_PID, Process.SYSTEM_UID, profileUserId); 17257 } 17258 intent = new Intent(Intent.ACTION_USER_SWITCHED); 17259 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 17260 | Intent.FLAG_RECEIVER_FOREGROUND); 17261 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 17262 broadcastIntentLocked(null, null, intent, 17263 null, null, 0, null, null, 17264 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 17265 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17266 } 17267 } finally { 17268 Binder.restoreCallingIdentity(ident); 17269 } 17270 } 17271 17272 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 17273 final int newUserId) { 17274 final int N = mUserSwitchObservers.beginBroadcast(); 17275 if (N > 0) { 17276 final IRemoteCallback callback = new IRemoteCallback.Stub() { 17277 int mCount = 0; 17278 @Override 17279 public void sendResult(Bundle data) throws RemoteException { 17280 synchronized (ActivityManagerService.this) { 17281 if (mCurUserSwitchCallback == this) { 17282 mCount++; 17283 if (mCount == N) { 17284 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17285 } 17286 } 17287 } 17288 } 17289 }; 17290 synchronized (this) { 17291 uss.switching = true; 17292 mCurUserSwitchCallback = callback; 17293 } 17294 for (int i=0; i<N; i++) { 17295 try { 17296 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 17297 newUserId, callback); 17298 } catch (RemoteException e) { 17299 } 17300 } 17301 } else { 17302 synchronized (this) { 17303 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17304 } 17305 } 17306 mUserSwitchObservers.finishBroadcast(); 17307 } 17308 17309 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17310 synchronized (this) { 17311 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 17312 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 17313 } 17314 } 17315 17316 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 17317 mCurUserSwitchCallback = null; 17318 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 17319 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 17320 oldUserId, newUserId, uss)); 17321 } 17322 17323 void userInitialized(UserStartedState uss, int newUserId) { 17324 completeSwitchAndInitalize(uss, newUserId, true, false); 17325 } 17326 17327 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 17328 completeSwitchAndInitalize(uss, newUserId, false, true); 17329 } 17330 17331 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 17332 boolean clearInitializing, boolean clearSwitching) { 17333 boolean unfrozen = false; 17334 synchronized (this) { 17335 if (clearInitializing) { 17336 uss.initializing = false; 17337 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 17338 } 17339 if (clearSwitching) { 17340 uss.switching = false; 17341 } 17342 if (!uss.switching && !uss.initializing) { 17343 mWindowManager.stopFreezingScreen(); 17344 unfrozen = true; 17345 } 17346 } 17347 if (unfrozen) { 17348 final int N = mUserSwitchObservers.beginBroadcast(); 17349 for (int i=0; i<N; i++) { 17350 try { 17351 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 17352 } catch (RemoteException e) { 17353 } 17354 } 17355 mUserSwitchObservers.finishBroadcast(); 17356 } 17357 } 17358 17359 void scheduleStartProfilesLocked() { 17360 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 17361 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 17362 DateUtils.SECOND_IN_MILLIS); 17363 } 17364 } 17365 17366 void startProfilesLocked() { 17367 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 17368 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 17369 mCurrentUserId, false /* enabledOnly */); 17370 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 17371 for (UserInfo user : profiles) { 17372 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 17373 && user.id != mCurrentUserId) { 17374 toStart.add(user); 17375 } 17376 } 17377 final int n = toStart.size(); 17378 int i = 0; 17379 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 17380 startUserInBackground(toStart.get(i).id); 17381 } 17382 if (i < n) { 17383 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 17384 } 17385 } 17386 17387 void finishUserBoot(UserStartedState uss) { 17388 synchronized (this) { 17389 if (uss.mState == UserStartedState.STATE_BOOTING 17390 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 17391 uss.mState = UserStartedState.STATE_RUNNING; 17392 final int userId = uss.mHandle.getIdentifier(); 17393 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 17394 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17395 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 17396 broadcastIntentLocked(null, null, intent, 17397 null, null, 0, null, null, 17398 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 17399 true, false, MY_PID, Process.SYSTEM_UID, userId); 17400 } 17401 } 17402 } 17403 17404 void finishUserSwitch(UserStartedState uss) { 17405 synchronized (this) { 17406 finishUserBoot(uss); 17407 17408 startProfilesLocked(); 17409 17410 int num = mUserLru.size(); 17411 int i = 0; 17412 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 17413 Integer oldUserId = mUserLru.get(i); 17414 UserStartedState oldUss = mStartedUsers.get(oldUserId); 17415 if (oldUss == null) { 17416 // Shouldn't happen, but be sane if it does. 17417 mUserLru.remove(i); 17418 num--; 17419 continue; 17420 } 17421 if (oldUss.mState == UserStartedState.STATE_STOPPING 17422 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 17423 // This user is already stopping, doesn't count. 17424 num--; 17425 i++; 17426 continue; 17427 } 17428 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 17429 // Owner and current can't be stopped, but count as running. 17430 i++; 17431 continue; 17432 } 17433 // This is a user to be stopped. 17434 stopUserLocked(oldUserId, null); 17435 num--; 17436 i++; 17437 } 17438 } 17439 } 17440 17441 @Override 17442 public int stopUser(final int userId, final IStopUserCallback callback) { 17443 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17444 != PackageManager.PERMISSION_GRANTED) { 17445 String msg = "Permission Denial: switchUser() from pid=" 17446 + Binder.getCallingPid() 17447 + ", uid=" + Binder.getCallingUid() 17448 + " requires " + INTERACT_ACROSS_USERS_FULL; 17449 Slog.w(TAG, msg); 17450 throw new SecurityException(msg); 17451 } 17452 if (userId <= 0) { 17453 throw new IllegalArgumentException("Can't stop primary user " + userId); 17454 } 17455 synchronized (this) { 17456 return stopUserLocked(userId, callback); 17457 } 17458 } 17459 17460 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 17461 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 17462 if (mCurrentUserId == userId) { 17463 return ActivityManager.USER_OP_IS_CURRENT; 17464 } 17465 17466 final UserStartedState uss = mStartedUsers.get(userId); 17467 if (uss == null) { 17468 // User is not started, nothing to do... but we do need to 17469 // callback if requested. 17470 if (callback != null) { 17471 mHandler.post(new Runnable() { 17472 @Override 17473 public void run() { 17474 try { 17475 callback.userStopped(userId); 17476 } catch (RemoteException e) { 17477 } 17478 } 17479 }); 17480 } 17481 return ActivityManager.USER_OP_SUCCESS; 17482 } 17483 17484 if (callback != null) { 17485 uss.mStopCallbacks.add(callback); 17486 } 17487 17488 if (uss.mState != UserStartedState.STATE_STOPPING 17489 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17490 uss.mState = UserStartedState.STATE_STOPPING; 17491 updateStartedUserArrayLocked(); 17492 17493 long ident = Binder.clearCallingIdentity(); 17494 try { 17495 // We are going to broadcast ACTION_USER_STOPPING and then 17496 // once that is done send a final ACTION_SHUTDOWN and then 17497 // stop the user. 17498 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 17499 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 17500 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 17501 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 17502 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 17503 // This is the result receiver for the final shutdown broadcast. 17504 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 17505 @Override 17506 public void performReceive(Intent intent, int resultCode, String data, 17507 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17508 finishUserStop(uss); 17509 } 17510 }; 17511 // This is the result receiver for the initial stopping broadcast. 17512 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 17513 @Override 17514 public void performReceive(Intent intent, int resultCode, String data, 17515 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 17516 // On to the next. 17517 synchronized (ActivityManagerService.this) { 17518 if (uss.mState != UserStartedState.STATE_STOPPING) { 17519 // Whoops, we are being started back up. Abort, abort! 17520 return; 17521 } 17522 uss.mState = UserStartedState.STATE_SHUTDOWN; 17523 } 17524 mBatteryStatsService.noteEvent( 17525 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH, 17526 Integer.toString(userId), userId); 17527 mSystemServiceManager.stopUser(userId); 17528 broadcastIntentLocked(null, null, shutdownIntent, 17529 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 17530 true, false, MY_PID, Process.SYSTEM_UID, userId); 17531 } 17532 }; 17533 // Kick things off. 17534 broadcastIntentLocked(null, null, stoppingIntent, 17535 null, stoppingReceiver, 0, null, null, 17536 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 17537 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 17538 } finally { 17539 Binder.restoreCallingIdentity(ident); 17540 } 17541 } 17542 17543 return ActivityManager.USER_OP_SUCCESS; 17544 } 17545 17546 void finishUserStop(UserStartedState uss) { 17547 final int userId = uss.mHandle.getIdentifier(); 17548 boolean stopped; 17549 ArrayList<IStopUserCallback> callbacks; 17550 synchronized (this) { 17551 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 17552 if (mStartedUsers.get(userId) != uss) { 17553 stopped = false; 17554 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 17555 stopped = false; 17556 } else { 17557 stopped = true; 17558 // User can no longer run. 17559 mStartedUsers.remove(userId); 17560 mUserLru.remove(Integer.valueOf(userId)); 17561 updateStartedUserArrayLocked(); 17562 17563 // Clean up all state and processes associated with the user. 17564 // Kill all the processes for the user. 17565 forceStopUserLocked(userId, "finish user"); 17566 } 17567 } 17568 17569 for (int i=0; i<callbacks.size(); i++) { 17570 try { 17571 if (stopped) callbacks.get(i).userStopped(userId); 17572 else callbacks.get(i).userStopAborted(userId); 17573 } catch (RemoteException e) { 17574 } 17575 } 17576 17577 if (stopped) { 17578 mSystemServiceManager.cleanupUser(userId); 17579 synchronized (this) { 17580 mStackSupervisor.removeUserLocked(userId); 17581 } 17582 } 17583 } 17584 17585 @Override 17586 public UserInfo getCurrentUser() { 17587 if ((checkCallingPermission(INTERACT_ACROSS_USERS) 17588 != PackageManager.PERMISSION_GRANTED) && ( 17589 checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17590 != PackageManager.PERMISSION_GRANTED)) { 17591 String msg = "Permission Denial: getCurrentUser() from pid=" 17592 + Binder.getCallingPid() 17593 + ", uid=" + Binder.getCallingUid() 17594 + " requires " + INTERACT_ACROSS_USERS; 17595 Slog.w(TAG, msg); 17596 throw new SecurityException(msg); 17597 } 17598 synchronized (this) { 17599 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17600 } 17601 } 17602 17603 int getCurrentUserIdLocked() { 17604 return mCurrentUserId; 17605 } 17606 17607 @Override 17608 public boolean isUserRunning(int userId, boolean orStopped) { 17609 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17610 != PackageManager.PERMISSION_GRANTED) { 17611 String msg = "Permission Denial: isUserRunning() from pid=" 17612 + Binder.getCallingPid() 17613 + ", uid=" + Binder.getCallingUid() 17614 + " requires " + INTERACT_ACROSS_USERS; 17615 Slog.w(TAG, msg); 17616 throw new SecurityException(msg); 17617 } 17618 synchronized (this) { 17619 return isUserRunningLocked(userId, orStopped); 17620 } 17621 } 17622 17623 boolean isUserRunningLocked(int userId, boolean orStopped) { 17624 UserStartedState state = mStartedUsers.get(userId); 17625 if (state == null) { 17626 return false; 17627 } 17628 if (orStopped) { 17629 return true; 17630 } 17631 return state.mState != UserStartedState.STATE_STOPPING 17632 && state.mState != UserStartedState.STATE_SHUTDOWN; 17633 } 17634 17635 @Override 17636 public int[] getRunningUserIds() { 17637 if (checkCallingPermission(INTERACT_ACROSS_USERS) 17638 != PackageManager.PERMISSION_GRANTED) { 17639 String msg = "Permission Denial: isUserRunning() from pid=" 17640 + Binder.getCallingPid() 17641 + ", uid=" + Binder.getCallingUid() 17642 + " requires " + INTERACT_ACROSS_USERS; 17643 Slog.w(TAG, msg); 17644 throw new SecurityException(msg); 17645 } 17646 synchronized (this) { 17647 return mStartedUserArray; 17648 } 17649 } 17650 17651 private void updateStartedUserArrayLocked() { 17652 int num = 0; 17653 for (int i=0; i<mStartedUsers.size(); i++) { 17654 UserStartedState uss = mStartedUsers.valueAt(i); 17655 // This list does not include stopping users. 17656 if (uss.mState != UserStartedState.STATE_STOPPING 17657 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17658 num++; 17659 } 17660 } 17661 mStartedUserArray = new int[num]; 17662 num = 0; 17663 for (int i=0; i<mStartedUsers.size(); i++) { 17664 UserStartedState uss = mStartedUsers.valueAt(i); 17665 if (uss.mState != UserStartedState.STATE_STOPPING 17666 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17667 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17668 num++; 17669 } 17670 } 17671 } 17672 17673 @Override 17674 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17675 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL) 17676 != PackageManager.PERMISSION_GRANTED) { 17677 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17678 + Binder.getCallingPid() 17679 + ", uid=" + Binder.getCallingUid() 17680 + " requires " + INTERACT_ACROSS_USERS_FULL; 17681 Slog.w(TAG, msg); 17682 throw new SecurityException(msg); 17683 } 17684 17685 mUserSwitchObservers.register(observer); 17686 } 17687 17688 @Override 17689 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17690 mUserSwitchObservers.unregister(observer); 17691 } 17692 17693 private boolean userExists(int userId) { 17694 if (userId == 0) { 17695 return true; 17696 } 17697 UserManagerService ums = getUserManagerLocked(); 17698 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17699 } 17700 17701 int[] getUsersLocked() { 17702 UserManagerService ums = getUserManagerLocked(); 17703 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17704 } 17705 17706 UserManagerService getUserManagerLocked() { 17707 if (mUserManager == null) { 17708 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17709 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17710 } 17711 return mUserManager; 17712 } 17713 17714 private int applyUserId(int uid, int userId) { 17715 return UserHandle.getUid(userId, uid); 17716 } 17717 17718 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17719 if (info == null) return null; 17720 ApplicationInfo newInfo = new ApplicationInfo(info); 17721 newInfo.uid = applyUserId(info.uid, userId); 17722 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17723 + info.packageName; 17724 return newInfo; 17725 } 17726 17727 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17728 if (aInfo == null 17729 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17730 return aInfo; 17731 } 17732 17733 ActivityInfo info = new ActivityInfo(aInfo); 17734 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17735 return info; 17736 } 17737 17738 private final class LocalService extends ActivityManagerInternal { 17739 @Override 17740 public void goingToSleep() { 17741 ActivityManagerService.this.goingToSleep(); 17742 } 17743 17744 @Override 17745 public void wakingUp() { 17746 ActivityManagerService.this.wakingUp(); 17747 } 17748 } 17749 17750 /** 17751 * An implementation of IAppTask, that allows an app to manage its own tasks via 17752 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that 17753 * only the process that calls getAppTasks() can call the AppTask methods. 17754 */ 17755 class AppTaskImpl extends IAppTask.Stub { 17756 private int mTaskId; 17757 private int mCallingUid; 17758 17759 public AppTaskImpl(int taskId, int callingUid) { 17760 mTaskId = taskId; 17761 mCallingUid = callingUid; 17762 } 17763 17764 @Override 17765 public void finishAndRemoveTask() { 17766 // Ensure that we are called from the same process that created this AppTask 17767 if (mCallingUid != Binder.getCallingUid()) { 17768 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17769 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17770 return; 17771 } 17772 17773 synchronized (ActivityManagerService.this) { 17774 long origId = Binder.clearCallingIdentity(); 17775 try { 17776 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17777 if (tr != null) { 17778 // Only kill the process if we are not a new document 17779 int flags = tr.getBaseIntent().getFlags(); 17780 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17781 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17782 removeTaskByIdLocked(mTaskId, 17783 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17784 } 17785 } finally { 17786 Binder.restoreCallingIdentity(origId); 17787 } 17788 } 17789 } 17790 17791 @Override 17792 public ActivityManager.RecentTaskInfo getTaskInfo() { 17793 // Ensure that we are called from the same process that created this AppTask 17794 if (mCallingUid != Binder.getCallingUid()) { 17795 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17796 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17797 return null; 17798 } 17799 17800 synchronized (ActivityManagerService.this) { 17801 long origId = Binder.clearCallingIdentity(); 17802 try { 17803 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17804 if (tr != null) { 17805 return createRecentTaskInfoFromTaskRecord(tr); 17806 } 17807 } finally { 17808 Binder.restoreCallingIdentity(origId); 17809 } 17810 return null; 17811 } 17812 } 17813 } 17814} 17815