ActivityManagerService.java revision a449dc033b79775b8945d9cc5a035a6deb145065
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.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readBooleanAttribute; 21import static com.android.internal.util.XmlUtils.readIntAttribute; 22import static com.android.internal.util.XmlUtils.readLongAttribute; 23import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 24import static com.android.internal.util.XmlUtils.writeIntAttribute; 25import static com.android.internal.util.XmlUtils.writeLongAttribute; 26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 28import static org.xmlpull.v1.XmlPullParser.START_TAG; 29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 30 31import android.Manifest; 32import android.app.AppOpsManager; 33import android.app.IActivityContainer; 34import android.app.IActivityContainerCallback; 35import android.app.IAppTask; 36import android.appwidget.AppWidgetManager; 37import android.graphics.Rect; 38import android.os.BatteryStats; 39import android.os.PersistableBundle; 40import android.service.voice.IVoiceInteractionSession; 41import android.util.ArrayMap; 42 43import com.android.internal.R; 44import com.android.internal.annotations.GuardedBy; 45import com.android.internal.app.IAppOpsService; 46import com.android.internal.app.IVoiceInteractor; 47import com.android.internal.app.ProcessMap; 48import com.android.internal.app.ProcessStats; 49import com.android.internal.content.PackageMonitor; 50import com.android.internal.os.BackgroundThread; 51import com.android.internal.os.BatteryStatsImpl; 52import com.android.internal.os.ProcessCpuTracker; 53import com.android.internal.os.TransferPipe; 54import com.android.internal.os.Zygote; 55import com.android.internal.util.FastPrintWriter; 56import com.android.internal.util.FastXmlSerializer; 57import com.android.internal.util.MemInfoReader; 58import com.android.internal.util.Preconditions; 59import com.android.server.AppOpsService; 60import com.android.server.AttributeCache; 61import com.android.server.IntentResolver; 62import com.android.server.LocalServices; 63import com.android.server.ServiceThread; 64import com.android.server.SystemService; 65import com.android.server.SystemServiceManager; 66import com.android.server.Watchdog; 67import com.android.server.am.ActivityStack.ActivityState; 68import com.android.server.firewall.IntentFirewall; 69import com.android.server.pm.UserManagerService; 70import com.android.server.wm.AppTransition; 71import com.android.server.wm.WindowManagerService; 72import com.google.android.collect.Lists; 73import com.google.android.collect.Maps; 74 75import libcore.io.IoUtils; 76 77import org.xmlpull.v1.XmlPullParser; 78import org.xmlpull.v1.XmlPullParserException; 79import org.xmlpull.v1.XmlSerializer; 80 81import android.app.Activity; 82import android.app.ActivityManager; 83import android.app.ActivityManager.RunningTaskInfo; 84import android.app.ActivityManager.StackInfo; 85import android.app.ActivityManagerInternal; 86import android.app.ActivityManagerNative; 87import android.app.ActivityOptions; 88import android.app.ActivityThread; 89import android.app.AlertDialog; 90import android.app.AppGlobals; 91import android.app.ApplicationErrorReport; 92import android.app.Dialog; 93import android.app.IActivityController; 94import android.app.IApplicationThread; 95import android.app.IInstrumentationWatcher; 96import android.app.INotificationManager; 97import android.app.IProcessObserver; 98import android.app.IServiceConnection; 99import android.app.IStopUserCallback; 100import android.app.IUiAutomationConnection; 101import android.app.IUserSwitchObserver; 102import android.app.Instrumentation; 103import android.app.Notification; 104import android.app.NotificationManager; 105import android.app.PendingIntent; 106import android.app.backup.IBackupManager; 107import android.content.ActivityNotFoundException; 108import android.content.BroadcastReceiver; 109import android.content.ClipData; 110import android.content.ComponentCallbacks2; 111import android.content.ComponentName; 112import android.content.ContentProvider; 113import android.content.ContentResolver; 114import android.content.Context; 115import android.content.DialogInterface; 116import android.content.IContentProvider; 117import android.content.IIntentReceiver; 118import android.content.IIntentSender; 119import android.content.Intent; 120import android.content.IntentFilter; 121import android.content.IntentSender; 122import android.content.pm.ActivityInfo; 123import android.content.pm.ApplicationInfo; 124import android.content.pm.ConfigurationInfo; 125import android.content.pm.IPackageDataObserver; 126import android.content.pm.IPackageManager; 127import android.content.pm.InstrumentationInfo; 128import android.content.pm.PackageInfo; 129import android.content.pm.PackageManager; 130import android.content.pm.ParceledListSlice; 131import android.content.pm.UserInfo; 132import android.content.pm.PackageManager.NameNotFoundException; 133import android.content.pm.PathPermission; 134import android.content.pm.ProviderInfo; 135import android.content.pm.ResolveInfo; 136import android.content.pm.ServiceInfo; 137import android.content.res.CompatibilityInfo; 138import android.content.res.Configuration; 139import android.graphics.Bitmap; 140import android.net.Proxy; 141import android.net.ProxyInfo; 142import android.net.Uri; 143import android.os.Binder; 144import android.os.Build; 145import android.os.Bundle; 146import android.os.Debug; 147import android.os.DropBoxManager; 148import android.os.Environment; 149import android.os.FactoryTest; 150import android.os.FileObserver; 151import android.os.FileUtils; 152import android.os.Handler; 153import android.os.IBinder; 154import android.os.IPermissionController; 155import android.os.IRemoteCallback; 156import android.os.IUserManager; 157import android.os.Looper; 158import android.os.Message; 159import android.os.Parcel; 160import android.os.ParcelFileDescriptor; 161import android.os.Process; 162import android.os.RemoteCallbackList; 163import android.os.RemoteException; 164import android.os.SELinux; 165import android.os.ServiceManager; 166import android.os.StrictMode; 167import android.os.SystemClock; 168import android.os.SystemProperties; 169import android.os.UpdateLock; 170import android.os.UserHandle; 171import android.provider.Settings; 172import android.text.format.DateUtils; 173import android.text.format.Time; 174import android.util.AtomicFile; 175import android.util.EventLog; 176import android.util.Log; 177import android.util.Pair; 178import android.util.PrintWriterPrinter; 179import android.util.Slog; 180import android.util.SparseArray; 181import android.util.TimeUtils; 182import android.util.Xml; 183import android.view.Gravity; 184import android.view.LayoutInflater; 185import android.view.View; 186import android.view.WindowManager; 187 188import java.io.BufferedInputStream; 189import java.io.BufferedOutputStream; 190import java.io.DataInputStream; 191import java.io.DataOutputStream; 192import java.io.File; 193import java.io.FileDescriptor; 194import java.io.FileInputStream; 195import java.io.FileNotFoundException; 196import java.io.FileOutputStream; 197import java.io.IOException; 198import java.io.InputStreamReader; 199import java.io.PrintWriter; 200import java.io.StringWriter; 201import java.lang.ref.WeakReference; 202import java.util.ArrayList; 203import java.util.Arrays; 204import java.util.Collections; 205import java.util.Comparator; 206import java.util.HashMap; 207import java.util.HashSet; 208import java.util.Iterator; 209import java.util.List; 210import java.util.Locale; 211import java.util.Map; 212import java.util.Set; 213import java.util.concurrent.atomic.AtomicBoolean; 214import java.util.concurrent.atomic.AtomicLong; 215 216public final class ActivityManagerService extends ActivityManagerNative 217 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 218 private static final String USER_DATA_DIR = "/data/user/"; 219 static final String TAG = "ActivityManager"; 220 static final String TAG_MU = "ActivityManagerServiceMU"; 221 static final boolean DEBUG = false; 222 static final boolean localLOGV = DEBUG; 223 static final boolean DEBUG_BACKUP = localLOGV || false; 224 static final boolean DEBUG_BROADCAST = localLOGV || false; 225 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 226 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 227 static final boolean DEBUG_CLEANUP = localLOGV || false; 228 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 229 static final boolean DEBUG_FOCUS = false; 230 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 231 static final boolean DEBUG_MU = localLOGV || false; 232 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 233 static final boolean DEBUG_LRU = localLOGV || false; 234 static final boolean DEBUG_PAUSE = localLOGV || false; 235 static final boolean DEBUG_POWER = localLOGV || false; 236 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 237 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 238 static final boolean DEBUG_PROCESSES = localLOGV || false; 239 static final boolean DEBUG_PROVIDER = localLOGV || false; 240 static final boolean DEBUG_RESULTS = localLOGV || false; 241 static final boolean DEBUG_SERVICE = localLOGV || false; 242 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 243 static final boolean DEBUG_STACK = localLOGV || false; 244 static final boolean DEBUG_SWITCH = localLOGV || false; 245 static final boolean DEBUG_TASKS = localLOGV || false; 246 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 247 static final boolean DEBUG_TRANSITION = localLOGV || false; 248 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 249 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 250 static final boolean DEBUG_VISBILITY = localLOGV || false; 251 static final boolean DEBUG_PSS = localLOGV || false; 252 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 253 static final boolean VALIDATE_TOKENS = false; 254 static final boolean SHOW_ACTIVITY_START_TIME = true; 255 256 // Control over CPU and battery monitoring. 257 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 258 static final boolean MONITOR_CPU_USAGE = true; 259 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 260 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 261 static final boolean MONITOR_THREAD_CPU_USAGE = false; 262 263 // The flags that are set for all calls we make to the package manager. 264 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 265 266 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 267 268 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 269 270 // Maximum number of recent tasks that we can remember. 271 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 272 273 // Amount of time after a call to stopAppSwitches() during which we will 274 // prevent further untrusted switches from happening. 275 static final long APP_SWITCH_DELAY_TIME = 5*1000; 276 277 // How long we wait for a launched process to attach to the activity manager 278 // before we decide it's never going to come up for real. 279 static final int PROC_START_TIMEOUT = 10*1000; 280 281 // How long we wait for a launched process to attach to the activity manager 282 // before we decide it's never going to come up for real, when the process was 283 // started with a wrapper for instrumentation (such as Valgrind) because it 284 // could take much longer than usual. 285 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 286 287 // How long to wait after going idle before forcing apps to GC. 288 static final int GC_TIMEOUT = 5*1000; 289 290 // The minimum amount of time between successive GC requests for a process. 291 static final int GC_MIN_INTERVAL = 60*1000; 292 293 // The minimum amount of time between successive PSS requests for a process. 294 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 295 296 // The minimum amount of time between successive PSS requests for a process 297 // when the request is due to the memory state being lowered. 298 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 299 300 // The rate at which we check for apps using excessive power -- 15 mins. 301 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 302 303 // The minimum sample duration we will allow before deciding we have 304 // enough data on wake locks to start killing things. 305 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 306 307 // The minimum sample duration we will allow before deciding we have 308 // enough data on CPU usage to start killing things. 309 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 310 311 // How long we allow a receiver to run before giving up on it. 312 static final int BROADCAST_FG_TIMEOUT = 10*1000; 313 static final int BROADCAST_BG_TIMEOUT = 60*1000; 314 315 // How long we wait until we timeout on key dispatching. 316 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 317 318 // How long we wait until we timeout on key dispatching during instrumentation. 319 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 320 321 // Amount of time we wait for observers to handle a user switch before 322 // giving up on them and unfreezing the screen. 323 static final int USER_SWITCH_TIMEOUT = 2*1000; 324 325 // Maximum number of users we allow to be running at a time. 326 static final int MAX_RUNNING_USERS = 3; 327 328 // How long to wait in getAssistContextExtras for the activity and foreground services 329 // to respond with the result. 330 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 331 332 // Maximum number of persisted Uri grants a package is allowed 333 static final int MAX_PERSISTED_URI_GRANTS = 128; 334 335 static final int MY_PID = Process.myPid(); 336 337 static final String[] EMPTY_STRING_ARRAY = new String[0]; 338 339 // How many bytes to write into the dropbox log before truncating 340 static final int DROPBOX_MAX_SIZE = 256 * 1024; 341 342 /** All system services */ 343 SystemServiceManager mSystemServiceManager; 344 345 /** Run all ActivityStacks through this */ 346 ActivityStackSupervisor mStackSupervisor; 347 348 public IntentFirewall mIntentFirewall; 349 350 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 351 // default actuion automatically. Important for devices without direct input 352 // devices. 353 private boolean mShowDialogs = true; 354 355 /** 356 * Description of a request to start a new activity, which has been held 357 * due to app switches being disabled. 358 */ 359 static class PendingActivityLaunch { 360 final ActivityRecord r; 361 final ActivityRecord sourceRecord; 362 final int startFlags; 363 final ActivityStack stack; 364 365 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 366 int _startFlags, ActivityStack _stack) { 367 r = _r; 368 sourceRecord = _sourceRecord; 369 startFlags = _startFlags; 370 stack = _stack; 371 } 372 } 373 374 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 375 = new ArrayList<PendingActivityLaunch>(); 376 377 BroadcastQueue mFgBroadcastQueue; 378 BroadcastQueue mBgBroadcastQueue; 379 // Convenient for easy iteration over the queues. Foreground is first 380 // so that dispatch of foreground broadcasts gets precedence. 381 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 382 383 BroadcastQueue broadcastQueueForIntent(Intent intent) { 384 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 385 if (DEBUG_BACKGROUND_BROADCAST) { 386 Slog.i(TAG, "Broadcast intent " + intent + " on " 387 + (isFg ? "foreground" : "background") 388 + " queue"); 389 } 390 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 391 } 392 393 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 394 for (BroadcastQueue queue : mBroadcastQueues) { 395 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 396 if (r != null) { 397 return r; 398 } 399 } 400 return null; 401 } 402 403 /** 404 * Activity we have told the window manager to have key focus. 405 */ 406 ActivityRecord mFocusedActivity = null; 407 408 /** 409 * List of intents that were used to start the most recent tasks. 410 */ 411 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 412 413 public class PendingAssistExtras extends Binder implements Runnable { 414 public final ActivityRecord activity; 415 public boolean haveResult = false; 416 public Bundle result = null; 417 public PendingAssistExtras(ActivityRecord _activity) { 418 activity = _activity; 419 } 420 @Override 421 public void run() { 422 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 423 synchronized (this) { 424 haveResult = true; 425 notifyAll(); 426 } 427 } 428 } 429 430 final ArrayList<PendingAssistExtras> mPendingAssistExtras 431 = new ArrayList<PendingAssistExtras>(); 432 433 /** 434 * Process management. 435 */ 436 final ProcessList mProcessList = new ProcessList(); 437 438 /** 439 * All of the applications we currently have running organized by name. 440 * The keys are strings of the application package name (as 441 * returned by the package manager), and the keys are ApplicationRecord 442 * objects. 443 */ 444 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 445 446 /** 447 * Tracking long-term execution of processes to look for abuse and other 448 * bad app behavior. 449 */ 450 final ProcessStatsService mProcessStats; 451 452 /** 453 * The currently running isolated processes. 454 */ 455 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 456 457 /** 458 * Counter for assigning isolated process uids, to avoid frequently reusing the 459 * same ones. 460 */ 461 int mNextIsolatedProcessUid = 0; 462 463 /** 464 * The currently running heavy-weight process, if any. 465 */ 466 ProcessRecord mHeavyWeightProcess = null; 467 468 /** 469 * The last time that various processes have crashed. 470 */ 471 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 472 473 /** 474 * Information about a process that is currently marked as bad. 475 */ 476 static final class BadProcessInfo { 477 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 478 this.time = time; 479 this.shortMsg = shortMsg; 480 this.longMsg = longMsg; 481 this.stack = stack; 482 } 483 484 final long time; 485 final String shortMsg; 486 final String longMsg; 487 final String stack; 488 } 489 490 /** 491 * Set of applications that we consider to be bad, and will reject 492 * incoming broadcasts from (which the user has no control over). 493 * Processes are added to this set when they have crashed twice within 494 * a minimum amount of time; they are removed from it when they are 495 * later restarted (hopefully due to some user action). The value is the 496 * time it was added to the list. 497 */ 498 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 499 500 /** 501 * All of the processes we currently have running organized by pid. 502 * The keys are the pid running the application. 503 * 504 * <p>NOTE: This object is protected by its own lock, NOT the global 505 * activity manager lock! 506 */ 507 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 508 509 /** 510 * All of the processes that have been forced to be foreground. The key 511 * is the pid of the caller who requested it (we hold a death 512 * link on it). 513 */ 514 abstract class ForegroundToken implements IBinder.DeathRecipient { 515 int pid; 516 IBinder token; 517 } 518 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 519 520 /** 521 * List of records for processes that someone had tried to start before the 522 * system was ready. We don't start them at that point, but ensure they 523 * are started by the time booting is complete. 524 */ 525 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 526 527 /** 528 * List of persistent applications that are in the process 529 * of being started. 530 */ 531 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 532 533 /** 534 * Processes that are being forcibly torn down. 535 */ 536 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 537 538 /** 539 * List of running applications, sorted by recent usage. 540 * The first entry in the list is the least recently used. 541 */ 542 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 543 544 /** 545 * Where in mLruProcesses that the processes hosting activities start. 546 */ 547 int mLruProcessActivityStart = 0; 548 549 /** 550 * Where in mLruProcesses that the processes hosting services start. 551 * This is after (lower index) than mLruProcessesActivityStart. 552 */ 553 int mLruProcessServiceStart = 0; 554 555 /** 556 * List of processes that should gc as soon as things are idle. 557 */ 558 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 559 560 /** 561 * Processes we want to collect PSS data from. 562 */ 563 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 564 565 /** 566 * Last time we requested PSS data of all processes. 567 */ 568 long mLastFullPssTime = SystemClock.uptimeMillis(); 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 final UsageStatsService mUsageStatsService; 817 818 /** 819 * Information about and control over application operations 820 */ 821 final AppOpsService mAppOpsService; 822 823 /** 824 * Current configuration information. HistoryRecord objects are given 825 * a reference to this object to indicate which configuration they are 826 * currently running in, so this object must be kept immutable. 827 */ 828 Configuration mConfiguration = new Configuration(); 829 830 /** 831 * Current sequencing integer of the configuration, for skipping old 832 * configurations. 833 */ 834 int mConfigurationSeq = 0; 835 836 /** 837 * Hardware-reported OpenGLES version. 838 */ 839 final int GL_ES_VERSION; 840 841 /** 842 * List of initialization arguments to pass to all processes when binding applications to them. 843 * For example, references to the commonly used services. 844 */ 845 HashMap<String, IBinder> mAppBindArgs; 846 847 /** 848 * Temporary to avoid allocations. Protected by main lock. 849 */ 850 final StringBuilder mStringBuilder = new StringBuilder(256); 851 852 /** 853 * Used to control how we initialize the service. 854 */ 855 ComponentName mTopComponent; 856 String mTopAction = Intent.ACTION_MAIN; 857 String mTopData; 858 boolean mProcessesReady = false; 859 boolean mSystemReady = false; 860 boolean mBooting = false; 861 boolean mWaitingUpdate = false; 862 boolean mDidUpdate = false; 863 boolean mOnBattery = false; 864 boolean mLaunchWarningShown = false; 865 866 Context mContext; 867 868 int mFactoryTest; 869 870 boolean mCheckedForSetup; 871 872 /** 873 * The time at which we will allow normal application switches again, 874 * after a call to {@link #stopAppSwitches()}. 875 */ 876 long mAppSwitchesAllowedTime; 877 878 /** 879 * This is set to true after the first switch after mAppSwitchesAllowedTime 880 * is set; any switches after that will clear the time. 881 */ 882 boolean mDidAppSwitch; 883 884 /** 885 * Last time (in realtime) at which we checked for power usage. 886 */ 887 long mLastPowerCheckRealtime; 888 889 /** 890 * Last time (in uptime) at which we checked for power usage. 891 */ 892 long mLastPowerCheckUptime; 893 894 /** 895 * Set while we are wanting to sleep, to prevent any 896 * activities from being started/resumed. 897 */ 898 private boolean mSleeping = false; 899 900 /** 901 * Set while we are running a voice interaction. This overrides 902 * sleeping while it is active. 903 */ 904 private boolean mRunningVoice = false; 905 906 /** 907 * State of external calls telling us if the device is asleep. 908 */ 909 private boolean mWentToSleep = false; 910 911 /** 912 * State of external call telling us if the lock screen is shown. 913 */ 914 private boolean mLockScreenShown = false; 915 916 /** 917 * Set if we are shutting down the system, similar to sleeping. 918 */ 919 boolean mShuttingDown = false; 920 921 /** 922 * Current sequence id for oom_adj computation traversal. 923 */ 924 int mAdjSeq = 0; 925 926 /** 927 * Current sequence id for process LRU updating. 928 */ 929 int mLruSeq = 0; 930 931 /** 932 * Keep track of the non-cached/empty process we last found, to help 933 * determine how to distribute cached/empty processes next time. 934 */ 935 int mNumNonCachedProcs = 0; 936 937 /** 938 * Keep track of the number of cached hidden procs, to balance oom adj 939 * distribution between those and empty procs. 940 */ 941 int mNumCachedHiddenProcs = 0; 942 943 /** 944 * Keep track of the number of service processes we last found, to 945 * determine on the next iteration which should be B services. 946 */ 947 int mNumServiceProcs = 0; 948 int mNewNumAServiceProcs = 0; 949 int mNewNumServiceProcs = 0; 950 951 /** 952 * Allow the current computed overall memory level of the system to go down? 953 * This is set to false when we are killing processes for reasons other than 954 * memory management, so that the now smaller process list will not be taken as 955 * an indication that memory is tighter. 956 */ 957 boolean mAllowLowerMemLevel = false; 958 959 /** 960 * The last computed memory level, for holding when we are in a state that 961 * processes are going away for other reasons. 962 */ 963 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 964 965 /** 966 * The last total number of process we have, to determine if changes actually look 967 * like a shrinking number of process due to lower RAM. 968 */ 969 int mLastNumProcesses; 970 971 /** 972 * The uptime of the last time we performed idle maintenance. 973 */ 974 long mLastIdleTime = SystemClock.uptimeMillis(); 975 976 /** 977 * Total time spent with RAM that has been added in the past since the last idle time. 978 */ 979 long mLowRamTimeSinceLastIdle = 0; 980 981 /** 982 * If RAM is currently low, when that horrible situation started. 983 */ 984 long mLowRamStartTime = 0; 985 986 /** 987 * For reporting to battery stats the current top application. 988 */ 989 private String mCurResumedPackage = null; 990 private int mCurResumedUid = -1; 991 992 /** 993 * For reporting to battery stats the apps currently running foreground 994 * service. The ProcessMap is package/uid tuples; each of these contain 995 * an array of the currently foreground processes. 996 */ 997 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 998 = new ProcessMap<ArrayList<ProcessRecord>>(); 999 1000 /** 1001 * This is set if we had to do a delayed dexopt of an app before launching 1002 * it, to increase the ANR timeouts in that case. 1003 */ 1004 boolean mDidDexOpt; 1005 1006 /** 1007 * Set if the systemServer made a call to enterSafeMode. 1008 */ 1009 boolean mSafeMode; 1010 1011 String mDebugApp = null; 1012 boolean mWaitForDebugger = false; 1013 boolean mDebugTransient = false; 1014 String mOrigDebugApp = null; 1015 boolean mOrigWaitForDebugger = false; 1016 boolean mAlwaysFinishActivities = false; 1017 IActivityController mController = null; 1018 String mProfileApp = null; 1019 ProcessRecord mProfileProc = null; 1020 String mProfileFile; 1021 ParcelFileDescriptor mProfileFd; 1022 int mProfileType = 0; 1023 boolean mAutoStopProfiler = false; 1024 String mOpenGlTraceApp = null; 1025 1026 static class ProcessChangeItem { 1027 static final int CHANGE_ACTIVITIES = 1<<0; 1028 static final int CHANGE_PROCESS_STATE = 1<<1; 1029 int changes; 1030 int uid; 1031 int pid; 1032 int processState; 1033 boolean foregroundActivities; 1034 } 1035 1036 final RemoteCallbackList<IProcessObserver> mProcessObservers 1037 = new RemoteCallbackList<IProcessObserver>(); 1038 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1039 1040 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1041 = new ArrayList<ProcessChangeItem>(); 1042 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1043 = new ArrayList<ProcessChangeItem>(); 1044 1045 /** 1046 * Runtime CPU use collection thread. This object's lock is used to 1047 * protect all related state. 1048 */ 1049 final Thread mProcessCpuThread; 1050 1051 /** 1052 * Used to collect process stats when showing not responding dialog. 1053 * Protected by mProcessCpuThread. 1054 */ 1055 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1056 MONITOR_THREAD_CPU_USAGE); 1057 final AtomicLong mLastCpuTime = new AtomicLong(0); 1058 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1059 1060 long mLastWriteTime = 0; 1061 1062 /** 1063 * Used to retain an update lock when the foreground activity is in 1064 * immersive mode. 1065 */ 1066 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1067 1068 /** 1069 * Set to true after the system has finished booting. 1070 */ 1071 boolean mBooted = false; 1072 1073 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1074 int mProcessLimitOverride = -1; 1075 1076 WindowManagerService mWindowManager; 1077 1078 final ActivityThread mSystemThread; 1079 1080 int mCurrentUserId = 0; 1081 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1082 private UserManagerService mUserManager; 1083 1084 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1085 final ProcessRecord mApp; 1086 final int mPid; 1087 final IApplicationThread mAppThread; 1088 1089 AppDeathRecipient(ProcessRecord app, int pid, 1090 IApplicationThread thread) { 1091 if (localLOGV) Slog.v( 1092 TAG, "New death recipient " + this 1093 + " for thread " + thread.asBinder()); 1094 mApp = app; 1095 mPid = pid; 1096 mAppThread = thread; 1097 } 1098 1099 @Override 1100 public void binderDied() { 1101 if (localLOGV) Slog.v( 1102 TAG, "Death received in " + this 1103 + " for thread " + mAppThread.asBinder()); 1104 synchronized(ActivityManagerService.this) { 1105 appDiedLocked(mApp, mPid, mAppThread); 1106 } 1107 } 1108 } 1109 1110 static final int SHOW_ERROR_MSG = 1; 1111 static final int SHOW_NOT_RESPONDING_MSG = 2; 1112 static final int SHOW_FACTORY_ERROR_MSG = 3; 1113 static final int UPDATE_CONFIGURATION_MSG = 4; 1114 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1115 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1116 static final int SERVICE_TIMEOUT_MSG = 12; 1117 static final int UPDATE_TIME_ZONE = 13; 1118 static final int SHOW_UID_ERROR_MSG = 14; 1119 static final int IM_FEELING_LUCKY_MSG = 15; 1120 static final int PROC_START_TIMEOUT_MSG = 20; 1121 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1122 static final int KILL_APPLICATION_MSG = 22; 1123 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1124 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1125 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1126 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1127 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1128 static final int CLEAR_DNS_CACHE_MSG = 28; 1129 static final int UPDATE_HTTP_PROXY_MSG = 29; 1130 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1131 static final int DISPATCH_PROCESSES_CHANGED = 31; 1132 static final int DISPATCH_PROCESS_DIED = 32; 1133 static final int REPORT_MEM_USAGE_MSG = 33; 1134 static final int REPORT_USER_SWITCH_MSG = 34; 1135 static final int CONTINUE_USER_SWITCH_MSG = 35; 1136 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1137 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1138 static final int PERSIST_URI_GRANTS_MSG = 38; 1139 static final int REQUEST_ALL_PSS_MSG = 39; 1140 static final int START_PROFILES_MSG = 40; 1141 static final int UPDATE_TIME = 41; 1142 static final int SYSTEM_USER_START_MSG = 42; 1143 static final int SYSTEM_USER_CURRENT_MSG = 43; 1144 1145 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1146 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1147 static final int FIRST_COMPAT_MODE_MSG = 300; 1148 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1149 1150 AlertDialog mUidAlert; 1151 CompatModeDialog mCompatModeDialog; 1152 long mLastMemUsageReportTime = 0; 1153 1154 /** 1155 * Flag whether the current user is a "monkey", i.e. whether 1156 * the UI is driven by a UI automation tool. 1157 */ 1158 private boolean mUserIsMonkey; 1159 1160 final ServiceThread mHandlerThread; 1161 final MainHandler mHandler; 1162 1163 final class MainHandler extends Handler { 1164 public MainHandler(Looper looper) { 1165 super(looper, null, true); 1166 } 1167 1168 @Override 1169 public void handleMessage(Message msg) { 1170 switch (msg.what) { 1171 case SHOW_ERROR_MSG: { 1172 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1173 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1174 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1175 synchronized (ActivityManagerService.this) { 1176 ProcessRecord proc = (ProcessRecord)data.get("app"); 1177 AppErrorResult res = (AppErrorResult) data.get("result"); 1178 if (proc != null && proc.crashDialog != null) { 1179 Slog.e(TAG, "App already has crash dialog: " + proc); 1180 if (res != null) { 1181 res.set(0); 1182 } 1183 return; 1184 } 1185 if (!showBackground && UserHandle.getAppId(proc.uid) 1186 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1187 && proc.pid != MY_PID) { 1188 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1189 if (res != null) { 1190 res.set(0); 1191 } 1192 return; 1193 } 1194 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1195 Dialog d = new AppErrorDialog(mContext, 1196 ActivityManagerService.this, res, proc); 1197 d.show(); 1198 proc.crashDialog = d; 1199 } else { 1200 // The device is asleep, so just pretend that the user 1201 // saw a crash dialog and hit "force quit". 1202 if (res != null) { 1203 res.set(0); 1204 } 1205 } 1206 } 1207 1208 ensureBootCompleted(); 1209 } break; 1210 case SHOW_NOT_RESPONDING_MSG: { 1211 synchronized (ActivityManagerService.this) { 1212 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1213 ProcessRecord proc = (ProcessRecord)data.get("app"); 1214 if (proc != null && proc.anrDialog != null) { 1215 Slog.e(TAG, "App already has anr dialog: " + proc); 1216 return; 1217 } 1218 1219 Intent intent = new Intent("android.intent.action.ANR"); 1220 if (!mProcessesReady) { 1221 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1222 | Intent.FLAG_RECEIVER_FOREGROUND); 1223 } 1224 broadcastIntentLocked(null, null, intent, 1225 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1226 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1227 1228 if (mShowDialogs) { 1229 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1230 mContext, proc, (ActivityRecord)data.get("activity"), 1231 msg.arg1 != 0); 1232 d.show(); 1233 proc.anrDialog = d; 1234 } else { 1235 // Just kill the app if there is no dialog to be shown. 1236 killAppAtUsersRequest(proc, null); 1237 } 1238 } 1239 1240 ensureBootCompleted(); 1241 } break; 1242 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1243 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1244 synchronized (ActivityManagerService.this) { 1245 ProcessRecord proc = (ProcessRecord) data.get("app"); 1246 if (proc == null) { 1247 Slog.e(TAG, "App not found when showing strict mode dialog."); 1248 break; 1249 } 1250 if (proc.crashDialog != null) { 1251 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1252 return; 1253 } 1254 AppErrorResult res = (AppErrorResult) data.get("result"); 1255 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1256 Dialog d = new StrictModeViolationDialog(mContext, 1257 ActivityManagerService.this, res, proc); 1258 d.show(); 1259 proc.crashDialog = d; 1260 } else { 1261 // The device is asleep, so just pretend that the user 1262 // saw a crash dialog and hit "force quit". 1263 res.set(0); 1264 } 1265 } 1266 ensureBootCompleted(); 1267 } break; 1268 case SHOW_FACTORY_ERROR_MSG: { 1269 Dialog d = new FactoryErrorDialog( 1270 mContext, msg.getData().getCharSequence("msg")); 1271 d.show(); 1272 ensureBootCompleted(); 1273 } break; 1274 case UPDATE_CONFIGURATION_MSG: { 1275 final ContentResolver resolver = mContext.getContentResolver(); 1276 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1277 } break; 1278 case GC_BACKGROUND_PROCESSES_MSG: { 1279 synchronized (ActivityManagerService.this) { 1280 performAppGcsIfAppropriateLocked(); 1281 } 1282 } break; 1283 case WAIT_FOR_DEBUGGER_MSG: { 1284 synchronized (ActivityManagerService.this) { 1285 ProcessRecord app = (ProcessRecord)msg.obj; 1286 if (msg.arg1 != 0) { 1287 if (!app.waitedForDebugger) { 1288 Dialog d = new AppWaitingForDebuggerDialog( 1289 ActivityManagerService.this, 1290 mContext, app); 1291 app.waitDialog = d; 1292 app.waitedForDebugger = true; 1293 d.show(); 1294 } 1295 } else { 1296 if (app.waitDialog != null) { 1297 app.waitDialog.dismiss(); 1298 app.waitDialog = null; 1299 } 1300 } 1301 } 1302 } break; 1303 case SERVICE_TIMEOUT_MSG: { 1304 if (mDidDexOpt) { 1305 mDidDexOpt = false; 1306 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1307 nmsg.obj = msg.obj; 1308 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1309 return; 1310 } 1311 mServices.serviceTimeout((ProcessRecord)msg.obj); 1312 } break; 1313 case UPDATE_TIME_ZONE: { 1314 synchronized (ActivityManagerService.this) { 1315 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1316 ProcessRecord r = mLruProcesses.get(i); 1317 if (r.thread != null) { 1318 try { 1319 r.thread.updateTimeZone(); 1320 } catch (RemoteException ex) { 1321 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1322 } 1323 } 1324 } 1325 } 1326 } break; 1327 case CLEAR_DNS_CACHE_MSG: { 1328 synchronized (ActivityManagerService.this) { 1329 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1330 ProcessRecord r = mLruProcesses.get(i); 1331 if (r.thread != null) { 1332 try { 1333 r.thread.clearDnsCache(); 1334 } catch (RemoteException ex) { 1335 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1336 } 1337 } 1338 } 1339 } 1340 } break; 1341 case UPDATE_HTTP_PROXY_MSG: { 1342 ProxyInfo proxy = (ProxyInfo)msg.obj; 1343 String host = ""; 1344 String port = ""; 1345 String exclList = ""; 1346 Uri pacFileUrl = Uri.EMPTY; 1347 if (proxy != null) { 1348 host = proxy.getHost(); 1349 port = Integer.toString(proxy.getPort()); 1350 exclList = proxy.getExclusionListAsString(); 1351 pacFileUrl = proxy.getPacFileUrl(); 1352 } 1353 synchronized (ActivityManagerService.this) { 1354 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1355 ProcessRecord r = mLruProcesses.get(i); 1356 if (r.thread != null) { 1357 try { 1358 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1359 } catch (RemoteException ex) { 1360 Slog.w(TAG, "Failed to update http proxy for: " + 1361 r.info.processName); 1362 } 1363 } 1364 } 1365 } 1366 } break; 1367 case SHOW_UID_ERROR_MSG: { 1368 String title = "System UIDs Inconsistent"; 1369 String text = "UIDs on the system are inconsistent, you need to wipe your" 1370 + " data partition or your device will be unstable."; 1371 Log.e(TAG, title + ": " + text); 1372 if (mShowDialogs) { 1373 // XXX This is a temporary dialog, no need to localize. 1374 AlertDialog d = new BaseErrorDialog(mContext); 1375 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1376 d.setCancelable(false); 1377 d.setTitle(title); 1378 d.setMessage(text); 1379 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1380 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1381 mUidAlert = d; 1382 d.show(); 1383 } 1384 } break; 1385 case IM_FEELING_LUCKY_MSG: { 1386 if (mUidAlert != null) { 1387 mUidAlert.dismiss(); 1388 mUidAlert = null; 1389 } 1390 } break; 1391 case PROC_START_TIMEOUT_MSG: { 1392 if (mDidDexOpt) { 1393 mDidDexOpt = false; 1394 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1395 nmsg.obj = msg.obj; 1396 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1397 return; 1398 } 1399 ProcessRecord app = (ProcessRecord)msg.obj; 1400 synchronized (ActivityManagerService.this) { 1401 processStartTimedOutLocked(app); 1402 } 1403 } break; 1404 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1405 synchronized (ActivityManagerService.this) { 1406 doPendingActivityLaunchesLocked(true); 1407 } 1408 } break; 1409 case KILL_APPLICATION_MSG: { 1410 synchronized (ActivityManagerService.this) { 1411 int appid = msg.arg1; 1412 boolean restart = (msg.arg2 == 1); 1413 Bundle bundle = (Bundle)msg.obj; 1414 String pkg = bundle.getString("pkg"); 1415 String reason = bundle.getString("reason"); 1416 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1417 false, UserHandle.USER_ALL, reason); 1418 } 1419 } break; 1420 case FINALIZE_PENDING_INTENT_MSG: { 1421 ((PendingIntentRecord)msg.obj).completeFinalize(); 1422 } break; 1423 case POST_HEAVY_NOTIFICATION_MSG: { 1424 INotificationManager inm = NotificationManager.getService(); 1425 if (inm == null) { 1426 return; 1427 } 1428 1429 ActivityRecord root = (ActivityRecord)msg.obj; 1430 ProcessRecord process = root.app; 1431 if (process == null) { 1432 return; 1433 } 1434 1435 try { 1436 Context context = mContext.createPackageContext(process.info.packageName, 0); 1437 String text = mContext.getString(R.string.heavy_weight_notification, 1438 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1439 Notification notification = new Notification(); 1440 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1441 notification.when = 0; 1442 notification.flags = Notification.FLAG_ONGOING_EVENT; 1443 notification.tickerText = text; 1444 notification.defaults = 0; // please be quiet 1445 notification.sound = null; 1446 notification.vibrate = null; 1447 notification.setLatestEventInfo(context, text, 1448 mContext.getText(R.string.heavy_weight_notification_detail), 1449 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1450 PendingIntent.FLAG_CANCEL_CURRENT, null, 1451 new UserHandle(root.userId))); 1452 1453 try { 1454 int[] outId = new int[1]; 1455 inm.enqueueNotificationWithTag("android", "android", null, 1456 R.string.heavy_weight_notification, 1457 notification, outId, root.userId); 1458 } catch (RuntimeException e) { 1459 Slog.w(ActivityManagerService.TAG, 1460 "Error showing notification for heavy-weight app", e); 1461 } catch (RemoteException e) { 1462 } 1463 } catch (NameNotFoundException e) { 1464 Slog.w(TAG, "Unable to create context for heavy notification", e); 1465 } 1466 } break; 1467 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1468 INotificationManager inm = NotificationManager.getService(); 1469 if (inm == null) { 1470 return; 1471 } 1472 try { 1473 inm.cancelNotificationWithTag("android", null, 1474 R.string.heavy_weight_notification, msg.arg1); 1475 } catch (RuntimeException e) { 1476 Slog.w(ActivityManagerService.TAG, 1477 "Error canceling notification for service", e); 1478 } catch (RemoteException e) { 1479 } 1480 } break; 1481 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1482 synchronized (ActivityManagerService.this) { 1483 checkExcessivePowerUsageLocked(true); 1484 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1485 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1486 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1487 } 1488 } break; 1489 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1490 synchronized (ActivityManagerService.this) { 1491 ActivityRecord ar = (ActivityRecord)msg.obj; 1492 if (mCompatModeDialog != null) { 1493 if (mCompatModeDialog.mAppInfo.packageName.equals( 1494 ar.info.applicationInfo.packageName)) { 1495 return; 1496 } 1497 mCompatModeDialog.dismiss(); 1498 mCompatModeDialog = null; 1499 } 1500 if (ar != null && false) { 1501 if (mCompatModePackages.getPackageAskCompatModeLocked( 1502 ar.packageName)) { 1503 int mode = mCompatModePackages.computeCompatModeLocked( 1504 ar.info.applicationInfo); 1505 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1506 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1507 mCompatModeDialog = new CompatModeDialog( 1508 ActivityManagerService.this, mContext, 1509 ar.info.applicationInfo); 1510 mCompatModeDialog.show(); 1511 } 1512 } 1513 } 1514 } 1515 break; 1516 } 1517 case DISPATCH_PROCESSES_CHANGED: { 1518 dispatchProcessesChanged(); 1519 break; 1520 } 1521 case DISPATCH_PROCESS_DIED: { 1522 final int pid = msg.arg1; 1523 final int uid = msg.arg2; 1524 dispatchProcessDied(pid, uid); 1525 break; 1526 } 1527 case REPORT_MEM_USAGE_MSG: { 1528 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1529 Thread thread = new Thread() { 1530 @Override public void run() { 1531 final SparseArray<ProcessMemInfo> infoMap 1532 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1533 for (int i=0, N=memInfos.size(); i<N; i++) { 1534 ProcessMemInfo mi = memInfos.get(i); 1535 infoMap.put(mi.pid, mi); 1536 } 1537 updateCpuStatsNow(); 1538 synchronized (mProcessCpuThread) { 1539 final int N = mProcessCpuTracker.countStats(); 1540 for (int i=0; i<N; i++) { 1541 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1542 if (st.vsize > 0) { 1543 long pss = Debug.getPss(st.pid, null); 1544 if (pss > 0) { 1545 if (infoMap.indexOfKey(st.pid) < 0) { 1546 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1547 ProcessList.NATIVE_ADJ, -1, "native", null); 1548 mi.pss = pss; 1549 memInfos.add(mi); 1550 } 1551 } 1552 } 1553 } 1554 } 1555 1556 long totalPss = 0; 1557 for (int i=0, N=memInfos.size(); i<N; i++) { 1558 ProcessMemInfo mi = memInfos.get(i); 1559 if (mi.pss == 0) { 1560 mi.pss = Debug.getPss(mi.pid, null); 1561 } 1562 totalPss += mi.pss; 1563 } 1564 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1565 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1566 if (lhs.oomAdj != rhs.oomAdj) { 1567 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1568 } 1569 if (lhs.pss != rhs.pss) { 1570 return lhs.pss < rhs.pss ? 1 : -1; 1571 } 1572 return 0; 1573 } 1574 }); 1575 1576 StringBuilder tag = new StringBuilder(128); 1577 StringBuilder stack = new StringBuilder(128); 1578 tag.append("Low on memory -- "); 1579 appendMemBucket(tag, totalPss, "total", false); 1580 appendMemBucket(stack, totalPss, "total", true); 1581 1582 StringBuilder logBuilder = new StringBuilder(1024); 1583 logBuilder.append("Low on memory:\n"); 1584 1585 boolean firstLine = true; 1586 int lastOomAdj = Integer.MIN_VALUE; 1587 for (int i=0, N=memInfos.size(); i<N; i++) { 1588 ProcessMemInfo mi = memInfos.get(i); 1589 1590 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1591 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1592 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1593 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1594 if (lastOomAdj != mi.oomAdj) { 1595 lastOomAdj = mi.oomAdj; 1596 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1597 tag.append(" / "); 1598 } 1599 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1600 if (firstLine) { 1601 stack.append(":"); 1602 firstLine = false; 1603 } 1604 stack.append("\n\t at "); 1605 } else { 1606 stack.append("$"); 1607 } 1608 } else { 1609 tag.append(" "); 1610 stack.append("$"); 1611 } 1612 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1613 appendMemBucket(tag, mi.pss, mi.name, false); 1614 } 1615 appendMemBucket(stack, mi.pss, mi.name, true); 1616 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1617 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1618 stack.append("("); 1619 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1620 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1621 stack.append(DUMP_MEM_OOM_LABEL[k]); 1622 stack.append(":"); 1623 stack.append(DUMP_MEM_OOM_ADJ[k]); 1624 } 1625 } 1626 stack.append(")"); 1627 } 1628 } 1629 1630 logBuilder.append(" "); 1631 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1632 logBuilder.append(' '); 1633 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1634 logBuilder.append(' '); 1635 ProcessList.appendRamKb(logBuilder, mi.pss); 1636 logBuilder.append(" kB: "); 1637 logBuilder.append(mi.name); 1638 logBuilder.append(" ("); 1639 logBuilder.append(mi.pid); 1640 logBuilder.append(") "); 1641 logBuilder.append(mi.adjType); 1642 logBuilder.append('\n'); 1643 if (mi.adjReason != null) { 1644 logBuilder.append(" "); 1645 logBuilder.append(mi.adjReason); 1646 logBuilder.append('\n'); 1647 } 1648 } 1649 1650 logBuilder.append(" "); 1651 ProcessList.appendRamKb(logBuilder, totalPss); 1652 logBuilder.append(" kB: TOTAL\n"); 1653 1654 long[] infos = new long[Debug.MEMINFO_COUNT]; 1655 Debug.getMemInfo(infos); 1656 logBuilder.append(" MemInfo: "); 1657 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1658 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1659 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1660 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1661 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1662 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1663 logBuilder.append(" ZRAM: "); 1664 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1665 logBuilder.append(" kB RAM, "); 1666 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1667 logBuilder.append(" kB swap total, "); 1668 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1669 logBuilder.append(" kB swap free\n"); 1670 } 1671 Slog.i(TAG, logBuilder.toString()); 1672 1673 StringBuilder dropBuilder = new StringBuilder(1024); 1674 /* 1675 StringWriter oomSw = new StringWriter(); 1676 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1677 StringWriter catSw = new StringWriter(); 1678 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1679 String[] emptyArgs = new String[] { }; 1680 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1681 oomPw.flush(); 1682 String oomString = oomSw.toString(); 1683 */ 1684 dropBuilder.append(stack); 1685 dropBuilder.append('\n'); 1686 dropBuilder.append('\n'); 1687 dropBuilder.append(logBuilder); 1688 dropBuilder.append('\n'); 1689 /* 1690 dropBuilder.append(oomString); 1691 dropBuilder.append('\n'); 1692 */ 1693 StringWriter catSw = new StringWriter(); 1694 synchronized (ActivityManagerService.this) { 1695 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1696 String[] emptyArgs = new String[] { }; 1697 catPw.println(); 1698 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1699 catPw.println(); 1700 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1701 false, false, null); 1702 catPw.println(); 1703 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1704 catPw.flush(); 1705 } 1706 dropBuilder.append(catSw.toString()); 1707 addErrorToDropBox("lowmem", null, "system_server", null, 1708 null, tag.toString(), dropBuilder.toString(), null, null); 1709 //Slog.i(TAG, "Sent to dropbox:"); 1710 //Slog.i(TAG, dropBuilder.toString()); 1711 synchronized (ActivityManagerService.this) { 1712 long now = SystemClock.uptimeMillis(); 1713 if (mLastMemUsageReportTime < now) { 1714 mLastMemUsageReportTime = now; 1715 } 1716 } 1717 } 1718 }; 1719 thread.start(); 1720 break; 1721 } 1722 case REPORT_USER_SWITCH_MSG: { 1723 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1724 break; 1725 } 1726 case CONTINUE_USER_SWITCH_MSG: { 1727 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1728 break; 1729 } 1730 case USER_SWITCH_TIMEOUT_MSG: { 1731 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1732 break; 1733 } 1734 case IMMERSIVE_MODE_LOCK_MSG: { 1735 final boolean nextState = (msg.arg1 != 0); 1736 if (mUpdateLock.isHeld() != nextState) { 1737 if (DEBUG_IMMERSIVE) { 1738 final ActivityRecord r = (ActivityRecord) msg.obj; 1739 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1740 } 1741 if (nextState) { 1742 mUpdateLock.acquire(); 1743 } else { 1744 mUpdateLock.release(); 1745 } 1746 } 1747 break; 1748 } 1749 case PERSIST_URI_GRANTS_MSG: { 1750 writeGrantedUriPermissions(); 1751 break; 1752 } 1753 case REQUEST_ALL_PSS_MSG: { 1754 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1755 break; 1756 } 1757 case START_PROFILES_MSG: { 1758 synchronized (ActivityManagerService.this) { 1759 startProfilesLocked(); 1760 } 1761 break; 1762 } 1763 case UPDATE_TIME: { 1764 synchronized (ActivityManagerService.this) { 1765 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1766 ProcessRecord r = mLruProcesses.get(i); 1767 if (r.thread != null) { 1768 try { 1769 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1770 } catch (RemoteException ex) { 1771 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1772 } 1773 } 1774 } 1775 } 1776 break; 1777 } 1778 case SYSTEM_USER_START_MSG: { 1779 mSystemServiceManager.startUser(msg.arg1); 1780 break; 1781 } 1782 case SYSTEM_USER_CURRENT_MSG: { 1783 mSystemServiceManager.switchUser(msg.arg1); 1784 break; 1785 } 1786 } 1787 } 1788 }; 1789 1790 static final int COLLECT_PSS_BG_MSG = 1; 1791 1792 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1793 @Override 1794 public void handleMessage(Message msg) { 1795 switch (msg.what) { 1796 case COLLECT_PSS_BG_MSG: { 1797 int i=0, num=0; 1798 long start = SystemClock.uptimeMillis(); 1799 long[] tmp = new long[1]; 1800 do { 1801 ProcessRecord proc; 1802 int procState; 1803 int pid; 1804 synchronized (ActivityManagerService.this) { 1805 if (i >= mPendingPssProcesses.size()) { 1806 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1807 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1808 mPendingPssProcesses.clear(); 1809 return; 1810 } 1811 proc = mPendingPssProcesses.get(i); 1812 procState = proc.pssProcState; 1813 if (proc.thread != null && procState == proc.setProcState) { 1814 pid = proc.pid; 1815 } else { 1816 proc = null; 1817 pid = 0; 1818 } 1819 i++; 1820 } 1821 if (proc != null) { 1822 long pss = Debug.getPss(pid, tmp); 1823 synchronized (ActivityManagerService.this) { 1824 if (proc.thread != null && proc.setProcState == procState 1825 && proc.pid == pid) { 1826 num++; 1827 proc.lastPssTime = SystemClock.uptimeMillis(); 1828 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1829 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1830 + ": " + pss + " lastPss=" + proc.lastPss 1831 + " state=" + ProcessList.makeProcStateString(procState)); 1832 if (proc.initialIdlePss == 0) { 1833 proc.initialIdlePss = pss; 1834 } 1835 proc.lastPss = pss; 1836 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1837 proc.lastCachedPss = pss; 1838 } 1839 } 1840 } 1841 } 1842 } while (true); 1843 } 1844 } 1845 } 1846 }; 1847 1848 /** 1849 * Monitor for package changes and update our internal state. 1850 */ 1851 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1852 @Override 1853 public void onPackageRemoved(String packageName, int uid) { 1854 // Remove all tasks with activities in the specified package from the list of recent tasks 1855 synchronized (ActivityManagerService.this) { 1856 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1857 TaskRecord tr = mRecentTasks.get(i); 1858 ComponentName cn = tr.intent.getComponent(); 1859 if (cn != null && cn.getPackageName().equals(packageName)) { 1860 // If the package name matches, remove the task and kill the process 1861 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1862 } 1863 } 1864 } 1865 } 1866 1867 @Override 1868 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1869 onPackageModified(packageName); 1870 return true; 1871 } 1872 1873 @Override 1874 public void onPackageModified(String packageName) { 1875 final PackageManager pm = mContext.getPackageManager(); 1876 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1877 new ArrayList<Pair<Intent, Integer>>(); 1878 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1879 // Copy the list of recent tasks so that we don't hold onto the lock on 1880 // ActivityManagerService for long periods while checking if components exist. 1881 synchronized (ActivityManagerService.this) { 1882 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1883 TaskRecord tr = mRecentTasks.get(i); 1884 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1885 } 1886 } 1887 // Check the recent tasks and filter out all tasks with components that no longer exist. 1888 Intent tmpI = new Intent(); 1889 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1890 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1891 ComponentName cn = p.first.getComponent(); 1892 if (cn != null && cn.getPackageName().equals(packageName)) { 1893 try { 1894 // Add the task to the list to remove if the component no longer exists 1895 tmpI.setComponent(cn); 1896 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1897 tasksToRemove.add(p.second); 1898 } 1899 } catch (Exception e) {} 1900 } 1901 } 1902 // Prune all the tasks with removed components from the list of recent tasks 1903 synchronized (ActivityManagerService.this) { 1904 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1905 // Remove the task but don't kill the process (since other components in that 1906 // package may still be running and in the background) 1907 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1908 } 1909 } 1910 } 1911 1912 @Override 1913 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1914 // Force stop the specified packages 1915 if (packages != null) { 1916 for (String pkg : packages) { 1917 synchronized (ActivityManagerService.this) { 1918 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1919 "finished booting")) { 1920 return true; 1921 } 1922 } 1923 } 1924 } 1925 return false; 1926 } 1927 }; 1928 1929 public void setSystemProcess() { 1930 try { 1931 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1932 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1933 ServiceManager.addService("meminfo", new MemBinder(this)); 1934 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1935 ServiceManager.addService("dbinfo", new DbBinder(this)); 1936 if (MONITOR_CPU_USAGE) { 1937 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1938 } 1939 ServiceManager.addService("permission", new PermissionController(this)); 1940 1941 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1942 "android", STOCK_PM_FLAGS); 1943 mSystemThread.installSystemApplicationInfo(info); 1944 1945 synchronized (this) { 1946 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1947 app.persistent = true; 1948 app.pid = MY_PID; 1949 app.maxAdj = ProcessList.SYSTEM_ADJ; 1950 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1951 mProcessNames.put(app.processName, app.uid, app); 1952 synchronized (mPidsSelfLocked) { 1953 mPidsSelfLocked.put(app.pid, app); 1954 } 1955 updateLruProcessLocked(app, false, null); 1956 updateOomAdjLocked(); 1957 } 1958 } catch (PackageManager.NameNotFoundException e) { 1959 throw new RuntimeException( 1960 "Unable to find android system package", e); 1961 } 1962 } 1963 1964 public void setWindowManager(WindowManagerService wm) { 1965 mWindowManager = wm; 1966 mStackSupervisor.setWindowManager(wm); 1967 } 1968 1969 public void startObservingNativeCrashes() { 1970 final NativeCrashListener ncl = new NativeCrashListener(this); 1971 ncl.start(); 1972 } 1973 1974 public IAppOpsService getAppOpsService() { 1975 return mAppOpsService; 1976 } 1977 1978 static class MemBinder extends Binder { 1979 ActivityManagerService mActivityManagerService; 1980 MemBinder(ActivityManagerService activityManagerService) { 1981 mActivityManagerService = activityManagerService; 1982 } 1983 1984 @Override 1985 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1986 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1987 != PackageManager.PERMISSION_GRANTED) { 1988 pw.println("Permission Denial: can't dump meminfo from from pid=" 1989 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1990 + " without permission " + android.Manifest.permission.DUMP); 1991 return; 1992 } 1993 1994 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1995 } 1996 } 1997 1998 static class GraphicsBinder extends Binder { 1999 ActivityManagerService mActivityManagerService; 2000 GraphicsBinder(ActivityManagerService activityManagerService) { 2001 mActivityManagerService = activityManagerService; 2002 } 2003 2004 @Override 2005 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2006 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2007 != PackageManager.PERMISSION_GRANTED) { 2008 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 2009 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2010 + " without permission " + android.Manifest.permission.DUMP); 2011 return; 2012 } 2013 2014 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2015 } 2016 } 2017 2018 static class DbBinder extends Binder { 2019 ActivityManagerService mActivityManagerService; 2020 DbBinder(ActivityManagerService activityManagerService) { 2021 mActivityManagerService = activityManagerService; 2022 } 2023 2024 @Override 2025 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2026 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2027 != PackageManager.PERMISSION_GRANTED) { 2028 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2029 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2030 + " without permission " + android.Manifest.permission.DUMP); 2031 return; 2032 } 2033 2034 mActivityManagerService.dumpDbInfo(fd, pw, args); 2035 } 2036 } 2037 2038 static class CpuBinder extends Binder { 2039 ActivityManagerService mActivityManagerService; 2040 CpuBinder(ActivityManagerService activityManagerService) { 2041 mActivityManagerService = activityManagerService; 2042 } 2043 2044 @Override 2045 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2046 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2047 != PackageManager.PERMISSION_GRANTED) { 2048 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2049 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2050 + " without permission " + android.Manifest.permission.DUMP); 2051 return; 2052 } 2053 2054 synchronized (mActivityManagerService.mProcessCpuThread) { 2055 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2056 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2057 SystemClock.uptimeMillis())); 2058 } 2059 } 2060 } 2061 2062 public static final class Lifecycle extends SystemService { 2063 private final ActivityManagerService mService; 2064 2065 public Lifecycle(Context context) { 2066 super(context); 2067 mService = new ActivityManagerService(context); 2068 } 2069 2070 @Override 2071 public void onStart() { 2072 mService.start(); 2073 } 2074 2075 public ActivityManagerService getService() { 2076 return mService; 2077 } 2078 } 2079 2080 // Note: This method is invoked on the main thread but may need to attach various 2081 // handlers to other threads. So take care to be explicit about the looper. 2082 public ActivityManagerService(Context systemContext) { 2083 mContext = systemContext; 2084 mFactoryTest = FactoryTest.getMode(); 2085 mSystemThread = ActivityThread.currentActivityThread(); 2086 2087 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2088 2089 mHandlerThread = new ServiceThread(TAG, 2090 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2091 mHandlerThread.start(); 2092 mHandler = new MainHandler(mHandlerThread.getLooper()); 2093 2094 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2095 "foreground", BROADCAST_FG_TIMEOUT, false); 2096 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2097 "background", BROADCAST_BG_TIMEOUT, true); 2098 mBroadcastQueues[0] = mFgBroadcastQueue; 2099 mBroadcastQueues[1] = mBgBroadcastQueue; 2100 2101 mServices = new ActiveServices(this); 2102 mProviderMap = new ProviderMap(this); 2103 2104 // TODO: Move creation of battery stats service outside of activity manager service. 2105 File dataDir = Environment.getDataDirectory(); 2106 File systemDir = new File(dataDir, "system"); 2107 systemDir.mkdirs(); 2108 mBatteryStatsService = new BatteryStatsService(new File( 2109 systemDir, "batterystats.bin").toString(), mHandler); 2110 mBatteryStatsService.getActiveStatistics().readLocked(); 2111 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2112 mOnBattery = DEBUG_POWER ? true 2113 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2114 mBatteryStatsService.getActiveStatistics().setCallback(this); 2115 2116 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2117 2118 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2119 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2120 2121 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2122 2123 // User 0 is the first and only user that runs at boot. 2124 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2125 mUserLru.add(Integer.valueOf(0)); 2126 updateStartedUserArrayLocked(); 2127 2128 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2129 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2130 2131 mConfiguration.setToDefaults(); 2132 mConfiguration.setLocale(Locale.getDefault()); 2133 2134 mConfigurationSeq = mConfiguration.seq = 1; 2135 mProcessCpuTracker.init(); 2136 2137 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2138 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2139 mStackSupervisor = new ActivityStackSupervisor(this); 2140 2141 mProcessCpuThread = new Thread("CpuTracker") { 2142 @Override 2143 public void run() { 2144 while (true) { 2145 try { 2146 try { 2147 synchronized(this) { 2148 final long now = SystemClock.uptimeMillis(); 2149 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2150 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2151 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2152 // + ", write delay=" + nextWriteDelay); 2153 if (nextWriteDelay < nextCpuDelay) { 2154 nextCpuDelay = nextWriteDelay; 2155 } 2156 if (nextCpuDelay > 0) { 2157 mProcessCpuMutexFree.set(true); 2158 this.wait(nextCpuDelay); 2159 } 2160 } 2161 } catch (InterruptedException e) { 2162 } 2163 updateCpuStatsNow(); 2164 } catch (Exception e) { 2165 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2166 } 2167 } 2168 } 2169 }; 2170 2171 Watchdog.getInstance().addMonitor(this); 2172 Watchdog.getInstance().addThread(mHandler); 2173 } 2174 2175 public void setSystemServiceManager(SystemServiceManager mgr) { 2176 mSystemServiceManager = mgr; 2177 } 2178 2179 private void start() { 2180 mProcessCpuThread.start(); 2181 2182 mBatteryStatsService.publish(mContext); 2183 mUsageStatsService.publish(mContext); 2184 mAppOpsService.publish(mContext); 2185 2186 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2187 } 2188 2189 @Override 2190 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2191 throws RemoteException { 2192 if (code == SYSPROPS_TRANSACTION) { 2193 // We need to tell all apps about the system property change. 2194 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2195 synchronized(this) { 2196 final int NP = mProcessNames.getMap().size(); 2197 for (int ip=0; ip<NP; ip++) { 2198 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2199 final int NA = apps.size(); 2200 for (int ia=0; ia<NA; ia++) { 2201 ProcessRecord app = apps.valueAt(ia); 2202 if (app.thread != null) { 2203 procs.add(app.thread.asBinder()); 2204 } 2205 } 2206 } 2207 } 2208 2209 int N = procs.size(); 2210 for (int i=0; i<N; i++) { 2211 Parcel data2 = Parcel.obtain(); 2212 try { 2213 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2214 } catch (RemoteException e) { 2215 } 2216 data2.recycle(); 2217 } 2218 } 2219 try { 2220 return super.onTransact(code, data, reply, flags); 2221 } catch (RuntimeException e) { 2222 // The activity manager only throws security exceptions, so let's 2223 // log all others. 2224 if (!(e instanceof SecurityException)) { 2225 Slog.wtf(TAG, "Activity Manager Crash", e); 2226 } 2227 throw e; 2228 } 2229 } 2230 2231 void updateCpuStats() { 2232 final long now = SystemClock.uptimeMillis(); 2233 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2234 return; 2235 } 2236 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2237 synchronized (mProcessCpuThread) { 2238 mProcessCpuThread.notify(); 2239 } 2240 } 2241 } 2242 2243 void updateCpuStatsNow() { 2244 synchronized (mProcessCpuThread) { 2245 mProcessCpuMutexFree.set(false); 2246 final long now = SystemClock.uptimeMillis(); 2247 boolean haveNewCpuStats = false; 2248 2249 if (MONITOR_CPU_USAGE && 2250 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2251 mLastCpuTime.set(now); 2252 haveNewCpuStats = true; 2253 mProcessCpuTracker.update(); 2254 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2255 //Slog.i(TAG, "Total CPU usage: " 2256 // + mProcessCpu.getTotalCpuPercent() + "%"); 2257 2258 // Slog the cpu usage if the property is set. 2259 if ("true".equals(SystemProperties.get("events.cpu"))) { 2260 int user = mProcessCpuTracker.getLastUserTime(); 2261 int system = mProcessCpuTracker.getLastSystemTime(); 2262 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2263 int irq = mProcessCpuTracker.getLastIrqTime(); 2264 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2265 int idle = mProcessCpuTracker.getLastIdleTime(); 2266 2267 int total = user + system + iowait + irq + softIrq + idle; 2268 if (total == 0) total = 1; 2269 2270 EventLog.writeEvent(EventLogTags.CPU, 2271 ((user+system+iowait+irq+softIrq) * 100) / total, 2272 (user * 100) / total, 2273 (system * 100) / total, 2274 (iowait * 100) / total, 2275 (irq * 100) / total, 2276 (softIrq * 100) / total); 2277 } 2278 } 2279 2280 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2281 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2282 synchronized(bstats) { 2283 synchronized(mPidsSelfLocked) { 2284 if (haveNewCpuStats) { 2285 if (mOnBattery) { 2286 int perc = bstats.startAddingCpuLocked(); 2287 int totalUTime = 0; 2288 int totalSTime = 0; 2289 final int N = mProcessCpuTracker.countStats(); 2290 for (int i=0; i<N; i++) { 2291 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2292 if (!st.working) { 2293 continue; 2294 } 2295 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2296 int otherUTime = (st.rel_utime*perc)/100; 2297 int otherSTime = (st.rel_stime*perc)/100; 2298 totalUTime += otherUTime; 2299 totalSTime += otherSTime; 2300 if (pr != null) { 2301 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2302 if (ps == null || !ps.isActive()) { 2303 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2304 pr.info.uid, pr.processName); 2305 } 2306 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2307 st.rel_stime-otherSTime); 2308 ps.addSpeedStepTimes(cpuSpeedTimes); 2309 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2310 } else { 2311 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2312 if (ps == null || !ps.isActive()) { 2313 st.batteryStats = ps = bstats.getProcessStatsLocked( 2314 bstats.mapUid(st.uid), st.name); 2315 } 2316 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2317 st.rel_stime-otherSTime); 2318 ps.addSpeedStepTimes(cpuSpeedTimes); 2319 } 2320 } 2321 bstats.finishAddingCpuLocked(perc, totalUTime, 2322 totalSTime, cpuSpeedTimes); 2323 } 2324 } 2325 } 2326 2327 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2328 mLastWriteTime = now; 2329 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2330 } 2331 } 2332 } 2333 } 2334 2335 @Override 2336 public void batteryNeedsCpuUpdate() { 2337 updateCpuStatsNow(); 2338 } 2339 2340 @Override 2341 public void batteryPowerChanged(boolean onBattery) { 2342 // When plugging in, update the CPU stats first before changing 2343 // the plug state. 2344 updateCpuStatsNow(); 2345 synchronized (this) { 2346 synchronized(mPidsSelfLocked) { 2347 mOnBattery = DEBUG_POWER ? true : onBattery; 2348 } 2349 } 2350 } 2351 2352 /** 2353 * Initialize the application bind args. These are passed to each 2354 * process when the bindApplication() IPC is sent to the process. They're 2355 * lazily setup to make sure the services are running when they're asked for. 2356 */ 2357 private HashMap<String, IBinder> getCommonServicesLocked() { 2358 if (mAppBindArgs == null) { 2359 mAppBindArgs = new HashMap<String, IBinder>(); 2360 2361 // Setup the application init args 2362 mAppBindArgs.put("package", ServiceManager.getService("package")); 2363 mAppBindArgs.put("window", ServiceManager.getService("window")); 2364 mAppBindArgs.put(Context.ALARM_SERVICE, 2365 ServiceManager.getService(Context.ALARM_SERVICE)); 2366 } 2367 return mAppBindArgs; 2368 } 2369 2370 final void setFocusedActivityLocked(ActivityRecord r) { 2371 if (mFocusedActivity != r) { 2372 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2373 mFocusedActivity = r; 2374 if (r.task != null && r.task.voiceInteractor != null) { 2375 startRunningVoiceLocked(); 2376 } else { 2377 finishRunningVoiceLocked(); 2378 } 2379 mStackSupervisor.setFocusedStack(r); 2380 if (r != null) { 2381 mWindowManager.setFocusedApp(r.appToken, true); 2382 } 2383 applyUpdateLockStateLocked(r); 2384 } 2385 } 2386 2387 final void clearFocusedActivity(ActivityRecord r) { 2388 if (mFocusedActivity == r) { 2389 mFocusedActivity = null; 2390 } 2391 } 2392 2393 @Override 2394 public void setFocusedStack(int stackId) { 2395 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2396 synchronized (ActivityManagerService.this) { 2397 ActivityStack stack = mStackSupervisor.getStack(stackId); 2398 if (stack != null) { 2399 ActivityRecord r = stack.topRunningActivityLocked(null); 2400 if (r != null) { 2401 setFocusedActivityLocked(r); 2402 } 2403 } 2404 } 2405 } 2406 2407 @Override 2408 public void notifyActivityDrawn(IBinder token) { 2409 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2410 synchronized (this) { 2411 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2412 if (r != null) { 2413 r.task.stack.notifyActivityDrawnLocked(r); 2414 } 2415 } 2416 } 2417 2418 final void applyUpdateLockStateLocked(ActivityRecord r) { 2419 // Modifications to the UpdateLock state are done on our handler, outside 2420 // the activity manager's locks. The new state is determined based on the 2421 // state *now* of the relevant activity record. The object is passed to 2422 // the handler solely for logging detail, not to be consulted/modified. 2423 final boolean nextState = r != null && r.immersive; 2424 mHandler.sendMessage( 2425 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2426 } 2427 2428 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2429 Message msg = Message.obtain(); 2430 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2431 msg.obj = r.task.askedCompatMode ? null : r; 2432 mHandler.sendMessage(msg); 2433 } 2434 2435 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2436 String what, Object obj, ProcessRecord srcApp) { 2437 app.lastActivityTime = now; 2438 2439 if (app.activities.size() > 0) { 2440 // Don't want to touch dependent processes that are hosting activities. 2441 return index; 2442 } 2443 2444 int lrui = mLruProcesses.lastIndexOf(app); 2445 if (lrui < 0) { 2446 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2447 + what + " " + obj + " from " + srcApp); 2448 return index; 2449 } 2450 2451 if (lrui >= index) { 2452 // Don't want to cause this to move dependent processes *back* in the 2453 // list as if they were less frequently used. 2454 return index; 2455 } 2456 2457 if (lrui >= mLruProcessActivityStart) { 2458 // Don't want to touch dependent processes that are hosting activities. 2459 return index; 2460 } 2461 2462 mLruProcesses.remove(lrui); 2463 if (index > 0) { 2464 index--; 2465 } 2466 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2467 + " in LRU list: " + app); 2468 mLruProcesses.add(index, app); 2469 return index; 2470 } 2471 2472 final void removeLruProcessLocked(ProcessRecord app) { 2473 int lrui = mLruProcesses.lastIndexOf(app); 2474 if (lrui >= 0) { 2475 if (lrui <= mLruProcessActivityStart) { 2476 mLruProcessActivityStart--; 2477 } 2478 if (lrui <= mLruProcessServiceStart) { 2479 mLruProcessServiceStart--; 2480 } 2481 mLruProcesses.remove(lrui); 2482 } 2483 } 2484 2485 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2486 ProcessRecord client) { 2487 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2488 || app.treatLikeActivity; 2489 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2490 if (!activityChange && hasActivity) { 2491 // The process has activities, so we are only allowing activity-based adjustments 2492 // to move it. It should be kept in the front of the list with other 2493 // processes that have activities, and we don't want those to change their 2494 // order except due to activity operations. 2495 return; 2496 } 2497 2498 mLruSeq++; 2499 final long now = SystemClock.uptimeMillis(); 2500 app.lastActivityTime = now; 2501 2502 // First a quick reject: if the app is already at the position we will 2503 // put it, then there is nothing to do. 2504 if (hasActivity) { 2505 final int N = mLruProcesses.size(); 2506 if (N > 0 && mLruProcesses.get(N-1) == app) { 2507 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2508 return; 2509 } 2510 } else { 2511 if (mLruProcessServiceStart > 0 2512 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2513 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2514 return; 2515 } 2516 } 2517 2518 int lrui = mLruProcesses.lastIndexOf(app); 2519 2520 if (app.persistent && lrui >= 0) { 2521 // We don't care about the position of persistent processes, as long as 2522 // they are in the list. 2523 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2524 return; 2525 } 2526 2527 /* In progress: compute new position first, so we can avoid doing work 2528 if the process is not actually going to move. Not yet working. 2529 int addIndex; 2530 int nextIndex; 2531 boolean inActivity = false, inService = false; 2532 if (hasActivity) { 2533 // Process has activities, put it at the very tipsy-top. 2534 addIndex = mLruProcesses.size(); 2535 nextIndex = mLruProcessServiceStart; 2536 inActivity = true; 2537 } else if (hasService) { 2538 // Process has services, put it at the top of the service list. 2539 addIndex = mLruProcessActivityStart; 2540 nextIndex = mLruProcessServiceStart; 2541 inActivity = true; 2542 inService = true; 2543 } else { 2544 // Process not otherwise of interest, it goes to the top of the non-service area. 2545 addIndex = mLruProcessServiceStart; 2546 if (client != null) { 2547 int clientIndex = mLruProcesses.lastIndexOf(client); 2548 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2549 + app); 2550 if (clientIndex >= 0 && addIndex > clientIndex) { 2551 addIndex = clientIndex; 2552 } 2553 } 2554 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2555 } 2556 2557 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2558 + mLruProcessActivityStart + "): " + app); 2559 */ 2560 2561 if (lrui >= 0) { 2562 if (lrui < mLruProcessActivityStart) { 2563 mLruProcessActivityStart--; 2564 } 2565 if (lrui < mLruProcessServiceStart) { 2566 mLruProcessServiceStart--; 2567 } 2568 /* 2569 if (addIndex > lrui) { 2570 addIndex--; 2571 } 2572 if (nextIndex > lrui) { 2573 nextIndex--; 2574 } 2575 */ 2576 mLruProcesses.remove(lrui); 2577 } 2578 2579 /* 2580 mLruProcesses.add(addIndex, app); 2581 if (inActivity) { 2582 mLruProcessActivityStart++; 2583 } 2584 if (inService) { 2585 mLruProcessActivityStart++; 2586 } 2587 */ 2588 2589 int nextIndex; 2590 if (hasActivity) { 2591 final int N = mLruProcesses.size(); 2592 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2593 // Process doesn't have activities, but has clients with 2594 // activities... move it up, but one below the top (the top 2595 // should always have a real activity). 2596 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2597 mLruProcesses.add(N-1, app); 2598 // To keep it from spamming the LRU list (by making a bunch of clients), 2599 // we will push down any other entries owned by the app. 2600 final int uid = app.info.uid; 2601 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2602 ProcessRecord subProc = mLruProcesses.get(i); 2603 if (subProc.info.uid == uid) { 2604 // We want to push this one down the list. If the process after 2605 // it is for the same uid, however, don't do so, because we don't 2606 // want them internally to be re-ordered. 2607 if (mLruProcesses.get(i-1).info.uid != uid) { 2608 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2609 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2610 ProcessRecord tmp = mLruProcesses.get(i); 2611 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2612 mLruProcesses.set(i-1, tmp); 2613 i--; 2614 } 2615 } else { 2616 // A gap, we can stop here. 2617 break; 2618 } 2619 } 2620 } else { 2621 // Process has activities, put it at the very tipsy-top. 2622 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2623 mLruProcesses.add(app); 2624 } 2625 nextIndex = mLruProcessServiceStart; 2626 } else if (hasService) { 2627 // Process has services, put it at the top of the service list. 2628 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2629 mLruProcesses.add(mLruProcessActivityStart, app); 2630 nextIndex = mLruProcessServiceStart; 2631 mLruProcessActivityStart++; 2632 } else { 2633 // Process not otherwise of interest, it goes to the top of the non-service area. 2634 int index = mLruProcessServiceStart; 2635 if (client != null) { 2636 // If there is a client, don't allow the process to be moved up higher 2637 // in the list than that client. 2638 int clientIndex = mLruProcesses.lastIndexOf(client); 2639 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2640 + " when updating " + app); 2641 if (clientIndex <= lrui) { 2642 // Don't allow the client index restriction to push it down farther in the 2643 // list than it already is. 2644 clientIndex = lrui; 2645 } 2646 if (clientIndex >= 0 && index > clientIndex) { 2647 index = clientIndex; 2648 } 2649 } 2650 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2651 mLruProcesses.add(index, app); 2652 nextIndex = index-1; 2653 mLruProcessActivityStart++; 2654 mLruProcessServiceStart++; 2655 } 2656 2657 // If the app is currently using a content provider or service, 2658 // bump those processes as well. 2659 for (int j=app.connections.size()-1; j>=0; j--) { 2660 ConnectionRecord cr = app.connections.valueAt(j); 2661 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2662 && cr.binding.service.app != null 2663 && cr.binding.service.app.lruSeq != mLruSeq 2664 && !cr.binding.service.app.persistent) { 2665 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2666 "service connection", cr, app); 2667 } 2668 } 2669 for (int j=app.conProviders.size()-1; j>=0; j--) { 2670 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2671 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2672 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2673 "provider reference", cpr, app); 2674 } 2675 } 2676 } 2677 2678 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2679 if (uid == Process.SYSTEM_UID) { 2680 // The system gets to run in any process. If there are multiple 2681 // processes with the same uid, just pick the first (this 2682 // should never happen). 2683 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2684 if (procs == null) return null; 2685 final int N = procs.size(); 2686 for (int i = 0; i < N; i++) { 2687 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2688 } 2689 } 2690 ProcessRecord proc = mProcessNames.get(processName, uid); 2691 if (false && proc != null && !keepIfLarge 2692 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2693 && proc.lastCachedPss >= 4000) { 2694 // Turn this condition on to cause killing to happen regularly, for testing. 2695 if (proc.baseProcessTracker != null) { 2696 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2697 } 2698 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2699 + "k from cached"); 2700 } else if (proc != null && !keepIfLarge 2701 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2702 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2703 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2704 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2705 if (proc.baseProcessTracker != null) { 2706 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2707 } 2708 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2709 + "k from cached"); 2710 } 2711 } 2712 return proc; 2713 } 2714 2715 void ensurePackageDexOpt(String packageName) { 2716 IPackageManager pm = AppGlobals.getPackageManager(); 2717 try { 2718 if (pm.performDexOpt(packageName)) { 2719 mDidDexOpt = true; 2720 } 2721 } catch (RemoteException e) { 2722 } 2723 } 2724 2725 boolean isNextTransitionForward() { 2726 int transit = mWindowManager.getPendingAppTransition(); 2727 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2728 || transit == AppTransition.TRANSIT_TASK_OPEN 2729 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2730 } 2731 2732 final ProcessRecord startProcessLocked(String processName, 2733 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2734 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2735 boolean isolated, boolean keepIfLarge) { 2736 ProcessRecord app; 2737 if (!isolated) { 2738 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2739 } else { 2740 // If this is an isolated process, it can't re-use an existing process. 2741 app = null; 2742 } 2743 // We don't have to do anything more if: 2744 // (1) There is an existing application record; and 2745 // (2) The caller doesn't think it is dead, OR there is no thread 2746 // object attached to it so we know it couldn't have crashed; and 2747 // (3) There is a pid assigned to it, so it is either starting or 2748 // already running. 2749 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2750 + " app=" + app + " knownToBeDead=" + knownToBeDead 2751 + " thread=" + (app != null ? app.thread : null) 2752 + " pid=" + (app != null ? app.pid : -1)); 2753 if (app != null && app.pid > 0) { 2754 if (!knownToBeDead || app.thread == null) { 2755 // We already have the app running, or are waiting for it to 2756 // come up (we have a pid but not yet its thread), so keep it. 2757 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2758 // If this is a new package in the process, add the package to the list 2759 app.addPackage(info.packageName, mProcessStats); 2760 return app; 2761 } 2762 2763 // An application record is attached to a previous process, 2764 // clean it up now. 2765 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2766 handleAppDiedLocked(app, true, true); 2767 } 2768 2769 String hostingNameStr = hostingName != null 2770 ? hostingName.flattenToShortString() : null; 2771 2772 if (!isolated) { 2773 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2774 // If we are in the background, then check to see if this process 2775 // is bad. If so, we will just silently fail. 2776 if (mBadProcesses.get(info.processName, info.uid) != null) { 2777 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2778 + "/" + info.processName); 2779 return null; 2780 } 2781 } else { 2782 // When the user is explicitly starting a process, then clear its 2783 // crash count so that we won't make it bad until they see at 2784 // least one crash dialog again, and make the process good again 2785 // if it had been bad. 2786 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2787 + "/" + info.processName); 2788 mProcessCrashTimes.remove(info.processName, info.uid); 2789 if (mBadProcesses.get(info.processName, info.uid) != null) { 2790 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2791 UserHandle.getUserId(info.uid), info.uid, 2792 info.processName); 2793 mBadProcesses.remove(info.processName, info.uid); 2794 if (app != null) { 2795 app.bad = false; 2796 } 2797 } 2798 } 2799 } 2800 2801 if (app == null) { 2802 app = newProcessRecordLocked(info, processName, isolated); 2803 if (app == null) { 2804 Slog.w(TAG, "Failed making new process record for " 2805 + processName + "/" + info.uid + " isolated=" + isolated); 2806 return null; 2807 } 2808 mProcessNames.put(processName, app.uid, app); 2809 if (isolated) { 2810 mIsolatedProcesses.put(app.uid, app); 2811 } 2812 } else { 2813 // If this is a new package in the process, add the package to the list 2814 app.addPackage(info.packageName, mProcessStats); 2815 } 2816 2817 // If the system is not ready yet, then hold off on starting this 2818 // process until it is. 2819 if (!mProcessesReady 2820 && !isAllowedWhileBooting(info) 2821 && !allowWhileBooting) { 2822 if (!mProcessesOnHold.contains(app)) { 2823 mProcessesOnHold.add(app); 2824 } 2825 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2826 return app; 2827 } 2828 2829 startProcessLocked(app, hostingType, hostingNameStr); 2830 return (app.pid != 0) ? app : null; 2831 } 2832 2833 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2834 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2835 } 2836 2837 private final void startProcessLocked(ProcessRecord app, 2838 String hostingType, String hostingNameStr) { 2839 if (app.pid > 0 && app.pid != MY_PID) { 2840 synchronized (mPidsSelfLocked) { 2841 mPidsSelfLocked.remove(app.pid); 2842 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2843 } 2844 app.setPid(0); 2845 } 2846 2847 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2848 "startProcessLocked removing on hold: " + app); 2849 mProcessesOnHold.remove(app); 2850 2851 updateCpuStats(); 2852 2853 try { 2854 int uid = app.uid; 2855 2856 int[] gids = null; 2857 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2858 if (!app.isolated) { 2859 int[] permGids = null; 2860 try { 2861 final PackageManager pm = mContext.getPackageManager(); 2862 permGids = pm.getPackageGids(app.info.packageName); 2863 2864 if (Environment.isExternalStorageEmulated()) { 2865 if (pm.checkPermission( 2866 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2867 app.info.packageName) == PERMISSION_GRANTED) { 2868 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2869 } else { 2870 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2871 } 2872 } 2873 } catch (PackageManager.NameNotFoundException e) { 2874 Slog.w(TAG, "Unable to retrieve gids", e); 2875 } 2876 2877 /* 2878 * Add shared application GID so applications can share some 2879 * resources like shared libraries 2880 */ 2881 if (permGids == null) { 2882 gids = new int[1]; 2883 } else { 2884 gids = new int[permGids.length + 1]; 2885 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2886 } 2887 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2888 } 2889 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2890 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2891 && mTopComponent != null 2892 && app.processName.equals(mTopComponent.getPackageName())) { 2893 uid = 0; 2894 } 2895 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2896 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2897 uid = 0; 2898 } 2899 } 2900 int debugFlags = 0; 2901 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2902 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2903 // Also turn on CheckJNI for debuggable apps. It's quite 2904 // awkward to turn on otherwise. 2905 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2906 } 2907 // Run the app in safe mode if its manifest requests so or the 2908 // system is booted in safe mode. 2909 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2910 mSafeMode == true) { 2911 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2912 } 2913 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2914 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2915 } 2916 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2917 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2918 } 2919 if ("1".equals(SystemProperties.get("debug.assert"))) { 2920 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2921 } 2922 2923 String requiredAbi = app.info.cpuAbi; 2924 if (requiredAbi == null) { 2925 requiredAbi = Build.SUPPORTED_ABIS[0]; 2926 } 2927 2928 // Start the process. It will either succeed and return a result containing 2929 // the PID of the new process, or else throw a RuntimeException. 2930 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2931 app.processName, uid, uid, gids, debugFlags, mountExternal, 2932 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2933 2934 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2935 synchronized (bs) { 2936 if (bs.isOnBattery()) { 2937 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2938 } 2939 } 2940 2941 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2942 UserHandle.getUserId(uid), startResult.pid, uid, 2943 app.processName, hostingType, 2944 hostingNameStr != null ? hostingNameStr : ""); 2945 2946 if (app.persistent) { 2947 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2948 } 2949 2950 StringBuilder buf = mStringBuilder; 2951 buf.setLength(0); 2952 buf.append("Start proc "); 2953 buf.append(app.processName); 2954 buf.append(" for "); 2955 buf.append(hostingType); 2956 if (hostingNameStr != null) { 2957 buf.append(" "); 2958 buf.append(hostingNameStr); 2959 } 2960 buf.append(": pid="); 2961 buf.append(startResult.pid); 2962 buf.append(" uid="); 2963 buf.append(uid); 2964 buf.append(" gids={"); 2965 if (gids != null) { 2966 for (int gi=0; gi<gids.length; gi++) { 2967 if (gi != 0) buf.append(", "); 2968 buf.append(gids[gi]); 2969 2970 } 2971 } 2972 buf.append("}"); 2973 Slog.i(TAG, buf.toString()); 2974 app.setPid(startResult.pid); 2975 app.usingWrapper = startResult.usingWrapper; 2976 app.removed = false; 2977 synchronized (mPidsSelfLocked) { 2978 this.mPidsSelfLocked.put(startResult.pid, app); 2979 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2980 msg.obj = app; 2981 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2982 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2983 } 2984 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2985 app.processName, app.info.uid); 2986 if (app.isolated) { 2987 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2988 } 2989 } catch (RuntimeException e) { 2990 // XXX do better error recovery. 2991 app.setPid(0); 2992 Slog.e(TAG, "Failure starting process " + app.processName, e); 2993 } 2994 } 2995 2996 void updateUsageStats(ActivityRecord component, boolean resumed) { 2997 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2998 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2999 if (resumed) { 3000 mUsageStatsService.noteResumeComponent(component.realActivity); 3001 synchronized (stats) { 3002 stats.noteActivityResumedLocked(component.app.uid); 3003 } 3004 } else { 3005 mUsageStatsService.notePauseComponent(component.realActivity); 3006 synchronized (stats) { 3007 stats.noteActivityPausedLocked(component.app.uid); 3008 } 3009 } 3010 } 3011 3012 Intent getHomeIntent() { 3013 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3014 intent.setComponent(mTopComponent); 3015 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3016 intent.addCategory(Intent.CATEGORY_HOME); 3017 } 3018 return intent; 3019 } 3020 3021 boolean startHomeActivityLocked(int userId) { 3022 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3023 && mTopAction == null) { 3024 // We are running in factory test mode, but unable to find 3025 // the factory test app, so just sit around displaying the 3026 // error message and don't try to start anything. 3027 return false; 3028 } 3029 Intent intent = getHomeIntent(); 3030 ActivityInfo aInfo = 3031 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3032 if (aInfo != null) { 3033 intent.setComponent(new ComponentName( 3034 aInfo.applicationInfo.packageName, aInfo.name)); 3035 // Don't do this if the home app is currently being 3036 // instrumented. 3037 aInfo = new ActivityInfo(aInfo); 3038 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3039 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3040 aInfo.applicationInfo.uid, true); 3041 if (app == null || app.instrumentationClass == null) { 3042 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3043 mStackSupervisor.startHomeActivity(intent, aInfo); 3044 } 3045 } 3046 3047 return true; 3048 } 3049 3050 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3051 ActivityInfo ai = null; 3052 ComponentName comp = intent.getComponent(); 3053 try { 3054 if (comp != null) { 3055 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3056 } else { 3057 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3058 intent, 3059 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3060 flags, userId); 3061 3062 if (info != null) { 3063 ai = info.activityInfo; 3064 } 3065 } 3066 } catch (RemoteException e) { 3067 // ignore 3068 } 3069 3070 return ai; 3071 } 3072 3073 /** 3074 * Starts the "new version setup screen" if appropriate. 3075 */ 3076 void startSetupActivityLocked() { 3077 // Only do this once per boot. 3078 if (mCheckedForSetup) { 3079 return; 3080 } 3081 3082 // We will show this screen if the current one is a different 3083 // version than the last one shown, and we are not running in 3084 // low-level factory test mode. 3085 final ContentResolver resolver = mContext.getContentResolver(); 3086 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3087 Settings.Global.getInt(resolver, 3088 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3089 mCheckedForSetup = true; 3090 3091 // See if we should be showing the platform update setup UI. 3092 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3093 List<ResolveInfo> ris = mContext.getPackageManager() 3094 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3095 3096 // We don't allow third party apps to replace this. 3097 ResolveInfo ri = null; 3098 for (int i=0; ris != null && i<ris.size(); i++) { 3099 if ((ris.get(i).activityInfo.applicationInfo.flags 3100 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3101 ri = ris.get(i); 3102 break; 3103 } 3104 } 3105 3106 if (ri != null) { 3107 String vers = ri.activityInfo.metaData != null 3108 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3109 : null; 3110 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3111 vers = ri.activityInfo.applicationInfo.metaData.getString( 3112 Intent.METADATA_SETUP_VERSION); 3113 } 3114 String lastVers = Settings.Secure.getString( 3115 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3116 if (vers != null && !vers.equals(lastVers)) { 3117 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3118 intent.setComponent(new ComponentName( 3119 ri.activityInfo.packageName, ri.activityInfo.name)); 3120 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3121 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3122 } 3123 } 3124 } 3125 } 3126 3127 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3128 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3129 } 3130 3131 void enforceNotIsolatedCaller(String caller) { 3132 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3133 throw new SecurityException("Isolated process not allowed to call " + caller); 3134 } 3135 } 3136 3137 @Override 3138 public int getFrontActivityScreenCompatMode() { 3139 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3140 synchronized (this) { 3141 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3142 } 3143 } 3144 3145 @Override 3146 public void setFrontActivityScreenCompatMode(int mode) { 3147 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3148 "setFrontActivityScreenCompatMode"); 3149 synchronized (this) { 3150 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3151 } 3152 } 3153 3154 @Override 3155 public int getPackageScreenCompatMode(String packageName) { 3156 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3157 synchronized (this) { 3158 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3159 } 3160 } 3161 3162 @Override 3163 public void setPackageScreenCompatMode(String packageName, int mode) { 3164 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3165 "setPackageScreenCompatMode"); 3166 synchronized (this) { 3167 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3168 } 3169 } 3170 3171 @Override 3172 public boolean getPackageAskScreenCompat(String packageName) { 3173 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3174 synchronized (this) { 3175 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3176 } 3177 } 3178 3179 @Override 3180 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3181 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3182 "setPackageAskScreenCompat"); 3183 synchronized (this) { 3184 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3185 } 3186 } 3187 3188 private void dispatchProcessesChanged() { 3189 int N; 3190 synchronized (this) { 3191 N = mPendingProcessChanges.size(); 3192 if (mActiveProcessChanges.length < N) { 3193 mActiveProcessChanges = new ProcessChangeItem[N]; 3194 } 3195 mPendingProcessChanges.toArray(mActiveProcessChanges); 3196 mAvailProcessChanges.addAll(mPendingProcessChanges); 3197 mPendingProcessChanges.clear(); 3198 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3199 } 3200 3201 int i = mProcessObservers.beginBroadcast(); 3202 while (i > 0) { 3203 i--; 3204 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3205 if (observer != null) { 3206 try { 3207 for (int j=0; j<N; j++) { 3208 ProcessChangeItem item = mActiveProcessChanges[j]; 3209 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3210 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3211 + item.pid + " uid=" + item.uid + ": " 3212 + item.foregroundActivities); 3213 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3214 item.foregroundActivities); 3215 } 3216 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3217 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3218 + item.pid + " uid=" + item.uid + ": " + item.processState); 3219 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3220 } 3221 } 3222 } catch (RemoteException e) { 3223 } 3224 } 3225 } 3226 mProcessObservers.finishBroadcast(); 3227 } 3228 3229 private void dispatchProcessDied(int pid, int uid) { 3230 int i = mProcessObservers.beginBroadcast(); 3231 while (i > 0) { 3232 i--; 3233 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3234 if (observer != null) { 3235 try { 3236 observer.onProcessDied(pid, uid); 3237 } catch (RemoteException e) { 3238 } 3239 } 3240 } 3241 mProcessObservers.finishBroadcast(); 3242 } 3243 3244 final void doPendingActivityLaunchesLocked(boolean doResume) { 3245 final int N = mPendingActivityLaunches.size(); 3246 if (N <= 0) { 3247 return; 3248 } 3249 for (int i=0; i<N; i++) { 3250 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3251 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3252 doResume && i == (N-1), null); 3253 } 3254 mPendingActivityLaunches.clear(); 3255 } 3256 3257 @Override 3258 public final int startActivity(IApplicationThread caller, String callingPackage, 3259 Intent intent, String resolvedType, IBinder resultTo, 3260 String resultWho, int requestCode, int startFlags, 3261 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3262 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3263 resultWho, requestCode, 3264 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3265 } 3266 3267 @Override 3268 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3269 Intent intent, String resolvedType, IBinder resultTo, 3270 String resultWho, int requestCode, int startFlags, 3271 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3272 enforceNotIsolatedCaller("startActivity"); 3273 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3274 false, true, "startActivity", null); 3275 // TODO: Switch to user app stacks here. 3276 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3277 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3278 null, null, options, userId, null); 3279 } 3280 3281 @Override 3282 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3283 Intent intent, String resolvedType, IBinder resultTo, 3284 String resultWho, int requestCode, int startFlags, String profileFile, 3285 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3286 enforceNotIsolatedCaller("startActivityAndWait"); 3287 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3288 false, true, "startActivityAndWait", null); 3289 WaitResult res = new WaitResult(); 3290 // TODO: Switch to user app stacks here. 3291 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3292 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3293 res, null, options, UserHandle.getCallingUserId(), null); 3294 return res; 3295 } 3296 3297 @Override 3298 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3299 Intent intent, String resolvedType, IBinder resultTo, 3300 String resultWho, int requestCode, int startFlags, Configuration config, 3301 Bundle options, int userId) { 3302 enforceNotIsolatedCaller("startActivityWithConfig"); 3303 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3304 false, true, "startActivityWithConfig", null); 3305 // TODO: Switch to user app stacks here. 3306 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3307 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3308 null, null, null, config, options, userId, null); 3309 return ret; 3310 } 3311 3312 @Override 3313 public int startActivityIntentSender(IApplicationThread caller, 3314 IntentSender intent, Intent fillInIntent, String resolvedType, 3315 IBinder resultTo, String resultWho, int requestCode, 3316 int flagsMask, int flagsValues, Bundle options) { 3317 enforceNotIsolatedCaller("startActivityIntentSender"); 3318 // Refuse possible leaked file descriptors 3319 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3320 throw new IllegalArgumentException("File descriptors passed in Intent"); 3321 } 3322 3323 IIntentSender sender = intent.getTarget(); 3324 if (!(sender instanceof PendingIntentRecord)) { 3325 throw new IllegalArgumentException("Bad PendingIntent object"); 3326 } 3327 3328 PendingIntentRecord pir = (PendingIntentRecord)sender; 3329 3330 synchronized (this) { 3331 // If this is coming from the currently resumed activity, it is 3332 // effectively saying that app switches are allowed at this point. 3333 final ActivityStack stack = getFocusedStack(); 3334 if (stack.mResumedActivity != null && 3335 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3336 mAppSwitchesAllowedTime = 0; 3337 } 3338 } 3339 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3340 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3341 return ret; 3342 } 3343 3344 @Override 3345 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3346 Intent intent, String resolvedType, IVoiceInteractionSession session, 3347 IVoiceInteractor interactor, int startFlags, String profileFile, 3348 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3349 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3350 != PackageManager.PERMISSION_GRANTED) { 3351 String msg = "Permission Denial: startVoiceActivity() from pid=" 3352 + Binder.getCallingPid() 3353 + ", uid=" + Binder.getCallingUid() 3354 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3355 Slog.w(TAG, msg); 3356 throw new SecurityException(msg); 3357 } 3358 if (session == null || interactor == null) { 3359 throw new NullPointerException("null session or interactor"); 3360 } 3361 userId = handleIncomingUser(callingPid, callingUid, userId, 3362 false, true, "startVoiceActivity", null); 3363 // TODO: Switch to user app stacks here. 3364 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3365 resolvedType, session, interactor, null, null, 0, startFlags, 3366 profileFile, profileFd, null, null, options, userId, null); 3367 } 3368 3369 @Override 3370 public boolean startNextMatchingActivity(IBinder callingActivity, 3371 Intent intent, Bundle options) { 3372 // Refuse possible leaked file descriptors 3373 if (intent != null && intent.hasFileDescriptors() == true) { 3374 throw new IllegalArgumentException("File descriptors passed in Intent"); 3375 } 3376 3377 synchronized (this) { 3378 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3379 if (r == null) { 3380 ActivityOptions.abort(options); 3381 return false; 3382 } 3383 if (r.app == null || r.app.thread == null) { 3384 // The caller is not running... d'oh! 3385 ActivityOptions.abort(options); 3386 return false; 3387 } 3388 intent = new Intent(intent); 3389 // The caller is not allowed to change the data. 3390 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3391 // And we are resetting to find the next component... 3392 intent.setComponent(null); 3393 3394 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3395 3396 ActivityInfo aInfo = null; 3397 try { 3398 List<ResolveInfo> resolves = 3399 AppGlobals.getPackageManager().queryIntentActivities( 3400 intent, r.resolvedType, 3401 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3402 UserHandle.getCallingUserId()); 3403 3404 // Look for the original activity in the list... 3405 final int N = resolves != null ? resolves.size() : 0; 3406 for (int i=0; i<N; i++) { 3407 ResolveInfo rInfo = resolves.get(i); 3408 if (rInfo.activityInfo.packageName.equals(r.packageName) 3409 && rInfo.activityInfo.name.equals(r.info.name)) { 3410 // We found the current one... the next matching is 3411 // after it. 3412 i++; 3413 if (i<N) { 3414 aInfo = resolves.get(i).activityInfo; 3415 } 3416 if (debug) { 3417 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3418 + "/" + r.info.name); 3419 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3420 + "/" + aInfo.name); 3421 } 3422 break; 3423 } 3424 } 3425 } catch (RemoteException e) { 3426 } 3427 3428 if (aInfo == null) { 3429 // Nobody who is next! 3430 ActivityOptions.abort(options); 3431 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3432 return false; 3433 } 3434 3435 intent.setComponent(new ComponentName( 3436 aInfo.applicationInfo.packageName, aInfo.name)); 3437 intent.setFlags(intent.getFlags()&~( 3438 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3439 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3440 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3441 Intent.FLAG_ACTIVITY_NEW_TASK)); 3442 3443 // Okay now we need to start the new activity, replacing the 3444 // currently running activity. This is a little tricky because 3445 // we want to start the new one as if the current one is finished, 3446 // but not finish the current one first so that there is no flicker. 3447 // And thus... 3448 final boolean wasFinishing = r.finishing; 3449 r.finishing = true; 3450 3451 // Propagate reply information over to the new activity. 3452 final ActivityRecord resultTo = r.resultTo; 3453 final String resultWho = r.resultWho; 3454 final int requestCode = r.requestCode; 3455 r.resultTo = null; 3456 if (resultTo != null) { 3457 resultTo.removeResultsLocked(r, resultWho, requestCode); 3458 } 3459 3460 final long origId = Binder.clearCallingIdentity(); 3461 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3462 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3463 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3464 options, false, null, null); 3465 Binder.restoreCallingIdentity(origId); 3466 3467 r.finishing = wasFinishing; 3468 if (res != ActivityManager.START_SUCCESS) { 3469 return false; 3470 } 3471 return true; 3472 } 3473 } 3474 3475 final int startActivityInPackage(int uid, String callingPackage, 3476 Intent intent, String resolvedType, IBinder resultTo, 3477 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3478 IActivityContainer container) { 3479 3480 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3481 false, true, "startActivityInPackage", null); 3482 3483 // TODO: Switch to user app stacks here. 3484 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3485 null, null, resultTo, resultWho, requestCode, startFlags, 3486 null, null, null, null, options, userId, container); 3487 return ret; 3488 } 3489 3490 @Override 3491 public final int startActivities(IApplicationThread caller, String callingPackage, 3492 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3493 int userId) { 3494 enforceNotIsolatedCaller("startActivities"); 3495 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3496 false, true, "startActivity", null); 3497 // TODO: Switch to user app stacks here. 3498 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3499 resolvedTypes, resultTo, options, userId); 3500 return ret; 3501 } 3502 3503 final int startActivitiesInPackage(int uid, String callingPackage, 3504 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3505 Bundle options, int userId) { 3506 3507 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3508 false, true, "startActivityInPackage", null); 3509 // TODO: Switch to user app stacks here. 3510 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3511 resultTo, options, userId); 3512 return ret; 3513 } 3514 3515 final void addRecentTaskLocked(TaskRecord task) { 3516 int N = mRecentTasks.size(); 3517 // Quick case: check if the top-most recent task is the same. 3518 if (N > 0 && mRecentTasks.get(0) == task) { 3519 return; 3520 } 3521 // Another quick case: never add voice sessions. 3522 if (task.voiceSession != null) { 3523 return; 3524 } 3525 // Remove any existing entries that are the same kind of task. 3526 final Intent intent = task.intent; 3527 final boolean document = intent != null && intent.isDocument(); 3528 for (int i=0; i<N; i++) { 3529 TaskRecord tr = mRecentTasks.get(i); 3530 if (task != tr) { 3531 if (task.userId != tr.userId) { 3532 continue; 3533 } 3534 final Intent trIntent = tr.intent; 3535 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3536 (intent == null || !intent.filterEquals(trIntent))) { 3537 continue; 3538 } 3539 if (document || trIntent != null && trIntent.isDocument()) { 3540 // Document tasks do not match other tasks. 3541 continue; 3542 } 3543 } 3544 3545 // Either task and tr are the same or, their affinities match or their intents match 3546 // and neither of them is a document. 3547 tr.disposeThumbnail(); 3548 mRecentTasks.remove(i); 3549 i--; 3550 N--; 3551 if (task.intent == null) { 3552 // If the new recent task we are adding is not fully 3553 // specified, then replace it with the existing recent task. 3554 task = tr; 3555 } 3556 } 3557 if (N >= MAX_RECENT_TASKS) { 3558 mRecentTasks.remove(N-1).disposeThumbnail(); 3559 } 3560 mRecentTasks.add(0, task); 3561 } 3562 3563 @Override 3564 public void reportActivityFullyDrawn(IBinder token) { 3565 synchronized (this) { 3566 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3567 if (r == null) { 3568 return; 3569 } 3570 r.reportFullyDrawnLocked(); 3571 } 3572 } 3573 3574 @Override 3575 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3576 synchronized (this) { 3577 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3578 if (r == null) { 3579 return; 3580 } 3581 final long origId = Binder.clearCallingIdentity(); 3582 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3583 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3584 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3585 if (config != null) { 3586 r.frozenBeforeDestroy = true; 3587 if (!updateConfigurationLocked(config, r, false, false)) { 3588 mStackSupervisor.resumeTopActivitiesLocked(); 3589 } 3590 } 3591 Binder.restoreCallingIdentity(origId); 3592 } 3593 } 3594 3595 @Override 3596 public int getRequestedOrientation(IBinder token) { 3597 synchronized (this) { 3598 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3599 if (r == null) { 3600 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3601 } 3602 return mWindowManager.getAppOrientation(r.appToken); 3603 } 3604 } 3605 3606 /** 3607 * This is the internal entry point for handling Activity.finish(). 3608 * 3609 * @param token The Binder token referencing the Activity we want to finish. 3610 * @param resultCode Result code, if any, from this Activity. 3611 * @param resultData Result data (Intent), if any, from this Activity. 3612 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3613 * the root Activity in the task. 3614 * 3615 * @return Returns true if the activity successfully finished, or false if it is still running. 3616 */ 3617 @Override 3618 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3619 boolean finishTask) { 3620 // Refuse possible leaked file descriptors 3621 if (resultData != null && resultData.hasFileDescriptors() == true) { 3622 throw new IllegalArgumentException("File descriptors passed in Intent"); 3623 } 3624 3625 synchronized(this) { 3626 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3627 if (r == null) { 3628 return true; 3629 } 3630 // Keep track of the root activity of the task before we finish it 3631 TaskRecord tr = r.task; 3632 ActivityRecord rootR = tr.getRootActivity(); 3633 if (mController != null) { 3634 // Find the first activity that is not finishing. 3635 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3636 if (next != null) { 3637 // ask watcher if this is allowed 3638 boolean resumeOK = true; 3639 try { 3640 resumeOK = mController.activityResuming(next.packageName); 3641 } catch (RemoteException e) { 3642 mController = null; 3643 Watchdog.getInstance().setActivityController(null); 3644 } 3645 3646 if (!resumeOK) { 3647 return false; 3648 } 3649 } 3650 } 3651 final long origId = Binder.clearCallingIdentity(); 3652 try { 3653 boolean res; 3654 if (finishTask && r == rootR) { 3655 // If requested, remove the task that is associated to this activity only if it 3656 // was the root activity in the task. The result code and data is ignored because 3657 // we don't support returning them across task boundaries. 3658 res = removeTaskByIdLocked(tr.taskId, 0); 3659 } else { 3660 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3661 resultData, "app-request", true); 3662 } 3663 return res; 3664 } finally { 3665 Binder.restoreCallingIdentity(origId); 3666 } 3667 } 3668 } 3669 3670 @Override 3671 public final void finishHeavyWeightApp() { 3672 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3673 != PackageManager.PERMISSION_GRANTED) { 3674 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3675 + Binder.getCallingPid() 3676 + ", uid=" + Binder.getCallingUid() 3677 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3678 Slog.w(TAG, msg); 3679 throw new SecurityException(msg); 3680 } 3681 3682 synchronized(this) { 3683 if (mHeavyWeightProcess == null) { 3684 return; 3685 } 3686 3687 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3688 mHeavyWeightProcess.activities); 3689 for (int i=0; i<activities.size(); i++) { 3690 ActivityRecord r = activities.get(i); 3691 if (!r.finishing) { 3692 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3693 null, "finish-heavy", true); 3694 } 3695 } 3696 3697 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3698 mHeavyWeightProcess.userId, 0)); 3699 mHeavyWeightProcess = null; 3700 } 3701 } 3702 3703 @Override 3704 public void crashApplication(int uid, int initialPid, String packageName, 3705 String message) { 3706 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3707 != PackageManager.PERMISSION_GRANTED) { 3708 String msg = "Permission Denial: crashApplication() from pid=" 3709 + Binder.getCallingPid() 3710 + ", uid=" + Binder.getCallingUid() 3711 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3712 Slog.w(TAG, msg); 3713 throw new SecurityException(msg); 3714 } 3715 3716 synchronized(this) { 3717 ProcessRecord proc = null; 3718 3719 // Figure out which process to kill. We don't trust that initialPid 3720 // still has any relation to current pids, so must scan through the 3721 // list. 3722 synchronized (mPidsSelfLocked) { 3723 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3724 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3725 if (p.uid != uid) { 3726 continue; 3727 } 3728 if (p.pid == initialPid) { 3729 proc = p; 3730 break; 3731 } 3732 if (p.pkgList.containsKey(packageName)) { 3733 proc = p; 3734 } 3735 } 3736 } 3737 3738 if (proc == null) { 3739 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3740 + " initialPid=" + initialPid 3741 + " packageName=" + packageName); 3742 return; 3743 } 3744 3745 if (proc.thread != null) { 3746 if (proc.pid == Process.myPid()) { 3747 Log.w(TAG, "crashApplication: trying to crash self!"); 3748 return; 3749 } 3750 long ident = Binder.clearCallingIdentity(); 3751 try { 3752 proc.thread.scheduleCrash(message); 3753 } catch (RemoteException e) { 3754 } 3755 Binder.restoreCallingIdentity(ident); 3756 } 3757 } 3758 } 3759 3760 @Override 3761 public final void finishSubActivity(IBinder token, String resultWho, 3762 int requestCode) { 3763 synchronized(this) { 3764 final long origId = Binder.clearCallingIdentity(); 3765 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3766 if (r != null) { 3767 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3768 } 3769 Binder.restoreCallingIdentity(origId); 3770 } 3771 } 3772 3773 @Override 3774 public boolean finishActivityAffinity(IBinder token) { 3775 synchronized(this) { 3776 final long origId = Binder.clearCallingIdentity(); 3777 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3778 boolean res = false; 3779 if (r != null) { 3780 res = r.task.stack.finishActivityAffinityLocked(r); 3781 } 3782 Binder.restoreCallingIdentity(origId); 3783 return res; 3784 } 3785 } 3786 3787 @Override 3788 public boolean willActivityBeVisible(IBinder token) { 3789 synchronized(this) { 3790 ActivityStack stack = ActivityRecord.getStackLocked(token); 3791 if (stack != null) { 3792 return stack.willActivityBeVisibleLocked(token); 3793 } 3794 return false; 3795 } 3796 } 3797 3798 @Override 3799 public void overridePendingTransition(IBinder token, String packageName, 3800 int enterAnim, int exitAnim) { 3801 synchronized(this) { 3802 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3803 if (self == null) { 3804 return; 3805 } 3806 3807 final long origId = Binder.clearCallingIdentity(); 3808 3809 if (self.state == ActivityState.RESUMED 3810 || self.state == ActivityState.PAUSING) { 3811 mWindowManager.overridePendingAppTransition(packageName, 3812 enterAnim, exitAnim, null); 3813 } 3814 3815 Binder.restoreCallingIdentity(origId); 3816 } 3817 } 3818 3819 /** 3820 * Main function for removing an existing process from the activity manager 3821 * as a result of that process going away. Clears out all connections 3822 * to the process. 3823 */ 3824 private final void handleAppDiedLocked(ProcessRecord app, 3825 boolean restarting, boolean allowRestart) { 3826 int pid = app.pid; 3827 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3828 if (!restarting) { 3829 removeLruProcessLocked(app); 3830 if (pid > 0) { 3831 ProcessList.remove(pid); 3832 } 3833 } 3834 3835 if (mProfileProc == app) { 3836 clearProfilerLocked(); 3837 } 3838 3839 // Remove this application's activities from active lists. 3840 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3841 3842 app.activities.clear(); 3843 3844 if (app.instrumentationClass != null) { 3845 Slog.w(TAG, "Crash of app " + app.processName 3846 + " running instrumentation " + app.instrumentationClass); 3847 Bundle info = new Bundle(); 3848 info.putString("shortMsg", "Process crashed."); 3849 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3850 } 3851 3852 if (!restarting) { 3853 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3854 // If there was nothing to resume, and we are not already 3855 // restarting this process, but there is a visible activity that 3856 // is hosted by the process... then make sure all visible 3857 // activities are running, taking care of restarting this 3858 // process. 3859 if (hasVisibleActivities) { 3860 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3861 } 3862 } 3863 } 3864 } 3865 3866 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3867 IBinder threadBinder = thread.asBinder(); 3868 // Find the application record. 3869 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3870 ProcessRecord rec = mLruProcesses.get(i); 3871 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3872 return i; 3873 } 3874 } 3875 return -1; 3876 } 3877 3878 final ProcessRecord getRecordForAppLocked( 3879 IApplicationThread thread) { 3880 if (thread == null) { 3881 return null; 3882 } 3883 3884 int appIndex = getLRURecordIndexForAppLocked(thread); 3885 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3886 } 3887 3888 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3889 // If there are no longer any background processes running, 3890 // and the app that died was not running instrumentation, 3891 // then tell everyone we are now low on memory. 3892 boolean haveBg = false; 3893 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3894 ProcessRecord rec = mLruProcesses.get(i); 3895 if (rec.thread != null 3896 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3897 haveBg = true; 3898 break; 3899 } 3900 } 3901 3902 if (!haveBg) { 3903 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3904 if (doReport) { 3905 long now = SystemClock.uptimeMillis(); 3906 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3907 doReport = false; 3908 } else { 3909 mLastMemUsageReportTime = now; 3910 } 3911 } 3912 final ArrayList<ProcessMemInfo> memInfos 3913 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3914 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3915 long now = SystemClock.uptimeMillis(); 3916 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3917 ProcessRecord rec = mLruProcesses.get(i); 3918 if (rec == dyingProc || rec.thread == null) { 3919 continue; 3920 } 3921 if (doReport) { 3922 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3923 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3924 } 3925 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3926 // The low memory report is overriding any current 3927 // state for a GC request. Make sure to do 3928 // heavy/important/visible/foreground processes first. 3929 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3930 rec.lastRequestedGc = 0; 3931 } else { 3932 rec.lastRequestedGc = rec.lastLowMemory; 3933 } 3934 rec.reportLowMemory = true; 3935 rec.lastLowMemory = now; 3936 mProcessesToGc.remove(rec); 3937 addProcessToGcListLocked(rec); 3938 } 3939 } 3940 if (doReport) { 3941 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3942 mHandler.sendMessage(msg); 3943 } 3944 scheduleAppGcsLocked(); 3945 } 3946 } 3947 3948 final void appDiedLocked(ProcessRecord app, int pid, 3949 IApplicationThread thread) { 3950 3951 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3952 synchronized (stats) { 3953 stats.noteProcessDiedLocked(app.info.uid, pid); 3954 } 3955 3956 // Clean up already done if the process has been re-started. 3957 if (app.pid == pid && app.thread != null && 3958 app.thread.asBinder() == thread.asBinder()) { 3959 boolean doLowMem = app.instrumentationClass == null; 3960 boolean doOomAdj = doLowMem; 3961 if (!app.killedByAm) { 3962 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3963 + ") has died."); 3964 mAllowLowerMemLevel = true; 3965 } else { 3966 // Note that we always want to do oom adj to update our state with the 3967 // new number of procs. 3968 mAllowLowerMemLevel = false; 3969 doLowMem = false; 3970 } 3971 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3972 if (DEBUG_CLEANUP) Slog.v( 3973 TAG, "Dying app: " + app + ", pid: " + pid 3974 + ", thread: " + thread.asBinder()); 3975 handleAppDiedLocked(app, false, true); 3976 3977 if (doOomAdj) { 3978 updateOomAdjLocked(); 3979 } 3980 if (doLowMem) { 3981 doLowMemReportIfNeededLocked(app); 3982 } 3983 } else if (app.pid != pid) { 3984 // A new process has already been started. 3985 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3986 + ") has died and restarted (pid " + app.pid + ")."); 3987 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3988 } else if (DEBUG_PROCESSES) { 3989 Slog.d(TAG, "Received spurious death notification for thread " 3990 + thread.asBinder()); 3991 } 3992 } 3993 3994 /** 3995 * If a stack trace dump file is configured, dump process stack traces. 3996 * @param clearTraces causes the dump file to be erased prior to the new 3997 * traces being written, if true; when false, the new traces will be 3998 * appended to any existing file content. 3999 * @param firstPids of dalvik VM processes to dump stack traces for first 4000 * @param lastPids of dalvik VM processes to dump stack traces for last 4001 * @param nativeProcs optional list of native process names to dump stack crawls 4002 * @return file containing stack traces, or null if no dump file is configured 4003 */ 4004 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 4005 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4006 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4007 if (tracesPath == null || tracesPath.length() == 0) { 4008 return null; 4009 } 4010 4011 File tracesFile = new File(tracesPath); 4012 try { 4013 File tracesDir = tracesFile.getParentFile(); 4014 if (!tracesDir.exists()) { 4015 tracesFile.mkdirs(); 4016 if (!SELinux.restorecon(tracesDir)) { 4017 return null; 4018 } 4019 } 4020 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4021 4022 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4023 tracesFile.createNewFile(); 4024 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4025 } catch (IOException e) { 4026 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4027 return null; 4028 } 4029 4030 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4031 return tracesFile; 4032 } 4033 4034 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4035 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4036 // Use a FileObserver to detect when traces finish writing. 4037 // The order of traces is considered important to maintain for legibility. 4038 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4039 @Override 4040 public synchronized void onEvent(int event, String path) { notify(); } 4041 }; 4042 4043 try { 4044 observer.startWatching(); 4045 4046 // First collect all of the stacks of the most important pids. 4047 if (firstPids != null) { 4048 try { 4049 int num = firstPids.size(); 4050 for (int i = 0; i < num; i++) { 4051 synchronized (observer) { 4052 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4053 observer.wait(200); // Wait for write-close, give up after 200msec 4054 } 4055 } 4056 } catch (InterruptedException e) { 4057 Log.wtf(TAG, e); 4058 } 4059 } 4060 4061 // Next collect the stacks of the native pids 4062 if (nativeProcs != null) { 4063 int[] pids = Process.getPidsForCommands(nativeProcs); 4064 if (pids != null) { 4065 for (int pid : pids) { 4066 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4067 } 4068 } 4069 } 4070 4071 // Lastly, measure CPU usage. 4072 if (processCpuTracker != null) { 4073 processCpuTracker.init(); 4074 System.gc(); 4075 processCpuTracker.update(); 4076 try { 4077 synchronized (processCpuTracker) { 4078 processCpuTracker.wait(500); // measure over 1/2 second. 4079 } 4080 } catch (InterruptedException e) { 4081 } 4082 processCpuTracker.update(); 4083 4084 // We'll take the stack crawls of just the top apps using CPU. 4085 final int N = processCpuTracker.countWorkingStats(); 4086 int numProcs = 0; 4087 for (int i=0; i<N && numProcs<5; i++) { 4088 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4089 if (lastPids.indexOfKey(stats.pid) >= 0) { 4090 numProcs++; 4091 try { 4092 synchronized (observer) { 4093 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4094 observer.wait(200); // Wait for write-close, give up after 200msec 4095 } 4096 } catch (InterruptedException e) { 4097 Log.wtf(TAG, e); 4098 } 4099 4100 } 4101 } 4102 } 4103 } finally { 4104 observer.stopWatching(); 4105 } 4106 } 4107 4108 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4109 if (true || IS_USER_BUILD) { 4110 return; 4111 } 4112 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4113 if (tracesPath == null || tracesPath.length() == 0) { 4114 return; 4115 } 4116 4117 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4118 StrictMode.allowThreadDiskWrites(); 4119 try { 4120 final File tracesFile = new File(tracesPath); 4121 final File tracesDir = tracesFile.getParentFile(); 4122 final File tracesTmp = new File(tracesDir, "__tmp__"); 4123 try { 4124 if (!tracesDir.exists()) { 4125 tracesFile.mkdirs(); 4126 if (!SELinux.restorecon(tracesDir.getPath())) { 4127 return; 4128 } 4129 } 4130 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4131 4132 if (tracesFile.exists()) { 4133 tracesTmp.delete(); 4134 tracesFile.renameTo(tracesTmp); 4135 } 4136 StringBuilder sb = new StringBuilder(); 4137 Time tobj = new Time(); 4138 tobj.set(System.currentTimeMillis()); 4139 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4140 sb.append(": "); 4141 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4142 sb.append(" since "); 4143 sb.append(msg); 4144 FileOutputStream fos = new FileOutputStream(tracesFile); 4145 fos.write(sb.toString().getBytes()); 4146 if (app == null) { 4147 fos.write("\n*** No application process!".getBytes()); 4148 } 4149 fos.close(); 4150 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4151 } catch (IOException e) { 4152 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4153 return; 4154 } 4155 4156 if (app != null) { 4157 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4158 firstPids.add(app.pid); 4159 dumpStackTraces(tracesPath, firstPids, null, null, null); 4160 } 4161 4162 File lastTracesFile = null; 4163 File curTracesFile = null; 4164 for (int i=9; i>=0; i--) { 4165 String name = String.format(Locale.US, "slow%02d.txt", i); 4166 curTracesFile = new File(tracesDir, name); 4167 if (curTracesFile.exists()) { 4168 if (lastTracesFile != null) { 4169 curTracesFile.renameTo(lastTracesFile); 4170 } else { 4171 curTracesFile.delete(); 4172 } 4173 } 4174 lastTracesFile = curTracesFile; 4175 } 4176 tracesFile.renameTo(curTracesFile); 4177 if (tracesTmp.exists()) { 4178 tracesTmp.renameTo(tracesFile); 4179 } 4180 } finally { 4181 StrictMode.setThreadPolicy(oldPolicy); 4182 } 4183 } 4184 4185 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4186 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4187 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4188 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4189 4190 if (mController != null) { 4191 try { 4192 // 0 == continue, -1 = kill process immediately 4193 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4194 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4195 } catch (RemoteException e) { 4196 mController = null; 4197 Watchdog.getInstance().setActivityController(null); 4198 } 4199 } 4200 4201 long anrTime = SystemClock.uptimeMillis(); 4202 if (MONITOR_CPU_USAGE) { 4203 updateCpuStatsNow(); 4204 } 4205 4206 synchronized (this) { 4207 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4208 if (mShuttingDown) { 4209 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4210 return; 4211 } else if (app.notResponding) { 4212 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4213 return; 4214 } else if (app.crashing) { 4215 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4216 return; 4217 } 4218 4219 // In case we come through here for the same app before completing 4220 // this one, mark as anring now so we will bail out. 4221 app.notResponding = true; 4222 4223 // Log the ANR to the event log. 4224 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4225 app.processName, app.info.flags, annotation); 4226 4227 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4228 firstPids.add(app.pid); 4229 4230 int parentPid = app.pid; 4231 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4232 if (parentPid != app.pid) firstPids.add(parentPid); 4233 4234 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4235 4236 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4237 ProcessRecord r = mLruProcesses.get(i); 4238 if (r != null && r.thread != null) { 4239 int pid = r.pid; 4240 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4241 if (r.persistent) { 4242 firstPids.add(pid); 4243 } else { 4244 lastPids.put(pid, Boolean.TRUE); 4245 } 4246 } 4247 } 4248 } 4249 } 4250 4251 // Log the ANR to the main log. 4252 StringBuilder info = new StringBuilder(); 4253 info.setLength(0); 4254 info.append("ANR in ").append(app.processName); 4255 if (activity != null && activity.shortComponentName != null) { 4256 info.append(" (").append(activity.shortComponentName).append(")"); 4257 } 4258 info.append("\n"); 4259 info.append("PID: ").append(app.pid).append("\n"); 4260 if (annotation != null) { 4261 info.append("Reason: ").append(annotation).append("\n"); 4262 } 4263 if (parent != null && parent != activity) { 4264 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4265 } 4266 4267 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4268 4269 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4270 NATIVE_STACKS_OF_INTEREST); 4271 4272 String cpuInfo = null; 4273 if (MONITOR_CPU_USAGE) { 4274 updateCpuStatsNow(); 4275 synchronized (mProcessCpuThread) { 4276 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4277 } 4278 info.append(processCpuTracker.printCurrentLoad()); 4279 info.append(cpuInfo); 4280 } 4281 4282 info.append(processCpuTracker.printCurrentState(anrTime)); 4283 4284 Slog.e(TAG, info.toString()); 4285 if (tracesFile == null) { 4286 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4287 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4288 } 4289 4290 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4291 cpuInfo, tracesFile, null); 4292 4293 if (mController != null) { 4294 try { 4295 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4296 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4297 if (res != 0) { 4298 if (res < 0 && app.pid != MY_PID) { 4299 Process.killProcess(app.pid); 4300 } else { 4301 synchronized (this) { 4302 mServices.scheduleServiceTimeoutLocked(app); 4303 } 4304 } 4305 return; 4306 } 4307 } catch (RemoteException e) { 4308 mController = null; 4309 Watchdog.getInstance().setActivityController(null); 4310 } 4311 } 4312 4313 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4314 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4315 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4316 4317 synchronized (this) { 4318 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4319 killUnneededProcessLocked(app, "background ANR"); 4320 return; 4321 } 4322 4323 // Set the app's notResponding state, and look up the errorReportReceiver 4324 makeAppNotRespondingLocked(app, 4325 activity != null ? activity.shortComponentName : null, 4326 annotation != null ? "ANR " + annotation : "ANR", 4327 info.toString()); 4328 4329 // Bring up the infamous App Not Responding dialog 4330 Message msg = Message.obtain(); 4331 HashMap<String, Object> map = new HashMap<String, Object>(); 4332 msg.what = SHOW_NOT_RESPONDING_MSG; 4333 msg.obj = map; 4334 msg.arg1 = aboveSystem ? 1 : 0; 4335 map.put("app", app); 4336 if (activity != null) { 4337 map.put("activity", activity); 4338 } 4339 4340 mHandler.sendMessage(msg); 4341 } 4342 } 4343 4344 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4345 if (!mLaunchWarningShown) { 4346 mLaunchWarningShown = true; 4347 mHandler.post(new Runnable() { 4348 @Override 4349 public void run() { 4350 synchronized (ActivityManagerService.this) { 4351 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4352 d.show(); 4353 mHandler.postDelayed(new Runnable() { 4354 @Override 4355 public void run() { 4356 synchronized (ActivityManagerService.this) { 4357 d.dismiss(); 4358 mLaunchWarningShown = false; 4359 } 4360 } 4361 }, 4000); 4362 } 4363 } 4364 }); 4365 } 4366 } 4367 4368 @Override 4369 public boolean clearApplicationUserData(final String packageName, 4370 final IPackageDataObserver observer, int userId) { 4371 enforceNotIsolatedCaller("clearApplicationUserData"); 4372 int uid = Binder.getCallingUid(); 4373 int pid = Binder.getCallingPid(); 4374 userId = handleIncomingUser(pid, uid, 4375 userId, false, true, "clearApplicationUserData", null); 4376 long callingId = Binder.clearCallingIdentity(); 4377 try { 4378 IPackageManager pm = AppGlobals.getPackageManager(); 4379 int pkgUid = -1; 4380 synchronized(this) { 4381 try { 4382 pkgUid = pm.getPackageUid(packageName, userId); 4383 } catch (RemoteException e) { 4384 } 4385 if (pkgUid == -1) { 4386 Slog.w(TAG, "Invalid packageName: " + packageName); 4387 if (observer != null) { 4388 try { 4389 observer.onRemoveCompleted(packageName, false); 4390 } catch (RemoteException e) { 4391 Slog.i(TAG, "Observer no longer exists."); 4392 } 4393 } 4394 return false; 4395 } 4396 if (uid == pkgUid || checkComponentPermission( 4397 android.Manifest.permission.CLEAR_APP_USER_DATA, 4398 pid, uid, -1, true) 4399 == PackageManager.PERMISSION_GRANTED) { 4400 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4401 } else { 4402 throw new SecurityException("PID " + pid + " does not have permission " 4403 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4404 + " of package " + packageName); 4405 } 4406 } 4407 4408 try { 4409 // Clear application user data 4410 pm.clearApplicationUserData(packageName, observer, userId); 4411 4412 // Remove all permissions granted from/to this package 4413 removeUriPermissionsForPackageLocked(packageName, userId, true); 4414 4415 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4416 Uri.fromParts("package", packageName, null)); 4417 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4418 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4419 null, null, 0, null, null, null, false, false, userId); 4420 } catch (RemoteException e) { 4421 } 4422 } finally { 4423 Binder.restoreCallingIdentity(callingId); 4424 } 4425 return true; 4426 } 4427 4428 @Override 4429 public void killBackgroundProcesses(final String packageName, int userId) { 4430 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4431 != PackageManager.PERMISSION_GRANTED && 4432 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4433 != PackageManager.PERMISSION_GRANTED) { 4434 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4435 + Binder.getCallingPid() 4436 + ", uid=" + Binder.getCallingUid() 4437 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4438 Slog.w(TAG, msg); 4439 throw new SecurityException(msg); 4440 } 4441 4442 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4443 userId, true, true, "killBackgroundProcesses", null); 4444 long callingId = Binder.clearCallingIdentity(); 4445 try { 4446 IPackageManager pm = AppGlobals.getPackageManager(); 4447 synchronized(this) { 4448 int appId = -1; 4449 try { 4450 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4451 } catch (RemoteException e) { 4452 } 4453 if (appId == -1) { 4454 Slog.w(TAG, "Invalid packageName: " + packageName); 4455 return; 4456 } 4457 killPackageProcessesLocked(packageName, appId, userId, 4458 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4459 } 4460 } finally { 4461 Binder.restoreCallingIdentity(callingId); 4462 } 4463 } 4464 4465 @Override 4466 public void killAllBackgroundProcesses() { 4467 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4468 != PackageManager.PERMISSION_GRANTED) { 4469 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4470 + Binder.getCallingPid() 4471 + ", uid=" + Binder.getCallingUid() 4472 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4473 Slog.w(TAG, msg); 4474 throw new SecurityException(msg); 4475 } 4476 4477 long callingId = Binder.clearCallingIdentity(); 4478 try { 4479 synchronized(this) { 4480 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4481 final int NP = mProcessNames.getMap().size(); 4482 for (int ip=0; ip<NP; ip++) { 4483 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4484 final int NA = apps.size(); 4485 for (int ia=0; ia<NA; ia++) { 4486 ProcessRecord app = apps.valueAt(ia); 4487 if (app.persistent) { 4488 // we don't kill persistent processes 4489 continue; 4490 } 4491 if (app.removed) { 4492 procs.add(app); 4493 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4494 app.removed = true; 4495 procs.add(app); 4496 } 4497 } 4498 } 4499 4500 int N = procs.size(); 4501 for (int i=0; i<N; i++) { 4502 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4503 } 4504 mAllowLowerMemLevel = true; 4505 updateOomAdjLocked(); 4506 doLowMemReportIfNeededLocked(null); 4507 } 4508 } finally { 4509 Binder.restoreCallingIdentity(callingId); 4510 } 4511 } 4512 4513 @Override 4514 public void forceStopPackage(final String packageName, int userId) { 4515 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4516 != PackageManager.PERMISSION_GRANTED) { 4517 String msg = "Permission Denial: forceStopPackage() from pid=" 4518 + Binder.getCallingPid() 4519 + ", uid=" + Binder.getCallingUid() 4520 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4521 Slog.w(TAG, msg); 4522 throw new SecurityException(msg); 4523 } 4524 final int callingPid = Binder.getCallingPid(); 4525 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4526 userId, true, true, "forceStopPackage", null); 4527 long callingId = Binder.clearCallingIdentity(); 4528 try { 4529 IPackageManager pm = AppGlobals.getPackageManager(); 4530 synchronized(this) { 4531 int[] users = userId == UserHandle.USER_ALL 4532 ? getUsersLocked() : new int[] { userId }; 4533 for (int user : users) { 4534 int pkgUid = -1; 4535 try { 4536 pkgUid = pm.getPackageUid(packageName, user); 4537 } catch (RemoteException e) { 4538 } 4539 if (pkgUid == -1) { 4540 Slog.w(TAG, "Invalid packageName: " + packageName); 4541 continue; 4542 } 4543 try { 4544 pm.setPackageStoppedState(packageName, true, user); 4545 } catch (RemoteException e) { 4546 } catch (IllegalArgumentException e) { 4547 Slog.w(TAG, "Failed trying to unstop package " 4548 + packageName + ": " + e); 4549 } 4550 if (isUserRunningLocked(user, false)) { 4551 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4552 } 4553 } 4554 } 4555 } finally { 4556 Binder.restoreCallingIdentity(callingId); 4557 } 4558 } 4559 4560 /* 4561 * The pkg name and app id have to be specified. 4562 */ 4563 @Override 4564 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4565 if (pkg == null) { 4566 return; 4567 } 4568 // Make sure the uid is valid. 4569 if (appid < 0) { 4570 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4571 return; 4572 } 4573 int callerUid = Binder.getCallingUid(); 4574 // Only the system server can kill an application 4575 if (callerUid == Process.SYSTEM_UID) { 4576 // Post an aysnc message to kill the application 4577 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4578 msg.arg1 = appid; 4579 msg.arg2 = 0; 4580 Bundle bundle = new Bundle(); 4581 bundle.putString("pkg", pkg); 4582 bundle.putString("reason", reason); 4583 msg.obj = bundle; 4584 mHandler.sendMessage(msg); 4585 } else { 4586 throw new SecurityException(callerUid + " cannot kill pkg: " + 4587 pkg); 4588 } 4589 } 4590 4591 @Override 4592 public void closeSystemDialogs(String reason) { 4593 enforceNotIsolatedCaller("closeSystemDialogs"); 4594 4595 final int pid = Binder.getCallingPid(); 4596 final int uid = Binder.getCallingUid(); 4597 final long origId = Binder.clearCallingIdentity(); 4598 try { 4599 synchronized (this) { 4600 // Only allow this from foreground processes, so that background 4601 // applications can't abuse it to prevent system UI from being shown. 4602 if (uid >= Process.FIRST_APPLICATION_UID) { 4603 ProcessRecord proc; 4604 synchronized (mPidsSelfLocked) { 4605 proc = mPidsSelfLocked.get(pid); 4606 } 4607 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4608 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4609 + " from background process " + proc); 4610 return; 4611 } 4612 } 4613 closeSystemDialogsLocked(reason); 4614 } 4615 } finally { 4616 Binder.restoreCallingIdentity(origId); 4617 } 4618 } 4619 4620 void closeSystemDialogsLocked(String reason) { 4621 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4622 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4623 | Intent.FLAG_RECEIVER_FOREGROUND); 4624 if (reason != null) { 4625 intent.putExtra("reason", reason); 4626 } 4627 mWindowManager.closeSystemDialogs(reason); 4628 4629 mStackSupervisor.closeSystemDialogsLocked(); 4630 4631 broadcastIntentLocked(null, null, intent, null, 4632 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4633 Process.SYSTEM_UID, UserHandle.USER_ALL); 4634 } 4635 4636 @Override 4637 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4638 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4639 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4640 for (int i=pids.length-1; i>=0; i--) { 4641 ProcessRecord proc; 4642 int oomAdj; 4643 synchronized (this) { 4644 synchronized (mPidsSelfLocked) { 4645 proc = mPidsSelfLocked.get(pids[i]); 4646 oomAdj = proc != null ? proc.setAdj : 0; 4647 } 4648 } 4649 infos[i] = new Debug.MemoryInfo(); 4650 Debug.getMemoryInfo(pids[i], infos[i]); 4651 if (proc != null) { 4652 synchronized (this) { 4653 if (proc.thread != null && proc.setAdj == oomAdj) { 4654 // Record this for posterity if the process has been stable. 4655 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4656 infos[i].getTotalUss(), false, proc.pkgList); 4657 } 4658 } 4659 } 4660 } 4661 return infos; 4662 } 4663 4664 @Override 4665 public long[] getProcessPss(int[] pids) { 4666 enforceNotIsolatedCaller("getProcessPss"); 4667 long[] pss = new long[pids.length]; 4668 for (int i=pids.length-1; i>=0; i--) { 4669 ProcessRecord proc; 4670 int oomAdj; 4671 synchronized (this) { 4672 synchronized (mPidsSelfLocked) { 4673 proc = mPidsSelfLocked.get(pids[i]); 4674 oomAdj = proc != null ? proc.setAdj : 0; 4675 } 4676 } 4677 long[] tmpUss = new long[1]; 4678 pss[i] = Debug.getPss(pids[i], tmpUss); 4679 if (proc != null) { 4680 synchronized (this) { 4681 if (proc.thread != null && proc.setAdj == oomAdj) { 4682 // Record this for posterity if the process has been stable. 4683 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4684 } 4685 } 4686 } 4687 } 4688 return pss; 4689 } 4690 4691 @Override 4692 public void killApplicationProcess(String processName, int uid) { 4693 if (processName == null) { 4694 return; 4695 } 4696 4697 int callerUid = Binder.getCallingUid(); 4698 // Only the system server can kill an application 4699 if (callerUid == Process.SYSTEM_UID) { 4700 synchronized (this) { 4701 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4702 if (app != null && app.thread != null) { 4703 try { 4704 app.thread.scheduleSuicide(); 4705 } catch (RemoteException e) { 4706 // If the other end already died, then our work here is done. 4707 } 4708 } else { 4709 Slog.w(TAG, "Process/uid not found attempting kill of " 4710 + processName + " / " + uid); 4711 } 4712 } 4713 } else { 4714 throw new SecurityException(callerUid + " cannot kill app process: " + 4715 processName); 4716 } 4717 } 4718 4719 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4720 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4721 false, true, false, false, UserHandle.getUserId(uid), reason); 4722 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4723 Uri.fromParts("package", packageName, null)); 4724 if (!mProcessesReady) { 4725 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4726 | Intent.FLAG_RECEIVER_FOREGROUND); 4727 } 4728 intent.putExtra(Intent.EXTRA_UID, uid); 4729 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4730 broadcastIntentLocked(null, null, intent, 4731 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4732 false, false, 4733 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4734 } 4735 4736 private void forceStopUserLocked(int userId, String reason) { 4737 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4738 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4739 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4740 | Intent.FLAG_RECEIVER_FOREGROUND); 4741 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4742 broadcastIntentLocked(null, null, intent, 4743 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4744 false, false, 4745 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4746 } 4747 4748 private final boolean killPackageProcessesLocked(String packageName, int appId, 4749 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4750 boolean doit, boolean evenPersistent, String reason) { 4751 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4752 4753 // Remove all processes this package may have touched: all with the 4754 // same UID (except for the system or root user), and all whose name 4755 // matches the package name. 4756 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4757 final int NP = mProcessNames.getMap().size(); 4758 for (int ip=0; ip<NP; ip++) { 4759 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4760 final int NA = apps.size(); 4761 for (int ia=0; ia<NA; ia++) { 4762 ProcessRecord app = apps.valueAt(ia); 4763 if (app.persistent && !evenPersistent) { 4764 // we don't kill persistent processes 4765 continue; 4766 } 4767 if (app.removed) { 4768 if (doit) { 4769 procs.add(app); 4770 } 4771 continue; 4772 } 4773 4774 // Skip process if it doesn't meet our oom adj requirement. 4775 if (app.setAdj < minOomAdj) { 4776 continue; 4777 } 4778 4779 // If no package is specified, we call all processes under the 4780 // give user id. 4781 if (packageName == null) { 4782 if (app.userId != userId) { 4783 continue; 4784 } 4785 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4786 continue; 4787 } 4788 // Package has been specified, we want to hit all processes 4789 // that match it. We need to qualify this by the processes 4790 // that are running under the specified app and user ID. 4791 } else { 4792 if (UserHandle.getAppId(app.uid) != appId) { 4793 continue; 4794 } 4795 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4796 continue; 4797 } 4798 if (!app.pkgList.containsKey(packageName)) { 4799 continue; 4800 } 4801 } 4802 4803 // Process has passed all conditions, kill it! 4804 if (!doit) { 4805 return true; 4806 } 4807 app.removed = true; 4808 procs.add(app); 4809 } 4810 } 4811 4812 int N = procs.size(); 4813 for (int i=0; i<N; i++) { 4814 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4815 } 4816 updateOomAdjLocked(); 4817 return N > 0; 4818 } 4819 4820 private final boolean forceStopPackageLocked(String name, int appId, 4821 boolean callerWillRestart, boolean purgeCache, boolean doit, 4822 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4823 int i; 4824 int N; 4825 4826 if (userId == UserHandle.USER_ALL && name == null) { 4827 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4828 } 4829 4830 if (appId < 0 && name != null) { 4831 try { 4832 appId = UserHandle.getAppId( 4833 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4834 } catch (RemoteException e) { 4835 } 4836 } 4837 4838 if (doit) { 4839 if (name != null) { 4840 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4841 + " user=" + userId + ": " + reason); 4842 } else { 4843 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4844 } 4845 4846 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4847 for (int ip=pmap.size()-1; ip>=0; ip--) { 4848 SparseArray<Long> ba = pmap.valueAt(ip); 4849 for (i=ba.size()-1; i>=0; i--) { 4850 boolean remove = false; 4851 final int entUid = ba.keyAt(i); 4852 if (name != null) { 4853 if (userId == UserHandle.USER_ALL) { 4854 if (UserHandle.getAppId(entUid) == appId) { 4855 remove = true; 4856 } 4857 } else { 4858 if (entUid == UserHandle.getUid(userId, appId)) { 4859 remove = true; 4860 } 4861 } 4862 } else if (UserHandle.getUserId(entUid) == userId) { 4863 remove = true; 4864 } 4865 if (remove) { 4866 ba.removeAt(i); 4867 } 4868 } 4869 if (ba.size() == 0) { 4870 pmap.removeAt(ip); 4871 } 4872 } 4873 } 4874 4875 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4876 -100, callerWillRestart, true, doit, evenPersistent, 4877 name == null ? ("stop user " + userId) : ("stop " + name)); 4878 4879 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4880 if (!doit) { 4881 return true; 4882 } 4883 didSomething = true; 4884 } 4885 4886 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4887 if (!doit) { 4888 return true; 4889 } 4890 didSomething = true; 4891 } 4892 4893 if (name == null) { 4894 // Remove all sticky broadcasts from this user. 4895 mStickyBroadcasts.remove(userId); 4896 } 4897 4898 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4899 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4900 userId, providers)) { 4901 if (!doit) { 4902 return true; 4903 } 4904 didSomething = true; 4905 } 4906 N = providers.size(); 4907 for (i=0; i<N; i++) { 4908 removeDyingProviderLocked(null, providers.get(i), true); 4909 } 4910 4911 // Remove transient permissions granted from/to this package/user 4912 removeUriPermissionsForPackageLocked(name, userId, false); 4913 4914 if (name == null || uninstalling) { 4915 // Remove pending intents. For now we only do this when force 4916 // stopping users, because we have some problems when doing this 4917 // for packages -- app widgets are not currently cleaned up for 4918 // such packages, so they can be left with bad pending intents. 4919 if (mIntentSenderRecords.size() > 0) { 4920 Iterator<WeakReference<PendingIntentRecord>> it 4921 = mIntentSenderRecords.values().iterator(); 4922 while (it.hasNext()) { 4923 WeakReference<PendingIntentRecord> wpir = it.next(); 4924 if (wpir == null) { 4925 it.remove(); 4926 continue; 4927 } 4928 PendingIntentRecord pir = wpir.get(); 4929 if (pir == null) { 4930 it.remove(); 4931 continue; 4932 } 4933 if (name == null) { 4934 // Stopping user, remove all objects for the user. 4935 if (pir.key.userId != userId) { 4936 // Not the same user, skip it. 4937 continue; 4938 } 4939 } else { 4940 if (UserHandle.getAppId(pir.uid) != appId) { 4941 // Different app id, skip it. 4942 continue; 4943 } 4944 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4945 // Different user, skip it. 4946 continue; 4947 } 4948 if (!pir.key.packageName.equals(name)) { 4949 // Different package, skip it. 4950 continue; 4951 } 4952 } 4953 if (!doit) { 4954 return true; 4955 } 4956 didSomething = true; 4957 it.remove(); 4958 pir.canceled = true; 4959 if (pir.key.activity != null) { 4960 pir.key.activity.pendingResults.remove(pir.ref); 4961 } 4962 } 4963 } 4964 } 4965 4966 if (doit) { 4967 if (purgeCache && name != null) { 4968 AttributeCache ac = AttributeCache.instance(); 4969 if (ac != null) { 4970 ac.removePackage(name); 4971 } 4972 } 4973 if (mBooted) { 4974 mStackSupervisor.resumeTopActivitiesLocked(); 4975 mStackSupervisor.scheduleIdleLocked(); 4976 } 4977 } 4978 4979 return didSomething; 4980 } 4981 4982 private final boolean removeProcessLocked(ProcessRecord app, 4983 boolean callerWillRestart, boolean allowRestart, String reason) { 4984 final String name = app.processName; 4985 final int uid = app.uid; 4986 if (DEBUG_PROCESSES) Slog.d( 4987 TAG, "Force removing proc " + app.toShortString() + " (" + name 4988 + "/" + uid + ")"); 4989 4990 mProcessNames.remove(name, uid); 4991 mIsolatedProcesses.remove(app.uid); 4992 if (mHeavyWeightProcess == app) { 4993 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4994 mHeavyWeightProcess.userId, 0)); 4995 mHeavyWeightProcess = null; 4996 } 4997 boolean needRestart = false; 4998 if (app.pid > 0 && app.pid != MY_PID) { 4999 int pid = app.pid; 5000 synchronized (mPidsSelfLocked) { 5001 mPidsSelfLocked.remove(pid); 5002 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5003 } 5004 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5005 app.processName, app.info.uid); 5006 if (app.isolated) { 5007 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5008 } 5009 killUnneededProcessLocked(app, reason); 5010 handleAppDiedLocked(app, true, allowRestart); 5011 removeLruProcessLocked(app); 5012 5013 if (app.persistent && !app.isolated) { 5014 if (!callerWillRestart) { 5015 addAppLocked(app.info, false); 5016 } else { 5017 needRestart = true; 5018 } 5019 } 5020 } else { 5021 mRemovedProcesses.add(app); 5022 } 5023 5024 return needRestart; 5025 } 5026 5027 private final void processStartTimedOutLocked(ProcessRecord app) { 5028 final int pid = app.pid; 5029 boolean gone = false; 5030 synchronized (mPidsSelfLocked) { 5031 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5032 if (knownApp != null && knownApp.thread == null) { 5033 mPidsSelfLocked.remove(pid); 5034 gone = true; 5035 } 5036 } 5037 5038 if (gone) { 5039 Slog.w(TAG, "Process " + app + " failed to attach"); 5040 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5041 pid, app.uid, app.processName); 5042 mProcessNames.remove(app.processName, app.uid); 5043 mIsolatedProcesses.remove(app.uid); 5044 if (mHeavyWeightProcess == app) { 5045 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5046 mHeavyWeightProcess.userId, 0)); 5047 mHeavyWeightProcess = null; 5048 } 5049 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5050 app.processName, app.info.uid); 5051 if (app.isolated) { 5052 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5053 } 5054 // Take care of any launching providers waiting for this process. 5055 checkAppInLaunchingProvidersLocked(app, true); 5056 // Take care of any services that are waiting for the process. 5057 mServices.processStartTimedOutLocked(app); 5058 killUnneededProcessLocked(app, "start timeout"); 5059 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5060 Slog.w(TAG, "Unattached app died before backup, skipping"); 5061 try { 5062 IBackupManager bm = IBackupManager.Stub.asInterface( 5063 ServiceManager.getService(Context.BACKUP_SERVICE)); 5064 bm.agentDisconnected(app.info.packageName); 5065 } catch (RemoteException e) { 5066 // Can't happen; the backup manager is local 5067 } 5068 } 5069 if (isPendingBroadcastProcessLocked(pid)) { 5070 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5071 skipPendingBroadcastLocked(pid); 5072 } 5073 } else { 5074 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5075 } 5076 } 5077 5078 private final boolean attachApplicationLocked(IApplicationThread thread, 5079 int pid) { 5080 5081 // Find the application record that is being attached... either via 5082 // the pid if we are running in multiple processes, or just pull the 5083 // next app record if we are emulating process with anonymous threads. 5084 ProcessRecord app; 5085 if (pid != MY_PID && pid >= 0) { 5086 synchronized (mPidsSelfLocked) { 5087 app = mPidsSelfLocked.get(pid); 5088 } 5089 } else { 5090 app = null; 5091 } 5092 5093 if (app == null) { 5094 Slog.w(TAG, "No pending application record for pid " + pid 5095 + " (IApplicationThread " + thread + "); dropping process"); 5096 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5097 if (pid > 0 && pid != MY_PID) { 5098 Process.killProcessQuiet(pid); 5099 } else { 5100 try { 5101 thread.scheduleExit(); 5102 } catch (Exception e) { 5103 // Ignore exceptions. 5104 } 5105 } 5106 return false; 5107 } 5108 5109 // If this application record is still attached to a previous 5110 // process, clean it up now. 5111 if (app.thread != null) { 5112 handleAppDiedLocked(app, true, true); 5113 } 5114 5115 // Tell the process all about itself. 5116 5117 if (localLOGV) Slog.v( 5118 TAG, "Binding process pid " + pid + " to record " + app); 5119 5120 final String processName = app.processName; 5121 try { 5122 AppDeathRecipient adr = new AppDeathRecipient( 5123 app, pid, thread); 5124 thread.asBinder().linkToDeath(adr, 0); 5125 app.deathRecipient = adr; 5126 } catch (RemoteException e) { 5127 app.resetPackageList(mProcessStats); 5128 startProcessLocked(app, "link fail", processName); 5129 return false; 5130 } 5131 5132 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5133 5134 app.makeActive(thread, mProcessStats); 5135 app.curAdj = app.setAdj = -100; 5136 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5137 app.forcingToForeground = null; 5138 updateProcessForegroundLocked(app, false, false); 5139 app.hasShownUi = false; 5140 app.debugging = false; 5141 app.cached = false; 5142 5143 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5144 5145 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5146 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5147 5148 if (!normalMode) { 5149 Slog.i(TAG, "Launching preboot mode app: " + app); 5150 } 5151 5152 if (localLOGV) Slog.v( 5153 TAG, "New app record " + app 5154 + " thread=" + thread.asBinder() + " pid=" + pid); 5155 try { 5156 int testMode = IApplicationThread.DEBUG_OFF; 5157 if (mDebugApp != null && mDebugApp.equals(processName)) { 5158 testMode = mWaitForDebugger 5159 ? IApplicationThread.DEBUG_WAIT 5160 : IApplicationThread.DEBUG_ON; 5161 app.debugging = true; 5162 if (mDebugTransient) { 5163 mDebugApp = mOrigDebugApp; 5164 mWaitForDebugger = mOrigWaitForDebugger; 5165 } 5166 } 5167 String profileFile = app.instrumentationProfileFile; 5168 ParcelFileDescriptor profileFd = null; 5169 boolean profileAutoStop = false; 5170 if (mProfileApp != null && mProfileApp.equals(processName)) { 5171 mProfileProc = app; 5172 profileFile = mProfileFile; 5173 profileFd = mProfileFd; 5174 profileAutoStop = mAutoStopProfiler; 5175 } 5176 boolean enableOpenGlTrace = false; 5177 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5178 enableOpenGlTrace = true; 5179 mOpenGlTraceApp = null; 5180 } 5181 5182 // If the app is being launched for restore or full backup, set it up specially 5183 boolean isRestrictedBackupMode = false; 5184 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5185 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5186 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5187 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5188 } 5189 5190 ensurePackageDexOpt(app.instrumentationInfo != null 5191 ? app.instrumentationInfo.packageName 5192 : app.info.packageName); 5193 if (app.instrumentationClass != null) { 5194 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5195 } 5196 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5197 + processName + " with config " + mConfiguration); 5198 ApplicationInfo appInfo = app.instrumentationInfo != null 5199 ? app.instrumentationInfo : app.info; 5200 app.compat = compatibilityInfoForPackageLocked(appInfo); 5201 if (profileFd != null) { 5202 profileFd = profileFd.dup(); 5203 } 5204 thread.bindApplication(processName, appInfo, providers, 5205 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5206 app.instrumentationArguments, app.instrumentationWatcher, 5207 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5208 isRestrictedBackupMode || !normalMode, app.persistent, 5209 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5210 mCoreSettingsObserver.getCoreSettingsLocked()); 5211 updateLruProcessLocked(app, false, null); 5212 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5213 } catch (Exception e) { 5214 // todo: Yikes! What should we do? For now we will try to 5215 // start another process, but that could easily get us in 5216 // an infinite loop of restarting processes... 5217 Slog.w(TAG, "Exception thrown during bind!", e); 5218 5219 app.resetPackageList(mProcessStats); 5220 app.unlinkDeathRecipient(); 5221 startProcessLocked(app, "bind fail", processName); 5222 return false; 5223 } 5224 5225 // Remove this record from the list of starting applications. 5226 mPersistentStartingProcesses.remove(app); 5227 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5228 "Attach application locked removing on hold: " + app); 5229 mProcessesOnHold.remove(app); 5230 5231 boolean badApp = false; 5232 boolean didSomething = false; 5233 5234 // See if the top visible activity is waiting to run in this process... 5235 if (normalMode) { 5236 try { 5237 if (mStackSupervisor.attachApplicationLocked(app)) { 5238 didSomething = true; 5239 } 5240 } catch (Exception e) { 5241 badApp = true; 5242 } 5243 } 5244 5245 // Find any services that should be running in this process... 5246 if (!badApp) { 5247 try { 5248 didSomething |= mServices.attachApplicationLocked(app, processName); 5249 } catch (Exception e) { 5250 badApp = true; 5251 } 5252 } 5253 5254 // Check if a next-broadcast receiver is in this process... 5255 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5256 try { 5257 didSomething |= sendPendingBroadcastsLocked(app); 5258 } catch (Exception e) { 5259 // If the app died trying to launch the receiver we declare it 'bad' 5260 badApp = true; 5261 } 5262 } 5263 5264 // Check whether the next backup agent is in this process... 5265 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5266 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5267 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5268 try { 5269 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5270 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5271 mBackupTarget.backupMode); 5272 } catch (Exception e) { 5273 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5274 e.printStackTrace(); 5275 } 5276 } 5277 5278 if (badApp) { 5279 // todo: Also need to kill application to deal with all 5280 // kinds of exceptions. 5281 handleAppDiedLocked(app, false, true); 5282 return false; 5283 } 5284 5285 if (!didSomething) { 5286 updateOomAdjLocked(); 5287 } 5288 5289 return true; 5290 } 5291 5292 @Override 5293 public final void attachApplication(IApplicationThread thread) { 5294 synchronized (this) { 5295 int callingPid = Binder.getCallingPid(); 5296 final long origId = Binder.clearCallingIdentity(); 5297 attachApplicationLocked(thread, callingPid); 5298 Binder.restoreCallingIdentity(origId); 5299 } 5300 } 5301 5302 @Override 5303 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5304 final long origId = Binder.clearCallingIdentity(); 5305 synchronized (this) { 5306 ActivityStack stack = ActivityRecord.getStackLocked(token); 5307 if (stack != null) { 5308 ActivityRecord r = 5309 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5310 if (stopProfiling) { 5311 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5312 try { 5313 mProfileFd.close(); 5314 } catch (IOException e) { 5315 } 5316 clearProfilerLocked(); 5317 } 5318 } 5319 } 5320 } 5321 Binder.restoreCallingIdentity(origId); 5322 } 5323 5324 void enableScreenAfterBoot() { 5325 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5326 SystemClock.uptimeMillis()); 5327 mWindowManager.enableScreenAfterBoot(); 5328 5329 synchronized (this) { 5330 updateEventDispatchingLocked(); 5331 } 5332 } 5333 5334 @Override 5335 public void showBootMessage(final CharSequence msg, final boolean always) { 5336 enforceNotIsolatedCaller("showBootMessage"); 5337 mWindowManager.showBootMessage(msg, always); 5338 } 5339 5340 @Override 5341 public void dismissKeyguardOnNextActivity() { 5342 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5343 final long token = Binder.clearCallingIdentity(); 5344 try { 5345 synchronized (this) { 5346 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5347 if (mLockScreenShown) { 5348 mLockScreenShown = false; 5349 comeOutOfSleepIfNeededLocked(); 5350 } 5351 mStackSupervisor.setDismissKeyguard(true); 5352 } 5353 } finally { 5354 Binder.restoreCallingIdentity(token); 5355 } 5356 } 5357 5358 final void finishBooting() { 5359 // Register receivers to handle package update events 5360 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5361 5362 synchronized (this) { 5363 // Ensure that any processes we had put on hold are now started 5364 // up. 5365 final int NP = mProcessesOnHold.size(); 5366 if (NP > 0) { 5367 ArrayList<ProcessRecord> procs = 5368 new ArrayList<ProcessRecord>(mProcessesOnHold); 5369 for (int ip=0; ip<NP; ip++) { 5370 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5371 + procs.get(ip)); 5372 startProcessLocked(procs.get(ip), "on-hold", null); 5373 } 5374 } 5375 5376 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5377 // Start looking for apps that are abusing wake locks. 5378 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5379 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5380 // Tell anyone interested that we are done booting! 5381 SystemProperties.set("sys.boot_completed", "1"); 5382 SystemProperties.set("dev.bootcomplete", "1"); 5383 for (int i=0; i<mStartedUsers.size(); i++) { 5384 UserStartedState uss = mStartedUsers.valueAt(i); 5385 if (uss.mState == UserStartedState.STATE_BOOTING) { 5386 uss.mState = UserStartedState.STATE_RUNNING; 5387 final int userId = mStartedUsers.keyAt(i); 5388 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5389 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5390 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5391 broadcastIntentLocked(null, null, intent, null, 5392 new IIntentReceiver.Stub() { 5393 @Override 5394 public void performReceive(Intent intent, int resultCode, 5395 String data, Bundle extras, boolean ordered, 5396 boolean sticky, int sendingUser) { 5397 synchronized (ActivityManagerService.this) { 5398 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5399 true, false); 5400 } 5401 } 5402 }, 5403 0, null, null, 5404 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5405 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5406 userId); 5407 } 5408 } 5409 scheduleStartProfilesLocked(); 5410 } 5411 } 5412 } 5413 5414 final void ensureBootCompleted() { 5415 boolean booting; 5416 boolean enableScreen; 5417 synchronized (this) { 5418 booting = mBooting; 5419 mBooting = false; 5420 enableScreen = !mBooted; 5421 mBooted = true; 5422 } 5423 5424 if (booting) { 5425 finishBooting(); 5426 } 5427 5428 if (enableScreen) { 5429 enableScreenAfterBoot(); 5430 } 5431 } 5432 5433 @Override 5434 public final void activityResumed(IBinder token) { 5435 final long origId = Binder.clearCallingIdentity(); 5436 synchronized(this) { 5437 ActivityStack stack = ActivityRecord.getStackLocked(token); 5438 if (stack != null) { 5439 ActivityRecord.activityResumedLocked(token); 5440 } 5441 } 5442 Binder.restoreCallingIdentity(origId); 5443 } 5444 5445 @Override 5446 public final void activityPaused(IBinder token, PersistableBundle persistentState) { 5447 final long origId = Binder.clearCallingIdentity(); 5448 synchronized(this) { 5449 ActivityStack stack = ActivityRecord.getStackLocked(token); 5450 if (stack != null) { 5451 stack.activityPausedLocked(token, false, persistentState); 5452 } 5453 } 5454 Binder.restoreCallingIdentity(origId); 5455 } 5456 5457 @Override 5458 public final void activityStopped(IBinder token, Bundle icicle, 5459 PersistableBundle persistentState, CharSequence description) { 5460 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token); 5461 5462 // Refuse possible leaked file descriptors 5463 if (icicle != null && icicle.hasFileDescriptors()) { 5464 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5465 } 5466 5467 final long origId = Binder.clearCallingIdentity(); 5468 5469 synchronized (this) { 5470 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5471 if (r != null) { 5472 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description); 5473 } 5474 } 5475 5476 trimApplications(); 5477 5478 Binder.restoreCallingIdentity(origId); 5479 } 5480 5481 @Override 5482 public final void activityDestroyed(IBinder token) { 5483 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5484 synchronized (this) { 5485 ActivityStack stack = ActivityRecord.getStackLocked(token); 5486 if (stack != null) { 5487 stack.activityDestroyedLocked(token); 5488 } 5489 } 5490 } 5491 5492 @Override 5493 public String getCallingPackage(IBinder token) { 5494 synchronized (this) { 5495 ActivityRecord r = getCallingRecordLocked(token); 5496 return r != null ? r.info.packageName : null; 5497 } 5498 } 5499 5500 @Override 5501 public ComponentName getCallingActivity(IBinder token) { 5502 synchronized (this) { 5503 ActivityRecord r = getCallingRecordLocked(token); 5504 return r != null ? r.intent.getComponent() : null; 5505 } 5506 } 5507 5508 private ActivityRecord getCallingRecordLocked(IBinder token) { 5509 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5510 if (r == null) { 5511 return null; 5512 } 5513 return r.resultTo; 5514 } 5515 5516 @Override 5517 public ComponentName getActivityClassForToken(IBinder token) { 5518 synchronized(this) { 5519 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5520 if (r == null) { 5521 return null; 5522 } 5523 return r.intent.getComponent(); 5524 } 5525 } 5526 5527 @Override 5528 public String getPackageForToken(IBinder token) { 5529 synchronized(this) { 5530 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5531 if (r == null) { 5532 return null; 5533 } 5534 return r.packageName; 5535 } 5536 } 5537 5538 @Override 5539 public IIntentSender getIntentSender(int type, 5540 String packageName, IBinder token, String resultWho, 5541 int requestCode, Intent[] intents, String[] resolvedTypes, 5542 int flags, Bundle options, int userId) { 5543 enforceNotIsolatedCaller("getIntentSender"); 5544 // Refuse possible leaked file descriptors 5545 if (intents != null) { 5546 if (intents.length < 1) { 5547 throw new IllegalArgumentException("Intents array length must be >= 1"); 5548 } 5549 for (int i=0; i<intents.length; i++) { 5550 Intent intent = intents[i]; 5551 if (intent != null) { 5552 if (intent.hasFileDescriptors()) { 5553 throw new IllegalArgumentException("File descriptors passed in Intent"); 5554 } 5555 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5556 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5557 throw new IllegalArgumentException( 5558 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5559 } 5560 intents[i] = new Intent(intent); 5561 } 5562 } 5563 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5564 throw new IllegalArgumentException( 5565 "Intent array length does not match resolvedTypes length"); 5566 } 5567 } 5568 if (options != null) { 5569 if (options.hasFileDescriptors()) { 5570 throw new IllegalArgumentException("File descriptors passed in options"); 5571 } 5572 } 5573 5574 synchronized(this) { 5575 int callingUid = Binder.getCallingUid(); 5576 int origUserId = userId; 5577 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5578 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5579 "getIntentSender", null); 5580 if (origUserId == UserHandle.USER_CURRENT) { 5581 // We don't want to evaluate this until the pending intent is 5582 // actually executed. However, we do want to always do the 5583 // security checking for it above. 5584 userId = UserHandle.USER_CURRENT; 5585 } 5586 try { 5587 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5588 int uid = AppGlobals.getPackageManager() 5589 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5590 if (!UserHandle.isSameApp(callingUid, uid)) { 5591 String msg = "Permission Denial: getIntentSender() from pid=" 5592 + Binder.getCallingPid() 5593 + ", uid=" + Binder.getCallingUid() 5594 + ", (need uid=" + uid + ")" 5595 + " is not allowed to send as package " + packageName; 5596 Slog.w(TAG, msg); 5597 throw new SecurityException(msg); 5598 } 5599 } 5600 5601 return getIntentSenderLocked(type, packageName, callingUid, userId, 5602 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5603 5604 } catch (RemoteException e) { 5605 throw new SecurityException(e); 5606 } 5607 } 5608 } 5609 5610 IIntentSender getIntentSenderLocked(int type, String packageName, 5611 int callingUid, int userId, IBinder token, String resultWho, 5612 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5613 Bundle options) { 5614 if (DEBUG_MU) 5615 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5616 ActivityRecord activity = null; 5617 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5618 activity = ActivityRecord.isInStackLocked(token); 5619 if (activity == null) { 5620 return null; 5621 } 5622 if (activity.finishing) { 5623 return null; 5624 } 5625 } 5626 5627 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5628 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5629 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5630 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5631 |PendingIntent.FLAG_UPDATE_CURRENT); 5632 5633 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5634 type, packageName, activity, resultWho, 5635 requestCode, intents, resolvedTypes, flags, options, userId); 5636 WeakReference<PendingIntentRecord> ref; 5637 ref = mIntentSenderRecords.get(key); 5638 PendingIntentRecord rec = ref != null ? ref.get() : null; 5639 if (rec != null) { 5640 if (!cancelCurrent) { 5641 if (updateCurrent) { 5642 if (rec.key.requestIntent != null) { 5643 rec.key.requestIntent.replaceExtras(intents != null ? 5644 intents[intents.length - 1] : null); 5645 } 5646 if (intents != null) { 5647 intents[intents.length-1] = rec.key.requestIntent; 5648 rec.key.allIntents = intents; 5649 rec.key.allResolvedTypes = resolvedTypes; 5650 } else { 5651 rec.key.allIntents = null; 5652 rec.key.allResolvedTypes = null; 5653 } 5654 } 5655 return rec; 5656 } 5657 rec.canceled = true; 5658 mIntentSenderRecords.remove(key); 5659 } 5660 if (noCreate) { 5661 return rec; 5662 } 5663 rec = new PendingIntentRecord(this, key, callingUid); 5664 mIntentSenderRecords.put(key, rec.ref); 5665 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5666 if (activity.pendingResults == null) { 5667 activity.pendingResults 5668 = new HashSet<WeakReference<PendingIntentRecord>>(); 5669 } 5670 activity.pendingResults.add(rec.ref); 5671 } 5672 return rec; 5673 } 5674 5675 @Override 5676 public void cancelIntentSender(IIntentSender sender) { 5677 if (!(sender instanceof PendingIntentRecord)) { 5678 return; 5679 } 5680 synchronized(this) { 5681 PendingIntentRecord rec = (PendingIntentRecord)sender; 5682 try { 5683 int uid = AppGlobals.getPackageManager() 5684 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5685 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5686 String msg = "Permission Denial: cancelIntentSender() from pid=" 5687 + Binder.getCallingPid() 5688 + ", uid=" + Binder.getCallingUid() 5689 + " is not allowed to cancel packges " 5690 + rec.key.packageName; 5691 Slog.w(TAG, msg); 5692 throw new SecurityException(msg); 5693 } 5694 } catch (RemoteException e) { 5695 throw new SecurityException(e); 5696 } 5697 cancelIntentSenderLocked(rec, true); 5698 } 5699 } 5700 5701 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5702 rec.canceled = true; 5703 mIntentSenderRecords.remove(rec.key); 5704 if (cleanActivity && rec.key.activity != null) { 5705 rec.key.activity.pendingResults.remove(rec.ref); 5706 } 5707 } 5708 5709 @Override 5710 public String getPackageForIntentSender(IIntentSender pendingResult) { 5711 if (!(pendingResult instanceof PendingIntentRecord)) { 5712 return null; 5713 } 5714 try { 5715 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5716 return res.key.packageName; 5717 } catch (ClassCastException e) { 5718 } 5719 return null; 5720 } 5721 5722 @Override 5723 public int getUidForIntentSender(IIntentSender sender) { 5724 if (sender instanceof PendingIntentRecord) { 5725 try { 5726 PendingIntentRecord res = (PendingIntentRecord)sender; 5727 return res.uid; 5728 } catch (ClassCastException e) { 5729 } 5730 } 5731 return -1; 5732 } 5733 5734 @Override 5735 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5736 if (!(pendingResult instanceof PendingIntentRecord)) { 5737 return false; 5738 } 5739 try { 5740 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5741 if (res.key.allIntents == null) { 5742 return false; 5743 } 5744 for (int i=0; i<res.key.allIntents.length; i++) { 5745 Intent intent = res.key.allIntents[i]; 5746 if (intent.getPackage() != null && intent.getComponent() != null) { 5747 return false; 5748 } 5749 } 5750 return true; 5751 } catch (ClassCastException e) { 5752 } 5753 return false; 5754 } 5755 5756 @Override 5757 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5758 if (!(pendingResult instanceof PendingIntentRecord)) { 5759 return false; 5760 } 5761 try { 5762 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5763 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5764 return true; 5765 } 5766 return false; 5767 } catch (ClassCastException e) { 5768 } 5769 return false; 5770 } 5771 5772 @Override 5773 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5774 if (!(pendingResult instanceof PendingIntentRecord)) { 5775 return null; 5776 } 5777 try { 5778 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5779 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5780 } catch (ClassCastException e) { 5781 } 5782 return null; 5783 } 5784 5785 @Override 5786 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5787 if (!(pendingResult instanceof PendingIntentRecord)) { 5788 return null; 5789 } 5790 try { 5791 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5792 Intent intent = res.key.requestIntent; 5793 if (intent != null) { 5794 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5795 || res.lastTagPrefix.equals(prefix))) { 5796 return res.lastTag; 5797 } 5798 res.lastTagPrefix = prefix; 5799 StringBuilder sb = new StringBuilder(128); 5800 if (prefix != null) { 5801 sb.append(prefix); 5802 } 5803 if (intent.getAction() != null) { 5804 sb.append(intent.getAction()); 5805 } else if (intent.getComponent() != null) { 5806 intent.getComponent().appendShortString(sb); 5807 } else { 5808 sb.append("?"); 5809 } 5810 return res.lastTag = sb.toString(); 5811 } 5812 } catch (ClassCastException e) { 5813 } 5814 return null; 5815 } 5816 5817 @Override 5818 public void setProcessLimit(int max) { 5819 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5820 "setProcessLimit()"); 5821 synchronized (this) { 5822 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5823 mProcessLimitOverride = max; 5824 } 5825 trimApplications(); 5826 } 5827 5828 @Override 5829 public int getProcessLimit() { 5830 synchronized (this) { 5831 return mProcessLimitOverride; 5832 } 5833 } 5834 5835 void foregroundTokenDied(ForegroundToken token) { 5836 synchronized (ActivityManagerService.this) { 5837 synchronized (mPidsSelfLocked) { 5838 ForegroundToken cur 5839 = mForegroundProcesses.get(token.pid); 5840 if (cur != token) { 5841 return; 5842 } 5843 mForegroundProcesses.remove(token.pid); 5844 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5845 if (pr == null) { 5846 return; 5847 } 5848 pr.forcingToForeground = null; 5849 updateProcessForegroundLocked(pr, false, false); 5850 } 5851 updateOomAdjLocked(); 5852 } 5853 } 5854 5855 @Override 5856 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5857 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5858 "setProcessForeground()"); 5859 synchronized(this) { 5860 boolean changed = false; 5861 5862 synchronized (mPidsSelfLocked) { 5863 ProcessRecord pr = mPidsSelfLocked.get(pid); 5864 if (pr == null && isForeground) { 5865 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5866 return; 5867 } 5868 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5869 if (oldToken != null) { 5870 oldToken.token.unlinkToDeath(oldToken, 0); 5871 mForegroundProcesses.remove(pid); 5872 if (pr != null) { 5873 pr.forcingToForeground = null; 5874 } 5875 changed = true; 5876 } 5877 if (isForeground && token != null) { 5878 ForegroundToken newToken = new ForegroundToken() { 5879 @Override 5880 public void binderDied() { 5881 foregroundTokenDied(this); 5882 } 5883 }; 5884 newToken.pid = pid; 5885 newToken.token = token; 5886 try { 5887 token.linkToDeath(newToken, 0); 5888 mForegroundProcesses.put(pid, newToken); 5889 pr.forcingToForeground = token; 5890 changed = true; 5891 } catch (RemoteException e) { 5892 // If the process died while doing this, we will later 5893 // do the cleanup with the process death link. 5894 } 5895 } 5896 } 5897 5898 if (changed) { 5899 updateOomAdjLocked(); 5900 } 5901 } 5902 } 5903 5904 // ========================================================= 5905 // PERMISSIONS 5906 // ========================================================= 5907 5908 static class PermissionController extends IPermissionController.Stub { 5909 ActivityManagerService mActivityManagerService; 5910 PermissionController(ActivityManagerService activityManagerService) { 5911 mActivityManagerService = activityManagerService; 5912 } 5913 5914 @Override 5915 public boolean checkPermission(String permission, int pid, int uid) { 5916 return mActivityManagerService.checkPermission(permission, pid, 5917 uid) == PackageManager.PERMISSION_GRANTED; 5918 } 5919 } 5920 5921 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5922 @Override 5923 public int checkComponentPermission(String permission, int pid, int uid, 5924 int owningUid, boolean exported) { 5925 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5926 owningUid, exported); 5927 } 5928 5929 @Override 5930 public Object getAMSLock() { 5931 return ActivityManagerService.this; 5932 } 5933 } 5934 5935 /** 5936 * This can be called with or without the global lock held. 5937 */ 5938 int checkComponentPermission(String permission, int pid, int uid, 5939 int owningUid, boolean exported) { 5940 // We might be performing an operation on behalf of an indirect binder 5941 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5942 // client identity accordingly before proceeding. 5943 Identity tlsIdentity = sCallerIdentity.get(); 5944 if (tlsIdentity != null) { 5945 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5946 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5947 uid = tlsIdentity.uid; 5948 pid = tlsIdentity.pid; 5949 } 5950 5951 if (pid == MY_PID) { 5952 return PackageManager.PERMISSION_GRANTED; 5953 } 5954 5955 return ActivityManager.checkComponentPermission(permission, uid, 5956 owningUid, exported); 5957 } 5958 5959 /** 5960 * As the only public entry point for permissions checking, this method 5961 * can enforce the semantic that requesting a check on a null global 5962 * permission is automatically denied. (Internally a null permission 5963 * string is used when calling {@link #checkComponentPermission} in cases 5964 * when only uid-based security is needed.) 5965 * 5966 * This can be called with or without the global lock held. 5967 */ 5968 @Override 5969 public int checkPermission(String permission, int pid, int uid) { 5970 if (permission == null) { 5971 return PackageManager.PERMISSION_DENIED; 5972 } 5973 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5974 } 5975 5976 /** 5977 * Binder IPC calls go through the public entry point. 5978 * This can be called with or without the global lock held. 5979 */ 5980 int checkCallingPermission(String permission) { 5981 return checkPermission(permission, 5982 Binder.getCallingPid(), 5983 UserHandle.getAppId(Binder.getCallingUid())); 5984 } 5985 5986 /** 5987 * This can be called with or without the global lock held. 5988 */ 5989 void enforceCallingPermission(String permission, String func) { 5990 if (checkCallingPermission(permission) 5991 == PackageManager.PERMISSION_GRANTED) { 5992 return; 5993 } 5994 5995 String msg = "Permission Denial: " + func + " from pid=" 5996 + Binder.getCallingPid() 5997 + ", uid=" + Binder.getCallingUid() 5998 + " requires " + permission; 5999 Slog.w(TAG, msg); 6000 throw new SecurityException(msg); 6001 } 6002 6003 /** 6004 * Determine if UID is holding permissions required to access {@link Uri} in 6005 * the given {@link ProviderInfo}. Final permission checking is always done 6006 * in {@link ContentProvider}. 6007 */ 6008 private final boolean checkHoldingPermissionsLocked( 6009 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) { 6010 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6011 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid); 6012 6013 if (pi.applicationInfo.uid == uid) { 6014 return true; 6015 } else if (!pi.exported) { 6016 return false; 6017 } 6018 6019 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6020 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6021 try { 6022 // check if target holds top-level <provider> permissions 6023 if (!readMet && pi.readPermission != null 6024 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6025 readMet = true; 6026 } 6027 if (!writeMet && pi.writePermission != null 6028 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6029 writeMet = true; 6030 } 6031 6032 // track if unprotected read/write is allowed; any denied 6033 // <path-permission> below removes this ability 6034 boolean allowDefaultRead = pi.readPermission == null; 6035 boolean allowDefaultWrite = pi.writePermission == null; 6036 6037 // check if target holds any <path-permission> that match uri 6038 final PathPermission[] pps = pi.pathPermissions; 6039 if (pps != null) { 6040 final String path = grantUri.uri.getPath(); 6041 int i = pps.length; 6042 while (i > 0 && (!readMet || !writeMet)) { 6043 i--; 6044 PathPermission pp = pps[i]; 6045 if (pp.match(path)) { 6046 if (!readMet) { 6047 final String pprperm = pp.getReadPermission(); 6048 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6049 + pprperm + " for " + pp.getPath() 6050 + ": match=" + pp.match(path) 6051 + " check=" + pm.checkUidPermission(pprperm, uid)); 6052 if (pprperm != null) { 6053 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6054 readMet = true; 6055 } else { 6056 allowDefaultRead = false; 6057 } 6058 } 6059 } 6060 if (!writeMet) { 6061 final String ppwperm = pp.getWritePermission(); 6062 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6063 + ppwperm + " for " + pp.getPath() 6064 + ": match=" + pp.match(path) 6065 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6066 if (ppwperm != null) { 6067 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6068 writeMet = true; 6069 } else { 6070 allowDefaultWrite = false; 6071 } 6072 } 6073 } 6074 } 6075 } 6076 } 6077 6078 // grant unprotected <provider> read/write, if not blocked by 6079 // <path-permission> above 6080 if (allowDefaultRead) readMet = true; 6081 if (allowDefaultWrite) writeMet = true; 6082 6083 } catch (RemoteException e) { 6084 return false; 6085 } 6086 6087 return readMet && writeMet; 6088 } 6089 6090 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6091 ProviderInfo pi = null; 6092 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6093 if (cpr != null) { 6094 pi = cpr.info; 6095 } else { 6096 try { 6097 pi = AppGlobals.getPackageManager().resolveContentProvider( 6098 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6099 } catch (RemoteException ex) { 6100 } 6101 } 6102 return pi; 6103 } 6104 6105 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) { 6106 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6107 if (targetUris != null) { 6108 return targetUris.get(grantUri); 6109 } 6110 return null; 6111 } 6112 6113 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6114 String targetPkg, int targetUid, GrantUri grantUri) { 6115 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6116 if (targetUris == null) { 6117 targetUris = Maps.newArrayMap(); 6118 mGrantedUriPermissions.put(targetUid, targetUris); 6119 } 6120 6121 UriPermission perm = targetUris.get(grantUri); 6122 if (perm == null) { 6123 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri); 6124 targetUris.put(grantUri, perm); 6125 } 6126 6127 return perm; 6128 } 6129 6130 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid, 6131 final int modeFlags) { 6132 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6133 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6134 : UriPermission.STRENGTH_OWNED; 6135 6136 // Root gets to do everything. 6137 if (uid == 0) { 6138 return true; 6139 } 6140 6141 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6142 if (perms == null) return false; 6143 6144 // First look for exact match 6145 final UriPermission exactPerm = perms.get(grantUri); 6146 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6147 return true; 6148 } 6149 6150 // No exact match, look for prefixes 6151 final int N = perms.size(); 6152 for (int i = 0; i < N; i++) { 6153 final UriPermission perm = perms.valueAt(i); 6154 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri) 6155 && perm.getStrength(modeFlags) >= minStrength) { 6156 return true; 6157 } 6158 } 6159 6160 return false; 6161 } 6162 6163 @Override 6164 public int checkUriPermission(Uri uri, int pid, int uid, 6165 final int modeFlags, int userId) { 6166 enforceNotIsolatedCaller("checkUriPermission"); 6167 6168 // Another redirected-binder-call permissions check as in 6169 // {@link checkComponentPermission}. 6170 Identity tlsIdentity = sCallerIdentity.get(); 6171 if (tlsIdentity != null) { 6172 uid = tlsIdentity.uid; 6173 pid = tlsIdentity.pid; 6174 } 6175 6176 // Our own process gets to do everything. 6177 if (pid == MY_PID) { 6178 return PackageManager.PERMISSION_GRANTED; 6179 } 6180 synchronized (this) { 6181 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags) 6182 ? PackageManager.PERMISSION_GRANTED 6183 : PackageManager.PERMISSION_DENIED; 6184 } 6185 } 6186 6187 /** 6188 * Check if the targetPkg can be granted permission to access uri by 6189 * the callingUid using the given modeFlags. Throws a security exception 6190 * if callingUid is not allowed to do this. Returns the uid of the target 6191 * if the URI permission grant should be performed; returns -1 if it is not 6192 * needed (for example targetPkg already has permission to access the URI). 6193 * If you already know the uid of the target, you can supply it in 6194 * lastTargetUid else set that to -1. 6195 */ 6196 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6197 final int modeFlags, int lastTargetUid) { 6198 if (!Intent.isAccessUriMode(modeFlags)) { 6199 return -1; 6200 } 6201 6202 if (targetPkg != null) { 6203 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6204 "Checking grant " + targetPkg + " permission to " + grantUri); 6205 } 6206 6207 final IPackageManager pm = AppGlobals.getPackageManager(); 6208 6209 // If this is not a content: uri, we can't do anything with it. 6210 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) { 6211 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6212 "Can't grant URI permission for non-content URI: " + grantUri); 6213 return -1; 6214 } 6215 6216 final String authority = grantUri.uri.getAuthority(); 6217 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6218 if (pi == null) { 6219 Slog.w(TAG, "No content provider found for permission check: " + 6220 grantUri.uri.toSafeString()); 6221 return -1; 6222 } 6223 6224 int targetUid = lastTargetUid; 6225 if (targetUid < 0 && targetPkg != null) { 6226 try { 6227 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6228 if (targetUid < 0) { 6229 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6230 "Can't grant URI permission no uid for: " + targetPkg); 6231 return -1; 6232 } 6233 } catch (RemoteException ex) { 6234 return -1; 6235 } 6236 } 6237 6238 if (targetUid >= 0) { 6239 // First... does the target actually need this permission? 6240 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) { 6241 // No need to grant the target this permission. 6242 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6243 "Target " + targetPkg + " already has full permission to " + grantUri); 6244 return -1; 6245 } 6246 } else { 6247 // First... there is no target package, so can anyone access it? 6248 boolean allowed = pi.exported; 6249 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6250 if (pi.readPermission != null) { 6251 allowed = false; 6252 } 6253 } 6254 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6255 if (pi.writePermission != null) { 6256 allowed = false; 6257 } 6258 } 6259 if (allowed) { 6260 return -1; 6261 } 6262 } 6263 6264 // Second... is the provider allowing granting of URI permissions? 6265 if (!pi.grantUriPermissions) { 6266 throw new SecurityException("Provider " + pi.packageName 6267 + "/" + pi.name 6268 + " does not allow granting of Uri permissions (uri " 6269 + grantUri + ")"); 6270 } 6271 if (pi.uriPermissionPatterns != null) { 6272 final int N = pi.uriPermissionPatterns.length; 6273 boolean allowed = false; 6274 for (int i=0; i<N; i++) { 6275 if (pi.uriPermissionPatterns[i] != null 6276 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) { 6277 allowed = true; 6278 break; 6279 } 6280 } 6281 if (!allowed) { 6282 throw new SecurityException("Provider " + pi.packageName 6283 + "/" + pi.name 6284 + " does not allow granting of permission to path of Uri " 6285 + grantUri); 6286 } 6287 } 6288 6289 // Third... does the caller itself have permission to access 6290 // this uri? 6291 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { 6292 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6293 // Require they hold a strong enough Uri permission 6294 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) { 6295 throw new SecurityException("Uid " + callingUid 6296 + " does not have permission to uri " + grantUri); 6297 } 6298 } 6299 } 6300 return targetUid; 6301 } 6302 6303 @Override 6304 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, 6305 final int modeFlags, int userId) { 6306 enforceNotIsolatedCaller("checkGrantUriPermission"); 6307 synchronized(this) { 6308 return checkGrantUriPermissionLocked(callingUid, targetPkg, 6309 new GrantUri(userId, uri, false), modeFlags, -1); 6310 } 6311 } 6312 6313 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, 6314 final int modeFlags, UriPermissionOwner owner) { 6315 if (!Intent.isAccessUriMode(modeFlags)) { 6316 return; 6317 } 6318 6319 // So here we are: the caller has the assumed permission 6320 // to the uri, and the target doesn't. Let's now give this to 6321 // the target. 6322 6323 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6324 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri); 6325 6326 final String authority = grantUri.uri.getAuthority(); 6327 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6328 if (pi == null) { 6329 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString()); 6330 return; 6331 } 6332 6333 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) { 6334 grantUri.prefix = true; 6335 } 6336 final UriPermission perm = findOrCreateUriPermissionLocked( 6337 pi.packageName, targetPkg, targetUid, grantUri); 6338 perm.grantModes(modeFlags, owner); 6339 } 6340 6341 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, 6342 final int modeFlags, UriPermissionOwner owner) { 6343 if (targetPkg == null) { 6344 throw new NullPointerException("targetPkg"); 6345 } 6346 6347 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags, 6348 -1); 6349 if (targetUid < 0) { 6350 return; 6351 } 6352 6353 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags, 6354 owner); 6355 } 6356 6357 static class NeededUriGrants extends ArrayList<GrantUri> { 6358 final String targetPkg; 6359 final int targetUid; 6360 final int flags; 6361 6362 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6363 this.targetPkg = targetPkg; 6364 this.targetUid = targetUid; 6365 this.flags = flags; 6366 } 6367 } 6368 6369 /** 6370 * Like checkGrantUriPermissionLocked, but takes an Intent. 6371 */ 6372 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6373 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6374 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6375 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6376 + " clip=" + (intent != null ? intent.getClipData() : null) 6377 + " from " + intent + "; flags=0x" 6378 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6379 6380 if (targetPkg == null) { 6381 throw new NullPointerException("targetPkg"); 6382 } 6383 6384 if (intent == null) { 6385 return null; 6386 } 6387 Uri data = intent.getData(); 6388 ClipData clip = intent.getClipData(); 6389 if (data == null && clip == null) { 6390 return null; 6391 } 6392 6393 if (data != null) { 6394 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data); 6395 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6396 needed != null ? needed.targetUid : -1); 6397 if (targetUid > 0) { 6398 if (needed == null) { 6399 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6400 } 6401 needed.add(grantUri); 6402 } 6403 } 6404 if (clip != null) { 6405 for (int i=0; i<clip.getItemCount(); i++) { 6406 Uri uri = clip.getItemAt(i).getUri(); 6407 if (uri != null) { 6408 int targetUid = -1; 6409 GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri); 6410 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode, 6411 needed != null ? needed.targetUid : -1); 6412 if (targetUid > 0) { 6413 if (needed == null) { 6414 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6415 } 6416 needed.add(grantUri); 6417 } 6418 } else { 6419 Intent clipIntent = clip.getItemAt(i).getIntent(); 6420 if (clipIntent != null) { 6421 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6422 callingUid, targetPkg, clipIntent, mode, needed); 6423 if (newNeeded != null) { 6424 needed = newNeeded; 6425 } 6426 } 6427 } 6428 } 6429 } 6430 6431 return needed; 6432 } 6433 6434 /** 6435 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6436 */ 6437 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6438 UriPermissionOwner owner) { 6439 if (needed != null) { 6440 for (int i=0; i<needed.size(); i++) { 6441 GrantUri grantUri = needed.get(i); 6442 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6443 grantUri, needed.flags, owner); 6444 } 6445 } 6446 } 6447 6448 void grantUriPermissionFromIntentLocked(int callingUid, 6449 String targetPkg, Intent intent, UriPermissionOwner owner) { 6450 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6451 intent, intent != null ? intent.getFlags() : 0, null); 6452 if (needed == null) { 6453 return; 6454 } 6455 6456 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6457 } 6458 6459 @Override 6460 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, 6461 final int modeFlags, int userId) { 6462 enforceNotIsolatedCaller("grantUriPermission"); 6463 GrantUri grantUri = new GrantUri(userId, uri, false); 6464 synchronized(this) { 6465 final ProcessRecord r = getRecordForAppLocked(caller); 6466 if (r == null) { 6467 throw new SecurityException("Unable to find app for caller " 6468 + caller 6469 + " when granting permission to uri " + grantUri); 6470 } 6471 if (targetPkg == null) { 6472 throw new IllegalArgumentException("null target"); 6473 } 6474 if (grantUri == null) { 6475 throw new IllegalArgumentException("null uri"); 6476 } 6477 6478 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6479 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6480 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6481 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6482 6483 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null); 6484 } 6485 } 6486 6487 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6488 if (perm.modeFlags == 0) { 6489 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6490 perm.targetUid); 6491 if (perms != null) { 6492 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6493 "Removing " + perm.targetUid + " permission to " + perm.uri); 6494 6495 perms.remove(perm.uri); 6496 if (perms.isEmpty()) { 6497 mGrantedUriPermissions.remove(perm.targetUid); 6498 } 6499 } 6500 } 6501 } 6502 6503 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) { 6504 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri); 6505 6506 final IPackageManager pm = AppGlobals.getPackageManager(); 6507 final String authority = grantUri.uri.getAuthority(); 6508 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId); 6509 if (pi == null) { 6510 Slog.w(TAG, "No content provider found for permission revoke: " 6511 + grantUri.toSafeString()); 6512 return; 6513 } 6514 6515 // Does the caller have this permission on the URI? 6516 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) { 6517 // Right now, if you are not the original owner of the permission, 6518 // you are not allowed to revoke it. 6519 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6520 throw new SecurityException("Uid " + callingUid 6521 + " does not have permission to uri " + grantUri); 6522 //} 6523 } 6524 6525 boolean persistChanged = false; 6526 6527 // Go through all of the permissions and remove any that match. 6528 int N = mGrantedUriPermissions.size(); 6529 for (int i = 0; i < N; i++) { 6530 final int targetUid = mGrantedUriPermissions.keyAt(i); 6531 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6532 6533 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6534 final UriPermission perm = it.next(); 6535 if (perm.uri.sourceUserId == grantUri.sourceUserId 6536 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) { 6537 if (DEBUG_URI_PERMISSION) 6538 Slog.v(TAG, 6539 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6540 persistChanged |= perm.revokeModes( 6541 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6542 if (perm.modeFlags == 0) { 6543 it.remove(); 6544 } 6545 } 6546 } 6547 6548 if (perms.isEmpty()) { 6549 mGrantedUriPermissions.remove(targetUid); 6550 N--; 6551 i--; 6552 } 6553 } 6554 6555 if (persistChanged) { 6556 schedulePersistUriGrants(); 6557 } 6558 } 6559 6560 @Override 6561 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, 6562 int userId) { 6563 enforceNotIsolatedCaller("revokeUriPermission"); 6564 synchronized(this) { 6565 final ProcessRecord r = getRecordForAppLocked(caller); 6566 if (r == null) { 6567 throw new SecurityException("Unable to find app for caller " 6568 + caller 6569 + " when revoking permission to uri " + uri); 6570 } 6571 if (uri == null) { 6572 Slog.w(TAG, "revokeUriPermission: null uri"); 6573 return; 6574 } 6575 6576 if (!Intent.isAccessUriMode(modeFlags)) { 6577 return; 6578 } 6579 6580 final IPackageManager pm = AppGlobals.getPackageManager(); 6581 final String authority = uri.getAuthority(); 6582 final ProviderInfo pi = getProviderInfoLocked(authority, userId); 6583 if (pi == null) { 6584 Slog.w(TAG, "No content provider found for permission revoke: " 6585 + uri.toSafeString()); 6586 return; 6587 } 6588 6589 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags); 6590 } 6591 } 6592 6593 /** 6594 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6595 * given package. 6596 * 6597 * @param packageName Package name to match, or {@code null} to apply to all 6598 * packages. 6599 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6600 * to all users. 6601 * @param persistable If persistable grants should be removed. 6602 */ 6603 private void removeUriPermissionsForPackageLocked( 6604 String packageName, int userHandle, boolean persistable) { 6605 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6606 throw new IllegalArgumentException("Must narrow by either package or user"); 6607 } 6608 6609 boolean persistChanged = false; 6610 6611 int N = mGrantedUriPermissions.size(); 6612 for (int i = 0; i < N; i++) { 6613 final int targetUid = mGrantedUriPermissions.keyAt(i); 6614 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6615 6616 // Only inspect grants matching user 6617 if (userHandle == UserHandle.USER_ALL 6618 || userHandle == UserHandle.getUserId(targetUid)) { 6619 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6620 final UriPermission perm = it.next(); 6621 6622 // Only inspect grants matching package 6623 if (packageName == null || perm.sourcePkg.equals(packageName) 6624 || perm.targetPkg.equals(packageName)) { 6625 persistChanged |= perm.revokeModes( 6626 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6627 6628 // Only remove when no modes remain; any persisted grants 6629 // will keep this alive. 6630 if (perm.modeFlags == 0) { 6631 it.remove(); 6632 } 6633 } 6634 } 6635 6636 if (perms.isEmpty()) { 6637 mGrantedUriPermissions.remove(targetUid); 6638 N--; 6639 i--; 6640 } 6641 } 6642 } 6643 6644 if (persistChanged) { 6645 schedulePersistUriGrants(); 6646 } 6647 } 6648 6649 @Override 6650 public IBinder newUriPermissionOwner(String name) { 6651 enforceNotIsolatedCaller("newUriPermissionOwner"); 6652 synchronized(this) { 6653 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6654 return owner.getExternalTokenLocked(); 6655 } 6656 } 6657 6658 @Override 6659 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, 6660 final int modeFlags, int userId) { 6661 synchronized(this) { 6662 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6663 if (owner == null) { 6664 throw new IllegalArgumentException("Unknown owner: " + token); 6665 } 6666 if (fromUid != Binder.getCallingUid()) { 6667 if (Binder.getCallingUid() != Process.myUid()) { 6668 // Only system code can grant URI permissions on behalf 6669 // of other users. 6670 throw new SecurityException("nice try"); 6671 } 6672 } 6673 if (targetPkg == null) { 6674 throw new IllegalArgumentException("null target"); 6675 } 6676 if (uri == null) { 6677 throw new IllegalArgumentException("null uri"); 6678 } 6679 6680 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false), 6681 modeFlags, owner); 6682 } 6683 } 6684 6685 @Override 6686 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) { 6687 synchronized(this) { 6688 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6689 if (owner == null) { 6690 throw new IllegalArgumentException("Unknown owner: " + token); 6691 } 6692 6693 if (uri == null) { 6694 owner.removeUriPermissionsLocked(mode); 6695 } else { 6696 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode); 6697 } 6698 } 6699 } 6700 6701 private void schedulePersistUriGrants() { 6702 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6703 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6704 10 * DateUtils.SECOND_IN_MILLIS); 6705 } 6706 } 6707 6708 private void writeGrantedUriPermissions() { 6709 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6710 6711 // Snapshot permissions so we can persist without lock 6712 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6713 synchronized (this) { 6714 final int size = mGrantedUriPermissions.size(); 6715 for (int i = 0; i < size; i++) { 6716 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6717 for (UriPermission perm : perms.values()) { 6718 if (perm.persistedModeFlags != 0) { 6719 persist.add(perm.snapshot()); 6720 } 6721 } 6722 } 6723 } 6724 6725 FileOutputStream fos = null; 6726 try { 6727 fos = mGrantFile.startWrite(); 6728 6729 XmlSerializer out = new FastXmlSerializer(); 6730 out.setOutput(fos, "utf-8"); 6731 out.startDocument(null, true); 6732 out.startTag(null, TAG_URI_GRANTS); 6733 for (UriPermission.Snapshot perm : persist) { 6734 out.startTag(null, TAG_URI_GRANT); 6735 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId); 6736 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId); 6737 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6738 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6739 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6740 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6741 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6742 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6743 out.endTag(null, TAG_URI_GRANT); 6744 } 6745 out.endTag(null, TAG_URI_GRANTS); 6746 out.endDocument(); 6747 6748 mGrantFile.finishWrite(fos); 6749 } catch (IOException e) { 6750 if (fos != null) { 6751 mGrantFile.failWrite(fos); 6752 } 6753 } 6754 } 6755 6756 private void readGrantedUriPermissionsLocked() { 6757 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6758 6759 final long now = System.currentTimeMillis(); 6760 6761 FileInputStream fis = null; 6762 try { 6763 fis = mGrantFile.openRead(); 6764 final XmlPullParser in = Xml.newPullParser(); 6765 in.setInput(fis, null); 6766 6767 int type; 6768 while ((type = in.next()) != END_DOCUMENT) { 6769 final String tag = in.getName(); 6770 if (type == START_TAG) { 6771 if (TAG_URI_GRANT.equals(tag)) { 6772 final int sourceUserId; 6773 final int targetUserId; 6774 final int userHandle = readIntAttribute(in, 6775 ATTR_USER_HANDLE, UserHandle.USER_NULL); 6776 if (userHandle != UserHandle.USER_NULL) { 6777 // For backwards compatibility. 6778 sourceUserId = userHandle; 6779 targetUserId = userHandle; 6780 } else { 6781 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID); 6782 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID); 6783 } 6784 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6785 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6786 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6787 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6788 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6789 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6790 6791 // Sanity check that provider still belongs to source package 6792 final ProviderInfo pi = getProviderInfoLocked( 6793 uri.getAuthority(), sourceUserId); 6794 if (pi != null && sourcePkg.equals(pi.packageName)) { 6795 int targetUid = -1; 6796 try { 6797 targetUid = AppGlobals.getPackageManager() 6798 .getPackageUid(targetPkg, targetUserId); 6799 } catch (RemoteException e) { 6800 } 6801 if (targetUid != -1) { 6802 final UriPermission perm = findOrCreateUriPermissionLocked( 6803 sourcePkg, targetPkg, targetUid, 6804 new GrantUri(sourceUserId, uri, prefix)); 6805 perm.initPersistedModes(modeFlags, createdTime); 6806 } 6807 } else { 6808 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6809 + " but instead found " + pi); 6810 } 6811 } 6812 } 6813 } 6814 } catch (FileNotFoundException e) { 6815 // Missing grants is okay 6816 } catch (IOException e) { 6817 Log.wtf(TAG, "Failed reading Uri grants", e); 6818 } catch (XmlPullParserException e) { 6819 Log.wtf(TAG, "Failed reading Uri grants", e); 6820 } finally { 6821 IoUtils.closeQuietly(fis); 6822 } 6823 } 6824 6825 @Override 6826 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6827 enforceNotIsolatedCaller("takePersistableUriPermission"); 6828 6829 Preconditions.checkFlagsArgument(modeFlags, 6830 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6831 6832 synchronized (this) { 6833 final int callingUid = Binder.getCallingUid(); 6834 boolean persistChanged = false; 6835 GrantUri grantUri = new GrantUri(userId, uri, false); 6836 6837 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6838 new GrantUri(userId, uri, false)); 6839 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6840 new GrantUri(userId, uri, true)); 6841 6842 final boolean exactValid = (exactPerm != null) 6843 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6844 final boolean prefixValid = (prefixPerm != null) 6845 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6846 6847 if (!(exactValid || prefixValid)) { 6848 throw new SecurityException("No persistable permission grants found for UID " 6849 + callingUid + " and Uri " + grantUri.toSafeString()); 6850 } 6851 6852 if (exactValid) { 6853 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6854 } 6855 if (prefixValid) { 6856 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6857 } 6858 6859 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6860 6861 if (persistChanged) { 6862 schedulePersistUriGrants(); 6863 } 6864 } 6865 } 6866 6867 @Override 6868 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) { 6869 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6870 6871 Preconditions.checkFlagsArgument(modeFlags, 6872 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6873 6874 synchronized (this) { 6875 final int callingUid = Binder.getCallingUid(); 6876 boolean persistChanged = false; 6877 6878 UriPermission exactPerm = findUriPermissionLocked(callingUid, 6879 new GrantUri(userId, uri, false)); 6880 UriPermission prefixPerm = findUriPermissionLocked(callingUid, 6881 new GrantUri(userId, uri, true)); 6882 if (exactPerm == null && prefixPerm == null) { 6883 throw new SecurityException("No permission grants found for UID " + callingUid 6884 + " and Uri " + uri.toSafeString()); 6885 } 6886 6887 if (exactPerm != null) { 6888 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6889 removeUriPermissionIfNeededLocked(exactPerm); 6890 } 6891 if (prefixPerm != null) { 6892 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6893 removeUriPermissionIfNeededLocked(prefixPerm); 6894 } 6895 6896 if (persistChanged) { 6897 schedulePersistUriGrants(); 6898 } 6899 } 6900 } 6901 6902 /** 6903 * Prune any older {@link UriPermission} for the given UID until outstanding 6904 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6905 * 6906 * @return if any mutations occured that require persisting. 6907 */ 6908 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6909 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6910 if (perms == null) return false; 6911 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6912 6913 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6914 for (UriPermission perm : perms.values()) { 6915 if (perm.persistedModeFlags != 0) { 6916 persisted.add(perm); 6917 } 6918 } 6919 6920 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6921 if (trimCount <= 0) return false; 6922 6923 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6924 for (int i = 0; i < trimCount; i++) { 6925 final UriPermission perm = persisted.get(i); 6926 6927 if (DEBUG_URI_PERMISSION) { 6928 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6929 } 6930 6931 perm.releasePersistableModes(~0); 6932 removeUriPermissionIfNeededLocked(perm); 6933 } 6934 6935 return true; 6936 } 6937 6938 @Override 6939 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6940 String packageName, boolean incoming) { 6941 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6942 Preconditions.checkNotNull(packageName, "packageName"); 6943 6944 final int callingUid = Binder.getCallingUid(); 6945 final IPackageManager pm = AppGlobals.getPackageManager(); 6946 try { 6947 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6948 if (packageUid != callingUid) { 6949 throw new SecurityException( 6950 "Package " + packageName + " does not belong to calling UID " + callingUid); 6951 } 6952 } catch (RemoteException e) { 6953 throw new SecurityException("Failed to verify package name ownership"); 6954 } 6955 6956 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6957 synchronized (this) { 6958 if (incoming) { 6959 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6960 callingUid); 6961 if (perms == null) { 6962 Slog.w(TAG, "No permission grants found for " + packageName); 6963 } else { 6964 for (UriPermission perm : perms.values()) { 6965 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6966 result.add(perm.buildPersistedPublicApiObject()); 6967 } 6968 } 6969 } 6970 } else { 6971 final int size = mGrantedUriPermissions.size(); 6972 for (int i = 0; i < size; i++) { 6973 final ArrayMap<GrantUri, UriPermission> perms = 6974 mGrantedUriPermissions.valueAt(i); 6975 for (UriPermission perm : perms.values()) { 6976 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6977 result.add(perm.buildPersistedPublicApiObject()); 6978 } 6979 } 6980 } 6981 } 6982 } 6983 return new ParceledListSlice<android.content.UriPermission>(result); 6984 } 6985 6986 @Override 6987 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6988 synchronized (this) { 6989 ProcessRecord app = 6990 who != null ? getRecordForAppLocked(who) : null; 6991 if (app == null) return; 6992 6993 Message msg = Message.obtain(); 6994 msg.what = WAIT_FOR_DEBUGGER_MSG; 6995 msg.obj = app; 6996 msg.arg1 = waiting ? 1 : 0; 6997 mHandler.sendMessage(msg); 6998 } 6999 } 7000 7001 @Override 7002 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 7003 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 7004 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 7005 outInfo.availMem = Process.getFreeMemory(); 7006 outInfo.totalMem = Process.getTotalMemory(); 7007 outInfo.threshold = homeAppMem; 7008 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 7009 outInfo.hiddenAppThreshold = cachedAppMem; 7010 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 7011 ProcessList.SERVICE_ADJ); 7012 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 7013 ProcessList.VISIBLE_APP_ADJ); 7014 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 7015 ProcessList.FOREGROUND_APP_ADJ); 7016 } 7017 7018 // ========================================================= 7019 // TASK MANAGEMENT 7020 // ========================================================= 7021 7022 @Override 7023 public List<IAppTask> getAppTasks() { 7024 int callingUid = Binder.getCallingUid(); 7025 long ident = Binder.clearCallingIdentity(); 7026 synchronized(this) { 7027 ArrayList<IAppTask> list = new ArrayList<IAppTask>(); 7028 try { 7029 if (localLOGV) Slog.v(TAG, "getAppTasks"); 7030 7031 final int N = mRecentTasks.size(); 7032 for (int i = 0; i < N; i++) { 7033 TaskRecord tr = mRecentTasks.get(i); 7034 // Skip tasks that are not created by the caller 7035 if (tr.creatorUid == callingUid) { 7036 ActivityManager.RecentTaskInfo taskInfo = 7037 createRecentTaskInfoFromTaskRecord(tr); 7038 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid); 7039 list.add(taskImpl); 7040 } 7041 } 7042 } finally { 7043 Binder.restoreCallingIdentity(ident); 7044 } 7045 return list; 7046 } 7047 } 7048 7049 @Override 7050 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 7051 final int callingUid = Binder.getCallingUid(); 7052 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 7053 7054 synchronized(this) { 7055 if (localLOGV) Slog.v( 7056 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 7057 7058 final boolean allowed = checkCallingPermission( 7059 android.Manifest.permission.GET_TASKS) 7060 == PackageManager.PERMISSION_GRANTED; 7061 if (!allowed) { 7062 Slog.w(TAG, "getTasks: caller " + callingUid 7063 + " does not hold GET_TASKS; limiting output"); 7064 } 7065 7066 // TODO: Improve with MRU list from all ActivityStacks. 7067 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 7068 } 7069 7070 return list; 7071 } 7072 7073 TaskRecord getMostRecentTask() { 7074 return mRecentTasks.get(0); 7075 } 7076 7077 /** 7078 * Creates a new RecentTaskInfo from a TaskRecord. 7079 */ 7080 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) { 7081 ActivityManager.RecentTaskInfo rti 7082 = new ActivityManager.RecentTaskInfo(); 7083 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7084 rti.persistentId = tr.taskId; 7085 rti.baseIntent = new Intent(tr.getBaseIntent()); 7086 rti.origActivity = tr.origActivity; 7087 rti.description = tr.lastDescription; 7088 rti.stackId = tr.stack.mStackId; 7089 rti.userId = tr.userId; 7090 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription); 7091 return rti; 7092 } 7093 7094 @Override 7095 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7096 int flags, int userId) { 7097 final int callingUid = Binder.getCallingUid(); 7098 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7099 false, true, "getRecentTasks", null); 7100 7101 synchronized (this) { 7102 final boolean allowed = checkCallingPermission( 7103 android.Manifest.permission.GET_TASKS) 7104 == PackageManager.PERMISSION_GRANTED; 7105 if (!allowed) { 7106 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7107 + " does not hold GET_TASKS; limiting output"); 7108 } 7109 final boolean detailed = checkCallingPermission( 7110 android.Manifest.permission.GET_DETAILED_TASKS) 7111 == PackageManager.PERMISSION_GRANTED; 7112 7113 IPackageManager pm = AppGlobals.getPackageManager(); 7114 7115 final int N = mRecentTasks.size(); 7116 ArrayList<ActivityManager.RecentTaskInfo> res 7117 = new ArrayList<ActivityManager.RecentTaskInfo>( 7118 maxNum < N ? maxNum : N); 7119 7120 final Set<Integer> includedUsers; 7121 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7122 includedUsers = getProfileIdsLocked(userId); 7123 } else { 7124 includedUsers = new HashSet<Integer>(); 7125 } 7126 includedUsers.add(Integer.valueOf(userId)); 7127 for (int i=0; i<N && maxNum > 0; i++) { 7128 TaskRecord tr = mRecentTasks.get(i); 7129 // Only add calling user or related users recent tasks 7130 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7131 7132 // Return the entry if desired by the caller. We always return 7133 // the first entry, because callers always expect this to be the 7134 // foreground app. We may filter others if the caller has 7135 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7136 // we should exclude the entry. 7137 7138 if (i == 0 7139 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7140 || (tr.intent == null) 7141 || ((tr.intent.getFlags() 7142 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7143 if (!allowed) { 7144 // If the caller doesn't have the GET_TASKS permission, then only 7145 // allow them to see a small subset of tasks -- their own and home. 7146 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7147 continue; 7148 } 7149 } 7150 7151 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr); 7152 if (!detailed) { 7153 rti.baseIntent.replaceExtras((Bundle)null); 7154 } 7155 7156 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7157 // Check whether this activity is currently available. 7158 try { 7159 if (rti.origActivity != null) { 7160 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7161 == null) { 7162 continue; 7163 } 7164 } else if (rti.baseIntent != null) { 7165 if (pm.queryIntentActivities(rti.baseIntent, 7166 null, 0, userId) == null) { 7167 continue; 7168 } 7169 } 7170 } catch (RemoteException e) { 7171 // Will never happen. 7172 } 7173 } 7174 7175 res.add(rti); 7176 maxNum--; 7177 } 7178 } 7179 return res; 7180 } 7181 } 7182 7183 private TaskRecord recentTaskForIdLocked(int id) { 7184 final int N = mRecentTasks.size(); 7185 for (int i=0; i<N; i++) { 7186 TaskRecord tr = mRecentTasks.get(i); 7187 if (tr.taskId == id) { 7188 return tr; 7189 } 7190 } 7191 return null; 7192 } 7193 7194 @Override 7195 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7196 synchronized (this) { 7197 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7198 "getTaskThumbnails()"); 7199 TaskRecord tr = recentTaskForIdLocked(id); 7200 if (tr != null) { 7201 return tr.getTaskThumbnailsLocked(); 7202 } 7203 } 7204 return null; 7205 } 7206 7207 @Override 7208 public Bitmap getTaskTopThumbnail(int id) { 7209 synchronized (this) { 7210 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7211 "getTaskTopThumbnail()"); 7212 TaskRecord tr = recentTaskForIdLocked(id); 7213 if (tr != null) { 7214 return tr.getTaskTopThumbnailLocked(); 7215 } 7216 } 7217 return null; 7218 } 7219 7220 @Override 7221 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) { 7222 synchronized (this) { 7223 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7224 if (r != null) { 7225 r.taskDescription = td; 7226 r.task.updateTaskDescription(); 7227 } 7228 } 7229 } 7230 7231 @Override 7232 public boolean removeSubTask(int taskId, int subTaskIndex) { 7233 synchronized (this) { 7234 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7235 "removeSubTask()"); 7236 long ident = Binder.clearCallingIdentity(); 7237 try { 7238 TaskRecord tr = recentTaskForIdLocked(taskId); 7239 if (tr != null) { 7240 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7241 } 7242 return false; 7243 } finally { 7244 Binder.restoreCallingIdentity(ident); 7245 } 7246 } 7247 } 7248 7249 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7250 if (!pr.killedByAm) { 7251 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7252 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7253 pr.processName, pr.setAdj, reason); 7254 pr.killedByAm = true; 7255 Process.killProcessQuiet(pr.pid); 7256 } 7257 } 7258 7259 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7260 tr.disposeThumbnail(); 7261 mRecentTasks.remove(tr); 7262 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7263 Intent baseIntent = new Intent( 7264 tr.intent != null ? tr.intent : tr.affinityIntent); 7265 ComponentName component = baseIntent.getComponent(); 7266 if (component == null) { 7267 Slog.w(TAG, "Now component for base intent of task: " + tr); 7268 return; 7269 } 7270 7271 // Find any running services associated with this app. 7272 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7273 7274 if (killProcesses) { 7275 // Find any running processes associated with this app. 7276 final String pkg = component.getPackageName(); 7277 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7278 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7279 for (int i=0; i<pmap.size(); i++) { 7280 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7281 for (int j=0; j<uids.size(); j++) { 7282 ProcessRecord proc = uids.valueAt(j); 7283 if (proc.userId != tr.userId) { 7284 continue; 7285 } 7286 if (!proc.pkgList.containsKey(pkg)) { 7287 continue; 7288 } 7289 procs.add(proc); 7290 } 7291 } 7292 7293 // Kill the running processes. 7294 for (int i=0; i<procs.size(); i++) { 7295 ProcessRecord pr = procs.get(i); 7296 if (pr == mHomeProcess) { 7297 // Don't kill the home process along with tasks from the same package. 7298 continue; 7299 } 7300 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7301 killUnneededProcessLocked(pr, "remove task"); 7302 } else { 7303 pr.waitingToKill = "remove task"; 7304 } 7305 } 7306 } 7307 } 7308 7309 /** 7310 * Removes the task with the specified task id. 7311 * 7312 * @param taskId Identifier of the task to be removed. 7313 * @param flags Additional operational flags. May be 0 or 7314 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7315 * @return Returns true if the given task was found and removed. 7316 */ 7317 private boolean removeTaskByIdLocked(int taskId, int flags) { 7318 TaskRecord tr = recentTaskForIdLocked(taskId); 7319 if (tr != null) { 7320 tr.removeTaskActivitiesLocked(-1, false); 7321 cleanUpRemovedTaskLocked(tr, flags); 7322 return true; 7323 } 7324 return false; 7325 } 7326 7327 @Override 7328 public boolean removeTask(int taskId, int flags) { 7329 synchronized (this) { 7330 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7331 "removeTask()"); 7332 long ident = Binder.clearCallingIdentity(); 7333 try { 7334 return removeTaskByIdLocked(taskId, flags); 7335 } finally { 7336 Binder.restoreCallingIdentity(ident); 7337 } 7338 } 7339 } 7340 7341 /** 7342 * TODO: Add mController hook 7343 */ 7344 @Override 7345 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7346 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7347 "moveTaskToFront()"); 7348 7349 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7350 synchronized(this) { 7351 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7352 Binder.getCallingUid(), "Task to front")) { 7353 ActivityOptions.abort(options); 7354 return; 7355 } 7356 final long origId = Binder.clearCallingIdentity(); 7357 try { 7358 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7359 if (task == null) { 7360 return; 7361 } 7362 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7363 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7364 return; 7365 } 7366 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7367 } finally { 7368 Binder.restoreCallingIdentity(origId); 7369 } 7370 ActivityOptions.abort(options); 7371 } 7372 } 7373 7374 @Override 7375 public void moveTaskToBack(int taskId) { 7376 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7377 "moveTaskToBack()"); 7378 7379 synchronized(this) { 7380 TaskRecord tr = recentTaskForIdLocked(taskId); 7381 if (tr != null) { 7382 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7383 ActivityStack stack = tr.stack; 7384 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7385 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7386 Binder.getCallingUid(), "Task to back")) { 7387 return; 7388 } 7389 } 7390 final long origId = Binder.clearCallingIdentity(); 7391 try { 7392 stack.moveTaskToBackLocked(taskId, null); 7393 } finally { 7394 Binder.restoreCallingIdentity(origId); 7395 } 7396 } 7397 } 7398 } 7399 7400 /** 7401 * Moves an activity, and all of the other activities within the same task, to the bottom 7402 * of the history stack. The activity's order within the task is unchanged. 7403 * 7404 * @param token A reference to the activity we wish to move 7405 * @param nonRoot If false then this only works if the activity is the root 7406 * of a task; if true it will work for any activity in a task. 7407 * @return Returns true if the move completed, false if not. 7408 */ 7409 @Override 7410 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7411 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7412 synchronized(this) { 7413 final long origId = Binder.clearCallingIdentity(); 7414 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7415 if (taskId >= 0) { 7416 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7417 } 7418 Binder.restoreCallingIdentity(origId); 7419 } 7420 return false; 7421 } 7422 7423 @Override 7424 public void moveTaskBackwards(int task) { 7425 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7426 "moveTaskBackwards()"); 7427 7428 synchronized(this) { 7429 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7430 Binder.getCallingUid(), "Task backwards")) { 7431 return; 7432 } 7433 final long origId = Binder.clearCallingIdentity(); 7434 moveTaskBackwardsLocked(task); 7435 Binder.restoreCallingIdentity(origId); 7436 } 7437 } 7438 7439 private final void moveTaskBackwardsLocked(int task) { 7440 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7441 } 7442 7443 @Override 7444 public IBinder getHomeActivityToken() throws RemoteException { 7445 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7446 "getHomeActivityToken()"); 7447 synchronized (this) { 7448 return mStackSupervisor.getHomeActivityToken(); 7449 } 7450 } 7451 7452 @Override 7453 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7454 IActivityContainerCallback callback) throws RemoteException { 7455 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7456 "createActivityContainer()"); 7457 synchronized (this) { 7458 if (parentActivityToken == null) { 7459 throw new IllegalArgumentException("parent token must not be null"); 7460 } 7461 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7462 if (r == null) { 7463 return null; 7464 } 7465 if (callback == null) { 7466 throw new IllegalArgumentException("callback must not be null"); 7467 } 7468 return mStackSupervisor.createActivityContainer(r, callback); 7469 } 7470 } 7471 7472 @Override 7473 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7474 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7475 "deleteActivityContainer()"); 7476 synchronized (this) { 7477 mStackSupervisor.deleteActivityContainer(container); 7478 } 7479 } 7480 7481 @Override 7482 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7483 throws RemoteException { 7484 synchronized (this) { 7485 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7486 if (stack != null) { 7487 return stack.mActivityContainer; 7488 } 7489 return null; 7490 } 7491 } 7492 7493 @Override 7494 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7495 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7496 "moveTaskToStack()"); 7497 if (stackId == HOME_STACK_ID) { 7498 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7499 new RuntimeException("here").fillInStackTrace()); 7500 } 7501 synchronized (this) { 7502 long ident = Binder.clearCallingIdentity(); 7503 try { 7504 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7505 + stackId + " toTop=" + toTop); 7506 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7507 } finally { 7508 Binder.restoreCallingIdentity(ident); 7509 } 7510 } 7511 } 7512 7513 @Override 7514 public void resizeStack(int stackBoxId, Rect bounds) { 7515 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7516 "resizeStackBox()"); 7517 long ident = Binder.clearCallingIdentity(); 7518 try { 7519 mWindowManager.resizeStack(stackBoxId, bounds); 7520 } finally { 7521 Binder.restoreCallingIdentity(ident); 7522 } 7523 } 7524 7525 @Override 7526 public List<StackInfo> getAllStackInfos() { 7527 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7528 "getAllStackInfos()"); 7529 long ident = Binder.clearCallingIdentity(); 7530 try { 7531 synchronized (this) { 7532 return mStackSupervisor.getAllStackInfosLocked(); 7533 } 7534 } finally { 7535 Binder.restoreCallingIdentity(ident); 7536 } 7537 } 7538 7539 @Override 7540 public StackInfo getStackInfo(int stackId) { 7541 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7542 "getStackInfo()"); 7543 long ident = Binder.clearCallingIdentity(); 7544 try { 7545 synchronized (this) { 7546 return mStackSupervisor.getStackInfoLocked(stackId); 7547 } 7548 } finally { 7549 Binder.restoreCallingIdentity(ident); 7550 } 7551 } 7552 7553 @Override 7554 public boolean isInHomeStack(int taskId) { 7555 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7556 "getStackInfo()"); 7557 long ident = Binder.clearCallingIdentity(); 7558 try { 7559 synchronized (this) { 7560 TaskRecord tr = recentTaskForIdLocked(taskId); 7561 if (tr != null) { 7562 return tr.stack.isHomeStack(); 7563 } 7564 } 7565 } finally { 7566 Binder.restoreCallingIdentity(ident); 7567 } 7568 return false; 7569 } 7570 7571 @Override 7572 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7573 synchronized(this) { 7574 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7575 } 7576 } 7577 7578 private boolean isLockTaskAuthorized(ComponentName name) { 7579// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7580// "startLockTaskMode()"); 7581// DevicePolicyManager dpm = (DevicePolicyManager) 7582// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7583// return dpm != null && dpm.isLockTaskPermitted(name); 7584 return true; 7585 } 7586 7587 private void startLockTaskMode(TaskRecord task) { 7588 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7589 return; 7590 } 7591 long ident = Binder.clearCallingIdentity(); 7592 try { 7593 synchronized (this) { 7594 // Since we lost lock on task, make sure it is still there. 7595 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7596 if (task != null) { 7597 mStackSupervisor.setLockTaskModeLocked(task); 7598 } 7599 } 7600 } finally { 7601 Binder.restoreCallingIdentity(ident); 7602 } 7603 } 7604 7605 @Override 7606 public void startLockTaskMode(int taskId) { 7607 long ident = Binder.clearCallingIdentity(); 7608 try { 7609 final TaskRecord task; 7610 synchronized (this) { 7611 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7612 } 7613 if (task != null) { 7614 startLockTaskMode(task); 7615 } 7616 } finally { 7617 Binder.restoreCallingIdentity(ident); 7618 } 7619 } 7620 7621 @Override 7622 public void startLockTaskMode(IBinder token) { 7623 long ident = Binder.clearCallingIdentity(); 7624 try { 7625 final TaskRecord task; 7626 synchronized (this) { 7627 final ActivityRecord r = ActivityRecord.forToken(token); 7628 if (r == null) { 7629 return; 7630 } 7631 task = r.task; 7632 } 7633 if (task != null) { 7634 startLockTaskMode(task); 7635 } 7636 } finally { 7637 Binder.restoreCallingIdentity(ident); 7638 } 7639 } 7640 7641 @Override 7642 public void stopLockTaskMode() { 7643// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7644// "stopLockTaskMode()"); 7645 synchronized (this) { 7646 mStackSupervisor.setLockTaskModeLocked(null); 7647 } 7648 } 7649 7650 @Override 7651 public boolean isInLockTaskMode() { 7652 synchronized (this) { 7653 return mStackSupervisor.isInLockTaskMode(); 7654 } 7655 } 7656 7657 // ========================================================= 7658 // CONTENT PROVIDERS 7659 // ========================================================= 7660 7661 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7662 List<ProviderInfo> providers = null; 7663 try { 7664 providers = AppGlobals.getPackageManager(). 7665 queryContentProviders(app.processName, app.uid, 7666 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7667 } catch (RemoteException ex) { 7668 } 7669 if (DEBUG_MU) 7670 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7671 int userId = app.userId; 7672 if (providers != null) { 7673 int N = providers.size(); 7674 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7675 for (int i=0; i<N; i++) { 7676 ProviderInfo cpi = 7677 (ProviderInfo)providers.get(i); 7678 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7679 cpi.name, cpi.flags); 7680 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7681 // This is a singleton provider, but a user besides the 7682 // default user is asking to initialize a process it runs 7683 // in... well, no, it doesn't actually run in this process, 7684 // it runs in the process of the default user. Get rid of it. 7685 providers.remove(i); 7686 N--; 7687 i--; 7688 continue; 7689 } 7690 7691 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7692 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7693 if (cpr == null) { 7694 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7695 mProviderMap.putProviderByClass(comp, cpr); 7696 } 7697 if (DEBUG_MU) 7698 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7699 app.pubProviders.put(cpi.name, cpr); 7700 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7701 // Don't add this if it is a platform component that is marked 7702 // to run in multiple processes, because this is actually 7703 // part of the framework so doesn't make sense to track as a 7704 // separate apk in the process. 7705 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7706 } 7707 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7708 } 7709 } 7710 return providers; 7711 } 7712 7713 /** 7714 * Check if {@link ProcessRecord} has a possible chance at accessing the 7715 * given {@link ProviderInfo}. Final permission checking is always done 7716 * in {@link ContentProvider}. 7717 */ 7718 private final String checkContentProviderPermissionLocked( 7719 ProviderInfo cpi, ProcessRecord r, int userId) { 7720 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7721 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7722 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7723 // Looking for cross-user grants before to enforce the typical cross-users permissions 7724 if (userId != UserHandle.getUserId(callingUid)) { 7725 if (perms != null) { 7726 for (GrantUri grantUri : perms.keySet()) { 7727 if (grantUri.sourceUserId == userId) { 7728 String authority = grantUri.uri.getAuthority(); 7729 if (authority.equals(cpi.authority)) { 7730 return null; 7731 } 7732 } 7733 } 7734 } 7735 } 7736 userId = handleIncomingUser(callingPid, callingUid, userId, 7737 false, true, "checkContentProviderPermissionLocked", null); 7738 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7739 cpi.applicationInfo.uid, cpi.exported) 7740 == PackageManager.PERMISSION_GRANTED) { 7741 return null; 7742 } 7743 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7744 cpi.applicationInfo.uid, cpi.exported) 7745 == PackageManager.PERMISSION_GRANTED) { 7746 return null; 7747 } 7748 7749 PathPermission[] pps = cpi.pathPermissions; 7750 if (pps != null) { 7751 int i = pps.length; 7752 while (i > 0) { 7753 i--; 7754 PathPermission pp = pps[i]; 7755 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7756 cpi.applicationInfo.uid, cpi.exported) 7757 == PackageManager.PERMISSION_GRANTED) { 7758 return null; 7759 } 7760 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7761 cpi.applicationInfo.uid, cpi.exported) 7762 == PackageManager.PERMISSION_GRANTED) { 7763 return null; 7764 } 7765 } 7766 } 7767 7768 if (perms != null) { 7769 for (GrantUri grantUri : perms.keySet()) { 7770 if (grantUri.uri.getAuthority().equals(cpi.authority)) { 7771 return null; 7772 } 7773 } 7774 } 7775 7776 String msg; 7777 if (!cpi.exported) { 7778 msg = "Permission Denial: opening provider " + cpi.name 7779 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7780 + ", uid=" + callingUid + ") that is not exported from uid " 7781 + cpi.applicationInfo.uid; 7782 } else { 7783 msg = "Permission Denial: opening provider " + cpi.name 7784 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7785 + ", uid=" + callingUid + ") requires " 7786 + cpi.readPermission + " or " + cpi.writePermission; 7787 } 7788 Slog.w(TAG, msg); 7789 return msg; 7790 } 7791 7792 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7793 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7794 if (r != null) { 7795 for (int i=0; i<r.conProviders.size(); i++) { 7796 ContentProviderConnection conn = r.conProviders.get(i); 7797 if (conn.provider == cpr) { 7798 if (DEBUG_PROVIDER) Slog.v(TAG, 7799 "Adding provider requested by " 7800 + r.processName + " from process " 7801 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7802 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7803 if (stable) { 7804 conn.stableCount++; 7805 conn.numStableIncs++; 7806 } else { 7807 conn.unstableCount++; 7808 conn.numUnstableIncs++; 7809 } 7810 return conn; 7811 } 7812 } 7813 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7814 if (stable) { 7815 conn.stableCount = 1; 7816 conn.numStableIncs = 1; 7817 } else { 7818 conn.unstableCount = 1; 7819 conn.numUnstableIncs = 1; 7820 } 7821 cpr.connections.add(conn); 7822 r.conProviders.add(conn); 7823 return conn; 7824 } 7825 cpr.addExternalProcessHandleLocked(externalProcessToken); 7826 return null; 7827 } 7828 7829 boolean decProviderCountLocked(ContentProviderConnection conn, 7830 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7831 if (conn != null) { 7832 cpr = conn.provider; 7833 if (DEBUG_PROVIDER) Slog.v(TAG, 7834 "Removing provider requested by " 7835 + conn.client.processName + " from process " 7836 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7837 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7838 if (stable) { 7839 conn.stableCount--; 7840 } else { 7841 conn.unstableCount--; 7842 } 7843 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7844 cpr.connections.remove(conn); 7845 conn.client.conProviders.remove(conn); 7846 return true; 7847 } 7848 return false; 7849 } 7850 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7851 return false; 7852 } 7853 7854 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7855 String name, IBinder token, boolean stable, int userId) { 7856 ContentProviderRecord cpr; 7857 ContentProviderConnection conn = null; 7858 ProviderInfo cpi = null; 7859 7860 synchronized(this) { 7861 ProcessRecord r = null; 7862 if (caller != null) { 7863 r = getRecordForAppLocked(caller); 7864 if (r == null) { 7865 throw new SecurityException( 7866 "Unable to find app for caller " + caller 7867 + " (pid=" + Binder.getCallingPid() 7868 + ") when getting content provider " + name); 7869 } 7870 } 7871 7872 // First check if this content provider has been published... 7873 cpr = mProviderMap.getProviderByName(name, userId); 7874 boolean providerRunning = cpr != null; 7875 if (providerRunning) { 7876 cpi = cpr.info; 7877 String msg; 7878 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7879 throw new SecurityException(msg); 7880 } 7881 7882 if (r != null && cpr.canRunHere(r)) { 7883 // This provider has been published or is in the process 7884 // of being published... but it is also allowed to run 7885 // in the caller's process, so don't make a connection 7886 // and just let the caller instantiate its own instance. 7887 ContentProviderHolder holder = cpr.newHolder(null); 7888 // don't give caller the provider object, it needs 7889 // to make its own. 7890 holder.provider = null; 7891 return holder; 7892 } 7893 7894 final long origId = Binder.clearCallingIdentity(); 7895 7896 // In this case the provider instance already exists, so we can 7897 // return it right away. 7898 conn = incProviderCountLocked(r, cpr, token, stable); 7899 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7900 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7901 // If this is a perceptible app accessing the provider, 7902 // make sure to count it as being accessed and thus 7903 // back up on the LRU list. This is good because 7904 // content providers are often expensive to start. 7905 updateLruProcessLocked(cpr.proc, false, null); 7906 } 7907 } 7908 7909 if (cpr.proc != null) { 7910 if (false) { 7911 if (cpr.name.flattenToShortString().equals( 7912 "com.android.providers.calendar/.CalendarProvider2")) { 7913 Slog.v(TAG, "****************** KILLING " 7914 + cpr.name.flattenToShortString()); 7915 Process.killProcess(cpr.proc.pid); 7916 } 7917 } 7918 boolean success = updateOomAdjLocked(cpr.proc); 7919 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7920 // NOTE: there is still a race here where a signal could be 7921 // pending on the process even though we managed to update its 7922 // adj level. Not sure what to do about this, but at least 7923 // the race is now smaller. 7924 if (!success) { 7925 // Uh oh... it looks like the provider's process 7926 // has been killed on us. We need to wait for a new 7927 // process to be started, and make sure its death 7928 // doesn't kill our process. 7929 Slog.i(TAG, 7930 "Existing provider " + cpr.name.flattenToShortString() 7931 + " is crashing; detaching " + r); 7932 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7933 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7934 if (!lastRef) { 7935 // This wasn't the last ref our process had on 7936 // the provider... we have now been killed, bail. 7937 return null; 7938 } 7939 providerRunning = false; 7940 conn = null; 7941 } 7942 } 7943 7944 Binder.restoreCallingIdentity(origId); 7945 } 7946 7947 boolean singleton; 7948 if (!providerRunning) { 7949 try { 7950 cpi = AppGlobals.getPackageManager(). 7951 resolveContentProvider(name, 7952 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7953 } catch (RemoteException ex) { 7954 } 7955 if (cpi == null) { 7956 return null; 7957 } 7958 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7959 cpi.name, cpi.flags); 7960 if (singleton) { 7961 userId = 0; 7962 } 7963 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7964 7965 String msg; 7966 if ((msg=checkContentProviderPermissionLocked(cpi, r, userId)) != null) { 7967 throw new SecurityException(msg); 7968 } 7969 7970 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7971 && !cpi.processName.equals("system")) { 7972 // If this content provider does not run in the system 7973 // process, and the system is not yet ready to run other 7974 // processes, then fail fast instead of hanging. 7975 throw new IllegalArgumentException( 7976 "Attempt to launch content provider before system ready"); 7977 } 7978 7979 // Make sure that the user who owns this provider is started. If not, 7980 // we don't want to allow it to run. 7981 if (mStartedUsers.get(userId) == null) { 7982 Slog.w(TAG, "Unable to launch app " 7983 + cpi.applicationInfo.packageName + "/" 7984 + cpi.applicationInfo.uid + " for provider " 7985 + name + ": user " + userId + " is stopped"); 7986 return null; 7987 } 7988 7989 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7990 cpr = mProviderMap.getProviderByClass(comp, userId); 7991 final boolean firstClass = cpr == null; 7992 if (firstClass) { 7993 try { 7994 ApplicationInfo ai = 7995 AppGlobals.getPackageManager(). 7996 getApplicationInfo( 7997 cpi.applicationInfo.packageName, 7998 STOCK_PM_FLAGS, userId); 7999 if (ai == null) { 8000 Slog.w(TAG, "No package info for content provider " 8001 + cpi.name); 8002 return null; 8003 } 8004 ai = getAppInfoForUser(ai, userId); 8005 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8006 } catch (RemoteException ex) { 8007 // pm is in same process, this will never happen. 8008 } 8009 } 8010 8011 if (r != null && cpr.canRunHere(r)) { 8012 // If this is a multiprocess provider, then just return its 8013 // info and allow the caller to instantiate it. Only do 8014 // this if the provider is the same user as the caller's 8015 // process, or can run as root (so can be in any process). 8016 return cpr.newHolder(null); 8017 } 8018 8019 if (DEBUG_PROVIDER) { 8020 RuntimeException e = new RuntimeException("here"); 8021 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8022 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8023 } 8024 8025 // This is single process, and our app is now connecting to it. 8026 // See if we are already in the process of launching this 8027 // provider. 8028 final int N = mLaunchingProviders.size(); 8029 int i; 8030 for (i=0; i<N; i++) { 8031 if (mLaunchingProviders.get(i) == cpr) { 8032 break; 8033 } 8034 } 8035 8036 // If the provider is not already being launched, then get it 8037 // started. 8038 if (i >= N) { 8039 final long origId = Binder.clearCallingIdentity(); 8040 8041 try { 8042 // Content provider is now in use, its package can't be stopped. 8043 try { 8044 AppGlobals.getPackageManager().setPackageStoppedState( 8045 cpr.appInfo.packageName, false, userId); 8046 } catch (RemoteException e) { 8047 } catch (IllegalArgumentException e) { 8048 Slog.w(TAG, "Failed trying to unstop package " 8049 + cpr.appInfo.packageName + ": " + e); 8050 } 8051 8052 // Use existing process if already started 8053 ProcessRecord proc = getProcessRecordLocked( 8054 cpi.processName, cpr.appInfo.uid, false); 8055 if (proc != null && proc.thread != null) { 8056 if (DEBUG_PROVIDER) { 8057 Slog.d(TAG, "Installing in existing process " + proc); 8058 } 8059 proc.pubProviders.put(cpi.name, cpr); 8060 try { 8061 proc.thread.scheduleInstallProvider(cpi); 8062 } catch (RemoteException e) { 8063 } 8064 } else { 8065 proc = startProcessLocked(cpi.processName, 8066 cpr.appInfo, false, 0, "content provider", 8067 new ComponentName(cpi.applicationInfo.packageName, 8068 cpi.name), false, false, false); 8069 if (proc == null) { 8070 Slog.w(TAG, "Unable to launch app " 8071 + cpi.applicationInfo.packageName + "/" 8072 + cpi.applicationInfo.uid + " for provider " 8073 + name + ": process is bad"); 8074 return null; 8075 } 8076 } 8077 cpr.launchingApp = proc; 8078 mLaunchingProviders.add(cpr); 8079 } finally { 8080 Binder.restoreCallingIdentity(origId); 8081 } 8082 } 8083 8084 // Make sure the provider is published (the same provider class 8085 // may be published under multiple names). 8086 if (firstClass) { 8087 mProviderMap.putProviderByClass(comp, cpr); 8088 } 8089 8090 mProviderMap.putProviderByName(name, cpr); 8091 conn = incProviderCountLocked(r, cpr, token, stable); 8092 if (conn != null) { 8093 conn.waiting = true; 8094 } 8095 } 8096 } 8097 8098 // Wait for the provider to be published... 8099 synchronized (cpr) { 8100 while (cpr.provider == null) { 8101 if (cpr.launchingApp == null) { 8102 Slog.w(TAG, "Unable to launch app " 8103 + cpi.applicationInfo.packageName + "/" 8104 + cpi.applicationInfo.uid + " for provider " 8105 + name + ": launching app became null"); 8106 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8107 UserHandle.getUserId(cpi.applicationInfo.uid), 8108 cpi.applicationInfo.packageName, 8109 cpi.applicationInfo.uid, name); 8110 return null; 8111 } 8112 try { 8113 if (DEBUG_MU) { 8114 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8115 + cpr.launchingApp); 8116 } 8117 if (conn != null) { 8118 conn.waiting = true; 8119 } 8120 cpr.wait(); 8121 } catch (InterruptedException ex) { 8122 } finally { 8123 if (conn != null) { 8124 conn.waiting = false; 8125 } 8126 } 8127 } 8128 } 8129 return cpr != null ? cpr.newHolder(conn) : null; 8130 } 8131 8132 @Override 8133 public final ContentProviderHolder getContentProvider( 8134 IApplicationThread caller, String name, int userId, boolean stable) { 8135 enforceNotIsolatedCaller("getContentProvider"); 8136 if (caller == null) { 8137 String msg = "null IApplicationThread when getting content provider " 8138 + name; 8139 Slog.w(TAG, msg); 8140 throw new SecurityException(msg); 8141 } 8142 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal 8143 // with cross-user grant. 8144 return getContentProviderImpl(caller, name, null, stable, userId); 8145 } 8146 8147 public ContentProviderHolder getContentProviderExternal( 8148 String name, int userId, IBinder token) { 8149 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8150 "Do not have permission in call getContentProviderExternal()"); 8151 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8152 false, true, "getContentProvider", null); 8153 return getContentProviderExternalUnchecked(name, token, userId); 8154 } 8155 8156 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8157 IBinder token, int userId) { 8158 return getContentProviderImpl(null, name, token, true, userId); 8159 } 8160 8161 /** 8162 * Drop a content provider from a ProcessRecord's bookkeeping 8163 */ 8164 public void removeContentProvider(IBinder connection, boolean stable) { 8165 enforceNotIsolatedCaller("removeContentProvider"); 8166 long ident = Binder.clearCallingIdentity(); 8167 try { 8168 synchronized (this) { 8169 ContentProviderConnection conn; 8170 try { 8171 conn = (ContentProviderConnection)connection; 8172 } catch (ClassCastException e) { 8173 String msg ="removeContentProvider: " + connection 8174 + " not a ContentProviderConnection"; 8175 Slog.w(TAG, msg); 8176 throw new IllegalArgumentException(msg); 8177 } 8178 if (conn == null) { 8179 throw new NullPointerException("connection is null"); 8180 } 8181 if (decProviderCountLocked(conn, null, null, stable)) { 8182 updateOomAdjLocked(); 8183 } 8184 } 8185 } finally { 8186 Binder.restoreCallingIdentity(ident); 8187 } 8188 } 8189 8190 public void removeContentProviderExternal(String name, IBinder token) { 8191 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8192 "Do not have permission in call removeContentProviderExternal()"); 8193 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8194 } 8195 8196 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8197 synchronized (this) { 8198 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8199 if(cpr == null) { 8200 //remove from mProvidersByClass 8201 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8202 return; 8203 } 8204 8205 //update content provider record entry info 8206 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8207 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8208 if (localCpr.hasExternalProcessHandles()) { 8209 if (localCpr.removeExternalProcessHandleLocked(token)) { 8210 updateOomAdjLocked(); 8211 } else { 8212 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8213 + " with no external reference for token: " 8214 + token + "."); 8215 } 8216 } else { 8217 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8218 + " with no external references."); 8219 } 8220 } 8221 } 8222 8223 public final void publishContentProviders(IApplicationThread caller, 8224 List<ContentProviderHolder> providers) { 8225 if (providers == null) { 8226 return; 8227 } 8228 8229 enforceNotIsolatedCaller("publishContentProviders"); 8230 synchronized (this) { 8231 final ProcessRecord r = getRecordForAppLocked(caller); 8232 if (DEBUG_MU) 8233 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8234 if (r == null) { 8235 throw new SecurityException( 8236 "Unable to find app for caller " + caller 8237 + " (pid=" + Binder.getCallingPid() 8238 + ") when publishing content providers"); 8239 } 8240 8241 final long origId = Binder.clearCallingIdentity(); 8242 8243 final int N = providers.size(); 8244 for (int i=0; i<N; i++) { 8245 ContentProviderHolder src = providers.get(i); 8246 if (src == null || src.info == null || src.provider == null) { 8247 continue; 8248 } 8249 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8250 if (DEBUG_MU) 8251 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8252 if (dst != null) { 8253 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8254 mProviderMap.putProviderByClass(comp, dst); 8255 String names[] = dst.info.authority.split(";"); 8256 for (int j = 0; j < names.length; j++) { 8257 mProviderMap.putProviderByName(names[j], dst); 8258 } 8259 8260 int NL = mLaunchingProviders.size(); 8261 int j; 8262 for (j=0; j<NL; j++) { 8263 if (mLaunchingProviders.get(j) == dst) { 8264 mLaunchingProviders.remove(j); 8265 j--; 8266 NL--; 8267 } 8268 } 8269 synchronized (dst) { 8270 dst.provider = src.provider; 8271 dst.proc = r; 8272 dst.notifyAll(); 8273 } 8274 updateOomAdjLocked(r); 8275 } 8276 } 8277 8278 Binder.restoreCallingIdentity(origId); 8279 } 8280 } 8281 8282 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8283 ContentProviderConnection conn; 8284 try { 8285 conn = (ContentProviderConnection)connection; 8286 } catch (ClassCastException e) { 8287 String msg ="refContentProvider: " + connection 8288 + " not a ContentProviderConnection"; 8289 Slog.w(TAG, msg); 8290 throw new IllegalArgumentException(msg); 8291 } 8292 if (conn == null) { 8293 throw new NullPointerException("connection is null"); 8294 } 8295 8296 synchronized (this) { 8297 if (stable > 0) { 8298 conn.numStableIncs += stable; 8299 } 8300 stable = conn.stableCount + stable; 8301 if (stable < 0) { 8302 throw new IllegalStateException("stableCount < 0: " + stable); 8303 } 8304 8305 if (unstable > 0) { 8306 conn.numUnstableIncs += unstable; 8307 } 8308 unstable = conn.unstableCount + unstable; 8309 if (unstable < 0) { 8310 throw new IllegalStateException("unstableCount < 0: " + unstable); 8311 } 8312 8313 if ((stable+unstable) <= 0) { 8314 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8315 + stable + " unstable=" + unstable); 8316 } 8317 conn.stableCount = stable; 8318 conn.unstableCount = unstable; 8319 return !conn.dead; 8320 } 8321 } 8322 8323 public void unstableProviderDied(IBinder connection) { 8324 ContentProviderConnection conn; 8325 try { 8326 conn = (ContentProviderConnection)connection; 8327 } catch (ClassCastException e) { 8328 String msg ="refContentProvider: " + connection 8329 + " not a ContentProviderConnection"; 8330 Slog.w(TAG, msg); 8331 throw new IllegalArgumentException(msg); 8332 } 8333 if (conn == null) { 8334 throw new NullPointerException("connection is null"); 8335 } 8336 8337 // Safely retrieve the content provider associated with the connection. 8338 IContentProvider provider; 8339 synchronized (this) { 8340 provider = conn.provider.provider; 8341 } 8342 8343 if (provider == null) { 8344 // Um, yeah, we're way ahead of you. 8345 return; 8346 } 8347 8348 // Make sure the caller is being honest with us. 8349 if (provider.asBinder().pingBinder()) { 8350 // Er, no, still looks good to us. 8351 synchronized (this) { 8352 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8353 + " says " + conn + " died, but we don't agree"); 8354 return; 8355 } 8356 } 8357 8358 // Well look at that! It's dead! 8359 synchronized (this) { 8360 if (conn.provider.provider != provider) { 8361 // But something changed... good enough. 8362 return; 8363 } 8364 8365 ProcessRecord proc = conn.provider.proc; 8366 if (proc == null || proc.thread == null) { 8367 // Seems like the process is already cleaned up. 8368 return; 8369 } 8370 8371 // As far as we're concerned, this is just like receiving a 8372 // death notification... just a bit prematurely. 8373 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8374 + ") early provider death"); 8375 final long ident = Binder.clearCallingIdentity(); 8376 try { 8377 appDiedLocked(proc, proc.pid, proc.thread); 8378 } finally { 8379 Binder.restoreCallingIdentity(ident); 8380 } 8381 } 8382 } 8383 8384 @Override 8385 public void appNotRespondingViaProvider(IBinder connection) { 8386 enforceCallingPermission( 8387 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8388 8389 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8390 if (conn == null) { 8391 Slog.w(TAG, "ContentProviderConnection is null"); 8392 return; 8393 } 8394 8395 final ProcessRecord host = conn.provider.proc; 8396 if (host == null) { 8397 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8398 return; 8399 } 8400 8401 final long token = Binder.clearCallingIdentity(); 8402 try { 8403 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8404 } finally { 8405 Binder.restoreCallingIdentity(token); 8406 } 8407 } 8408 8409 public final void installSystemProviders() { 8410 List<ProviderInfo> providers; 8411 synchronized (this) { 8412 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8413 providers = generateApplicationProvidersLocked(app); 8414 if (providers != null) { 8415 for (int i=providers.size()-1; i>=0; i--) { 8416 ProviderInfo pi = (ProviderInfo)providers.get(i); 8417 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8418 Slog.w(TAG, "Not installing system proc provider " + pi.name 8419 + ": not system .apk"); 8420 providers.remove(i); 8421 } 8422 } 8423 } 8424 } 8425 if (providers != null) { 8426 mSystemThread.installSystemProviders(providers); 8427 } 8428 8429 mCoreSettingsObserver = new CoreSettingsObserver(this); 8430 8431 mUsageStatsService.monitorPackages(); 8432 } 8433 8434 /** 8435 * Allows app to retrieve the MIME type of a URI without having permission 8436 * to access its content provider. 8437 * 8438 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8439 * 8440 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8441 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8442 */ 8443 public String getProviderMimeType(Uri uri, int userId) { 8444 enforceNotIsolatedCaller("getProviderMimeType"); 8445 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8446 userId, false, true, "getProviderMimeType", null); 8447 final String name = uri.getAuthority(); 8448 final long ident = Binder.clearCallingIdentity(); 8449 ContentProviderHolder holder = null; 8450 8451 try { 8452 holder = getContentProviderExternalUnchecked(name, null, userId); 8453 if (holder != null) { 8454 return holder.provider.getType(uri); 8455 } 8456 } catch (RemoteException e) { 8457 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8458 return null; 8459 } finally { 8460 if (holder != null) { 8461 removeContentProviderExternalUnchecked(name, null, userId); 8462 } 8463 Binder.restoreCallingIdentity(ident); 8464 } 8465 8466 return null; 8467 } 8468 8469 // ========================================================= 8470 // GLOBAL MANAGEMENT 8471 // ========================================================= 8472 8473 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8474 boolean isolated) { 8475 String proc = customProcess != null ? customProcess : info.processName; 8476 BatteryStatsImpl.Uid.Proc ps = null; 8477 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8478 int uid = info.uid; 8479 if (isolated) { 8480 int userId = UserHandle.getUserId(uid); 8481 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8482 while (true) { 8483 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8484 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8485 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8486 } 8487 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8488 mNextIsolatedProcessUid++; 8489 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8490 // No process for this uid, use it. 8491 break; 8492 } 8493 stepsLeft--; 8494 if (stepsLeft <= 0) { 8495 return null; 8496 } 8497 } 8498 } 8499 return new ProcessRecord(stats, info, proc, uid); 8500 } 8501 8502 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8503 ProcessRecord app; 8504 if (!isolated) { 8505 app = getProcessRecordLocked(info.processName, info.uid, true); 8506 } else { 8507 app = null; 8508 } 8509 8510 if (app == null) { 8511 app = newProcessRecordLocked(info, null, isolated); 8512 mProcessNames.put(info.processName, app.uid, app); 8513 if (isolated) { 8514 mIsolatedProcesses.put(app.uid, app); 8515 } 8516 updateLruProcessLocked(app, false, null); 8517 updateOomAdjLocked(); 8518 } 8519 8520 // This package really, really can not be stopped. 8521 try { 8522 AppGlobals.getPackageManager().setPackageStoppedState( 8523 info.packageName, false, UserHandle.getUserId(app.uid)); 8524 } catch (RemoteException e) { 8525 } catch (IllegalArgumentException e) { 8526 Slog.w(TAG, "Failed trying to unstop package " 8527 + info.packageName + ": " + e); 8528 } 8529 8530 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8531 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8532 app.persistent = true; 8533 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8534 } 8535 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8536 mPersistentStartingProcesses.add(app); 8537 startProcessLocked(app, "added application", app.processName); 8538 } 8539 8540 return app; 8541 } 8542 8543 public void unhandledBack() { 8544 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8545 "unhandledBack()"); 8546 8547 synchronized(this) { 8548 final long origId = Binder.clearCallingIdentity(); 8549 try { 8550 getFocusedStack().unhandledBackLocked(); 8551 } finally { 8552 Binder.restoreCallingIdentity(origId); 8553 } 8554 } 8555 } 8556 8557 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8558 enforceNotIsolatedCaller("openContentUri"); 8559 final int userId = UserHandle.getCallingUserId(); 8560 String name = uri.getAuthority(); 8561 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8562 ParcelFileDescriptor pfd = null; 8563 if (cph != null) { 8564 // We record the binder invoker's uid in thread-local storage before 8565 // going to the content provider to open the file. Later, in the code 8566 // that handles all permissions checks, we look for this uid and use 8567 // that rather than the Activity Manager's own uid. The effect is that 8568 // we do the check against the caller's permissions even though it looks 8569 // to the content provider like the Activity Manager itself is making 8570 // the request. 8571 sCallerIdentity.set(new Identity( 8572 Binder.getCallingPid(), Binder.getCallingUid())); 8573 try { 8574 pfd = cph.provider.openFile(null, uri, "r", null); 8575 } catch (FileNotFoundException e) { 8576 // do nothing; pfd will be returned null 8577 } finally { 8578 // Ensure that whatever happens, we clean up the identity state 8579 sCallerIdentity.remove(); 8580 } 8581 8582 // We've got the fd now, so we're done with the provider. 8583 removeContentProviderExternalUnchecked(name, null, userId); 8584 } else { 8585 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8586 } 8587 return pfd; 8588 } 8589 8590 // Actually is sleeping or shutting down or whatever else in the future 8591 // is an inactive state. 8592 public boolean isSleepingOrShuttingDown() { 8593 return mSleeping || mShuttingDown; 8594 } 8595 8596 public boolean isSleeping() { 8597 return mSleeping; 8598 } 8599 8600 void goingToSleep() { 8601 synchronized(this) { 8602 mWentToSleep = true; 8603 updateEventDispatchingLocked(); 8604 goToSleepIfNeededLocked(); 8605 } 8606 } 8607 8608 void finishRunningVoiceLocked() { 8609 if (mRunningVoice) { 8610 mRunningVoice = false; 8611 goToSleepIfNeededLocked(); 8612 } 8613 } 8614 8615 void goToSleepIfNeededLocked() { 8616 if (mWentToSleep && !mRunningVoice) { 8617 if (!mSleeping) { 8618 mSleeping = true; 8619 mStackSupervisor.goingToSleepLocked(); 8620 8621 // Initialize the wake times of all processes. 8622 checkExcessivePowerUsageLocked(false); 8623 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8624 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8625 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8626 } 8627 } 8628 } 8629 8630 @Override 8631 public boolean shutdown(int timeout) { 8632 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8633 != PackageManager.PERMISSION_GRANTED) { 8634 throw new SecurityException("Requires permission " 8635 + android.Manifest.permission.SHUTDOWN); 8636 } 8637 8638 boolean timedout = false; 8639 8640 synchronized(this) { 8641 mShuttingDown = true; 8642 updateEventDispatchingLocked(); 8643 timedout = mStackSupervisor.shutdownLocked(timeout); 8644 } 8645 8646 mAppOpsService.shutdown(); 8647 mUsageStatsService.shutdown(); 8648 mBatteryStatsService.shutdown(); 8649 synchronized (this) { 8650 mProcessStats.shutdownLocked(); 8651 } 8652 8653 return timedout; 8654 } 8655 8656 public final void activitySlept(IBinder token) { 8657 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8658 8659 final long origId = Binder.clearCallingIdentity(); 8660 8661 synchronized (this) { 8662 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8663 if (r != null) { 8664 mStackSupervisor.activitySleptLocked(r); 8665 } 8666 } 8667 8668 Binder.restoreCallingIdentity(origId); 8669 } 8670 8671 void logLockScreen(String msg) { 8672 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8673 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8674 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8675 mStackSupervisor.mDismissKeyguardOnNextActivity); 8676 } 8677 8678 private void comeOutOfSleepIfNeededLocked() { 8679 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8680 if (mSleeping) { 8681 mSleeping = false; 8682 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8683 } 8684 } 8685 } 8686 8687 void wakingUp() { 8688 synchronized(this) { 8689 mWentToSleep = false; 8690 updateEventDispatchingLocked(); 8691 comeOutOfSleepIfNeededLocked(); 8692 } 8693 } 8694 8695 void startRunningVoiceLocked() { 8696 if (!mRunningVoice) { 8697 mRunningVoice = true; 8698 comeOutOfSleepIfNeededLocked(); 8699 } 8700 } 8701 8702 private void updateEventDispatchingLocked() { 8703 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8704 } 8705 8706 public void setLockScreenShown(boolean shown) { 8707 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8708 != PackageManager.PERMISSION_GRANTED) { 8709 throw new SecurityException("Requires permission " 8710 + android.Manifest.permission.DEVICE_POWER); 8711 } 8712 8713 synchronized(this) { 8714 long ident = Binder.clearCallingIdentity(); 8715 try { 8716 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8717 mLockScreenShown = shown; 8718 comeOutOfSleepIfNeededLocked(); 8719 } finally { 8720 Binder.restoreCallingIdentity(ident); 8721 } 8722 } 8723 } 8724 8725 public void stopAppSwitches() { 8726 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8727 != PackageManager.PERMISSION_GRANTED) { 8728 throw new SecurityException("Requires permission " 8729 + android.Manifest.permission.STOP_APP_SWITCHES); 8730 } 8731 8732 synchronized(this) { 8733 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8734 + APP_SWITCH_DELAY_TIME; 8735 mDidAppSwitch = false; 8736 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8737 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8738 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8739 } 8740 } 8741 8742 public void resumeAppSwitches() { 8743 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8744 != PackageManager.PERMISSION_GRANTED) { 8745 throw new SecurityException("Requires permission " 8746 + android.Manifest.permission.STOP_APP_SWITCHES); 8747 } 8748 8749 synchronized(this) { 8750 // Note that we don't execute any pending app switches... we will 8751 // let those wait until either the timeout, or the next start 8752 // activity request. 8753 mAppSwitchesAllowedTime = 0; 8754 } 8755 } 8756 8757 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8758 String name) { 8759 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8760 return true; 8761 } 8762 8763 final int perm = checkComponentPermission( 8764 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8765 callingUid, -1, true); 8766 if (perm == PackageManager.PERMISSION_GRANTED) { 8767 return true; 8768 } 8769 8770 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8771 return false; 8772 } 8773 8774 public void setDebugApp(String packageName, boolean waitForDebugger, 8775 boolean persistent) { 8776 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8777 "setDebugApp()"); 8778 8779 long ident = Binder.clearCallingIdentity(); 8780 try { 8781 // Note that this is not really thread safe if there are multiple 8782 // callers into it at the same time, but that's not a situation we 8783 // care about. 8784 if (persistent) { 8785 final ContentResolver resolver = mContext.getContentResolver(); 8786 Settings.Global.putString( 8787 resolver, Settings.Global.DEBUG_APP, 8788 packageName); 8789 Settings.Global.putInt( 8790 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8791 waitForDebugger ? 1 : 0); 8792 } 8793 8794 synchronized (this) { 8795 if (!persistent) { 8796 mOrigDebugApp = mDebugApp; 8797 mOrigWaitForDebugger = mWaitForDebugger; 8798 } 8799 mDebugApp = packageName; 8800 mWaitForDebugger = waitForDebugger; 8801 mDebugTransient = !persistent; 8802 if (packageName != null) { 8803 forceStopPackageLocked(packageName, -1, false, false, true, true, 8804 false, UserHandle.USER_ALL, "set debug app"); 8805 } 8806 } 8807 } finally { 8808 Binder.restoreCallingIdentity(ident); 8809 } 8810 } 8811 8812 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8813 synchronized (this) { 8814 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8815 if (!isDebuggable) { 8816 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8817 throw new SecurityException("Process not debuggable: " + app.packageName); 8818 } 8819 } 8820 8821 mOpenGlTraceApp = processName; 8822 } 8823 } 8824 8825 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8826 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8827 synchronized (this) { 8828 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8829 if (!isDebuggable) { 8830 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8831 throw new SecurityException("Process not debuggable: " + app.packageName); 8832 } 8833 } 8834 mProfileApp = processName; 8835 mProfileFile = profileFile; 8836 if (mProfileFd != null) { 8837 try { 8838 mProfileFd.close(); 8839 } catch (IOException e) { 8840 } 8841 mProfileFd = null; 8842 } 8843 mProfileFd = profileFd; 8844 mProfileType = 0; 8845 mAutoStopProfiler = autoStopProfiler; 8846 } 8847 } 8848 8849 @Override 8850 public void setAlwaysFinish(boolean enabled) { 8851 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8852 "setAlwaysFinish()"); 8853 8854 Settings.Global.putInt( 8855 mContext.getContentResolver(), 8856 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8857 8858 synchronized (this) { 8859 mAlwaysFinishActivities = enabled; 8860 } 8861 } 8862 8863 @Override 8864 public void setActivityController(IActivityController controller) { 8865 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8866 "setActivityController()"); 8867 synchronized (this) { 8868 mController = controller; 8869 Watchdog.getInstance().setActivityController(controller); 8870 } 8871 } 8872 8873 @Override 8874 public void setUserIsMonkey(boolean userIsMonkey) { 8875 synchronized (this) { 8876 synchronized (mPidsSelfLocked) { 8877 final int callingPid = Binder.getCallingPid(); 8878 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8879 if (precessRecord == null) { 8880 throw new SecurityException("Unknown process: " + callingPid); 8881 } 8882 if (precessRecord.instrumentationUiAutomationConnection == null) { 8883 throw new SecurityException("Only an instrumentation process " 8884 + "with a UiAutomation can call setUserIsMonkey"); 8885 } 8886 } 8887 mUserIsMonkey = userIsMonkey; 8888 } 8889 } 8890 8891 @Override 8892 public boolean isUserAMonkey() { 8893 synchronized (this) { 8894 // If there is a controller also implies the user is a monkey. 8895 return (mUserIsMonkey || mController != null); 8896 } 8897 } 8898 8899 public void requestBugReport() { 8900 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8901 SystemProperties.set("ctl.start", "bugreport"); 8902 } 8903 8904 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8905 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8906 } 8907 8908 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8909 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8910 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8911 } 8912 return KEY_DISPATCHING_TIMEOUT; 8913 } 8914 8915 @Override 8916 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8917 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8918 != PackageManager.PERMISSION_GRANTED) { 8919 throw new SecurityException("Requires permission " 8920 + android.Manifest.permission.FILTER_EVENTS); 8921 } 8922 ProcessRecord proc; 8923 long timeout; 8924 synchronized (this) { 8925 synchronized (mPidsSelfLocked) { 8926 proc = mPidsSelfLocked.get(pid); 8927 } 8928 timeout = getInputDispatchingTimeoutLocked(proc); 8929 } 8930 8931 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8932 return -1; 8933 } 8934 8935 return timeout; 8936 } 8937 8938 /** 8939 * Handle input dispatching timeouts. 8940 * Returns whether input dispatching should be aborted or not. 8941 */ 8942 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8943 final ActivityRecord activity, final ActivityRecord parent, 8944 final boolean aboveSystem, String reason) { 8945 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8946 != PackageManager.PERMISSION_GRANTED) { 8947 throw new SecurityException("Requires permission " 8948 + android.Manifest.permission.FILTER_EVENTS); 8949 } 8950 8951 final String annotation; 8952 if (reason == null) { 8953 annotation = "Input dispatching timed out"; 8954 } else { 8955 annotation = "Input dispatching timed out (" + reason + ")"; 8956 } 8957 8958 if (proc != null) { 8959 synchronized (this) { 8960 if (proc.debugging) { 8961 return false; 8962 } 8963 8964 if (mDidDexOpt) { 8965 // Give more time since we were dexopting. 8966 mDidDexOpt = false; 8967 return false; 8968 } 8969 8970 if (proc.instrumentationClass != null) { 8971 Bundle info = new Bundle(); 8972 info.putString("shortMsg", "keyDispatchingTimedOut"); 8973 info.putString("longMsg", annotation); 8974 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8975 return true; 8976 } 8977 } 8978 mHandler.post(new Runnable() { 8979 @Override 8980 public void run() { 8981 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8982 } 8983 }); 8984 } 8985 8986 return true; 8987 } 8988 8989 public Bundle getAssistContextExtras(int requestType) { 8990 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8991 "getAssistContextExtras()"); 8992 PendingAssistExtras pae; 8993 Bundle extras = new Bundle(); 8994 synchronized (this) { 8995 ActivityRecord activity = getFocusedStack().mResumedActivity; 8996 if (activity == null) { 8997 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8998 return null; 8999 } 9000 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9001 if (activity.app == null || activity.app.thread == null) { 9002 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9003 return extras; 9004 } 9005 if (activity.app.pid == Binder.getCallingPid()) { 9006 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9007 return extras; 9008 } 9009 pae = new PendingAssistExtras(activity); 9010 try { 9011 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9012 requestType); 9013 mPendingAssistExtras.add(pae); 9014 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9015 } catch (RemoteException e) { 9016 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9017 return extras; 9018 } 9019 } 9020 synchronized (pae) { 9021 while (!pae.haveResult) { 9022 try { 9023 pae.wait(); 9024 } catch (InterruptedException e) { 9025 } 9026 } 9027 if (pae.result != null) { 9028 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9029 } 9030 } 9031 synchronized (this) { 9032 mPendingAssistExtras.remove(pae); 9033 mHandler.removeCallbacks(pae); 9034 } 9035 return extras; 9036 } 9037 9038 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9039 PendingAssistExtras pae = (PendingAssistExtras)token; 9040 synchronized (pae) { 9041 pae.result = extras; 9042 pae.haveResult = true; 9043 pae.notifyAll(); 9044 } 9045 } 9046 9047 public void registerProcessObserver(IProcessObserver observer) { 9048 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9049 "registerProcessObserver()"); 9050 synchronized (this) { 9051 mProcessObservers.register(observer); 9052 } 9053 } 9054 9055 @Override 9056 public void unregisterProcessObserver(IProcessObserver observer) { 9057 synchronized (this) { 9058 mProcessObservers.unregister(observer); 9059 } 9060 } 9061 9062 @Override 9063 public boolean convertFromTranslucent(IBinder token) { 9064 final long origId = Binder.clearCallingIdentity(); 9065 try { 9066 synchronized (this) { 9067 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9068 if (r == null) { 9069 return false; 9070 } 9071 if (r.changeWindowTranslucency(true)) { 9072 mWindowManager.setAppFullscreen(token, true); 9073 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9074 return true; 9075 } 9076 return false; 9077 } 9078 } finally { 9079 Binder.restoreCallingIdentity(origId); 9080 } 9081 } 9082 9083 @Override 9084 public boolean convertToTranslucent(IBinder token, ActivityOptions options) { 9085 final long origId = Binder.clearCallingIdentity(); 9086 try { 9087 synchronized (this) { 9088 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9089 if (r == null) { 9090 return false; 9091 } 9092 if (r.changeWindowTranslucency(false)) { 9093 r.task.stack.convertToTranslucent(r, options); 9094 mWindowManager.setAppFullscreen(token, false); 9095 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9096 return true; 9097 } 9098 return false; 9099 } 9100 } finally { 9101 Binder.restoreCallingIdentity(origId); 9102 } 9103 } 9104 9105 @Override 9106 public ActivityOptions getActivityOptions(IBinder token) { 9107 final long origId = Binder.clearCallingIdentity(); 9108 try { 9109 synchronized (this) { 9110 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9111 if (r != null) { 9112 final ActivityOptions activityOptions = r.pendingOptions; 9113 r.pendingOptions = null; 9114 return activityOptions; 9115 } 9116 return null; 9117 } 9118 } finally { 9119 Binder.restoreCallingIdentity(origId); 9120 } 9121 } 9122 9123 @Override 9124 public void setImmersive(IBinder token, boolean immersive) { 9125 synchronized(this) { 9126 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9127 if (r == null) { 9128 throw new IllegalArgumentException(); 9129 } 9130 r.immersive = immersive; 9131 9132 // update associated state if we're frontmost 9133 if (r == mFocusedActivity) { 9134 if (DEBUG_IMMERSIVE) { 9135 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9136 } 9137 applyUpdateLockStateLocked(r); 9138 } 9139 } 9140 } 9141 9142 @Override 9143 public boolean isImmersive(IBinder token) { 9144 synchronized (this) { 9145 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9146 if (r == null) { 9147 throw new IllegalArgumentException(); 9148 } 9149 return r.immersive; 9150 } 9151 } 9152 9153 public boolean isTopActivityImmersive() { 9154 enforceNotIsolatedCaller("startActivity"); 9155 synchronized (this) { 9156 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9157 return (r != null) ? r.immersive : false; 9158 } 9159 } 9160 9161 public final void enterSafeMode() { 9162 synchronized(this) { 9163 // It only makes sense to do this before the system is ready 9164 // and started launching other packages. 9165 if (!mSystemReady) { 9166 try { 9167 AppGlobals.getPackageManager().enterSafeMode(); 9168 } catch (RemoteException e) { 9169 } 9170 } 9171 9172 mSafeMode = true; 9173 } 9174 } 9175 9176 public final void showSafeModeOverlay() { 9177 View v = LayoutInflater.from(mContext).inflate( 9178 com.android.internal.R.layout.safe_mode, null); 9179 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9180 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9181 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9182 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9183 lp.gravity = Gravity.BOTTOM | Gravity.START; 9184 lp.format = v.getBackground().getOpacity(); 9185 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9186 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9187 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9188 ((WindowManager)mContext.getSystemService( 9189 Context.WINDOW_SERVICE)).addView(v, lp); 9190 } 9191 9192 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9193 if (!(sender instanceof PendingIntentRecord)) { 9194 return; 9195 } 9196 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9197 synchronized (stats) { 9198 if (mBatteryStatsService.isOnBattery()) { 9199 mBatteryStatsService.enforceCallingPermission(); 9200 PendingIntentRecord rec = (PendingIntentRecord)sender; 9201 int MY_UID = Binder.getCallingUid(); 9202 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9203 BatteryStatsImpl.Uid.Pkg pkg = 9204 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9205 sourcePkg != null ? sourcePkg : rec.key.packageName); 9206 pkg.incWakeupsLocked(); 9207 } 9208 } 9209 } 9210 9211 public boolean killPids(int[] pids, String pReason, boolean secure) { 9212 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9213 throw new SecurityException("killPids only available to the system"); 9214 } 9215 String reason = (pReason == null) ? "Unknown" : pReason; 9216 // XXX Note: don't acquire main activity lock here, because the window 9217 // manager calls in with its locks held. 9218 9219 boolean killed = false; 9220 synchronized (mPidsSelfLocked) { 9221 int[] types = new int[pids.length]; 9222 int worstType = 0; 9223 for (int i=0; i<pids.length; i++) { 9224 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9225 if (proc != null) { 9226 int type = proc.setAdj; 9227 types[i] = type; 9228 if (type > worstType) { 9229 worstType = type; 9230 } 9231 } 9232 } 9233 9234 // If the worst oom_adj is somewhere in the cached proc LRU range, 9235 // then constrain it so we will kill all cached procs. 9236 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9237 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9238 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9239 } 9240 9241 // If this is not a secure call, don't let it kill processes that 9242 // are important. 9243 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9244 worstType = ProcessList.SERVICE_ADJ; 9245 } 9246 9247 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9248 for (int i=0; i<pids.length; i++) { 9249 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9250 if (proc == null) { 9251 continue; 9252 } 9253 int adj = proc.setAdj; 9254 if (adj >= worstType && !proc.killedByAm) { 9255 killUnneededProcessLocked(proc, reason); 9256 killed = true; 9257 } 9258 } 9259 } 9260 return killed; 9261 } 9262 9263 @Override 9264 public void killUid(int uid, String reason) { 9265 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9266 throw new SecurityException("killUid only available to the system"); 9267 } 9268 synchronized (this) { 9269 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9270 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9271 reason != null ? reason : "kill uid"); 9272 } 9273 } 9274 9275 @Override 9276 public boolean killProcessesBelowForeground(String reason) { 9277 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9278 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9279 } 9280 9281 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9282 } 9283 9284 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9285 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9286 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9287 } 9288 9289 boolean killed = false; 9290 synchronized (mPidsSelfLocked) { 9291 final int size = mPidsSelfLocked.size(); 9292 for (int i = 0; i < size; i++) { 9293 final int pid = mPidsSelfLocked.keyAt(i); 9294 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9295 if (proc == null) continue; 9296 9297 final int adj = proc.setAdj; 9298 if (adj > belowAdj && !proc.killedByAm) { 9299 killUnneededProcessLocked(proc, reason); 9300 killed = true; 9301 } 9302 } 9303 } 9304 return killed; 9305 } 9306 9307 @Override 9308 public void hang(final IBinder who, boolean allowRestart) { 9309 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9310 != PackageManager.PERMISSION_GRANTED) { 9311 throw new SecurityException("Requires permission " 9312 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9313 } 9314 9315 final IBinder.DeathRecipient death = new DeathRecipient() { 9316 @Override 9317 public void binderDied() { 9318 synchronized (this) { 9319 notifyAll(); 9320 } 9321 } 9322 }; 9323 9324 try { 9325 who.linkToDeath(death, 0); 9326 } catch (RemoteException e) { 9327 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9328 return; 9329 } 9330 9331 synchronized (this) { 9332 Watchdog.getInstance().setAllowRestart(allowRestart); 9333 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9334 synchronized (death) { 9335 while (who.isBinderAlive()) { 9336 try { 9337 death.wait(); 9338 } catch (InterruptedException e) { 9339 } 9340 } 9341 } 9342 Watchdog.getInstance().setAllowRestart(true); 9343 } 9344 } 9345 9346 @Override 9347 public void restart() { 9348 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9349 != PackageManager.PERMISSION_GRANTED) { 9350 throw new SecurityException("Requires permission " 9351 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9352 } 9353 9354 Log.i(TAG, "Sending shutdown broadcast..."); 9355 9356 BroadcastReceiver br = new BroadcastReceiver() { 9357 @Override public void onReceive(Context context, Intent intent) { 9358 // Now the broadcast is done, finish up the low-level shutdown. 9359 Log.i(TAG, "Shutting down activity manager..."); 9360 shutdown(10000); 9361 Log.i(TAG, "Shutdown complete, restarting!"); 9362 Process.killProcess(Process.myPid()); 9363 System.exit(10); 9364 } 9365 }; 9366 9367 // First send the high-level shut down broadcast. 9368 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9369 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9370 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9371 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9372 mContext.sendOrderedBroadcastAsUser(intent, 9373 UserHandle.ALL, null, br, mHandler, 0, null, null); 9374 */ 9375 br.onReceive(mContext, intent); 9376 } 9377 9378 private long getLowRamTimeSinceIdle(long now) { 9379 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9380 } 9381 9382 @Override 9383 public void performIdleMaintenance() { 9384 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9385 != PackageManager.PERMISSION_GRANTED) { 9386 throw new SecurityException("Requires permission " 9387 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9388 } 9389 9390 synchronized (this) { 9391 final long now = SystemClock.uptimeMillis(); 9392 final long timeSinceLastIdle = now - mLastIdleTime; 9393 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9394 mLastIdleTime = now; 9395 mLowRamTimeSinceLastIdle = 0; 9396 if (mLowRamStartTime != 0) { 9397 mLowRamStartTime = now; 9398 } 9399 9400 StringBuilder sb = new StringBuilder(128); 9401 sb.append("Idle maintenance over "); 9402 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9403 sb.append(" low RAM for "); 9404 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9405 Slog.i(TAG, sb.toString()); 9406 9407 // If at least 1/3 of our time since the last idle period has been spent 9408 // with RAM low, then we want to kill processes. 9409 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9410 9411 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9412 ProcessRecord proc = mLruProcesses.get(i); 9413 if (proc.notCachedSinceIdle) { 9414 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9415 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9416 if (doKilling && proc.initialIdlePss != 0 9417 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9418 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9419 + " from " + proc.initialIdlePss + ")"); 9420 } 9421 } 9422 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9423 proc.notCachedSinceIdle = true; 9424 proc.initialIdlePss = 0; 9425 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9426 isSleeping(), now); 9427 } 9428 } 9429 9430 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9431 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9432 } 9433 } 9434 9435 private void retrieveSettings() { 9436 final ContentResolver resolver = mContext.getContentResolver(); 9437 String debugApp = Settings.Global.getString( 9438 resolver, Settings.Global.DEBUG_APP); 9439 boolean waitForDebugger = Settings.Global.getInt( 9440 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9441 boolean alwaysFinishActivities = Settings.Global.getInt( 9442 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9443 boolean forceRtl = Settings.Global.getInt( 9444 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9445 // Transfer any global setting for forcing RTL layout, into a System Property 9446 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9447 9448 Configuration configuration = new Configuration(); 9449 Settings.System.getConfiguration(resolver, configuration); 9450 if (forceRtl) { 9451 // This will take care of setting the correct layout direction flags 9452 configuration.setLayoutDirection(configuration.locale); 9453 } 9454 9455 synchronized (this) { 9456 mDebugApp = mOrigDebugApp = debugApp; 9457 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9458 mAlwaysFinishActivities = alwaysFinishActivities; 9459 // This happens before any activities are started, so we can 9460 // change mConfiguration in-place. 9461 updateConfigurationLocked(configuration, null, false, true); 9462 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9463 } 9464 } 9465 9466 public boolean testIsSystemReady() { 9467 // no need to synchronize(this) just to read & return the value 9468 return mSystemReady; 9469 } 9470 9471 private static File getCalledPreBootReceiversFile() { 9472 File dataDir = Environment.getDataDirectory(); 9473 File systemDir = new File(dataDir, "system"); 9474 File fname = new File(systemDir, "called_pre_boots.dat"); 9475 return fname; 9476 } 9477 9478 static final int LAST_DONE_VERSION = 10000; 9479 9480 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9481 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9482 File file = getCalledPreBootReceiversFile(); 9483 FileInputStream fis = null; 9484 try { 9485 fis = new FileInputStream(file); 9486 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9487 int fvers = dis.readInt(); 9488 if (fvers == LAST_DONE_VERSION) { 9489 String vers = dis.readUTF(); 9490 String codename = dis.readUTF(); 9491 String build = dis.readUTF(); 9492 if (android.os.Build.VERSION.RELEASE.equals(vers) 9493 && android.os.Build.VERSION.CODENAME.equals(codename) 9494 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9495 int num = dis.readInt(); 9496 while (num > 0) { 9497 num--; 9498 String pkg = dis.readUTF(); 9499 String cls = dis.readUTF(); 9500 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9501 } 9502 } 9503 } 9504 } catch (FileNotFoundException e) { 9505 } catch (IOException e) { 9506 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9507 } finally { 9508 if (fis != null) { 9509 try { 9510 fis.close(); 9511 } catch (IOException e) { 9512 } 9513 } 9514 } 9515 return lastDoneReceivers; 9516 } 9517 9518 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9519 File file = getCalledPreBootReceiversFile(); 9520 FileOutputStream fos = null; 9521 DataOutputStream dos = null; 9522 try { 9523 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9524 fos = new FileOutputStream(file); 9525 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9526 dos.writeInt(LAST_DONE_VERSION); 9527 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9528 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9529 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9530 dos.writeInt(list.size()); 9531 for (int i=0; i<list.size(); i++) { 9532 dos.writeUTF(list.get(i).getPackageName()); 9533 dos.writeUTF(list.get(i).getClassName()); 9534 } 9535 } catch (IOException e) { 9536 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9537 file.delete(); 9538 } finally { 9539 FileUtils.sync(fos); 9540 if (dos != null) { 9541 try { 9542 dos.close(); 9543 } catch (IOException e) { 9544 // TODO Auto-generated catch block 9545 e.printStackTrace(); 9546 } 9547 } 9548 } 9549 } 9550 9551 public void systemReady(final Runnable goingCallback) { 9552 synchronized(this) { 9553 if (mSystemReady) { 9554 if (goingCallback != null) goingCallback.run(); 9555 return; 9556 } 9557 9558 // Check to see if there are any update receivers to run. 9559 if (!mDidUpdate) { 9560 if (mWaitingUpdate) { 9561 return; 9562 } 9563 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9564 List<ResolveInfo> ris = null; 9565 try { 9566 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9567 intent, null, 0, 0); 9568 } catch (RemoteException e) { 9569 } 9570 if (ris != null) { 9571 for (int i=ris.size()-1; i>=0; i--) { 9572 if ((ris.get(i).activityInfo.applicationInfo.flags 9573 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9574 ris.remove(i); 9575 } 9576 } 9577 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9578 9579 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9580 9581 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9582 for (int i=0; i<ris.size(); i++) { 9583 ActivityInfo ai = ris.get(i).activityInfo; 9584 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9585 if (lastDoneReceivers.contains(comp)) { 9586 // We already did the pre boot receiver for this app with the current 9587 // platform version, so don't do it again... 9588 ris.remove(i); 9589 i--; 9590 // ...however, do keep it as one that has been done, so we don't 9591 // forget about it when rewriting the file of last done receivers. 9592 doneReceivers.add(comp); 9593 } 9594 } 9595 9596 final int[] users = getUsersLocked(); 9597 for (int i=0; i<ris.size(); i++) { 9598 ActivityInfo ai = ris.get(i).activityInfo; 9599 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9600 doneReceivers.add(comp); 9601 intent.setComponent(comp); 9602 for (int j=0; j<users.length; j++) { 9603 IIntentReceiver finisher = null; 9604 if (i == ris.size()-1 && j == users.length-1) { 9605 finisher = new IIntentReceiver.Stub() { 9606 public void performReceive(Intent intent, int resultCode, 9607 String data, Bundle extras, boolean ordered, 9608 boolean sticky, int sendingUser) { 9609 // The raw IIntentReceiver interface is called 9610 // with the AM lock held, so redispatch to 9611 // execute our code without the lock. 9612 mHandler.post(new Runnable() { 9613 public void run() { 9614 synchronized (ActivityManagerService.this) { 9615 mDidUpdate = true; 9616 } 9617 writeLastDonePreBootReceivers(doneReceivers); 9618 showBootMessage(mContext.getText( 9619 R.string.android_upgrading_complete), 9620 false); 9621 systemReady(goingCallback); 9622 } 9623 }); 9624 } 9625 }; 9626 } 9627 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9628 + " for user " + users[j]); 9629 broadcastIntentLocked(null, null, intent, null, finisher, 9630 0, null, null, null, AppOpsManager.OP_NONE, 9631 true, false, MY_PID, Process.SYSTEM_UID, 9632 users[j]); 9633 if (finisher != null) { 9634 mWaitingUpdate = true; 9635 } 9636 } 9637 } 9638 } 9639 if (mWaitingUpdate) { 9640 return; 9641 } 9642 mDidUpdate = true; 9643 } 9644 9645 mAppOpsService.systemReady(); 9646 mUsageStatsService.systemReady(); 9647 mSystemReady = true; 9648 } 9649 9650 ArrayList<ProcessRecord> procsToKill = null; 9651 synchronized(mPidsSelfLocked) { 9652 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9653 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9654 if (!isAllowedWhileBooting(proc.info)){ 9655 if (procsToKill == null) { 9656 procsToKill = new ArrayList<ProcessRecord>(); 9657 } 9658 procsToKill.add(proc); 9659 } 9660 } 9661 } 9662 9663 synchronized(this) { 9664 if (procsToKill != null) { 9665 for (int i=procsToKill.size()-1; i>=0; i--) { 9666 ProcessRecord proc = procsToKill.get(i); 9667 Slog.i(TAG, "Removing system update proc: " + proc); 9668 removeProcessLocked(proc, true, false, "system update done"); 9669 } 9670 } 9671 9672 // Now that we have cleaned up any update processes, we 9673 // are ready to start launching real processes and know that 9674 // we won't trample on them any more. 9675 mProcessesReady = true; 9676 } 9677 9678 Slog.i(TAG, "System now ready"); 9679 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9680 SystemClock.uptimeMillis()); 9681 9682 synchronized(this) { 9683 // Make sure we have no pre-ready processes sitting around. 9684 9685 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9686 ResolveInfo ri = mContext.getPackageManager() 9687 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9688 STOCK_PM_FLAGS); 9689 CharSequence errorMsg = null; 9690 if (ri != null) { 9691 ActivityInfo ai = ri.activityInfo; 9692 ApplicationInfo app = ai.applicationInfo; 9693 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9694 mTopAction = Intent.ACTION_FACTORY_TEST; 9695 mTopData = null; 9696 mTopComponent = new ComponentName(app.packageName, 9697 ai.name); 9698 } else { 9699 errorMsg = mContext.getResources().getText( 9700 com.android.internal.R.string.factorytest_not_system); 9701 } 9702 } else { 9703 errorMsg = mContext.getResources().getText( 9704 com.android.internal.R.string.factorytest_no_action); 9705 } 9706 if (errorMsg != null) { 9707 mTopAction = null; 9708 mTopData = null; 9709 mTopComponent = null; 9710 Message msg = Message.obtain(); 9711 msg.what = SHOW_FACTORY_ERROR_MSG; 9712 msg.getData().putCharSequence("msg", errorMsg); 9713 mHandler.sendMessage(msg); 9714 } 9715 } 9716 } 9717 9718 retrieveSettings(); 9719 9720 synchronized (this) { 9721 readGrantedUriPermissionsLocked(); 9722 } 9723 9724 if (goingCallback != null) goingCallback.run(); 9725 9726 mSystemServiceManager.startUser(mCurrentUserId); 9727 9728 synchronized (this) { 9729 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9730 try { 9731 List apps = AppGlobals.getPackageManager(). 9732 getPersistentApplications(STOCK_PM_FLAGS); 9733 if (apps != null) { 9734 int N = apps.size(); 9735 int i; 9736 for (i=0; i<N; i++) { 9737 ApplicationInfo info 9738 = (ApplicationInfo)apps.get(i); 9739 if (info != null && 9740 !info.packageName.equals("android")) { 9741 addAppLocked(info, false); 9742 } 9743 } 9744 } 9745 } catch (RemoteException ex) { 9746 // pm is in same process, this will never happen. 9747 } 9748 } 9749 9750 // Start up initial activity. 9751 mBooting = true; 9752 9753 try { 9754 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9755 Message msg = Message.obtain(); 9756 msg.what = SHOW_UID_ERROR_MSG; 9757 mHandler.sendMessage(msg); 9758 } 9759 } catch (RemoteException e) { 9760 } 9761 9762 long ident = Binder.clearCallingIdentity(); 9763 try { 9764 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9765 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9766 | Intent.FLAG_RECEIVER_FOREGROUND); 9767 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9768 broadcastIntentLocked(null, null, intent, 9769 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9770 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9771 intent = new Intent(Intent.ACTION_USER_STARTING); 9772 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9773 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9774 broadcastIntentLocked(null, null, intent, 9775 null, new IIntentReceiver.Stub() { 9776 @Override 9777 public void performReceive(Intent intent, int resultCode, String data, 9778 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9779 throws RemoteException { 9780 } 9781 }, 0, null, null, 9782 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9783 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9784 } catch (Throwable t) { 9785 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9786 } finally { 9787 Binder.restoreCallingIdentity(ident); 9788 } 9789 mStackSupervisor.resumeTopActivitiesLocked(); 9790 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9791 } 9792 } 9793 9794 private boolean makeAppCrashingLocked(ProcessRecord app, 9795 String shortMsg, String longMsg, String stackTrace) { 9796 app.crashing = true; 9797 app.crashingReport = generateProcessError(app, 9798 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9799 startAppProblemLocked(app); 9800 app.stopFreezingAllLocked(); 9801 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9802 } 9803 9804 private void makeAppNotRespondingLocked(ProcessRecord app, 9805 String activity, String shortMsg, String longMsg) { 9806 app.notResponding = true; 9807 app.notRespondingReport = generateProcessError(app, 9808 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9809 activity, shortMsg, longMsg, null); 9810 startAppProblemLocked(app); 9811 app.stopFreezingAllLocked(); 9812 } 9813 9814 /** 9815 * Generate a process error record, suitable for attachment to a ProcessRecord. 9816 * 9817 * @param app The ProcessRecord in which the error occurred. 9818 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9819 * ActivityManager.AppErrorStateInfo 9820 * @param activity The activity associated with the crash, if known. 9821 * @param shortMsg Short message describing the crash. 9822 * @param longMsg Long message describing the crash. 9823 * @param stackTrace Full crash stack trace, may be null. 9824 * 9825 * @return Returns a fully-formed AppErrorStateInfo record. 9826 */ 9827 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9828 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9829 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9830 9831 report.condition = condition; 9832 report.processName = app.processName; 9833 report.pid = app.pid; 9834 report.uid = app.info.uid; 9835 report.tag = activity; 9836 report.shortMsg = shortMsg; 9837 report.longMsg = longMsg; 9838 report.stackTrace = stackTrace; 9839 9840 return report; 9841 } 9842 9843 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9844 synchronized (this) { 9845 app.crashing = false; 9846 app.crashingReport = null; 9847 app.notResponding = false; 9848 app.notRespondingReport = null; 9849 if (app.anrDialog == fromDialog) { 9850 app.anrDialog = null; 9851 } 9852 if (app.waitDialog == fromDialog) { 9853 app.waitDialog = null; 9854 } 9855 if (app.pid > 0 && app.pid != MY_PID) { 9856 handleAppCrashLocked(app, null, null, null); 9857 killUnneededProcessLocked(app, "user request after error"); 9858 } 9859 } 9860 } 9861 9862 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9863 String stackTrace) { 9864 long now = SystemClock.uptimeMillis(); 9865 9866 Long crashTime; 9867 if (!app.isolated) { 9868 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9869 } else { 9870 crashTime = null; 9871 } 9872 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9873 // This process loses! 9874 Slog.w(TAG, "Process " + app.info.processName 9875 + " has crashed too many times: killing!"); 9876 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9877 app.userId, app.info.processName, app.uid); 9878 mStackSupervisor.handleAppCrashLocked(app); 9879 if (!app.persistent) { 9880 // We don't want to start this process again until the user 9881 // explicitly does so... but for persistent process, we really 9882 // need to keep it running. If a persistent process is actually 9883 // repeatedly crashing, then badness for everyone. 9884 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9885 app.info.processName); 9886 if (!app.isolated) { 9887 // XXX We don't have a way to mark isolated processes 9888 // as bad, since they don't have a peristent identity. 9889 mBadProcesses.put(app.info.processName, app.uid, 9890 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9891 mProcessCrashTimes.remove(app.info.processName, app.uid); 9892 } 9893 app.bad = true; 9894 app.removed = true; 9895 // Don't let services in this process be restarted and potentially 9896 // annoy the user repeatedly. Unless it is persistent, since those 9897 // processes run critical code. 9898 removeProcessLocked(app, false, false, "crash"); 9899 mStackSupervisor.resumeTopActivitiesLocked(); 9900 return false; 9901 } 9902 mStackSupervisor.resumeTopActivitiesLocked(); 9903 } else { 9904 mStackSupervisor.finishTopRunningActivityLocked(app); 9905 } 9906 9907 // Bump up the crash count of any services currently running in the proc. 9908 for (int i=app.services.size()-1; i>=0; i--) { 9909 // Any services running in the application need to be placed 9910 // back in the pending list. 9911 ServiceRecord sr = app.services.valueAt(i); 9912 sr.crashCount++; 9913 } 9914 9915 // If the crashing process is what we consider to be the "home process" and it has been 9916 // replaced by a third-party app, clear the package preferred activities from packages 9917 // with a home activity running in the process to prevent a repeatedly crashing app 9918 // from blocking the user to manually clear the list. 9919 final ArrayList<ActivityRecord> activities = app.activities; 9920 if (app == mHomeProcess && activities.size() > 0 9921 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9922 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9923 final ActivityRecord r = activities.get(activityNdx); 9924 if (r.isHomeActivity()) { 9925 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9926 try { 9927 ActivityThread.getPackageManager() 9928 .clearPackagePreferredActivities(r.packageName); 9929 } catch (RemoteException c) { 9930 // pm is in same process, this will never happen. 9931 } 9932 } 9933 } 9934 } 9935 9936 if (!app.isolated) { 9937 // XXX Can't keep track of crash times for isolated processes, 9938 // because they don't have a perisistent identity. 9939 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9940 } 9941 9942 return true; 9943 } 9944 9945 void startAppProblemLocked(ProcessRecord app) { 9946 if (app.userId == mCurrentUserId) { 9947 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9948 mContext, app.info.packageName, app.info.flags); 9949 } else { 9950 // If this app is not running under the current user, then we 9951 // can't give it a report button because that would require 9952 // launching the report UI under a different user. 9953 app.errorReportReceiver = null; 9954 } 9955 skipCurrentReceiverLocked(app); 9956 } 9957 9958 void skipCurrentReceiverLocked(ProcessRecord app) { 9959 for (BroadcastQueue queue : mBroadcastQueues) { 9960 queue.skipCurrentReceiverLocked(app); 9961 } 9962 } 9963 9964 /** 9965 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9966 * The application process will exit immediately after this call returns. 9967 * @param app object of the crashing app, null for the system server 9968 * @param crashInfo describing the exception 9969 */ 9970 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9971 ProcessRecord r = findAppProcess(app, "Crash"); 9972 final String processName = app == null ? "system_server" 9973 : (r == null ? "unknown" : r.processName); 9974 9975 handleApplicationCrashInner("crash", r, processName, crashInfo); 9976 } 9977 9978 /* Native crash reporting uses this inner version because it needs to be somewhat 9979 * decoupled from the AM-managed cleanup lifecycle 9980 */ 9981 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9982 ApplicationErrorReport.CrashInfo crashInfo) { 9983 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9984 UserHandle.getUserId(Binder.getCallingUid()), processName, 9985 r == null ? -1 : r.info.flags, 9986 crashInfo.exceptionClassName, 9987 crashInfo.exceptionMessage, 9988 crashInfo.throwFileName, 9989 crashInfo.throwLineNumber); 9990 9991 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9992 9993 crashApplication(r, crashInfo); 9994 } 9995 9996 public void handleApplicationStrictModeViolation( 9997 IBinder app, 9998 int violationMask, 9999 StrictMode.ViolationInfo info) { 10000 ProcessRecord r = findAppProcess(app, "StrictMode"); 10001 if (r == null) { 10002 return; 10003 } 10004 10005 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10006 Integer stackFingerprint = info.hashCode(); 10007 boolean logIt = true; 10008 synchronized (mAlreadyLoggedViolatedStacks) { 10009 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10010 logIt = false; 10011 // TODO: sub-sample into EventLog for these, with 10012 // the info.durationMillis? Then we'd get 10013 // the relative pain numbers, without logging all 10014 // the stack traces repeatedly. We'd want to do 10015 // likewise in the client code, which also does 10016 // dup suppression, before the Binder call. 10017 } else { 10018 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10019 mAlreadyLoggedViolatedStacks.clear(); 10020 } 10021 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10022 } 10023 } 10024 if (logIt) { 10025 logStrictModeViolationToDropBox(r, info); 10026 } 10027 } 10028 10029 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10030 AppErrorResult result = new AppErrorResult(); 10031 synchronized (this) { 10032 final long origId = Binder.clearCallingIdentity(); 10033 10034 Message msg = Message.obtain(); 10035 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10036 HashMap<String, Object> data = new HashMap<String, Object>(); 10037 data.put("result", result); 10038 data.put("app", r); 10039 data.put("violationMask", violationMask); 10040 data.put("info", info); 10041 msg.obj = data; 10042 mHandler.sendMessage(msg); 10043 10044 Binder.restoreCallingIdentity(origId); 10045 } 10046 int res = result.get(); 10047 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10048 } 10049 } 10050 10051 // Depending on the policy in effect, there could be a bunch of 10052 // these in quick succession so we try to batch these together to 10053 // minimize disk writes, number of dropbox entries, and maximize 10054 // compression, by having more fewer, larger records. 10055 private void logStrictModeViolationToDropBox( 10056 ProcessRecord process, 10057 StrictMode.ViolationInfo info) { 10058 if (info == null) { 10059 return; 10060 } 10061 final boolean isSystemApp = process == null || 10062 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10063 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10064 final String processName = process == null ? "unknown" : process.processName; 10065 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10066 final DropBoxManager dbox = (DropBoxManager) 10067 mContext.getSystemService(Context.DROPBOX_SERVICE); 10068 10069 // Exit early if the dropbox isn't configured to accept this report type. 10070 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10071 10072 boolean bufferWasEmpty; 10073 boolean needsFlush; 10074 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10075 synchronized (sb) { 10076 bufferWasEmpty = sb.length() == 0; 10077 appendDropBoxProcessHeaders(process, processName, sb); 10078 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10079 sb.append("System-App: ").append(isSystemApp).append("\n"); 10080 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10081 if (info.violationNumThisLoop != 0) { 10082 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10083 } 10084 if (info.numAnimationsRunning != 0) { 10085 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10086 } 10087 if (info.broadcastIntentAction != null) { 10088 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10089 } 10090 if (info.durationMillis != -1) { 10091 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10092 } 10093 if (info.numInstances != -1) { 10094 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10095 } 10096 if (info.tags != null) { 10097 for (String tag : info.tags) { 10098 sb.append("Span-Tag: ").append(tag).append("\n"); 10099 } 10100 } 10101 sb.append("\n"); 10102 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10103 sb.append(info.crashInfo.stackTrace); 10104 } 10105 sb.append("\n"); 10106 10107 // Only buffer up to ~64k. Various logging bits truncate 10108 // things at 128k. 10109 needsFlush = (sb.length() > 64 * 1024); 10110 } 10111 10112 // Flush immediately if the buffer's grown too large, or this 10113 // is a non-system app. Non-system apps are isolated with a 10114 // different tag & policy and not batched. 10115 // 10116 // Batching is useful during internal testing with 10117 // StrictMode settings turned up high. Without batching, 10118 // thousands of separate files could be created on boot. 10119 if (!isSystemApp || needsFlush) { 10120 new Thread("Error dump: " + dropboxTag) { 10121 @Override 10122 public void run() { 10123 String report; 10124 synchronized (sb) { 10125 report = sb.toString(); 10126 sb.delete(0, sb.length()); 10127 sb.trimToSize(); 10128 } 10129 if (report.length() != 0) { 10130 dbox.addText(dropboxTag, report); 10131 } 10132 } 10133 }.start(); 10134 return; 10135 } 10136 10137 // System app batching: 10138 if (!bufferWasEmpty) { 10139 // An existing dropbox-writing thread is outstanding, so 10140 // we don't need to start it up. The existing thread will 10141 // catch the buffer appends we just did. 10142 return; 10143 } 10144 10145 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10146 // (After this point, we shouldn't access AMS internal data structures.) 10147 new Thread("Error dump: " + dropboxTag) { 10148 @Override 10149 public void run() { 10150 // 5 second sleep to let stacks arrive and be batched together 10151 try { 10152 Thread.sleep(5000); // 5 seconds 10153 } catch (InterruptedException e) {} 10154 10155 String errorReport; 10156 synchronized (mStrictModeBuffer) { 10157 errorReport = mStrictModeBuffer.toString(); 10158 if (errorReport.length() == 0) { 10159 return; 10160 } 10161 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10162 mStrictModeBuffer.trimToSize(); 10163 } 10164 dbox.addText(dropboxTag, errorReport); 10165 } 10166 }.start(); 10167 } 10168 10169 /** 10170 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10171 * @param app object of the crashing app, null for the system server 10172 * @param tag reported by the caller 10173 * @param crashInfo describing the context of the error 10174 * @return true if the process should exit immediately (WTF is fatal) 10175 */ 10176 public boolean handleApplicationWtf(IBinder app, String tag, 10177 ApplicationErrorReport.CrashInfo crashInfo) { 10178 ProcessRecord r = findAppProcess(app, "WTF"); 10179 final String processName = app == null ? "system_server" 10180 : (r == null ? "unknown" : r.processName); 10181 10182 EventLog.writeEvent(EventLogTags.AM_WTF, 10183 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10184 processName, 10185 r == null ? -1 : r.info.flags, 10186 tag, crashInfo.exceptionMessage); 10187 10188 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10189 10190 if (r != null && r.pid != Process.myPid() && 10191 Settings.Global.getInt(mContext.getContentResolver(), 10192 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10193 crashApplication(r, crashInfo); 10194 return true; 10195 } else { 10196 return false; 10197 } 10198 } 10199 10200 /** 10201 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10202 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10203 */ 10204 private ProcessRecord findAppProcess(IBinder app, String reason) { 10205 if (app == null) { 10206 return null; 10207 } 10208 10209 synchronized (this) { 10210 final int NP = mProcessNames.getMap().size(); 10211 for (int ip=0; ip<NP; ip++) { 10212 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10213 final int NA = apps.size(); 10214 for (int ia=0; ia<NA; ia++) { 10215 ProcessRecord p = apps.valueAt(ia); 10216 if (p.thread != null && p.thread.asBinder() == app) { 10217 return p; 10218 } 10219 } 10220 } 10221 10222 Slog.w(TAG, "Can't find mystery application for " + reason 10223 + " from pid=" + Binder.getCallingPid() 10224 + " uid=" + Binder.getCallingUid() + ": " + app); 10225 return null; 10226 } 10227 } 10228 10229 /** 10230 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10231 * to append various headers to the dropbox log text. 10232 */ 10233 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10234 StringBuilder sb) { 10235 // Watchdog thread ends up invoking this function (with 10236 // a null ProcessRecord) to add the stack file to dropbox. 10237 // Do not acquire a lock on this (am) in such cases, as it 10238 // could cause a potential deadlock, if and when watchdog 10239 // is invoked due to unavailability of lock on am and it 10240 // would prevent watchdog from killing system_server. 10241 if (process == null) { 10242 sb.append("Process: ").append(processName).append("\n"); 10243 return; 10244 } 10245 // Note: ProcessRecord 'process' is guarded by the service 10246 // instance. (notably process.pkgList, which could otherwise change 10247 // concurrently during execution of this method) 10248 synchronized (this) { 10249 sb.append("Process: ").append(processName).append("\n"); 10250 int flags = process.info.flags; 10251 IPackageManager pm = AppGlobals.getPackageManager(); 10252 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10253 for (int ip=0; ip<process.pkgList.size(); ip++) { 10254 String pkg = process.pkgList.keyAt(ip); 10255 sb.append("Package: ").append(pkg); 10256 try { 10257 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10258 if (pi != null) { 10259 sb.append(" v").append(pi.versionCode); 10260 if (pi.versionName != null) { 10261 sb.append(" (").append(pi.versionName).append(")"); 10262 } 10263 } 10264 } catch (RemoteException e) { 10265 Slog.e(TAG, "Error getting package info: " + pkg, e); 10266 } 10267 sb.append("\n"); 10268 } 10269 } 10270 } 10271 10272 private static String processClass(ProcessRecord process) { 10273 if (process == null || process.pid == MY_PID) { 10274 return "system_server"; 10275 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10276 return "system_app"; 10277 } else { 10278 return "data_app"; 10279 } 10280 } 10281 10282 /** 10283 * Write a description of an error (crash, WTF, ANR) to the drop box. 10284 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10285 * @param process which caused the error, null means the system server 10286 * @param activity which triggered the error, null if unknown 10287 * @param parent activity related to the error, null if unknown 10288 * @param subject line related to the error, null if absent 10289 * @param report in long form describing the error, null if absent 10290 * @param logFile to include in the report, null if none 10291 * @param crashInfo giving an application stack trace, null if absent 10292 */ 10293 public void addErrorToDropBox(String eventType, 10294 ProcessRecord process, String processName, ActivityRecord activity, 10295 ActivityRecord parent, String subject, 10296 final String report, final File logFile, 10297 final ApplicationErrorReport.CrashInfo crashInfo) { 10298 // NOTE -- this must never acquire the ActivityManagerService lock, 10299 // otherwise the watchdog may be prevented from resetting the system. 10300 10301 final String dropboxTag = processClass(process) + "_" + eventType; 10302 final DropBoxManager dbox = (DropBoxManager) 10303 mContext.getSystemService(Context.DROPBOX_SERVICE); 10304 10305 // Exit early if the dropbox isn't configured to accept this report type. 10306 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10307 10308 final StringBuilder sb = new StringBuilder(1024); 10309 appendDropBoxProcessHeaders(process, processName, sb); 10310 if (activity != null) { 10311 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10312 } 10313 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10314 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10315 } 10316 if (parent != null && parent != activity) { 10317 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10318 } 10319 if (subject != null) { 10320 sb.append("Subject: ").append(subject).append("\n"); 10321 } 10322 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10323 if (Debug.isDebuggerConnected()) { 10324 sb.append("Debugger: Connected\n"); 10325 } 10326 sb.append("\n"); 10327 10328 // Do the rest in a worker thread to avoid blocking the caller on I/O 10329 // (After this point, we shouldn't access AMS internal data structures.) 10330 Thread worker = new Thread("Error dump: " + dropboxTag) { 10331 @Override 10332 public void run() { 10333 if (report != null) { 10334 sb.append(report); 10335 } 10336 if (logFile != null) { 10337 try { 10338 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10339 "\n\n[[TRUNCATED]]")); 10340 } catch (IOException e) { 10341 Slog.e(TAG, "Error reading " + logFile, e); 10342 } 10343 } 10344 if (crashInfo != null && crashInfo.stackTrace != null) { 10345 sb.append(crashInfo.stackTrace); 10346 } 10347 10348 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10349 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10350 if (lines > 0) { 10351 sb.append("\n"); 10352 10353 // Merge several logcat streams, and take the last N lines 10354 InputStreamReader input = null; 10355 try { 10356 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10357 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10358 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10359 10360 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10361 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10362 input = new InputStreamReader(logcat.getInputStream()); 10363 10364 int num; 10365 char[] buf = new char[8192]; 10366 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10367 } catch (IOException e) { 10368 Slog.e(TAG, "Error running logcat", e); 10369 } finally { 10370 if (input != null) try { input.close(); } catch (IOException e) {} 10371 } 10372 } 10373 10374 dbox.addText(dropboxTag, sb.toString()); 10375 } 10376 }; 10377 10378 if (process == null) { 10379 // If process is null, we are being called from some internal code 10380 // and may be about to die -- run this synchronously. 10381 worker.run(); 10382 } else { 10383 worker.start(); 10384 } 10385 } 10386 10387 /** 10388 * Bring up the "unexpected error" dialog box for a crashing app. 10389 * Deal with edge cases (intercepts from instrumented applications, 10390 * ActivityController, error intent receivers, that sort of thing). 10391 * @param r the application crashing 10392 * @param crashInfo describing the failure 10393 */ 10394 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10395 long timeMillis = System.currentTimeMillis(); 10396 String shortMsg = crashInfo.exceptionClassName; 10397 String longMsg = crashInfo.exceptionMessage; 10398 String stackTrace = crashInfo.stackTrace; 10399 if (shortMsg != null && longMsg != null) { 10400 longMsg = shortMsg + ": " + longMsg; 10401 } else if (shortMsg != null) { 10402 longMsg = shortMsg; 10403 } 10404 10405 AppErrorResult result = new AppErrorResult(); 10406 synchronized (this) { 10407 if (mController != null) { 10408 try { 10409 String name = r != null ? r.processName : null; 10410 int pid = r != null ? r.pid : Binder.getCallingPid(); 10411 if (!mController.appCrashed(name, pid, 10412 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10413 Slog.w(TAG, "Force-killing crashed app " + name 10414 + " at watcher's request"); 10415 Process.killProcess(pid); 10416 return; 10417 } 10418 } catch (RemoteException e) { 10419 mController = null; 10420 Watchdog.getInstance().setActivityController(null); 10421 } 10422 } 10423 10424 final long origId = Binder.clearCallingIdentity(); 10425 10426 // If this process is running instrumentation, finish it. 10427 if (r != null && r.instrumentationClass != null) { 10428 Slog.w(TAG, "Error in app " + r.processName 10429 + " running instrumentation " + r.instrumentationClass + ":"); 10430 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10431 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10432 Bundle info = new Bundle(); 10433 info.putString("shortMsg", shortMsg); 10434 info.putString("longMsg", longMsg); 10435 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10436 Binder.restoreCallingIdentity(origId); 10437 return; 10438 } 10439 10440 // If we can't identify the process or it's already exceeded its crash quota, 10441 // quit right away without showing a crash dialog. 10442 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10443 Binder.restoreCallingIdentity(origId); 10444 return; 10445 } 10446 10447 Message msg = Message.obtain(); 10448 msg.what = SHOW_ERROR_MSG; 10449 HashMap data = new HashMap(); 10450 data.put("result", result); 10451 data.put("app", r); 10452 msg.obj = data; 10453 mHandler.sendMessage(msg); 10454 10455 Binder.restoreCallingIdentity(origId); 10456 } 10457 10458 int res = result.get(); 10459 10460 Intent appErrorIntent = null; 10461 synchronized (this) { 10462 if (r != null && !r.isolated) { 10463 // XXX Can't keep track of crash time for isolated processes, 10464 // since they don't have a persistent identity. 10465 mProcessCrashTimes.put(r.info.processName, r.uid, 10466 SystemClock.uptimeMillis()); 10467 } 10468 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10469 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10470 } 10471 } 10472 10473 if (appErrorIntent != null) { 10474 try { 10475 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10476 } catch (ActivityNotFoundException e) { 10477 Slog.w(TAG, "bug report receiver dissappeared", e); 10478 } 10479 } 10480 } 10481 10482 Intent createAppErrorIntentLocked(ProcessRecord r, 10483 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10484 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10485 if (report == null) { 10486 return null; 10487 } 10488 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10489 result.setComponent(r.errorReportReceiver); 10490 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10491 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10492 return result; 10493 } 10494 10495 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10496 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10497 if (r.errorReportReceiver == null) { 10498 return null; 10499 } 10500 10501 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10502 return null; 10503 } 10504 10505 ApplicationErrorReport report = new ApplicationErrorReport(); 10506 report.packageName = r.info.packageName; 10507 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10508 report.processName = r.processName; 10509 report.time = timeMillis; 10510 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10511 10512 if (r.crashing || r.forceCrashReport) { 10513 report.type = ApplicationErrorReport.TYPE_CRASH; 10514 report.crashInfo = crashInfo; 10515 } else if (r.notResponding) { 10516 report.type = ApplicationErrorReport.TYPE_ANR; 10517 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10518 10519 report.anrInfo.activity = r.notRespondingReport.tag; 10520 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10521 report.anrInfo.info = r.notRespondingReport.longMsg; 10522 } 10523 10524 return report; 10525 } 10526 10527 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10528 enforceNotIsolatedCaller("getProcessesInErrorState"); 10529 // assume our apps are happy - lazy create the list 10530 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10531 10532 final boolean allUsers = ActivityManager.checkUidPermission( 10533 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10534 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10535 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10536 10537 synchronized (this) { 10538 10539 // iterate across all processes 10540 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10541 ProcessRecord app = mLruProcesses.get(i); 10542 if (!allUsers && app.userId != userId) { 10543 continue; 10544 } 10545 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10546 // This one's in trouble, so we'll generate a report for it 10547 // crashes are higher priority (in case there's a crash *and* an anr) 10548 ActivityManager.ProcessErrorStateInfo report = null; 10549 if (app.crashing) { 10550 report = app.crashingReport; 10551 } else if (app.notResponding) { 10552 report = app.notRespondingReport; 10553 } 10554 10555 if (report != null) { 10556 if (errList == null) { 10557 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10558 } 10559 errList.add(report); 10560 } else { 10561 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10562 " crashing = " + app.crashing + 10563 " notResponding = " + app.notResponding); 10564 } 10565 } 10566 } 10567 } 10568 10569 return errList; 10570 } 10571 10572 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10573 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10574 if (currApp != null) { 10575 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10576 } 10577 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10578 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10579 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10580 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10581 if (currApp != null) { 10582 currApp.lru = 0; 10583 } 10584 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10585 } else if (adj >= ProcessList.SERVICE_ADJ) { 10586 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10587 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10588 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10589 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10590 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10591 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10592 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10593 } else { 10594 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10595 } 10596 } 10597 10598 private void fillInProcMemInfo(ProcessRecord app, 10599 ActivityManager.RunningAppProcessInfo outInfo) { 10600 outInfo.pid = app.pid; 10601 outInfo.uid = app.info.uid; 10602 if (mHeavyWeightProcess == app) { 10603 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10604 } 10605 if (app.persistent) { 10606 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10607 } 10608 if (app.activities.size() > 0) { 10609 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10610 } 10611 outInfo.lastTrimLevel = app.trimMemoryLevel; 10612 int adj = app.curAdj; 10613 outInfo.importance = oomAdjToImportance(adj, outInfo); 10614 outInfo.importanceReasonCode = app.adjTypeCode; 10615 outInfo.processState = app.curProcState; 10616 } 10617 10618 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10619 enforceNotIsolatedCaller("getRunningAppProcesses"); 10620 // Lazy instantiation of list 10621 List<ActivityManager.RunningAppProcessInfo> runList = null; 10622 final boolean allUsers = ActivityManager.checkUidPermission( 10623 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10624 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10625 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10626 synchronized (this) { 10627 // Iterate across all processes 10628 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10629 ProcessRecord app = mLruProcesses.get(i); 10630 if (!allUsers && app.userId != userId) { 10631 continue; 10632 } 10633 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10634 // Generate process state info for running application 10635 ActivityManager.RunningAppProcessInfo currApp = 10636 new ActivityManager.RunningAppProcessInfo(app.processName, 10637 app.pid, app.getPackageList()); 10638 fillInProcMemInfo(app, currApp); 10639 if (app.adjSource instanceof ProcessRecord) { 10640 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10641 currApp.importanceReasonImportance = oomAdjToImportance( 10642 app.adjSourceOom, null); 10643 } else if (app.adjSource instanceof ActivityRecord) { 10644 ActivityRecord r = (ActivityRecord)app.adjSource; 10645 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10646 } 10647 if (app.adjTarget instanceof ComponentName) { 10648 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10649 } 10650 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10651 // + " lru=" + currApp.lru); 10652 if (runList == null) { 10653 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10654 } 10655 runList.add(currApp); 10656 } 10657 } 10658 } 10659 return runList; 10660 } 10661 10662 public List<ApplicationInfo> getRunningExternalApplications() { 10663 enforceNotIsolatedCaller("getRunningExternalApplications"); 10664 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10665 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10666 if (runningApps != null && runningApps.size() > 0) { 10667 Set<String> extList = new HashSet<String>(); 10668 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10669 if (app.pkgList != null) { 10670 for (String pkg : app.pkgList) { 10671 extList.add(pkg); 10672 } 10673 } 10674 } 10675 IPackageManager pm = AppGlobals.getPackageManager(); 10676 for (String pkg : extList) { 10677 try { 10678 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10679 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10680 retList.add(info); 10681 } 10682 } catch (RemoteException e) { 10683 } 10684 } 10685 } 10686 return retList; 10687 } 10688 10689 @Override 10690 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10691 enforceNotIsolatedCaller("getMyMemoryState"); 10692 synchronized (this) { 10693 ProcessRecord proc; 10694 synchronized (mPidsSelfLocked) { 10695 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10696 } 10697 fillInProcMemInfo(proc, outInfo); 10698 } 10699 } 10700 10701 @Override 10702 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10703 if (checkCallingPermission(android.Manifest.permission.DUMP) 10704 != PackageManager.PERMISSION_GRANTED) { 10705 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10706 + Binder.getCallingPid() 10707 + ", uid=" + Binder.getCallingUid() 10708 + " without permission " 10709 + android.Manifest.permission.DUMP); 10710 return; 10711 } 10712 10713 boolean dumpAll = false; 10714 boolean dumpClient = false; 10715 String dumpPackage = null; 10716 10717 int opti = 0; 10718 while (opti < args.length) { 10719 String opt = args[opti]; 10720 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10721 break; 10722 } 10723 opti++; 10724 if ("-a".equals(opt)) { 10725 dumpAll = true; 10726 } else if ("-c".equals(opt)) { 10727 dumpClient = true; 10728 } else if ("-h".equals(opt)) { 10729 pw.println("Activity manager dump options:"); 10730 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10731 pw.println(" cmd may be one of:"); 10732 pw.println(" a[ctivities]: activity stack state"); 10733 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10734 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10735 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10736 pw.println(" o[om]: out of memory management"); 10737 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10738 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10739 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10740 pw.println(" service [COMP_SPEC]: service client-side state"); 10741 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10742 pw.println(" all: dump all activities"); 10743 pw.println(" top: dump the top activity"); 10744 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10745 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10746 pw.println(" a partial substring in a component name, a"); 10747 pw.println(" hex object identifier."); 10748 pw.println(" -a: include all available server state."); 10749 pw.println(" -c: include client state."); 10750 return; 10751 } else { 10752 pw.println("Unknown argument: " + opt + "; use -h for help"); 10753 } 10754 } 10755 10756 long origId = Binder.clearCallingIdentity(); 10757 boolean more = false; 10758 // Is the caller requesting to dump a particular piece of data? 10759 if (opti < args.length) { 10760 String cmd = args[opti]; 10761 opti++; 10762 if ("activities".equals(cmd) || "a".equals(cmd)) { 10763 synchronized (this) { 10764 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10765 } 10766 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10767 String[] newArgs; 10768 String name; 10769 if (opti >= args.length) { 10770 name = null; 10771 newArgs = EMPTY_STRING_ARRAY; 10772 } else { 10773 name = args[opti]; 10774 opti++; 10775 newArgs = new String[args.length - opti]; 10776 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10777 args.length - opti); 10778 } 10779 synchronized (this) { 10780 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10781 } 10782 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10783 String[] newArgs; 10784 String name; 10785 if (opti >= args.length) { 10786 name = null; 10787 newArgs = EMPTY_STRING_ARRAY; 10788 } else { 10789 name = args[opti]; 10790 opti++; 10791 newArgs = new String[args.length - opti]; 10792 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10793 args.length - opti); 10794 } 10795 synchronized (this) { 10796 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10797 } 10798 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10799 String[] newArgs; 10800 String name; 10801 if (opti >= args.length) { 10802 name = null; 10803 newArgs = EMPTY_STRING_ARRAY; 10804 } else { 10805 name = args[opti]; 10806 opti++; 10807 newArgs = new String[args.length - opti]; 10808 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10809 args.length - opti); 10810 } 10811 synchronized (this) { 10812 dumpProcessesLocked(fd, pw, args, opti, true, name); 10813 } 10814 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10815 synchronized (this) { 10816 dumpOomLocked(fd, pw, args, opti, true); 10817 } 10818 } else if ("provider".equals(cmd)) { 10819 String[] newArgs; 10820 String name; 10821 if (opti >= args.length) { 10822 name = null; 10823 newArgs = EMPTY_STRING_ARRAY; 10824 } else { 10825 name = args[opti]; 10826 opti++; 10827 newArgs = new String[args.length - opti]; 10828 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10829 } 10830 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10831 pw.println("No providers match: " + name); 10832 pw.println("Use -h for help."); 10833 } 10834 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10835 synchronized (this) { 10836 dumpProvidersLocked(fd, pw, args, opti, true, null); 10837 } 10838 } else if ("service".equals(cmd)) { 10839 String[] newArgs; 10840 String name; 10841 if (opti >= args.length) { 10842 name = null; 10843 newArgs = EMPTY_STRING_ARRAY; 10844 } else { 10845 name = args[opti]; 10846 opti++; 10847 newArgs = new String[args.length - opti]; 10848 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10849 args.length - opti); 10850 } 10851 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10852 pw.println("No services match: " + name); 10853 pw.println("Use -h for help."); 10854 } 10855 } else if ("package".equals(cmd)) { 10856 String[] newArgs; 10857 if (opti >= args.length) { 10858 pw.println("package: no package name specified"); 10859 pw.println("Use -h for help."); 10860 } else { 10861 dumpPackage = args[opti]; 10862 opti++; 10863 newArgs = new String[args.length - opti]; 10864 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10865 args.length - opti); 10866 args = newArgs; 10867 opti = 0; 10868 more = true; 10869 } 10870 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10871 synchronized (this) { 10872 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10873 } 10874 } else { 10875 // Dumping a single activity? 10876 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10877 pw.println("Bad activity command, or no activities match: " + cmd); 10878 pw.println("Use -h for help."); 10879 } 10880 } 10881 if (!more) { 10882 Binder.restoreCallingIdentity(origId); 10883 return; 10884 } 10885 } 10886 10887 // No piece of data specified, dump everything. 10888 synchronized (this) { 10889 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10890 pw.println(); 10891 if (dumpAll) { 10892 pw.println("-------------------------------------------------------------------------------"); 10893 } 10894 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10895 pw.println(); 10896 if (dumpAll) { 10897 pw.println("-------------------------------------------------------------------------------"); 10898 } 10899 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10900 pw.println(); 10901 if (dumpAll) { 10902 pw.println("-------------------------------------------------------------------------------"); 10903 } 10904 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10905 pw.println(); 10906 if (dumpAll) { 10907 pw.println("-------------------------------------------------------------------------------"); 10908 } 10909 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10910 pw.println(); 10911 if (dumpAll) { 10912 pw.println("-------------------------------------------------------------------------------"); 10913 } 10914 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10915 } 10916 Binder.restoreCallingIdentity(origId); 10917 } 10918 10919 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10920 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10921 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10922 10923 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10924 dumpPackage); 10925 boolean needSep = printedAnything; 10926 10927 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10928 dumpPackage, needSep, " mFocusedActivity: "); 10929 if (printed) { 10930 printedAnything = true; 10931 needSep = false; 10932 } 10933 10934 if (dumpPackage == null) { 10935 if (needSep) { 10936 pw.println(); 10937 } 10938 needSep = true; 10939 printedAnything = true; 10940 mStackSupervisor.dump(pw, " "); 10941 } 10942 10943 if (mRecentTasks.size() > 0) { 10944 boolean printedHeader = false; 10945 10946 final int N = mRecentTasks.size(); 10947 for (int i=0; i<N; i++) { 10948 TaskRecord tr = mRecentTasks.get(i); 10949 if (dumpPackage != null) { 10950 if (tr.realActivity == null || 10951 !dumpPackage.equals(tr.realActivity)) { 10952 continue; 10953 } 10954 } 10955 if (!printedHeader) { 10956 if (needSep) { 10957 pw.println(); 10958 } 10959 pw.println(" Recent tasks:"); 10960 printedHeader = true; 10961 printedAnything = true; 10962 } 10963 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10964 pw.println(tr); 10965 if (dumpAll) { 10966 mRecentTasks.get(i).dump(pw, " "); 10967 } 10968 } 10969 } 10970 10971 if (!printedAnything) { 10972 pw.println(" (nothing)"); 10973 } 10974 } 10975 10976 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10977 int opti, boolean dumpAll, String dumpPackage) { 10978 boolean needSep = false; 10979 boolean printedAnything = false; 10980 int numPers = 0; 10981 10982 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10983 10984 if (dumpAll) { 10985 final int NP = mProcessNames.getMap().size(); 10986 for (int ip=0; ip<NP; ip++) { 10987 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10988 final int NA = procs.size(); 10989 for (int ia=0; ia<NA; ia++) { 10990 ProcessRecord r = procs.valueAt(ia); 10991 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10992 continue; 10993 } 10994 if (!needSep) { 10995 pw.println(" All known processes:"); 10996 needSep = true; 10997 printedAnything = true; 10998 } 10999 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11000 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11001 pw.print(" "); pw.println(r); 11002 r.dump(pw, " "); 11003 if (r.persistent) { 11004 numPers++; 11005 } 11006 } 11007 } 11008 } 11009 11010 if (mIsolatedProcesses.size() > 0) { 11011 boolean printed = false; 11012 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11013 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11014 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11015 continue; 11016 } 11017 if (!printed) { 11018 if (needSep) { 11019 pw.println(); 11020 } 11021 pw.println(" Isolated process list (sorted by uid):"); 11022 printedAnything = true; 11023 printed = true; 11024 needSep = true; 11025 } 11026 pw.println(String.format("%sIsolated #%2d: %s", 11027 " ", i, r.toString())); 11028 } 11029 } 11030 11031 if (mLruProcesses.size() > 0) { 11032 if (needSep) { 11033 pw.println(); 11034 } 11035 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11036 pw.print(" total, non-act at "); 11037 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11038 pw.print(", non-svc at "); 11039 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11040 pw.println("):"); 11041 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11042 needSep = true; 11043 printedAnything = true; 11044 } 11045 11046 if (dumpAll || dumpPackage != null) { 11047 synchronized (mPidsSelfLocked) { 11048 boolean printed = false; 11049 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11050 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11051 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11052 continue; 11053 } 11054 if (!printed) { 11055 if (needSep) pw.println(); 11056 needSep = true; 11057 pw.println(" PID mappings:"); 11058 printed = true; 11059 printedAnything = true; 11060 } 11061 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11062 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11063 } 11064 } 11065 } 11066 11067 if (mForegroundProcesses.size() > 0) { 11068 synchronized (mPidsSelfLocked) { 11069 boolean printed = false; 11070 for (int i=0; i<mForegroundProcesses.size(); i++) { 11071 ProcessRecord r = mPidsSelfLocked.get( 11072 mForegroundProcesses.valueAt(i).pid); 11073 if (dumpPackage != null && (r == null 11074 || !r.pkgList.containsKey(dumpPackage))) { 11075 continue; 11076 } 11077 if (!printed) { 11078 if (needSep) pw.println(); 11079 needSep = true; 11080 pw.println(" Foreground Processes:"); 11081 printed = true; 11082 printedAnything = true; 11083 } 11084 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11085 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11086 } 11087 } 11088 } 11089 11090 if (mPersistentStartingProcesses.size() > 0) { 11091 if (needSep) pw.println(); 11092 needSep = true; 11093 printedAnything = true; 11094 pw.println(" Persisent processes that are starting:"); 11095 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11096 "Starting Norm", "Restarting PERS", dumpPackage); 11097 } 11098 11099 if (mRemovedProcesses.size() > 0) { 11100 if (needSep) pw.println(); 11101 needSep = true; 11102 printedAnything = true; 11103 pw.println(" Processes that are being removed:"); 11104 dumpProcessList(pw, this, mRemovedProcesses, " ", 11105 "Removed Norm", "Removed PERS", dumpPackage); 11106 } 11107 11108 if (mProcessesOnHold.size() > 0) { 11109 if (needSep) pw.println(); 11110 needSep = true; 11111 printedAnything = true; 11112 pw.println(" Processes that are on old until the system is ready:"); 11113 dumpProcessList(pw, this, mProcessesOnHold, " ", 11114 "OnHold Norm", "OnHold PERS", dumpPackage); 11115 } 11116 11117 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11118 11119 if (mProcessCrashTimes.getMap().size() > 0) { 11120 boolean printed = false; 11121 long now = SystemClock.uptimeMillis(); 11122 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11123 final int NP = pmap.size(); 11124 for (int ip=0; ip<NP; ip++) { 11125 String pname = pmap.keyAt(ip); 11126 SparseArray<Long> uids = pmap.valueAt(ip); 11127 final int N = uids.size(); 11128 for (int i=0; i<N; i++) { 11129 int puid = uids.keyAt(i); 11130 ProcessRecord r = mProcessNames.get(pname, puid); 11131 if (dumpPackage != null && (r == null 11132 || !r.pkgList.containsKey(dumpPackage))) { 11133 continue; 11134 } 11135 if (!printed) { 11136 if (needSep) pw.println(); 11137 needSep = true; 11138 pw.println(" Time since processes crashed:"); 11139 printed = true; 11140 printedAnything = true; 11141 } 11142 pw.print(" Process "); pw.print(pname); 11143 pw.print(" uid "); pw.print(puid); 11144 pw.print(": last crashed "); 11145 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11146 pw.println(" ago"); 11147 } 11148 } 11149 } 11150 11151 if (mBadProcesses.getMap().size() > 0) { 11152 boolean printed = false; 11153 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11154 final int NP = pmap.size(); 11155 for (int ip=0; ip<NP; ip++) { 11156 String pname = pmap.keyAt(ip); 11157 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11158 final int N = uids.size(); 11159 for (int i=0; i<N; i++) { 11160 int puid = uids.keyAt(i); 11161 ProcessRecord r = mProcessNames.get(pname, puid); 11162 if (dumpPackage != null && (r == null 11163 || !r.pkgList.containsKey(dumpPackage))) { 11164 continue; 11165 } 11166 if (!printed) { 11167 if (needSep) pw.println(); 11168 needSep = true; 11169 pw.println(" Bad processes:"); 11170 printedAnything = true; 11171 } 11172 BadProcessInfo info = uids.valueAt(i); 11173 pw.print(" Bad process "); pw.print(pname); 11174 pw.print(" uid "); pw.print(puid); 11175 pw.print(": crashed at time "); pw.println(info.time); 11176 if (info.shortMsg != null) { 11177 pw.print(" Short msg: "); pw.println(info.shortMsg); 11178 } 11179 if (info.longMsg != null) { 11180 pw.print(" Long msg: "); pw.println(info.longMsg); 11181 } 11182 if (info.stack != null) { 11183 pw.println(" Stack:"); 11184 int lastPos = 0; 11185 for (int pos=0; pos<info.stack.length(); pos++) { 11186 if (info.stack.charAt(pos) == '\n') { 11187 pw.print(" "); 11188 pw.write(info.stack, lastPos, pos-lastPos); 11189 pw.println(); 11190 lastPos = pos+1; 11191 } 11192 } 11193 if (lastPos < info.stack.length()) { 11194 pw.print(" "); 11195 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11196 pw.println(); 11197 } 11198 } 11199 } 11200 } 11201 } 11202 11203 if (dumpPackage == null) { 11204 pw.println(); 11205 needSep = false; 11206 pw.println(" mStartedUsers:"); 11207 for (int i=0; i<mStartedUsers.size(); i++) { 11208 UserStartedState uss = mStartedUsers.valueAt(i); 11209 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11210 pw.print(": "); uss.dump("", pw); 11211 } 11212 pw.print(" mStartedUserArray: ["); 11213 for (int i=0; i<mStartedUserArray.length; i++) { 11214 if (i > 0) pw.print(", "); 11215 pw.print(mStartedUserArray[i]); 11216 } 11217 pw.println("]"); 11218 pw.print(" mUserLru: ["); 11219 for (int i=0; i<mUserLru.size(); i++) { 11220 if (i > 0) pw.print(", "); 11221 pw.print(mUserLru.get(i)); 11222 } 11223 pw.println("]"); 11224 if (dumpAll) { 11225 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11226 } 11227 } 11228 if (mHomeProcess != null && (dumpPackage == null 11229 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11230 if (needSep) { 11231 pw.println(); 11232 needSep = false; 11233 } 11234 pw.println(" mHomeProcess: " + mHomeProcess); 11235 } 11236 if (mPreviousProcess != null && (dumpPackage == null 11237 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11238 if (needSep) { 11239 pw.println(); 11240 needSep = false; 11241 } 11242 pw.println(" mPreviousProcess: " + mPreviousProcess); 11243 } 11244 if (dumpAll) { 11245 StringBuilder sb = new StringBuilder(128); 11246 sb.append(" mPreviousProcessVisibleTime: "); 11247 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11248 pw.println(sb); 11249 } 11250 if (mHeavyWeightProcess != null && (dumpPackage == null 11251 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11252 if (needSep) { 11253 pw.println(); 11254 needSep = false; 11255 } 11256 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11257 } 11258 if (dumpPackage == null) { 11259 pw.println(" mConfiguration: " + mConfiguration); 11260 } 11261 if (dumpAll) { 11262 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11263 if (mCompatModePackages.getPackages().size() > 0) { 11264 boolean printed = false; 11265 for (Map.Entry<String, Integer> entry 11266 : mCompatModePackages.getPackages().entrySet()) { 11267 String pkg = entry.getKey(); 11268 int mode = entry.getValue(); 11269 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11270 continue; 11271 } 11272 if (!printed) { 11273 pw.println(" mScreenCompatPackages:"); 11274 printed = true; 11275 } 11276 pw.print(" "); pw.print(pkg); pw.print(": "); 11277 pw.print(mode); pw.println(); 11278 } 11279 } 11280 } 11281 if (dumpPackage == null) { 11282 if (mSleeping || mWentToSleep || mLockScreenShown) { 11283 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11284 + " mLockScreenShown " + mLockScreenShown); 11285 } 11286 if (mShuttingDown || mRunningVoice) { 11287 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11288 } 11289 } 11290 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11291 || mOrigWaitForDebugger) { 11292 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11293 || dumpPackage.equals(mOrigDebugApp)) { 11294 if (needSep) { 11295 pw.println(); 11296 needSep = false; 11297 } 11298 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11299 + " mDebugTransient=" + mDebugTransient 11300 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11301 } 11302 } 11303 if (mOpenGlTraceApp != null) { 11304 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11305 if (needSep) { 11306 pw.println(); 11307 needSep = false; 11308 } 11309 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11310 } 11311 } 11312 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11313 || mProfileFd != null) { 11314 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11315 if (needSep) { 11316 pw.println(); 11317 needSep = false; 11318 } 11319 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11320 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11321 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11322 + mAutoStopProfiler); 11323 } 11324 } 11325 if (dumpPackage == null) { 11326 if (mAlwaysFinishActivities || mController != null) { 11327 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11328 + " mController=" + mController); 11329 } 11330 if (dumpAll) { 11331 pw.println(" Total persistent processes: " + numPers); 11332 pw.println(" mProcessesReady=" + mProcessesReady 11333 + " mSystemReady=" + mSystemReady); 11334 pw.println(" mBooting=" + mBooting 11335 + " mBooted=" + mBooted 11336 + " mFactoryTest=" + mFactoryTest); 11337 pw.print(" mLastPowerCheckRealtime="); 11338 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11339 pw.println(""); 11340 pw.print(" mLastPowerCheckUptime="); 11341 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11342 pw.println(""); 11343 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11344 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11345 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11346 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11347 + " (" + mLruProcesses.size() + " total)" 11348 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11349 + " mNumServiceProcs=" + mNumServiceProcs 11350 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11351 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11352 + " mLastMemoryLevel" + mLastMemoryLevel 11353 + " mLastNumProcesses" + mLastNumProcesses); 11354 long now = SystemClock.uptimeMillis(); 11355 pw.print(" mLastIdleTime="); 11356 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11357 pw.print(" mLowRamSinceLastIdle="); 11358 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11359 pw.println(); 11360 } 11361 } 11362 11363 if (!printedAnything) { 11364 pw.println(" (nothing)"); 11365 } 11366 } 11367 11368 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11369 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11370 if (mProcessesToGc.size() > 0) { 11371 boolean printed = false; 11372 long now = SystemClock.uptimeMillis(); 11373 for (int i=0; i<mProcessesToGc.size(); i++) { 11374 ProcessRecord proc = mProcessesToGc.get(i); 11375 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11376 continue; 11377 } 11378 if (!printed) { 11379 if (needSep) pw.println(); 11380 needSep = true; 11381 pw.println(" Processes that are waiting to GC:"); 11382 printed = true; 11383 } 11384 pw.print(" Process "); pw.println(proc); 11385 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11386 pw.print(", last gced="); 11387 pw.print(now-proc.lastRequestedGc); 11388 pw.print(" ms ago, last lowMem="); 11389 pw.print(now-proc.lastLowMemory); 11390 pw.println(" ms ago"); 11391 11392 } 11393 } 11394 return needSep; 11395 } 11396 11397 void printOomLevel(PrintWriter pw, String name, int adj) { 11398 pw.print(" "); 11399 if (adj >= 0) { 11400 pw.print(' '); 11401 if (adj < 10) pw.print(' '); 11402 } else { 11403 if (adj > -10) pw.print(' '); 11404 } 11405 pw.print(adj); 11406 pw.print(": "); 11407 pw.print(name); 11408 pw.print(" ("); 11409 pw.print(mProcessList.getMemLevel(adj)/1024); 11410 pw.println(" kB)"); 11411 } 11412 11413 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11414 int opti, boolean dumpAll) { 11415 boolean needSep = false; 11416 11417 if (mLruProcesses.size() > 0) { 11418 if (needSep) pw.println(); 11419 needSep = true; 11420 pw.println(" OOM levels:"); 11421 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11422 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11423 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11424 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11425 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11426 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11427 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11428 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11429 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11430 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11431 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11432 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11433 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11434 11435 if (needSep) pw.println(); 11436 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11437 pw.print(" total, non-act at "); 11438 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11439 pw.print(", non-svc at "); 11440 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11441 pw.println("):"); 11442 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11443 needSep = true; 11444 } 11445 11446 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11447 11448 pw.println(); 11449 pw.println(" mHomeProcess: " + mHomeProcess); 11450 pw.println(" mPreviousProcess: " + mPreviousProcess); 11451 if (mHeavyWeightProcess != null) { 11452 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11453 } 11454 11455 return true; 11456 } 11457 11458 /** 11459 * There are three ways to call this: 11460 * - no provider specified: dump all the providers 11461 * - a flattened component name that matched an existing provider was specified as the 11462 * first arg: dump that one provider 11463 * - the first arg isn't the flattened component name of an existing provider: 11464 * dump all providers whose component contains the first arg as a substring 11465 */ 11466 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11467 int opti, boolean dumpAll) { 11468 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11469 } 11470 11471 static class ItemMatcher { 11472 ArrayList<ComponentName> components; 11473 ArrayList<String> strings; 11474 ArrayList<Integer> objects; 11475 boolean all; 11476 11477 ItemMatcher() { 11478 all = true; 11479 } 11480 11481 void build(String name) { 11482 ComponentName componentName = ComponentName.unflattenFromString(name); 11483 if (componentName != null) { 11484 if (components == null) { 11485 components = new ArrayList<ComponentName>(); 11486 } 11487 components.add(componentName); 11488 all = false; 11489 } else { 11490 int objectId = 0; 11491 // Not a '/' separated full component name; maybe an object ID? 11492 try { 11493 objectId = Integer.parseInt(name, 16); 11494 if (objects == null) { 11495 objects = new ArrayList<Integer>(); 11496 } 11497 objects.add(objectId); 11498 all = false; 11499 } catch (RuntimeException e) { 11500 // Not an integer; just do string match. 11501 if (strings == null) { 11502 strings = new ArrayList<String>(); 11503 } 11504 strings.add(name); 11505 all = false; 11506 } 11507 } 11508 } 11509 11510 int build(String[] args, int opti) { 11511 for (; opti<args.length; opti++) { 11512 String name = args[opti]; 11513 if ("--".equals(name)) { 11514 return opti+1; 11515 } 11516 build(name); 11517 } 11518 return opti; 11519 } 11520 11521 boolean match(Object object, ComponentName comp) { 11522 if (all) { 11523 return true; 11524 } 11525 if (components != null) { 11526 for (int i=0; i<components.size(); i++) { 11527 if (components.get(i).equals(comp)) { 11528 return true; 11529 } 11530 } 11531 } 11532 if (objects != null) { 11533 for (int i=0; i<objects.size(); i++) { 11534 if (System.identityHashCode(object) == objects.get(i)) { 11535 return true; 11536 } 11537 } 11538 } 11539 if (strings != null) { 11540 String flat = comp.flattenToString(); 11541 for (int i=0; i<strings.size(); i++) { 11542 if (flat.contains(strings.get(i))) { 11543 return true; 11544 } 11545 } 11546 } 11547 return false; 11548 } 11549 } 11550 11551 /** 11552 * There are three things that cmd can be: 11553 * - a flattened component name that matches an existing activity 11554 * - the cmd arg isn't the flattened component name of an existing activity: 11555 * dump all activity whose component contains the cmd as a substring 11556 * - A hex number of the ActivityRecord object instance. 11557 */ 11558 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11559 int opti, boolean dumpAll) { 11560 ArrayList<ActivityRecord> activities; 11561 11562 synchronized (this) { 11563 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11564 } 11565 11566 if (activities.size() <= 0) { 11567 return false; 11568 } 11569 11570 String[] newArgs = new String[args.length - opti]; 11571 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11572 11573 TaskRecord lastTask = null; 11574 boolean needSep = false; 11575 for (int i=activities.size()-1; i>=0; i--) { 11576 ActivityRecord r = activities.get(i); 11577 if (needSep) { 11578 pw.println(); 11579 } 11580 needSep = true; 11581 synchronized (this) { 11582 if (lastTask != r.task) { 11583 lastTask = r.task; 11584 pw.print("TASK "); pw.print(lastTask.affinity); 11585 pw.print(" id="); pw.println(lastTask.taskId); 11586 if (dumpAll) { 11587 lastTask.dump(pw, " "); 11588 } 11589 } 11590 } 11591 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11592 } 11593 return true; 11594 } 11595 11596 /** 11597 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11598 * there is a thread associated with the activity. 11599 */ 11600 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11601 final ActivityRecord r, String[] args, boolean dumpAll) { 11602 String innerPrefix = prefix + " "; 11603 synchronized (this) { 11604 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11605 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11606 pw.print(" pid="); 11607 if (r.app != null) pw.println(r.app.pid); 11608 else pw.println("(not running)"); 11609 if (dumpAll) { 11610 r.dump(pw, innerPrefix); 11611 } 11612 } 11613 if (r.app != null && r.app.thread != null) { 11614 // flush anything that is already in the PrintWriter since the thread is going 11615 // to write to the file descriptor directly 11616 pw.flush(); 11617 try { 11618 TransferPipe tp = new TransferPipe(); 11619 try { 11620 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11621 r.appToken, innerPrefix, args); 11622 tp.go(fd); 11623 } finally { 11624 tp.kill(); 11625 } 11626 } catch (IOException e) { 11627 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11628 } catch (RemoteException e) { 11629 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11630 } 11631 } 11632 } 11633 11634 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11635 int opti, boolean dumpAll, String dumpPackage) { 11636 boolean needSep = false; 11637 boolean onlyHistory = false; 11638 boolean printedAnything = false; 11639 11640 if ("history".equals(dumpPackage)) { 11641 if (opti < args.length && "-s".equals(args[opti])) { 11642 dumpAll = false; 11643 } 11644 onlyHistory = true; 11645 dumpPackage = null; 11646 } 11647 11648 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11649 if (!onlyHistory && dumpAll) { 11650 if (mRegisteredReceivers.size() > 0) { 11651 boolean printed = false; 11652 Iterator it = mRegisteredReceivers.values().iterator(); 11653 while (it.hasNext()) { 11654 ReceiverList r = (ReceiverList)it.next(); 11655 if (dumpPackage != null && (r.app == null || 11656 !dumpPackage.equals(r.app.info.packageName))) { 11657 continue; 11658 } 11659 if (!printed) { 11660 pw.println(" Registered Receivers:"); 11661 needSep = true; 11662 printed = true; 11663 printedAnything = true; 11664 } 11665 pw.print(" * "); pw.println(r); 11666 r.dump(pw, " "); 11667 } 11668 } 11669 11670 if (mReceiverResolver.dump(pw, needSep ? 11671 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11672 " ", dumpPackage, false)) { 11673 needSep = true; 11674 printedAnything = true; 11675 } 11676 } 11677 11678 for (BroadcastQueue q : mBroadcastQueues) { 11679 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11680 printedAnything |= needSep; 11681 } 11682 11683 needSep = true; 11684 11685 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11686 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11687 if (needSep) { 11688 pw.println(); 11689 } 11690 needSep = true; 11691 printedAnything = true; 11692 pw.print(" Sticky broadcasts for user "); 11693 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11694 StringBuilder sb = new StringBuilder(128); 11695 for (Map.Entry<String, ArrayList<Intent>> ent 11696 : mStickyBroadcasts.valueAt(user).entrySet()) { 11697 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11698 if (dumpAll) { 11699 pw.println(":"); 11700 ArrayList<Intent> intents = ent.getValue(); 11701 final int N = intents.size(); 11702 for (int i=0; i<N; i++) { 11703 sb.setLength(0); 11704 sb.append(" Intent: "); 11705 intents.get(i).toShortString(sb, false, true, false, false); 11706 pw.println(sb.toString()); 11707 Bundle bundle = intents.get(i).getExtras(); 11708 if (bundle != null) { 11709 pw.print(" "); 11710 pw.println(bundle.toString()); 11711 } 11712 } 11713 } else { 11714 pw.println(""); 11715 } 11716 } 11717 } 11718 } 11719 11720 if (!onlyHistory && dumpAll) { 11721 pw.println(); 11722 for (BroadcastQueue queue : mBroadcastQueues) { 11723 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11724 + queue.mBroadcastsScheduled); 11725 } 11726 pw.println(" mHandler:"); 11727 mHandler.dump(new PrintWriterPrinter(pw), " "); 11728 needSep = true; 11729 printedAnything = true; 11730 } 11731 11732 if (!printedAnything) { 11733 pw.println(" (nothing)"); 11734 } 11735 } 11736 11737 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11738 int opti, boolean dumpAll, String dumpPackage) { 11739 boolean needSep; 11740 boolean printedAnything = false; 11741 11742 ItemMatcher matcher = new ItemMatcher(); 11743 matcher.build(args, opti); 11744 11745 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11746 11747 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11748 printedAnything |= needSep; 11749 11750 if (mLaunchingProviders.size() > 0) { 11751 boolean printed = false; 11752 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11753 ContentProviderRecord r = mLaunchingProviders.get(i); 11754 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11755 continue; 11756 } 11757 if (!printed) { 11758 if (needSep) pw.println(); 11759 needSep = true; 11760 pw.println(" Launching content providers:"); 11761 printed = true; 11762 printedAnything = true; 11763 } 11764 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11765 pw.println(r); 11766 } 11767 } 11768 11769 if (mGrantedUriPermissions.size() > 0) { 11770 boolean printed = false; 11771 int dumpUid = -2; 11772 if (dumpPackage != null) { 11773 try { 11774 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11775 } catch (NameNotFoundException e) { 11776 dumpUid = -1; 11777 } 11778 } 11779 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11780 int uid = mGrantedUriPermissions.keyAt(i); 11781 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11782 continue; 11783 } 11784 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11785 if (!printed) { 11786 if (needSep) pw.println(); 11787 needSep = true; 11788 pw.println(" Granted Uri Permissions:"); 11789 printed = true; 11790 printedAnything = true; 11791 } 11792 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11793 for (UriPermission perm : perms.values()) { 11794 pw.print(" "); pw.println(perm); 11795 if (dumpAll) { 11796 perm.dump(pw, " "); 11797 } 11798 } 11799 } 11800 } 11801 11802 if (!printedAnything) { 11803 pw.println(" (nothing)"); 11804 } 11805 } 11806 11807 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11808 int opti, boolean dumpAll, String dumpPackage) { 11809 boolean printed = false; 11810 11811 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11812 11813 if (mIntentSenderRecords.size() > 0) { 11814 Iterator<WeakReference<PendingIntentRecord>> it 11815 = mIntentSenderRecords.values().iterator(); 11816 while (it.hasNext()) { 11817 WeakReference<PendingIntentRecord> ref = it.next(); 11818 PendingIntentRecord rec = ref != null ? ref.get(): null; 11819 if (dumpPackage != null && (rec == null 11820 || !dumpPackage.equals(rec.key.packageName))) { 11821 continue; 11822 } 11823 printed = true; 11824 if (rec != null) { 11825 pw.print(" * "); pw.println(rec); 11826 if (dumpAll) { 11827 rec.dump(pw, " "); 11828 } 11829 } else { 11830 pw.print(" * "); pw.println(ref); 11831 } 11832 } 11833 } 11834 11835 if (!printed) { 11836 pw.println(" (nothing)"); 11837 } 11838 } 11839 11840 private static final int dumpProcessList(PrintWriter pw, 11841 ActivityManagerService service, List list, 11842 String prefix, String normalLabel, String persistentLabel, 11843 String dumpPackage) { 11844 int numPers = 0; 11845 final int N = list.size()-1; 11846 for (int i=N; i>=0; i--) { 11847 ProcessRecord r = (ProcessRecord)list.get(i); 11848 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11849 continue; 11850 } 11851 pw.println(String.format("%s%s #%2d: %s", 11852 prefix, (r.persistent ? persistentLabel : normalLabel), 11853 i, r.toString())); 11854 if (r.persistent) { 11855 numPers++; 11856 } 11857 } 11858 return numPers; 11859 } 11860 11861 private static final boolean dumpProcessOomList(PrintWriter pw, 11862 ActivityManagerService service, List<ProcessRecord> origList, 11863 String prefix, String normalLabel, String persistentLabel, 11864 boolean inclDetails, String dumpPackage) { 11865 11866 ArrayList<Pair<ProcessRecord, Integer>> list 11867 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11868 for (int i=0; i<origList.size(); i++) { 11869 ProcessRecord r = origList.get(i); 11870 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11871 continue; 11872 } 11873 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11874 } 11875 11876 if (list.size() <= 0) { 11877 return false; 11878 } 11879 11880 Comparator<Pair<ProcessRecord, Integer>> comparator 11881 = new Comparator<Pair<ProcessRecord, Integer>>() { 11882 @Override 11883 public int compare(Pair<ProcessRecord, Integer> object1, 11884 Pair<ProcessRecord, Integer> object2) { 11885 if (object1.first.setAdj != object2.first.setAdj) { 11886 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11887 } 11888 if (object1.second.intValue() != object2.second.intValue()) { 11889 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11890 } 11891 return 0; 11892 } 11893 }; 11894 11895 Collections.sort(list, comparator); 11896 11897 final long curRealtime = SystemClock.elapsedRealtime(); 11898 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11899 final long curUptime = SystemClock.uptimeMillis(); 11900 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11901 11902 for (int i=list.size()-1; i>=0; i--) { 11903 ProcessRecord r = list.get(i).first; 11904 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11905 char schedGroup; 11906 switch (r.setSchedGroup) { 11907 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11908 schedGroup = 'B'; 11909 break; 11910 case Process.THREAD_GROUP_DEFAULT: 11911 schedGroup = 'F'; 11912 break; 11913 default: 11914 schedGroup = '?'; 11915 break; 11916 } 11917 char foreground; 11918 if (r.foregroundActivities) { 11919 foreground = 'A'; 11920 } else if (r.foregroundServices) { 11921 foreground = 'S'; 11922 } else { 11923 foreground = ' '; 11924 } 11925 String procState = ProcessList.makeProcStateString(r.curProcState); 11926 pw.print(prefix); 11927 pw.print(r.persistent ? persistentLabel : normalLabel); 11928 pw.print(" #"); 11929 int num = (origList.size()-1)-list.get(i).second; 11930 if (num < 10) pw.print(' '); 11931 pw.print(num); 11932 pw.print(": "); 11933 pw.print(oomAdj); 11934 pw.print(' '); 11935 pw.print(schedGroup); 11936 pw.print('/'); 11937 pw.print(foreground); 11938 pw.print('/'); 11939 pw.print(procState); 11940 pw.print(" trm:"); 11941 if (r.trimMemoryLevel < 10) pw.print(' '); 11942 pw.print(r.trimMemoryLevel); 11943 pw.print(' '); 11944 pw.print(r.toShortString()); 11945 pw.print(" ("); 11946 pw.print(r.adjType); 11947 pw.println(')'); 11948 if (r.adjSource != null || r.adjTarget != null) { 11949 pw.print(prefix); 11950 pw.print(" "); 11951 if (r.adjTarget instanceof ComponentName) { 11952 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11953 } else if (r.adjTarget != null) { 11954 pw.print(r.adjTarget.toString()); 11955 } else { 11956 pw.print("{null}"); 11957 } 11958 pw.print("<="); 11959 if (r.adjSource instanceof ProcessRecord) { 11960 pw.print("Proc{"); 11961 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11962 pw.println("}"); 11963 } else if (r.adjSource != null) { 11964 pw.println(r.adjSource.toString()); 11965 } else { 11966 pw.println("{null}"); 11967 } 11968 } 11969 if (inclDetails) { 11970 pw.print(prefix); 11971 pw.print(" "); 11972 pw.print("oom: max="); pw.print(r.maxAdj); 11973 pw.print(" curRaw="); pw.print(r.curRawAdj); 11974 pw.print(" setRaw="); pw.print(r.setRawAdj); 11975 pw.print(" cur="); pw.print(r.curAdj); 11976 pw.print(" set="); pw.println(r.setAdj); 11977 pw.print(prefix); 11978 pw.print(" "); 11979 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11980 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11981 pw.print(" lastPss="); pw.print(r.lastPss); 11982 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11983 pw.print(prefix); 11984 pw.print(" "); 11985 pw.print("keeping="); pw.print(r.keeping); 11986 pw.print(" cached="); pw.print(r.cached); 11987 pw.print(" empty="); pw.print(r.empty); 11988 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11989 11990 if (!r.keeping) { 11991 if (r.lastWakeTime != 0) { 11992 long wtime; 11993 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11994 synchronized (stats) { 11995 wtime = stats.getProcessWakeTime(r.info.uid, 11996 r.pid, curRealtime); 11997 } 11998 long timeUsed = wtime - r.lastWakeTime; 11999 pw.print(prefix); 12000 pw.print(" "); 12001 pw.print("keep awake over "); 12002 TimeUtils.formatDuration(realtimeSince, pw); 12003 pw.print(" used "); 12004 TimeUtils.formatDuration(timeUsed, pw); 12005 pw.print(" ("); 12006 pw.print((timeUsed*100)/realtimeSince); 12007 pw.println("%)"); 12008 } 12009 if (r.lastCpuTime != 0) { 12010 long timeUsed = r.curCpuTime - r.lastCpuTime; 12011 pw.print(prefix); 12012 pw.print(" "); 12013 pw.print("run cpu over "); 12014 TimeUtils.formatDuration(uptimeSince, pw); 12015 pw.print(" used "); 12016 TimeUtils.formatDuration(timeUsed, pw); 12017 pw.print(" ("); 12018 pw.print((timeUsed*100)/uptimeSince); 12019 pw.println("%)"); 12020 } 12021 } 12022 } 12023 } 12024 return true; 12025 } 12026 12027 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12028 ArrayList<ProcessRecord> procs; 12029 synchronized (this) { 12030 if (args != null && args.length > start 12031 && args[start].charAt(0) != '-') { 12032 procs = new ArrayList<ProcessRecord>(); 12033 int pid = -1; 12034 try { 12035 pid = Integer.parseInt(args[start]); 12036 } catch (NumberFormatException e) { 12037 } 12038 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12039 ProcessRecord proc = mLruProcesses.get(i); 12040 if (proc.pid == pid) { 12041 procs.add(proc); 12042 } else if (proc.processName.equals(args[start])) { 12043 procs.add(proc); 12044 } 12045 } 12046 if (procs.size() <= 0) { 12047 return null; 12048 } 12049 } else { 12050 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12051 } 12052 } 12053 return procs; 12054 } 12055 12056 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12057 PrintWriter pw, String[] args) { 12058 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12059 if (procs == null) { 12060 pw.println("No process found for: " + args[0]); 12061 return; 12062 } 12063 12064 long uptime = SystemClock.uptimeMillis(); 12065 long realtime = SystemClock.elapsedRealtime(); 12066 pw.println("Applications Graphics Acceleration Info:"); 12067 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12068 12069 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12070 ProcessRecord r = procs.get(i); 12071 if (r.thread != null) { 12072 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12073 pw.flush(); 12074 try { 12075 TransferPipe tp = new TransferPipe(); 12076 try { 12077 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12078 tp.go(fd); 12079 } finally { 12080 tp.kill(); 12081 } 12082 } catch (IOException e) { 12083 pw.println("Failure while dumping the app: " + r); 12084 pw.flush(); 12085 } catch (RemoteException e) { 12086 pw.println("Got a RemoteException while dumping the app " + r); 12087 pw.flush(); 12088 } 12089 } 12090 } 12091 } 12092 12093 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12094 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12095 if (procs == null) { 12096 pw.println("No process found for: " + args[0]); 12097 return; 12098 } 12099 12100 pw.println("Applications Database Info:"); 12101 12102 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12103 ProcessRecord r = procs.get(i); 12104 if (r.thread != null) { 12105 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12106 pw.flush(); 12107 try { 12108 TransferPipe tp = new TransferPipe(); 12109 try { 12110 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12111 tp.go(fd); 12112 } finally { 12113 tp.kill(); 12114 } 12115 } catch (IOException e) { 12116 pw.println("Failure while dumping the app: " + r); 12117 pw.flush(); 12118 } catch (RemoteException e) { 12119 pw.println("Got a RemoteException while dumping the app " + r); 12120 pw.flush(); 12121 } 12122 } 12123 } 12124 } 12125 12126 final static class MemItem { 12127 final boolean isProc; 12128 final String label; 12129 final String shortLabel; 12130 final long pss; 12131 final int id; 12132 final boolean hasActivities; 12133 ArrayList<MemItem> subitems; 12134 12135 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12136 boolean _hasActivities) { 12137 isProc = true; 12138 label = _label; 12139 shortLabel = _shortLabel; 12140 pss = _pss; 12141 id = _id; 12142 hasActivities = _hasActivities; 12143 } 12144 12145 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12146 isProc = false; 12147 label = _label; 12148 shortLabel = _shortLabel; 12149 pss = _pss; 12150 id = _id; 12151 hasActivities = false; 12152 } 12153 } 12154 12155 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12156 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12157 if (sort && !isCompact) { 12158 Collections.sort(items, new Comparator<MemItem>() { 12159 @Override 12160 public int compare(MemItem lhs, MemItem rhs) { 12161 if (lhs.pss < rhs.pss) { 12162 return 1; 12163 } else if (lhs.pss > rhs.pss) { 12164 return -1; 12165 } 12166 return 0; 12167 } 12168 }); 12169 } 12170 12171 for (int i=0; i<items.size(); i++) { 12172 MemItem mi = items.get(i); 12173 if (!isCompact) { 12174 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12175 } else if (mi.isProc) { 12176 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12177 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12178 pw.println(mi.hasActivities ? ",a" : ",e"); 12179 } else { 12180 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12181 pw.println(mi.pss); 12182 } 12183 if (mi.subitems != null) { 12184 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12185 true, isCompact); 12186 } 12187 } 12188 } 12189 12190 // These are in KB. 12191 static final long[] DUMP_MEM_BUCKETS = new long[] { 12192 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12193 120*1024, 160*1024, 200*1024, 12194 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12195 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12196 }; 12197 12198 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12199 boolean stackLike) { 12200 int start = label.lastIndexOf('.'); 12201 if (start >= 0) start++; 12202 else start = 0; 12203 int end = label.length(); 12204 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12205 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12206 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12207 out.append(bucket); 12208 out.append(stackLike ? "MB." : "MB "); 12209 out.append(label, start, end); 12210 return; 12211 } 12212 } 12213 out.append(memKB/1024); 12214 out.append(stackLike ? "MB." : "MB "); 12215 out.append(label, start, end); 12216 } 12217 12218 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12219 ProcessList.NATIVE_ADJ, 12220 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12221 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12222 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12223 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12224 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12225 }; 12226 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12227 "Native", 12228 "System", "Persistent", "Foreground", 12229 "Visible", "Perceptible", 12230 "Heavy Weight", "Backup", 12231 "A Services", "Home", 12232 "Previous", "B Services", "Cached" 12233 }; 12234 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12235 "native", 12236 "sys", "pers", "fore", 12237 "vis", "percept", 12238 "heavy", "backup", 12239 "servicea", "home", 12240 "prev", "serviceb", "cached" 12241 }; 12242 12243 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12244 long realtime, boolean isCheckinRequest, boolean isCompact) { 12245 if (isCheckinRequest || isCompact) { 12246 // short checkin version 12247 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12248 } else { 12249 pw.println("Applications Memory Usage (kB):"); 12250 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12251 } 12252 } 12253 12254 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12255 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12256 boolean dumpDetails = false; 12257 boolean dumpFullDetails = false; 12258 boolean dumpDalvik = false; 12259 boolean oomOnly = false; 12260 boolean isCompact = false; 12261 boolean localOnly = false; 12262 12263 int opti = 0; 12264 while (opti < args.length) { 12265 String opt = args[opti]; 12266 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12267 break; 12268 } 12269 opti++; 12270 if ("-a".equals(opt)) { 12271 dumpDetails = true; 12272 dumpFullDetails = true; 12273 dumpDalvik = true; 12274 } else if ("-d".equals(opt)) { 12275 dumpDalvik = true; 12276 } else if ("-c".equals(opt)) { 12277 isCompact = true; 12278 } else if ("--oom".equals(opt)) { 12279 oomOnly = true; 12280 } else if ("--local".equals(opt)) { 12281 localOnly = true; 12282 } else if ("-h".equals(opt)) { 12283 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12284 pw.println(" -a: include all available information for each process."); 12285 pw.println(" -d: include dalvik details when dumping process details."); 12286 pw.println(" -c: dump in a compact machine-parseable representation."); 12287 pw.println(" --oom: only show processes organized by oom adj."); 12288 pw.println(" --local: only collect details locally, don't call process."); 12289 pw.println("If [process] is specified it can be the name or "); 12290 pw.println("pid of a specific process to dump."); 12291 return; 12292 } else { 12293 pw.println("Unknown argument: " + opt + "; use -h for help"); 12294 } 12295 } 12296 12297 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12298 long uptime = SystemClock.uptimeMillis(); 12299 long realtime = SystemClock.elapsedRealtime(); 12300 final long[] tmpLong = new long[1]; 12301 12302 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12303 if (procs == null) { 12304 // No Java processes. Maybe they want to print a native process. 12305 if (args != null && args.length > opti 12306 && args[opti].charAt(0) != '-') { 12307 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12308 = new ArrayList<ProcessCpuTracker.Stats>(); 12309 updateCpuStatsNow(); 12310 int findPid = -1; 12311 try { 12312 findPid = Integer.parseInt(args[opti]); 12313 } catch (NumberFormatException e) { 12314 } 12315 synchronized (mProcessCpuThread) { 12316 final int N = mProcessCpuTracker.countStats(); 12317 for (int i=0; i<N; i++) { 12318 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12319 if (st.pid == findPid || (st.baseName != null 12320 && st.baseName.equals(args[opti]))) { 12321 nativeProcs.add(st); 12322 } 12323 } 12324 } 12325 if (nativeProcs.size() > 0) { 12326 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12327 isCompact); 12328 Debug.MemoryInfo mi = null; 12329 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12330 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12331 final int pid = r.pid; 12332 if (!isCheckinRequest && dumpDetails) { 12333 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12334 } 12335 if (mi == null) { 12336 mi = new Debug.MemoryInfo(); 12337 } 12338 if (dumpDetails || (!brief && !oomOnly)) { 12339 Debug.getMemoryInfo(pid, mi); 12340 } else { 12341 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12342 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12343 } 12344 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12345 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12346 if (isCheckinRequest) { 12347 pw.println(); 12348 } 12349 } 12350 return; 12351 } 12352 } 12353 pw.println("No process found for: " + args[opti]); 12354 return; 12355 } 12356 12357 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12358 dumpDetails = true; 12359 } 12360 12361 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12362 12363 String[] innerArgs = new String[args.length-opti]; 12364 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12365 12366 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12367 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12368 long nativePss=0, dalvikPss=0, otherPss=0; 12369 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12370 12371 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12372 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12373 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12374 12375 long totalPss = 0; 12376 long cachedPss = 0; 12377 12378 Debug.MemoryInfo mi = null; 12379 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12380 final ProcessRecord r = procs.get(i); 12381 final IApplicationThread thread; 12382 final int pid; 12383 final int oomAdj; 12384 final boolean hasActivities; 12385 synchronized (this) { 12386 thread = r.thread; 12387 pid = r.pid; 12388 oomAdj = r.getSetAdjWithServices(); 12389 hasActivities = r.activities.size() > 0; 12390 } 12391 if (thread != null) { 12392 if (!isCheckinRequest && dumpDetails) { 12393 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12394 } 12395 if (mi == null) { 12396 mi = new Debug.MemoryInfo(); 12397 } 12398 if (dumpDetails || (!brief && !oomOnly)) { 12399 Debug.getMemoryInfo(pid, mi); 12400 } else { 12401 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12402 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12403 } 12404 if (dumpDetails) { 12405 if (localOnly) { 12406 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12407 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12408 if (isCheckinRequest) { 12409 pw.println(); 12410 } 12411 } else { 12412 try { 12413 pw.flush(); 12414 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12415 dumpDalvik, innerArgs); 12416 } catch (RemoteException e) { 12417 if (!isCheckinRequest) { 12418 pw.println("Got RemoteException!"); 12419 pw.flush(); 12420 } 12421 } 12422 } 12423 } 12424 12425 final long myTotalPss = mi.getTotalPss(); 12426 final long myTotalUss = mi.getTotalUss(); 12427 12428 synchronized (this) { 12429 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12430 // Record this for posterity if the process has been stable. 12431 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12432 } 12433 } 12434 12435 if (!isCheckinRequest && mi != null) { 12436 totalPss += myTotalPss; 12437 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12438 (hasActivities ? " / activities)" : ")"), 12439 r.processName, myTotalPss, pid, hasActivities); 12440 procMems.add(pssItem); 12441 procMemsMap.put(pid, pssItem); 12442 12443 nativePss += mi.nativePss; 12444 dalvikPss += mi.dalvikPss; 12445 otherPss += mi.otherPss; 12446 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12447 long mem = mi.getOtherPss(j); 12448 miscPss[j] += mem; 12449 otherPss -= mem; 12450 } 12451 12452 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12453 cachedPss += myTotalPss; 12454 } 12455 12456 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12457 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12458 || oomIndex == (oomPss.length-1)) { 12459 oomPss[oomIndex] += myTotalPss; 12460 if (oomProcs[oomIndex] == null) { 12461 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12462 } 12463 oomProcs[oomIndex].add(pssItem); 12464 break; 12465 } 12466 } 12467 } 12468 } 12469 } 12470 12471 if (!isCheckinRequest && procs.size() > 1) { 12472 // If we are showing aggregations, also look for native processes to 12473 // include so that our aggregations are more accurate. 12474 updateCpuStatsNow(); 12475 synchronized (mProcessCpuThread) { 12476 final int N = mProcessCpuTracker.countStats(); 12477 for (int i=0; i<N; i++) { 12478 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12479 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12480 if (mi == null) { 12481 mi = new Debug.MemoryInfo(); 12482 } 12483 if (!brief && !oomOnly) { 12484 Debug.getMemoryInfo(st.pid, mi); 12485 } else { 12486 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12487 mi.nativePrivateDirty = (int)tmpLong[0]; 12488 } 12489 12490 final long myTotalPss = mi.getTotalPss(); 12491 totalPss += myTotalPss; 12492 12493 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12494 st.name, myTotalPss, st.pid, false); 12495 procMems.add(pssItem); 12496 12497 nativePss += mi.nativePss; 12498 dalvikPss += mi.dalvikPss; 12499 otherPss += mi.otherPss; 12500 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12501 long mem = mi.getOtherPss(j); 12502 miscPss[j] += mem; 12503 otherPss -= mem; 12504 } 12505 oomPss[0] += myTotalPss; 12506 if (oomProcs[0] == null) { 12507 oomProcs[0] = new ArrayList<MemItem>(); 12508 } 12509 oomProcs[0].add(pssItem); 12510 } 12511 } 12512 } 12513 12514 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12515 12516 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12517 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12518 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12519 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12520 String label = Debug.MemoryInfo.getOtherLabel(j); 12521 catMems.add(new MemItem(label, label, miscPss[j], j)); 12522 } 12523 12524 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12525 for (int j=0; j<oomPss.length; j++) { 12526 if (oomPss[j] != 0) { 12527 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12528 : DUMP_MEM_OOM_LABEL[j]; 12529 MemItem item = new MemItem(label, label, oomPss[j], 12530 DUMP_MEM_OOM_ADJ[j]); 12531 item.subitems = oomProcs[j]; 12532 oomMems.add(item); 12533 } 12534 } 12535 12536 if (!brief && !oomOnly && !isCompact) { 12537 pw.println(); 12538 pw.println("Total PSS by process:"); 12539 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12540 pw.println(); 12541 } 12542 if (!isCompact) { 12543 pw.println("Total PSS by OOM adjustment:"); 12544 } 12545 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12546 if (!brief && !oomOnly) { 12547 PrintWriter out = categoryPw != null ? categoryPw : pw; 12548 if (!isCompact) { 12549 out.println(); 12550 out.println("Total PSS by category:"); 12551 } 12552 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12553 } 12554 if (!isCompact) { 12555 pw.println(); 12556 } 12557 MemInfoReader memInfo = new MemInfoReader(); 12558 memInfo.readMemInfo(); 12559 if (!brief) { 12560 if (!isCompact) { 12561 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12562 pw.print(" kB (status "); 12563 switch (mLastMemoryLevel) { 12564 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12565 pw.println("normal)"); 12566 break; 12567 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12568 pw.println("moderate)"); 12569 break; 12570 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12571 pw.println("low)"); 12572 break; 12573 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12574 pw.println("critical)"); 12575 break; 12576 default: 12577 pw.print(mLastMemoryLevel); 12578 pw.println(")"); 12579 break; 12580 } 12581 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12582 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12583 pw.print(cachedPss); pw.print(" cached pss + "); 12584 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12585 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12586 } else { 12587 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12588 pw.print(cachedPss + memInfo.getCachedSizeKb() 12589 + memInfo.getFreeSizeKb()); pw.print(","); 12590 pw.println(totalPss - cachedPss); 12591 } 12592 } 12593 if (!isCompact) { 12594 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12595 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12596 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12597 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12598 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12599 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12600 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12601 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12602 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12603 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12604 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12605 } 12606 if (!brief) { 12607 if (memInfo.getZramTotalSizeKb() != 0) { 12608 if (!isCompact) { 12609 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12610 pw.print(" kB physical used for "); 12611 pw.print(memInfo.getSwapTotalSizeKb() 12612 - memInfo.getSwapFreeSizeKb()); 12613 pw.print(" kB in swap ("); 12614 pw.print(memInfo.getSwapTotalSizeKb()); 12615 pw.println(" kB total swap)"); 12616 } else { 12617 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12618 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12619 pw.println(memInfo.getSwapFreeSizeKb()); 12620 } 12621 } 12622 final int[] SINGLE_LONG_FORMAT = new int[] { 12623 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12624 }; 12625 long[] longOut = new long[1]; 12626 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12627 SINGLE_LONG_FORMAT, null, longOut, null); 12628 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12629 longOut[0] = 0; 12630 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12631 SINGLE_LONG_FORMAT, null, longOut, null); 12632 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12633 longOut[0] = 0; 12634 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12635 SINGLE_LONG_FORMAT, null, longOut, null); 12636 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12637 longOut[0] = 0; 12638 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12639 SINGLE_LONG_FORMAT, null, longOut, null); 12640 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12641 if (!isCompact) { 12642 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12643 pw.print(" KSM: "); pw.print(sharing); 12644 pw.print(" kB saved from shared "); 12645 pw.print(shared); pw.println(" kB"); 12646 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12647 pw.print(voltile); pw.println(" kB volatile"); 12648 } 12649 pw.print(" Tuning: "); 12650 pw.print(ActivityManager.staticGetMemoryClass()); 12651 pw.print(" (large "); 12652 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12653 pw.print("), oom "); 12654 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12655 pw.print(" kB"); 12656 pw.print(", restore limit "); 12657 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12658 pw.print(" kB"); 12659 if (ActivityManager.isLowRamDeviceStatic()) { 12660 pw.print(" (low-ram)"); 12661 } 12662 if (ActivityManager.isHighEndGfx()) { 12663 pw.print(" (high-end-gfx)"); 12664 } 12665 pw.println(); 12666 } else { 12667 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12668 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12669 pw.println(voltile); 12670 pw.print("tuning,"); 12671 pw.print(ActivityManager.staticGetMemoryClass()); 12672 pw.print(','); 12673 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12674 pw.print(','); 12675 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12676 if (ActivityManager.isLowRamDeviceStatic()) { 12677 pw.print(",low-ram"); 12678 } 12679 if (ActivityManager.isHighEndGfx()) { 12680 pw.print(",high-end-gfx"); 12681 } 12682 pw.println(); 12683 } 12684 } 12685 } 12686 } 12687 12688 /** 12689 * Searches array of arguments for the specified string 12690 * @param args array of argument strings 12691 * @param value value to search for 12692 * @return true if the value is contained in the array 12693 */ 12694 private static boolean scanArgs(String[] args, String value) { 12695 if (args != null) { 12696 for (String arg : args) { 12697 if (value.equals(arg)) { 12698 return true; 12699 } 12700 } 12701 } 12702 return false; 12703 } 12704 12705 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12706 ContentProviderRecord cpr, boolean always) { 12707 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12708 12709 if (!inLaunching || always) { 12710 synchronized (cpr) { 12711 cpr.launchingApp = null; 12712 cpr.notifyAll(); 12713 } 12714 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12715 String names[] = cpr.info.authority.split(";"); 12716 for (int j = 0; j < names.length; j++) { 12717 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12718 } 12719 } 12720 12721 for (int i=0; i<cpr.connections.size(); i++) { 12722 ContentProviderConnection conn = cpr.connections.get(i); 12723 if (conn.waiting) { 12724 // If this connection is waiting for the provider, then we don't 12725 // need to mess with its process unless we are always removing 12726 // or for some reason the provider is not currently launching. 12727 if (inLaunching && !always) { 12728 continue; 12729 } 12730 } 12731 ProcessRecord capp = conn.client; 12732 conn.dead = true; 12733 if (conn.stableCount > 0) { 12734 if (!capp.persistent && capp.thread != null 12735 && capp.pid != 0 12736 && capp.pid != MY_PID) { 12737 killUnneededProcessLocked(capp, "depends on provider " 12738 + cpr.name.flattenToShortString() 12739 + " in dying proc " + (proc != null ? proc.processName : "??")); 12740 } 12741 } else if (capp.thread != null && conn.provider.provider != null) { 12742 try { 12743 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12744 } catch (RemoteException e) { 12745 } 12746 // In the protocol here, we don't expect the client to correctly 12747 // clean up this connection, we'll just remove it. 12748 cpr.connections.remove(i); 12749 conn.client.conProviders.remove(conn); 12750 } 12751 } 12752 12753 if (inLaunching && always) { 12754 mLaunchingProviders.remove(cpr); 12755 } 12756 return inLaunching; 12757 } 12758 12759 /** 12760 * Main code for cleaning up a process when it has gone away. This is 12761 * called both as a result of the process dying, or directly when stopping 12762 * a process when running in single process mode. 12763 */ 12764 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12765 boolean restarting, boolean allowRestart, int index) { 12766 if (index >= 0) { 12767 removeLruProcessLocked(app); 12768 ProcessList.remove(app.pid); 12769 } 12770 12771 mProcessesToGc.remove(app); 12772 mPendingPssProcesses.remove(app); 12773 12774 // Dismiss any open dialogs. 12775 if (app.crashDialog != null && !app.forceCrashReport) { 12776 app.crashDialog.dismiss(); 12777 app.crashDialog = null; 12778 } 12779 if (app.anrDialog != null) { 12780 app.anrDialog.dismiss(); 12781 app.anrDialog = null; 12782 } 12783 if (app.waitDialog != null) { 12784 app.waitDialog.dismiss(); 12785 app.waitDialog = null; 12786 } 12787 12788 app.crashing = false; 12789 app.notResponding = false; 12790 12791 app.resetPackageList(mProcessStats); 12792 app.unlinkDeathRecipient(); 12793 app.makeInactive(mProcessStats); 12794 app.forcingToForeground = null; 12795 updateProcessForegroundLocked(app, false, false); 12796 app.foregroundActivities = false; 12797 app.hasShownUi = false; 12798 app.treatLikeActivity = false; 12799 app.hasAboveClient = false; 12800 app.hasClientActivities = false; 12801 12802 mServices.killServicesLocked(app, allowRestart); 12803 12804 boolean restart = false; 12805 12806 // Remove published content providers. 12807 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12808 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12809 final boolean always = app.bad || !allowRestart; 12810 if (removeDyingProviderLocked(app, cpr, always) || always) { 12811 // We left the provider in the launching list, need to 12812 // restart it. 12813 restart = true; 12814 } 12815 12816 cpr.provider = null; 12817 cpr.proc = null; 12818 } 12819 app.pubProviders.clear(); 12820 12821 // Take care of any launching providers waiting for this process. 12822 if (checkAppInLaunchingProvidersLocked(app, false)) { 12823 restart = true; 12824 } 12825 12826 // Unregister from connected content providers. 12827 if (!app.conProviders.isEmpty()) { 12828 for (int i=0; i<app.conProviders.size(); i++) { 12829 ContentProviderConnection conn = app.conProviders.get(i); 12830 conn.provider.connections.remove(conn); 12831 } 12832 app.conProviders.clear(); 12833 } 12834 12835 // At this point there may be remaining entries in mLaunchingProviders 12836 // where we were the only one waiting, so they are no longer of use. 12837 // Look for these and clean up if found. 12838 // XXX Commented out for now. Trying to figure out a way to reproduce 12839 // the actual situation to identify what is actually going on. 12840 if (false) { 12841 for (int i=0; i<mLaunchingProviders.size(); i++) { 12842 ContentProviderRecord cpr = (ContentProviderRecord) 12843 mLaunchingProviders.get(i); 12844 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12845 synchronized (cpr) { 12846 cpr.launchingApp = null; 12847 cpr.notifyAll(); 12848 } 12849 } 12850 } 12851 } 12852 12853 skipCurrentReceiverLocked(app); 12854 12855 // Unregister any receivers. 12856 for (int i=app.receivers.size()-1; i>=0; i--) { 12857 removeReceiverLocked(app.receivers.valueAt(i)); 12858 } 12859 app.receivers.clear(); 12860 12861 // If the app is undergoing backup, tell the backup manager about it 12862 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12863 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12864 + mBackupTarget.appInfo + " died during backup"); 12865 try { 12866 IBackupManager bm = IBackupManager.Stub.asInterface( 12867 ServiceManager.getService(Context.BACKUP_SERVICE)); 12868 bm.agentDisconnected(app.info.packageName); 12869 } catch (RemoteException e) { 12870 // can't happen; backup manager is local 12871 } 12872 } 12873 12874 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12875 ProcessChangeItem item = mPendingProcessChanges.get(i); 12876 if (item.pid == app.pid) { 12877 mPendingProcessChanges.remove(i); 12878 mAvailProcessChanges.add(item); 12879 } 12880 } 12881 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12882 12883 // If the caller is restarting this app, then leave it in its 12884 // current lists and let the caller take care of it. 12885 if (restarting) { 12886 return; 12887 } 12888 12889 if (!app.persistent || app.isolated) { 12890 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12891 "Removing non-persistent process during cleanup: " + app); 12892 mProcessNames.remove(app.processName, app.uid); 12893 mIsolatedProcesses.remove(app.uid); 12894 if (mHeavyWeightProcess == app) { 12895 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12896 mHeavyWeightProcess.userId, 0)); 12897 mHeavyWeightProcess = null; 12898 } 12899 } else if (!app.removed) { 12900 // This app is persistent, so we need to keep its record around. 12901 // If it is not already on the pending app list, add it there 12902 // and start a new process for it. 12903 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12904 mPersistentStartingProcesses.add(app); 12905 restart = true; 12906 } 12907 } 12908 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12909 "Clean-up removing on hold: " + app); 12910 mProcessesOnHold.remove(app); 12911 12912 if (app == mHomeProcess) { 12913 mHomeProcess = null; 12914 } 12915 if (app == mPreviousProcess) { 12916 mPreviousProcess = null; 12917 } 12918 12919 if (restart && !app.isolated) { 12920 // We have components that still need to be running in the 12921 // process, so re-launch it. 12922 mProcessNames.put(app.processName, app.uid, app); 12923 startProcessLocked(app, "restart", app.processName); 12924 } else if (app.pid > 0 && app.pid != MY_PID) { 12925 // Goodbye! 12926 boolean removed; 12927 synchronized (mPidsSelfLocked) { 12928 mPidsSelfLocked.remove(app.pid); 12929 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12930 } 12931 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12932 app.processName, app.info.uid); 12933 if (app.isolated) { 12934 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12935 } 12936 app.setPid(0); 12937 } 12938 } 12939 12940 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12941 // Look through the content providers we are waiting to have launched, 12942 // and if any run in this process then either schedule a restart of 12943 // the process or kill the client waiting for it if this process has 12944 // gone bad. 12945 int NL = mLaunchingProviders.size(); 12946 boolean restart = false; 12947 for (int i=0; i<NL; i++) { 12948 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12949 if (cpr.launchingApp == app) { 12950 if (!alwaysBad && !app.bad) { 12951 restart = true; 12952 } else { 12953 removeDyingProviderLocked(app, cpr, true); 12954 // cpr should have been removed from mLaunchingProviders 12955 NL = mLaunchingProviders.size(); 12956 i--; 12957 } 12958 } 12959 } 12960 return restart; 12961 } 12962 12963 // ========================================================= 12964 // SERVICES 12965 // ========================================================= 12966 12967 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12968 int flags) { 12969 enforceNotIsolatedCaller("getServices"); 12970 synchronized (this) { 12971 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12972 } 12973 } 12974 12975 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12976 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12977 synchronized (this) { 12978 return mServices.getRunningServiceControlPanelLocked(name); 12979 } 12980 } 12981 12982 public ComponentName startService(IApplicationThread caller, Intent service, 12983 String resolvedType, int userId) { 12984 enforceNotIsolatedCaller("startService"); 12985 // Refuse possible leaked file descriptors 12986 if (service != null && service.hasFileDescriptors() == true) { 12987 throw new IllegalArgumentException("File descriptors passed in Intent"); 12988 } 12989 12990 if (DEBUG_SERVICE) 12991 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12992 synchronized(this) { 12993 final int callingPid = Binder.getCallingPid(); 12994 final int callingUid = Binder.getCallingUid(); 12995 final long origId = Binder.clearCallingIdentity(); 12996 ComponentName res = mServices.startServiceLocked(caller, service, 12997 resolvedType, callingPid, callingUid, userId); 12998 Binder.restoreCallingIdentity(origId); 12999 return res; 13000 } 13001 } 13002 13003 ComponentName startServiceInPackage(int uid, 13004 Intent service, String resolvedType, int userId) { 13005 synchronized(this) { 13006 if (DEBUG_SERVICE) 13007 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13008 final long origId = Binder.clearCallingIdentity(); 13009 ComponentName res = mServices.startServiceLocked(null, service, 13010 resolvedType, -1, uid, userId); 13011 Binder.restoreCallingIdentity(origId); 13012 return res; 13013 } 13014 } 13015 13016 public int stopService(IApplicationThread caller, Intent service, 13017 String resolvedType, int userId) { 13018 enforceNotIsolatedCaller("stopService"); 13019 // Refuse possible leaked file descriptors 13020 if (service != null && service.hasFileDescriptors() == true) { 13021 throw new IllegalArgumentException("File descriptors passed in Intent"); 13022 } 13023 13024 synchronized(this) { 13025 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13026 } 13027 } 13028 13029 public IBinder peekService(Intent service, String resolvedType) { 13030 enforceNotIsolatedCaller("peekService"); 13031 // Refuse possible leaked file descriptors 13032 if (service != null && service.hasFileDescriptors() == true) { 13033 throw new IllegalArgumentException("File descriptors passed in Intent"); 13034 } 13035 synchronized(this) { 13036 return mServices.peekServiceLocked(service, resolvedType); 13037 } 13038 } 13039 13040 public boolean stopServiceToken(ComponentName className, IBinder token, 13041 int startId) { 13042 synchronized(this) { 13043 return mServices.stopServiceTokenLocked(className, token, startId); 13044 } 13045 } 13046 13047 public void setServiceForeground(ComponentName className, IBinder token, 13048 int id, Notification notification, boolean removeNotification) { 13049 synchronized(this) { 13050 mServices.setServiceForegroundLocked(className, token, id, notification, 13051 removeNotification); 13052 } 13053 } 13054 13055 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13056 boolean requireFull, String name, String callerPackage) { 13057 final int callingUserId = UserHandle.getUserId(callingUid); 13058 if (callingUserId != userId) { 13059 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13060 if ((requireFull || checkComponentPermission( 13061 android.Manifest.permission.INTERACT_ACROSS_USERS, 13062 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13063 && checkComponentPermission( 13064 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13065 callingPid, callingUid, -1, true) 13066 != PackageManager.PERMISSION_GRANTED) { 13067 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13068 // In this case, they would like to just execute as their 13069 // owner user instead of failing. 13070 userId = callingUserId; 13071 } else { 13072 StringBuilder builder = new StringBuilder(128); 13073 builder.append("Permission Denial: "); 13074 builder.append(name); 13075 if (callerPackage != null) { 13076 builder.append(" from "); 13077 builder.append(callerPackage); 13078 } 13079 builder.append(" asks to run as user "); 13080 builder.append(userId); 13081 builder.append(" but is calling from user "); 13082 builder.append(UserHandle.getUserId(callingUid)); 13083 builder.append("; this requires "); 13084 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13085 if (!requireFull) { 13086 builder.append(" or "); 13087 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13088 } 13089 String msg = builder.toString(); 13090 Slog.w(TAG, msg); 13091 throw new SecurityException(msg); 13092 } 13093 } 13094 } 13095 if (userId == UserHandle.USER_CURRENT 13096 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13097 // Note that we may be accessing this outside of a lock... 13098 // shouldn't be a big deal, if this is being called outside 13099 // of a locked context there is intrinsically a race with 13100 // the value the caller will receive and someone else changing it. 13101 userId = mCurrentUserId; 13102 } 13103 if (!allowAll && userId < 0) { 13104 throw new IllegalArgumentException( 13105 "Call does not support special user #" + userId); 13106 } 13107 } 13108 return userId; 13109 } 13110 13111 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13112 String className, int flags) { 13113 boolean result = false; 13114 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13115 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13116 if (ActivityManager.checkUidPermission( 13117 android.Manifest.permission.INTERACT_ACROSS_USERS, 13118 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13119 ComponentName comp = new ComponentName(aInfo.packageName, className); 13120 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13121 + " requests FLAG_SINGLE_USER, but app does not hold " 13122 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13123 Slog.w(TAG, msg); 13124 throw new SecurityException(msg); 13125 } 13126 result = true; 13127 } 13128 } else if (componentProcessName == aInfo.packageName) { 13129 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13130 } else if ("system".equals(componentProcessName)) { 13131 result = true; 13132 } 13133 if (DEBUG_MU) { 13134 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13135 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13136 } 13137 return result; 13138 } 13139 13140 public int bindService(IApplicationThread caller, IBinder token, 13141 Intent service, String resolvedType, 13142 IServiceConnection connection, int flags, int userId) { 13143 enforceNotIsolatedCaller("bindService"); 13144 // Refuse possible leaked file descriptors 13145 if (service != null && service.hasFileDescriptors() == true) { 13146 throw new IllegalArgumentException("File descriptors passed in Intent"); 13147 } 13148 13149 synchronized(this) { 13150 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13151 connection, flags, userId); 13152 } 13153 } 13154 13155 public boolean unbindService(IServiceConnection connection) { 13156 synchronized (this) { 13157 return mServices.unbindServiceLocked(connection); 13158 } 13159 } 13160 13161 public void publishService(IBinder token, Intent intent, IBinder service) { 13162 // Refuse possible leaked file descriptors 13163 if (intent != null && intent.hasFileDescriptors() == true) { 13164 throw new IllegalArgumentException("File descriptors passed in Intent"); 13165 } 13166 13167 synchronized(this) { 13168 if (!(token instanceof ServiceRecord)) { 13169 throw new IllegalArgumentException("Invalid service token"); 13170 } 13171 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13172 } 13173 } 13174 13175 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13176 // Refuse possible leaked file descriptors 13177 if (intent != null && intent.hasFileDescriptors() == true) { 13178 throw new IllegalArgumentException("File descriptors passed in Intent"); 13179 } 13180 13181 synchronized(this) { 13182 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13183 } 13184 } 13185 13186 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13187 synchronized(this) { 13188 if (!(token instanceof ServiceRecord)) { 13189 throw new IllegalArgumentException("Invalid service token"); 13190 } 13191 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13192 } 13193 } 13194 13195 // ========================================================= 13196 // BACKUP AND RESTORE 13197 // ========================================================= 13198 13199 // Cause the target app to be launched if necessary and its backup agent 13200 // instantiated. The backup agent will invoke backupAgentCreated() on the 13201 // activity manager to announce its creation. 13202 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13203 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13204 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13205 13206 synchronized(this) { 13207 // !!! TODO: currently no check here that we're already bound 13208 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13209 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13210 synchronized (stats) { 13211 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13212 } 13213 13214 // Backup agent is now in use, its package can't be stopped. 13215 try { 13216 AppGlobals.getPackageManager().setPackageStoppedState( 13217 app.packageName, false, UserHandle.getUserId(app.uid)); 13218 } catch (RemoteException e) { 13219 } catch (IllegalArgumentException e) { 13220 Slog.w(TAG, "Failed trying to unstop package " 13221 + app.packageName + ": " + e); 13222 } 13223 13224 BackupRecord r = new BackupRecord(ss, app, backupMode); 13225 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13226 ? new ComponentName(app.packageName, app.backupAgentName) 13227 : new ComponentName("android", "FullBackupAgent"); 13228 // startProcessLocked() returns existing proc's record if it's already running 13229 ProcessRecord proc = startProcessLocked(app.processName, app, 13230 false, 0, "backup", hostingName, false, false, false); 13231 if (proc == null) { 13232 Slog.e(TAG, "Unable to start backup agent process " + r); 13233 return false; 13234 } 13235 13236 r.app = proc; 13237 mBackupTarget = r; 13238 mBackupAppName = app.packageName; 13239 13240 // Try not to kill the process during backup 13241 updateOomAdjLocked(proc); 13242 13243 // If the process is already attached, schedule the creation of the backup agent now. 13244 // If it is not yet live, this will be done when it attaches to the framework. 13245 if (proc.thread != null) { 13246 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13247 try { 13248 proc.thread.scheduleCreateBackupAgent(app, 13249 compatibilityInfoForPackageLocked(app), backupMode); 13250 } catch (RemoteException e) { 13251 // Will time out on the backup manager side 13252 } 13253 } else { 13254 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13255 } 13256 // Invariants: at this point, the target app process exists and the application 13257 // is either already running or in the process of coming up. mBackupTarget and 13258 // mBackupAppName describe the app, so that when it binds back to the AM we 13259 // know that it's scheduled for a backup-agent operation. 13260 } 13261 13262 return true; 13263 } 13264 13265 @Override 13266 public void clearPendingBackup() { 13267 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13268 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13269 13270 synchronized (this) { 13271 mBackupTarget = null; 13272 mBackupAppName = null; 13273 } 13274 } 13275 13276 // A backup agent has just come up 13277 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13278 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13279 + " = " + agent); 13280 13281 synchronized(this) { 13282 if (!agentPackageName.equals(mBackupAppName)) { 13283 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13284 return; 13285 } 13286 } 13287 13288 long oldIdent = Binder.clearCallingIdentity(); 13289 try { 13290 IBackupManager bm = IBackupManager.Stub.asInterface( 13291 ServiceManager.getService(Context.BACKUP_SERVICE)); 13292 bm.agentConnected(agentPackageName, agent); 13293 } catch (RemoteException e) { 13294 // can't happen; the backup manager service is local 13295 } catch (Exception e) { 13296 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13297 e.printStackTrace(); 13298 } finally { 13299 Binder.restoreCallingIdentity(oldIdent); 13300 } 13301 } 13302 13303 // done with this agent 13304 public void unbindBackupAgent(ApplicationInfo appInfo) { 13305 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13306 if (appInfo == null) { 13307 Slog.w(TAG, "unbind backup agent for null app"); 13308 return; 13309 } 13310 13311 synchronized(this) { 13312 try { 13313 if (mBackupAppName == null) { 13314 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13315 return; 13316 } 13317 13318 if (!mBackupAppName.equals(appInfo.packageName)) { 13319 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13320 return; 13321 } 13322 13323 // Not backing this app up any more; reset its OOM adjustment 13324 final ProcessRecord proc = mBackupTarget.app; 13325 updateOomAdjLocked(proc); 13326 13327 // If the app crashed during backup, 'thread' will be null here 13328 if (proc.thread != null) { 13329 try { 13330 proc.thread.scheduleDestroyBackupAgent(appInfo, 13331 compatibilityInfoForPackageLocked(appInfo)); 13332 } catch (Exception e) { 13333 Slog.e(TAG, "Exception when unbinding backup agent:"); 13334 e.printStackTrace(); 13335 } 13336 } 13337 } finally { 13338 mBackupTarget = null; 13339 mBackupAppName = null; 13340 } 13341 } 13342 } 13343 // ========================================================= 13344 // BROADCASTS 13345 // ========================================================= 13346 13347 private final List getStickiesLocked(String action, IntentFilter filter, 13348 List cur, int userId) { 13349 final ContentResolver resolver = mContext.getContentResolver(); 13350 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13351 if (stickies == null) { 13352 return cur; 13353 } 13354 final ArrayList<Intent> list = stickies.get(action); 13355 if (list == null) { 13356 return cur; 13357 } 13358 int N = list.size(); 13359 for (int i=0; i<N; i++) { 13360 Intent intent = list.get(i); 13361 if (filter.match(resolver, intent, true, TAG) >= 0) { 13362 if (cur == null) { 13363 cur = new ArrayList<Intent>(); 13364 } 13365 cur.add(intent); 13366 } 13367 } 13368 return cur; 13369 } 13370 13371 boolean isPendingBroadcastProcessLocked(int pid) { 13372 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13373 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13374 } 13375 13376 void skipPendingBroadcastLocked(int pid) { 13377 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13378 for (BroadcastQueue queue : mBroadcastQueues) { 13379 queue.skipPendingBroadcastLocked(pid); 13380 } 13381 } 13382 13383 // The app just attached; send any pending broadcasts that it should receive 13384 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13385 boolean didSomething = false; 13386 for (BroadcastQueue queue : mBroadcastQueues) { 13387 didSomething |= queue.sendPendingBroadcastsLocked(app); 13388 } 13389 return didSomething; 13390 } 13391 13392 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13393 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13394 enforceNotIsolatedCaller("registerReceiver"); 13395 int callingUid; 13396 int callingPid; 13397 synchronized(this) { 13398 ProcessRecord callerApp = null; 13399 if (caller != null) { 13400 callerApp = getRecordForAppLocked(caller); 13401 if (callerApp == null) { 13402 throw new SecurityException( 13403 "Unable to find app for caller " + caller 13404 + " (pid=" + Binder.getCallingPid() 13405 + ") when registering receiver " + receiver); 13406 } 13407 if (callerApp.info.uid != Process.SYSTEM_UID && 13408 !callerApp.pkgList.containsKey(callerPackage) && 13409 !"android".equals(callerPackage)) { 13410 throw new SecurityException("Given caller package " + callerPackage 13411 + " is not running in process " + callerApp); 13412 } 13413 callingUid = callerApp.info.uid; 13414 callingPid = callerApp.pid; 13415 } else { 13416 callerPackage = null; 13417 callingUid = Binder.getCallingUid(); 13418 callingPid = Binder.getCallingPid(); 13419 } 13420 13421 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13422 true, true, "registerReceiver", callerPackage); 13423 13424 List allSticky = null; 13425 13426 // Look for any matching sticky broadcasts... 13427 Iterator actions = filter.actionsIterator(); 13428 if (actions != null) { 13429 while (actions.hasNext()) { 13430 String action = (String)actions.next(); 13431 allSticky = getStickiesLocked(action, filter, allSticky, 13432 UserHandle.USER_ALL); 13433 allSticky = getStickiesLocked(action, filter, allSticky, 13434 UserHandle.getUserId(callingUid)); 13435 } 13436 } else { 13437 allSticky = getStickiesLocked(null, filter, allSticky, 13438 UserHandle.USER_ALL); 13439 allSticky = getStickiesLocked(null, filter, allSticky, 13440 UserHandle.getUserId(callingUid)); 13441 } 13442 13443 // The first sticky in the list is returned directly back to 13444 // the client. 13445 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13446 13447 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13448 + ": " + sticky); 13449 13450 if (receiver == null) { 13451 return sticky; 13452 } 13453 13454 ReceiverList rl 13455 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13456 if (rl == null) { 13457 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13458 userId, receiver); 13459 if (rl.app != null) { 13460 rl.app.receivers.add(rl); 13461 } else { 13462 try { 13463 receiver.asBinder().linkToDeath(rl, 0); 13464 } catch (RemoteException e) { 13465 return sticky; 13466 } 13467 rl.linkedToDeath = true; 13468 } 13469 mRegisteredReceivers.put(receiver.asBinder(), rl); 13470 } else if (rl.uid != callingUid) { 13471 throw new IllegalArgumentException( 13472 "Receiver requested to register for uid " + callingUid 13473 + " was previously registered for uid " + rl.uid); 13474 } else if (rl.pid != callingPid) { 13475 throw new IllegalArgumentException( 13476 "Receiver requested to register for pid " + callingPid 13477 + " was previously registered for pid " + rl.pid); 13478 } else if (rl.userId != userId) { 13479 throw new IllegalArgumentException( 13480 "Receiver requested to register for user " + userId 13481 + " was previously registered for user " + rl.userId); 13482 } 13483 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13484 permission, callingUid, userId); 13485 rl.add(bf); 13486 if (!bf.debugCheck()) { 13487 Slog.w(TAG, "==> For Dynamic broadast"); 13488 } 13489 mReceiverResolver.addFilter(bf); 13490 13491 // Enqueue broadcasts for all existing stickies that match 13492 // this filter. 13493 if (allSticky != null) { 13494 ArrayList receivers = new ArrayList(); 13495 receivers.add(bf); 13496 13497 int N = allSticky.size(); 13498 for (int i=0; i<N; i++) { 13499 Intent intent = (Intent)allSticky.get(i); 13500 BroadcastQueue queue = broadcastQueueForIntent(intent); 13501 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13502 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13503 null, null, false, true, true, -1); 13504 queue.enqueueParallelBroadcastLocked(r); 13505 queue.scheduleBroadcastsLocked(); 13506 } 13507 } 13508 13509 return sticky; 13510 } 13511 } 13512 13513 public void unregisterReceiver(IIntentReceiver receiver) { 13514 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13515 13516 final long origId = Binder.clearCallingIdentity(); 13517 try { 13518 boolean doTrim = false; 13519 13520 synchronized(this) { 13521 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13522 if (rl != null) { 13523 if (rl.curBroadcast != null) { 13524 BroadcastRecord r = rl.curBroadcast; 13525 final boolean doNext = finishReceiverLocked( 13526 receiver.asBinder(), r.resultCode, r.resultData, 13527 r.resultExtras, r.resultAbort); 13528 if (doNext) { 13529 doTrim = true; 13530 r.queue.processNextBroadcast(false); 13531 } 13532 } 13533 13534 if (rl.app != null) { 13535 rl.app.receivers.remove(rl); 13536 } 13537 removeReceiverLocked(rl); 13538 if (rl.linkedToDeath) { 13539 rl.linkedToDeath = false; 13540 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13541 } 13542 } 13543 } 13544 13545 // If we actually concluded any broadcasts, we might now be able 13546 // to trim the recipients' apps from our working set 13547 if (doTrim) { 13548 trimApplications(); 13549 return; 13550 } 13551 13552 } finally { 13553 Binder.restoreCallingIdentity(origId); 13554 } 13555 } 13556 13557 void removeReceiverLocked(ReceiverList rl) { 13558 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13559 int N = rl.size(); 13560 for (int i=0; i<N; i++) { 13561 mReceiverResolver.removeFilter(rl.get(i)); 13562 } 13563 } 13564 13565 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13566 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13567 ProcessRecord r = mLruProcesses.get(i); 13568 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13569 try { 13570 r.thread.dispatchPackageBroadcast(cmd, packages); 13571 } catch (RemoteException ex) { 13572 } 13573 } 13574 } 13575 } 13576 13577 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13578 int[] users) { 13579 List<ResolveInfo> receivers = null; 13580 try { 13581 HashSet<ComponentName> singleUserReceivers = null; 13582 boolean scannedFirstReceivers = false; 13583 for (int user : users) { 13584 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13585 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13586 if (user != 0 && newReceivers != null) { 13587 // If this is not the primary user, we need to check for 13588 // any receivers that should be filtered out. 13589 for (int i=0; i<newReceivers.size(); i++) { 13590 ResolveInfo ri = newReceivers.get(i); 13591 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13592 newReceivers.remove(i); 13593 i--; 13594 } 13595 } 13596 } 13597 if (newReceivers != null && newReceivers.size() == 0) { 13598 newReceivers = null; 13599 } 13600 if (receivers == null) { 13601 receivers = newReceivers; 13602 } else if (newReceivers != null) { 13603 // We need to concatenate the additional receivers 13604 // found with what we have do far. This would be easy, 13605 // but we also need to de-dup any receivers that are 13606 // singleUser. 13607 if (!scannedFirstReceivers) { 13608 // Collect any single user receivers we had already retrieved. 13609 scannedFirstReceivers = true; 13610 for (int i=0; i<receivers.size(); i++) { 13611 ResolveInfo ri = receivers.get(i); 13612 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13613 ComponentName cn = new ComponentName( 13614 ri.activityInfo.packageName, ri.activityInfo.name); 13615 if (singleUserReceivers == null) { 13616 singleUserReceivers = new HashSet<ComponentName>(); 13617 } 13618 singleUserReceivers.add(cn); 13619 } 13620 } 13621 } 13622 // Add the new results to the existing results, tracking 13623 // and de-dupping single user receivers. 13624 for (int i=0; i<newReceivers.size(); i++) { 13625 ResolveInfo ri = newReceivers.get(i); 13626 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13627 ComponentName cn = new ComponentName( 13628 ri.activityInfo.packageName, ri.activityInfo.name); 13629 if (singleUserReceivers == null) { 13630 singleUserReceivers = new HashSet<ComponentName>(); 13631 } 13632 if (!singleUserReceivers.contains(cn)) { 13633 singleUserReceivers.add(cn); 13634 receivers.add(ri); 13635 } 13636 } else { 13637 receivers.add(ri); 13638 } 13639 } 13640 } 13641 } 13642 } catch (RemoteException ex) { 13643 // pm is in same process, this will never happen. 13644 } 13645 return receivers; 13646 } 13647 13648 private final int broadcastIntentLocked(ProcessRecord callerApp, 13649 String callerPackage, Intent intent, String resolvedType, 13650 IIntentReceiver resultTo, int resultCode, String resultData, 13651 Bundle map, String requiredPermission, int appOp, 13652 boolean ordered, boolean sticky, int callingPid, int callingUid, 13653 int userId) { 13654 intent = new Intent(intent); 13655 13656 // By default broadcasts do not go to stopped apps. 13657 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13658 13659 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13660 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13661 + " ordered=" + ordered + " userid=" + userId); 13662 if ((resultTo != null) && !ordered) { 13663 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13664 } 13665 13666 userId = handleIncomingUser(callingPid, callingUid, userId, 13667 true, false, "broadcast", callerPackage); 13668 13669 // Make sure that the user who is receiving this broadcast is started. 13670 // If not, we will just skip it. 13671 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13672 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13673 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13674 Slog.w(TAG, "Skipping broadcast of " + intent 13675 + ": user " + userId + " is stopped"); 13676 return ActivityManager.BROADCAST_SUCCESS; 13677 } 13678 } 13679 13680 /* 13681 * Prevent non-system code (defined here to be non-persistent 13682 * processes) from sending protected broadcasts. 13683 */ 13684 int callingAppId = UserHandle.getAppId(callingUid); 13685 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13686 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13687 callingUid == 0) { 13688 // Always okay. 13689 } else if (callerApp == null || !callerApp.persistent) { 13690 try { 13691 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13692 intent.getAction())) { 13693 String msg = "Permission Denial: not allowed to send broadcast " 13694 + intent.getAction() + " from pid=" 13695 + callingPid + ", uid=" + callingUid; 13696 Slog.w(TAG, msg); 13697 throw new SecurityException(msg); 13698 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13699 // Special case for compatibility: we don't want apps to send this, 13700 // but historically it has not been protected and apps may be using it 13701 // to poke their own app widget. So, instead of making it protected, 13702 // just limit it to the caller. 13703 if (callerApp == null) { 13704 String msg = "Permission Denial: not allowed to send broadcast " 13705 + intent.getAction() + " from unknown caller."; 13706 Slog.w(TAG, msg); 13707 throw new SecurityException(msg); 13708 } else if (intent.getComponent() != null) { 13709 // They are good enough to send to an explicit component... verify 13710 // it is being sent to the calling app. 13711 if (!intent.getComponent().getPackageName().equals( 13712 callerApp.info.packageName)) { 13713 String msg = "Permission Denial: not allowed to send broadcast " 13714 + intent.getAction() + " to " 13715 + intent.getComponent().getPackageName() + " from " 13716 + callerApp.info.packageName; 13717 Slog.w(TAG, msg); 13718 throw new SecurityException(msg); 13719 } 13720 } else { 13721 // Limit broadcast to their own package. 13722 intent.setPackage(callerApp.info.packageName); 13723 } 13724 } 13725 } catch (RemoteException e) { 13726 Slog.w(TAG, "Remote exception", e); 13727 return ActivityManager.BROADCAST_SUCCESS; 13728 } 13729 } 13730 13731 // Handle special intents: if this broadcast is from the package 13732 // manager about a package being removed, we need to remove all of 13733 // its activities from the history stack. 13734 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13735 intent.getAction()); 13736 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13737 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13738 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13739 || uidRemoved) { 13740 if (checkComponentPermission( 13741 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13742 callingPid, callingUid, -1, true) 13743 == PackageManager.PERMISSION_GRANTED) { 13744 if (uidRemoved) { 13745 final Bundle intentExtras = intent.getExtras(); 13746 final int uid = intentExtras != null 13747 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13748 if (uid >= 0) { 13749 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13750 synchronized (bs) { 13751 bs.removeUidStatsLocked(uid); 13752 } 13753 mAppOpsService.uidRemoved(uid); 13754 } 13755 } else { 13756 // If resources are unavailable just force stop all 13757 // those packages and flush the attribute cache as well. 13758 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13759 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13760 if (list != null && (list.length > 0)) { 13761 for (String pkg : list) { 13762 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13763 "storage unmount"); 13764 } 13765 sendPackageBroadcastLocked( 13766 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13767 } 13768 } else { 13769 Uri data = intent.getData(); 13770 String ssp; 13771 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13772 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13773 intent.getAction()); 13774 boolean fullUninstall = removed && 13775 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13776 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13777 forceStopPackageLocked(ssp, UserHandle.getAppId( 13778 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13779 false, fullUninstall, userId, 13780 removed ? "pkg removed" : "pkg changed"); 13781 } 13782 if (removed) { 13783 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13784 new String[] {ssp}, userId); 13785 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13786 mAppOpsService.packageRemoved( 13787 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13788 13789 // Remove all permissions granted from/to this package 13790 removeUriPermissionsForPackageLocked(ssp, userId, true); 13791 } 13792 } 13793 } 13794 } 13795 } 13796 } else { 13797 String msg = "Permission Denial: " + intent.getAction() 13798 + " broadcast from " + callerPackage + " (pid=" + callingPid 13799 + ", uid=" + callingUid + ")" 13800 + " requires " 13801 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13802 Slog.w(TAG, msg); 13803 throw new SecurityException(msg); 13804 } 13805 13806 // Special case for adding a package: by default turn on compatibility 13807 // mode. 13808 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13809 Uri data = intent.getData(); 13810 String ssp; 13811 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13812 mCompatModePackages.handlePackageAddedLocked(ssp, 13813 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13814 } 13815 } 13816 13817 /* 13818 * If this is the time zone changed action, queue up a message that will reset the timezone 13819 * of all currently running processes. This message will get queued up before the broadcast 13820 * happens. 13821 */ 13822 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13823 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13824 } 13825 13826 /* 13827 * If the user set the time, let all running processes know. 13828 */ 13829 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13830 final int is24Hour = intent.getBooleanExtra( 13831 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13832 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13833 } 13834 13835 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13836 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13837 } 13838 13839 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13840 ProxyInfo proxy = intent.getParcelableExtra("proxy"); 13841 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13842 } 13843 13844 // Add to the sticky list if requested. 13845 if (sticky) { 13846 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13847 callingPid, callingUid) 13848 != PackageManager.PERMISSION_GRANTED) { 13849 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13850 + callingPid + ", uid=" + callingUid 13851 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13852 Slog.w(TAG, msg); 13853 throw new SecurityException(msg); 13854 } 13855 if (requiredPermission != null) { 13856 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13857 + " and enforce permission " + requiredPermission); 13858 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13859 } 13860 if (intent.getComponent() != null) { 13861 throw new SecurityException( 13862 "Sticky broadcasts can't target a specific component"); 13863 } 13864 // We use userId directly here, since the "all" target is maintained 13865 // as a separate set of sticky broadcasts. 13866 if (userId != UserHandle.USER_ALL) { 13867 // But first, if this is not a broadcast to all users, then 13868 // make sure it doesn't conflict with an existing broadcast to 13869 // all users. 13870 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13871 UserHandle.USER_ALL); 13872 if (stickies != null) { 13873 ArrayList<Intent> list = stickies.get(intent.getAction()); 13874 if (list != null) { 13875 int N = list.size(); 13876 int i; 13877 for (i=0; i<N; i++) { 13878 if (intent.filterEquals(list.get(i))) { 13879 throw new IllegalArgumentException( 13880 "Sticky broadcast " + intent + " for user " 13881 + userId + " conflicts with existing global broadcast"); 13882 } 13883 } 13884 } 13885 } 13886 } 13887 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13888 if (stickies == null) { 13889 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13890 mStickyBroadcasts.put(userId, stickies); 13891 } 13892 ArrayList<Intent> list = stickies.get(intent.getAction()); 13893 if (list == null) { 13894 list = new ArrayList<Intent>(); 13895 stickies.put(intent.getAction(), list); 13896 } 13897 int N = list.size(); 13898 int i; 13899 for (i=0; i<N; i++) { 13900 if (intent.filterEquals(list.get(i))) { 13901 // This sticky already exists, replace it. 13902 list.set(i, new Intent(intent)); 13903 break; 13904 } 13905 } 13906 if (i >= N) { 13907 list.add(new Intent(intent)); 13908 } 13909 } 13910 13911 int[] users; 13912 if (userId == UserHandle.USER_ALL) { 13913 // Caller wants broadcast to go to all started users. 13914 users = mStartedUserArray; 13915 } else { 13916 // Caller wants broadcast to go to one specific user. 13917 users = new int[] {userId}; 13918 } 13919 13920 // Figure out who all will receive this broadcast. 13921 List receivers = null; 13922 List<BroadcastFilter> registeredReceivers = null; 13923 // Need to resolve the intent to interested receivers... 13924 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13925 == 0) { 13926 receivers = collectReceiverComponents(intent, resolvedType, users); 13927 } 13928 if (intent.getComponent() == null) { 13929 registeredReceivers = mReceiverResolver.queryIntent(intent, 13930 resolvedType, false, userId); 13931 } 13932 13933 final boolean replacePending = 13934 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13935 13936 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13937 + " replacePending=" + replacePending); 13938 13939 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13940 if (!ordered && NR > 0) { 13941 // If we are not serializing this broadcast, then send the 13942 // registered receivers separately so they don't wait for the 13943 // components to be launched. 13944 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13945 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13946 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13947 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13948 ordered, sticky, false, userId); 13949 if (DEBUG_BROADCAST) Slog.v( 13950 TAG, "Enqueueing parallel broadcast " + r); 13951 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13952 if (!replaced) { 13953 queue.enqueueParallelBroadcastLocked(r); 13954 queue.scheduleBroadcastsLocked(); 13955 } 13956 registeredReceivers = null; 13957 NR = 0; 13958 } 13959 13960 // Merge into one list. 13961 int ir = 0; 13962 if (receivers != null) { 13963 // A special case for PACKAGE_ADDED: do not allow the package 13964 // being added to see this broadcast. This prevents them from 13965 // using this as a back door to get run as soon as they are 13966 // installed. Maybe in the future we want to have a special install 13967 // broadcast or such for apps, but we'd like to deliberately make 13968 // this decision. 13969 String skipPackages[] = null; 13970 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13971 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13972 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13973 Uri data = intent.getData(); 13974 if (data != null) { 13975 String pkgName = data.getSchemeSpecificPart(); 13976 if (pkgName != null) { 13977 skipPackages = new String[] { pkgName }; 13978 } 13979 } 13980 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13981 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13982 } 13983 if (skipPackages != null && (skipPackages.length > 0)) { 13984 for (String skipPackage : skipPackages) { 13985 if (skipPackage != null) { 13986 int NT = receivers.size(); 13987 for (int it=0; it<NT; it++) { 13988 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13989 if (curt.activityInfo.packageName.equals(skipPackage)) { 13990 receivers.remove(it); 13991 it--; 13992 NT--; 13993 } 13994 } 13995 } 13996 } 13997 } 13998 13999 int NT = receivers != null ? receivers.size() : 0; 14000 int it = 0; 14001 ResolveInfo curt = null; 14002 BroadcastFilter curr = null; 14003 while (it < NT && ir < NR) { 14004 if (curt == null) { 14005 curt = (ResolveInfo)receivers.get(it); 14006 } 14007 if (curr == null) { 14008 curr = registeredReceivers.get(ir); 14009 } 14010 if (curr.getPriority() >= curt.priority) { 14011 // Insert this broadcast record into the final list. 14012 receivers.add(it, curr); 14013 ir++; 14014 curr = null; 14015 it++; 14016 NT++; 14017 } else { 14018 // Skip to the next ResolveInfo in the final list. 14019 it++; 14020 curt = null; 14021 } 14022 } 14023 } 14024 while (ir < NR) { 14025 if (receivers == null) { 14026 receivers = new ArrayList(); 14027 } 14028 receivers.add(registeredReceivers.get(ir)); 14029 ir++; 14030 } 14031 14032 if ((receivers != null && receivers.size() > 0) 14033 || resultTo != null) { 14034 BroadcastQueue queue = broadcastQueueForIntent(intent); 14035 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14036 callerPackage, callingPid, callingUid, resolvedType, 14037 requiredPermission, appOp, receivers, resultTo, resultCode, 14038 resultData, map, ordered, sticky, false, userId); 14039 if (DEBUG_BROADCAST) Slog.v( 14040 TAG, "Enqueueing ordered broadcast " + r 14041 + ": prev had " + queue.mOrderedBroadcasts.size()); 14042 if (DEBUG_BROADCAST) { 14043 int seq = r.intent.getIntExtra("seq", -1); 14044 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14045 } 14046 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14047 if (!replaced) { 14048 queue.enqueueOrderedBroadcastLocked(r); 14049 queue.scheduleBroadcastsLocked(); 14050 } 14051 } 14052 14053 return ActivityManager.BROADCAST_SUCCESS; 14054 } 14055 14056 final Intent verifyBroadcastLocked(Intent intent) { 14057 // Refuse possible leaked file descriptors 14058 if (intent != null && intent.hasFileDescriptors() == true) { 14059 throw new IllegalArgumentException("File descriptors passed in Intent"); 14060 } 14061 14062 int flags = intent.getFlags(); 14063 14064 if (!mProcessesReady) { 14065 // if the caller really truly claims to know what they're doing, go 14066 // ahead and allow the broadcast without launching any receivers 14067 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14068 intent = new Intent(intent); 14069 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14070 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14071 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14072 + " before boot completion"); 14073 throw new IllegalStateException("Cannot broadcast before boot completed"); 14074 } 14075 } 14076 14077 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14078 throw new IllegalArgumentException( 14079 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14080 } 14081 14082 return intent; 14083 } 14084 14085 public final int broadcastIntent(IApplicationThread caller, 14086 Intent intent, String resolvedType, IIntentReceiver resultTo, 14087 int resultCode, String resultData, Bundle map, 14088 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14089 enforceNotIsolatedCaller("broadcastIntent"); 14090 synchronized(this) { 14091 intent = verifyBroadcastLocked(intent); 14092 14093 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14094 final int callingPid = Binder.getCallingPid(); 14095 final int callingUid = Binder.getCallingUid(); 14096 final long origId = Binder.clearCallingIdentity(); 14097 int res = broadcastIntentLocked(callerApp, 14098 callerApp != null ? callerApp.info.packageName : null, 14099 intent, resolvedType, resultTo, 14100 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14101 callingPid, callingUid, userId); 14102 Binder.restoreCallingIdentity(origId); 14103 return res; 14104 } 14105 } 14106 14107 int broadcastIntentInPackage(String packageName, int uid, 14108 Intent intent, String resolvedType, IIntentReceiver resultTo, 14109 int resultCode, String resultData, Bundle map, 14110 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14111 synchronized(this) { 14112 intent = verifyBroadcastLocked(intent); 14113 14114 final long origId = Binder.clearCallingIdentity(); 14115 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14116 resultTo, resultCode, resultData, map, requiredPermission, 14117 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14118 Binder.restoreCallingIdentity(origId); 14119 return res; 14120 } 14121 } 14122 14123 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14124 // Refuse possible leaked file descriptors 14125 if (intent != null && intent.hasFileDescriptors() == true) { 14126 throw new IllegalArgumentException("File descriptors passed in Intent"); 14127 } 14128 14129 userId = handleIncomingUser(Binder.getCallingPid(), 14130 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14131 14132 synchronized(this) { 14133 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14134 != PackageManager.PERMISSION_GRANTED) { 14135 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14136 + Binder.getCallingPid() 14137 + ", uid=" + Binder.getCallingUid() 14138 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14139 Slog.w(TAG, msg); 14140 throw new SecurityException(msg); 14141 } 14142 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14143 if (stickies != null) { 14144 ArrayList<Intent> list = stickies.get(intent.getAction()); 14145 if (list != null) { 14146 int N = list.size(); 14147 int i; 14148 for (i=0; i<N; i++) { 14149 if (intent.filterEquals(list.get(i))) { 14150 list.remove(i); 14151 break; 14152 } 14153 } 14154 if (list.size() <= 0) { 14155 stickies.remove(intent.getAction()); 14156 } 14157 } 14158 if (stickies.size() <= 0) { 14159 mStickyBroadcasts.remove(userId); 14160 } 14161 } 14162 } 14163 } 14164 14165 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14166 String resultData, Bundle resultExtras, boolean resultAbort) { 14167 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14168 if (r == null) { 14169 Slog.w(TAG, "finishReceiver called but not found on queue"); 14170 return false; 14171 } 14172 14173 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14174 } 14175 14176 void backgroundServicesFinishedLocked(int userId) { 14177 for (BroadcastQueue queue : mBroadcastQueues) { 14178 queue.backgroundServicesFinishedLocked(userId); 14179 } 14180 } 14181 14182 public void finishReceiver(IBinder who, int resultCode, String resultData, 14183 Bundle resultExtras, boolean resultAbort) { 14184 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14185 14186 // Refuse possible leaked file descriptors 14187 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14188 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14189 } 14190 14191 final long origId = Binder.clearCallingIdentity(); 14192 try { 14193 boolean doNext = false; 14194 BroadcastRecord r; 14195 14196 synchronized(this) { 14197 r = broadcastRecordForReceiverLocked(who); 14198 if (r != null) { 14199 doNext = r.queue.finishReceiverLocked(r, resultCode, 14200 resultData, resultExtras, resultAbort, true); 14201 } 14202 } 14203 14204 if (doNext) { 14205 r.queue.processNextBroadcast(false); 14206 } 14207 trimApplications(); 14208 } finally { 14209 Binder.restoreCallingIdentity(origId); 14210 } 14211 } 14212 14213 // ========================================================= 14214 // INSTRUMENTATION 14215 // ========================================================= 14216 14217 public boolean startInstrumentation(ComponentName className, 14218 String profileFile, int flags, Bundle arguments, 14219 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14220 int userId) { 14221 enforceNotIsolatedCaller("startInstrumentation"); 14222 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14223 userId, false, true, "startInstrumentation", null); 14224 // Refuse possible leaked file descriptors 14225 if (arguments != null && arguments.hasFileDescriptors()) { 14226 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14227 } 14228 14229 synchronized(this) { 14230 InstrumentationInfo ii = null; 14231 ApplicationInfo ai = null; 14232 try { 14233 ii = mContext.getPackageManager().getInstrumentationInfo( 14234 className, STOCK_PM_FLAGS); 14235 ai = AppGlobals.getPackageManager().getApplicationInfo( 14236 ii.targetPackage, STOCK_PM_FLAGS, userId); 14237 } catch (PackageManager.NameNotFoundException e) { 14238 } catch (RemoteException e) { 14239 } 14240 if (ii == null) { 14241 reportStartInstrumentationFailure(watcher, className, 14242 "Unable to find instrumentation info for: " + className); 14243 return false; 14244 } 14245 if (ai == null) { 14246 reportStartInstrumentationFailure(watcher, className, 14247 "Unable to find instrumentation target package: " + ii.targetPackage); 14248 return false; 14249 } 14250 14251 int match = mContext.getPackageManager().checkSignatures( 14252 ii.targetPackage, ii.packageName); 14253 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14254 String msg = "Permission Denial: starting instrumentation " 14255 + className + " from pid=" 14256 + Binder.getCallingPid() 14257 + ", uid=" + Binder.getCallingPid() 14258 + " not allowed because package " + ii.packageName 14259 + " does not have a signature matching the target " 14260 + ii.targetPackage; 14261 reportStartInstrumentationFailure(watcher, className, msg); 14262 throw new SecurityException(msg); 14263 } 14264 14265 final long origId = Binder.clearCallingIdentity(); 14266 // Instrumentation can kill and relaunch even persistent processes 14267 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14268 "start instr"); 14269 ProcessRecord app = addAppLocked(ai, false); 14270 app.instrumentationClass = className; 14271 app.instrumentationInfo = ai; 14272 app.instrumentationProfileFile = profileFile; 14273 app.instrumentationArguments = arguments; 14274 app.instrumentationWatcher = watcher; 14275 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14276 app.instrumentationResultClass = className; 14277 Binder.restoreCallingIdentity(origId); 14278 } 14279 14280 return true; 14281 } 14282 14283 /** 14284 * Report errors that occur while attempting to start Instrumentation. Always writes the 14285 * error to the logs, but if somebody is watching, send the report there too. This enables 14286 * the "am" command to report errors with more information. 14287 * 14288 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14289 * @param cn The component name of the instrumentation. 14290 * @param report The error report. 14291 */ 14292 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14293 ComponentName cn, String report) { 14294 Slog.w(TAG, report); 14295 try { 14296 if (watcher != null) { 14297 Bundle results = new Bundle(); 14298 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14299 results.putString("Error", report); 14300 watcher.instrumentationStatus(cn, -1, results); 14301 } 14302 } catch (RemoteException e) { 14303 Slog.w(TAG, e); 14304 } 14305 } 14306 14307 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14308 if (app.instrumentationWatcher != null) { 14309 try { 14310 // NOTE: IInstrumentationWatcher *must* be oneway here 14311 app.instrumentationWatcher.instrumentationFinished( 14312 app.instrumentationClass, 14313 resultCode, 14314 results); 14315 } catch (RemoteException e) { 14316 } 14317 } 14318 if (app.instrumentationUiAutomationConnection != null) { 14319 try { 14320 app.instrumentationUiAutomationConnection.shutdown(); 14321 } catch (RemoteException re) { 14322 /* ignore */ 14323 } 14324 // Only a UiAutomation can set this flag and now that 14325 // it is finished we make sure it is reset to its default. 14326 mUserIsMonkey = false; 14327 } 14328 app.instrumentationWatcher = null; 14329 app.instrumentationUiAutomationConnection = null; 14330 app.instrumentationClass = null; 14331 app.instrumentationInfo = null; 14332 app.instrumentationProfileFile = null; 14333 app.instrumentationArguments = null; 14334 14335 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14336 "finished inst"); 14337 } 14338 14339 public void finishInstrumentation(IApplicationThread target, 14340 int resultCode, Bundle results) { 14341 int userId = UserHandle.getCallingUserId(); 14342 // Refuse possible leaked file descriptors 14343 if (results != null && results.hasFileDescriptors()) { 14344 throw new IllegalArgumentException("File descriptors passed in Intent"); 14345 } 14346 14347 synchronized(this) { 14348 ProcessRecord app = getRecordForAppLocked(target); 14349 if (app == null) { 14350 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14351 return; 14352 } 14353 final long origId = Binder.clearCallingIdentity(); 14354 finishInstrumentationLocked(app, resultCode, results); 14355 Binder.restoreCallingIdentity(origId); 14356 } 14357 } 14358 14359 // ========================================================= 14360 // CONFIGURATION 14361 // ========================================================= 14362 14363 public ConfigurationInfo getDeviceConfigurationInfo() { 14364 ConfigurationInfo config = new ConfigurationInfo(); 14365 synchronized (this) { 14366 config.reqTouchScreen = mConfiguration.touchscreen; 14367 config.reqKeyboardType = mConfiguration.keyboard; 14368 config.reqNavigation = mConfiguration.navigation; 14369 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14370 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14371 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14372 } 14373 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14374 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14375 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14376 } 14377 config.reqGlEsVersion = GL_ES_VERSION; 14378 } 14379 return config; 14380 } 14381 14382 ActivityStack getFocusedStack() { 14383 return mStackSupervisor.getFocusedStack(); 14384 } 14385 14386 public Configuration getConfiguration() { 14387 Configuration ci; 14388 synchronized(this) { 14389 ci = new Configuration(mConfiguration); 14390 } 14391 return ci; 14392 } 14393 14394 public void updatePersistentConfiguration(Configuration values) { 14395 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14396 "updateConfiguration()"); 14397 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14398 "updateConfiguration()"); 14399 if (values == null) { 14400 throw new NullPointerException("Configuration must not be null"); 14401 } 14402 14403 synchronized(this) { 14404 final long origId = Binder.clearCallingIdentity(); 14405 updateConfigurationLocked(values, null, true, false); 14406 Binder.restoreCallingIdentity(origId); 14407 } 14408 } 14409 14410 public void updateConfiguration(Configuration values) { 14411 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14412 "updateConfiguration()"); 14413 14414 synchronized(this) { 14415 if (values == null && mWindowManager != null) { 14416 // sentinel: fetch the current configuration from the window manager 14417 values = mWindowManager.computeNewConfiguration(); 14418 } 14419 14420 if (mWindowManager != null) { 14421 mProcessList.applyDisplaySize(mWindowManager); 14422 } 14423 14424 final long origId = Binder.clearCallingIdentity(); 14425 if (values != null) { 14426 Settings.System.clearConfiguration(values); 14427 } 14428 updateConfigurationLocked(values, null, false, false); 14429 Binder.restoreCallingIdentity(origId); 14430 } 14431 } 14432 14433 /** 14434 * Do either or both things: (1) change the current configuration, and (2) 14435 * make sure the given activity is running with the (now) current 14436 * configuration. Returns true if the activity has been left running, or 14437 * false if <var>starting</var> is being destroyed to match the new 14438 * configuration. 14439 * @param persistent TODO 14440 */ 14441 boolean updateConfigurationLocked(Configuration values, 14442 ActivityRecord starting, boolean persistent, boolean initLocale) { 14443 int changes = 0; 14444 14445 if (values != null) { 14446 Configuration newConfig = new Configuration(mConfiguration); 14447 changes = newConfig.updateFrom(values); 14448 if (changes != 0) { 14449 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14450 Slog.i(TAG, "Updating configuration to: " + values); 14451 } 14452 14453 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14454 14455 if (values.locale != null && !initLocale) { 14456 saveLocaleLocked(values.locale, 14457 !values.locale.equals(mConfiguration.locale), 14458 values.userSetLocale); 14459 } 14460 14461 mConfigurationSeq++; 14462 if (mConfigurationSeq <= 0) { 14463 mConfigurationSeq = 1; 14464 } 14465 newConfig.seq = mConfigurationSeq; 14466 mConfiguration = newConfig; 14467 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14468 mUsageStatsService.noteStartConfig(newConfig); 14469 14470 final Configuration configCopy = new Configuration(mConfiguration); 14471 14472 // TODO: If our config changes, should we auto dismiss any currently 14473 // showing dialogs? 14474 mShowDialogs = shouldShowDialogs(newConfig); 14475 14476 AttributeCache ac = AttributeCache.instance(); 14477 if (ac != null) { 14478 ac.updateConfiguration(configCopy); 14479 } 14480 14481 // Make sure all resources in our process are updated 14482 // right now, so that anyone who is going to retrieve 14483 // resource values after we return will be sure to get 14484 // the new ones. This is especially important during 14485 // boot, where the first config change needs to guarantee 14486 // all resources have that config before following boot 14487 // code is executed. 14488 mSystemThread.applyConfigurationToResources(configCopy); 14489 14490 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14491 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14492 msg.obj = new Configuration(configCopy); 14493 mHandler.sendMessage(msg); 14494 } 14495 14496 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14497 ProcessRecord app = mLruProcesses.get(i); 14498 try { 14499 if (app.thread != null) { 14500 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14501 + app.processName + " new config " + mConfiguration); 14502 app.thread.scheduleConfigurationChanged(configCopy); 14503 } 14504 } catch (Exception e) { 14505 } 14506 } 14507 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14508 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14509 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14510 | Intent.FLAG_RECEIVER_FOREGROUND); 14511 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14512 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14513 Process.SYSTEM_UID, UserHandle.USER_ALL); 14514 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14515 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14516 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14517 broadcastIntentLocked(null, null, intent, 14518 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14519 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14520 } 14521 } 14522 } 14523 14524 boolean kept = true; 14525 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14526 // mainStack is null during startup. 14527 if (mainStack != null) { 14528 if (changes != 0 && starting == null) { 14529 // If the configuration changed, and the caller is not already 14530 // in the process of starting an activity, then find the top 14531 // activity to check if its configuration needs to change. 14532 starting = mainStack.topRunningActivityLocked(null); 14533 } 14534 14535 if (starting != null) { 14536 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14537 // And we need to make sure at this point that all other activities 14538 // are made visible with the correct configuration. 14539 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14540 } 14541 } 14542 14543 if (values != null && mWindowManager != null) { 14544 mWindowManager.setNewConfiguration(mConfiguration); 14545 } 14546 14547 return kept; 14548 } 14549 14550 /** 14551 * Decide based on the configuration whether we should shouw the ANR, 14552 * crash, etc dialogs. The idea is that if there is no affordnace to 14553 * press the on-screen buttons, we shouldn't show the dialog. 14554 * 14555 * A thought: SystemUI might also want to get told about this, the Power 14556 * dialog / global actions also might want different behaviors. 14557 */ 14558 private static final boolean shouldShowDialogs(Configuration config) { 14559 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14560 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14561 } 14562 14563 /** 14564 * Save the locale. You must be inside a synchronized (this) block. 14565 */ 14566 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14567 if(isDiff) { 14568 SystemProperties.set("user.language", l.getLanguage()); 14569 SystemProperties.set("user.region", l.getCountry()); 14570 } 14571 14572 if(isPersist) { 14573 SystemProperties.set("persist.sys.language", l.getLanguage()); 14574 SystemProperties.set("persist.sys.country", l.getCountry()); 14575 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14576 } 14577 } 14578 14579 @Override 14580 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14581 ActivityRecord srec = ActivityRecord.forToken(token); 14582 return srec != null && srec.task.affinity != null && 14583 srec.task.affinity.equals(destAffinity); 14584 } 14585 14586 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14587 Intent resultData) { 14588 14589 synchronized (this) { 14590 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14591 if (stack != null) { 14592 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14593 } 14594 return false; 14595 } 14596 } 14597 14598 public int getLaunchedFromUid(IBinder activityToken) { 14599 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14600 if (srec == null) { 14601 return -1; 14602 } 14603 return srec.launchedFromUid; 14604 } 14605 14606 public String getLaunchedFromPackage(IBinder activityToken) { 14607 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14608 if (srec == null) { 14609 return null; 14610 } 14611 return srec.launchedFromPackage; 14612 } 14613 14614 // ========================================================= 14615 // LIFETIME MANAGEMENT 14616 // ========================================================= 14617 14618 // Returns which broadcast queue the app is the current [or imminent] receiver 14619 // on, or 'null' if the app is not an active broadcast recipient. 14620 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14621 BroadcastRecord r = app.curReceiver; 14622 if (r != null) { 14623 return r.queue; 14624 } 14625 14626 // It's not the current receiver, but it might be starting up to become one 14627 synchronized (this) { 14628 for (BroadcastQueue queue : mBroadcastQueues) { 14629 r = queue.mPendingBroadcast; 14630 if (r != null && r.curApp == app) { 14631 // found it; report which queue it's in 14632 return queue; 14633 } 14634 } 14635 } 14636 14637 return null; 14638 } 14639 14640 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14641 boolean doingAll, long now) { 14642 if (mAdjSeq == app.adjSeq) { 14643 // This adjustment has already been computed. 14644 return app.curRawAdj; 14645 } 14646 14647 if (app.thread == null) { 14648 app.adjSeq = mAdjSeq; 14649 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14650 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14651 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14652 } 14653 14654 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14655 app.adjSource = null; 14656 app.adjTarget = null; 14657 app.empty = false; 14658 app.cached = false; 14659 14660 final int activitiesSize = app.activities.size(); 14661 14662 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14663 // The max adjustment doesn't allow this app to be anything 14664 // below foreground, so it is not worth doing work for it. 14665 app.adjType = "fixed"; 14666 app.adjSeq = mAdjSeq; 14667 app.curRawAdj = app.maxAdj; 14668 app.foregroundActivities = false; 14669 app.keeping = true; 14670 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14671 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14672 // System processes can do UI, and when they do we want to have 14673 // them trim their memory after the user leaves the UI. To 14674 // facilitate this, here we need to determine whether or not it 14675 // is currently showing UI. 14676 app.systemNoUi = true; 14677 if (app == TOP_APP) { 14678 app.systemNoUi = false; 14679 } else if (activitiesSize > 0) { 14680 for (int j = 0; j < activitiesSize; j++) { 14681 final ActivityRecord r = app.activities.get(j); 14682 if (r.visible) { 14683 app.systemNoUi = false; 14684 } 14685 } 14686 } 14687 if (!app.systemNoUi) { 14688 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14689 } 14690 return (app.curAdj=app.maxAdj); 14691 } 14692 14693 app.keeping = false; 14694 app.systemNoUi = false; 14695 14696 // Determine the importance of the process, starting with most 14697 // important to least, and assign an appropriate OOM adjustment. 14698 int adj; 14699 int schedGroup; 14700 int procState; 14701 boolean foregroundActivities = false; 14702 boolean interesting = false; 14703 BroadcastQueue queue; 14704 if (app == TOP_APP) { 14705 // The last app on the list is the foreground app. 14706 adj = ProcessList.FOREGROUND_APP_ADJ; 14707 schedGroup = Process.THREAD_GROUP_DEFAULT; 14708 app.adjType = "top-activity"; 14709 foregroundActivities = true; 14710 interesting = true; 14711 procState = ActivityManager.PROCESS_STATE_TOP; 14712 } else if (app.instrumentationClass != null) { 14713 // Don't want to kill running instrumentation. 14714 adj = ProcessList.FOREGROUND_APP_ADJ; 14715 schedGroup = Process.THREAD_GROUP_DEFAULT; 14716 app.adjType = "instrumentation"; 14717 interesting = true; 14718 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14719 } else if ((queue = isReceivingBroadcast(app)) != null) { 14720 // An app that is currently receiving a broadcast also 14721 // counts as being in the foreground for OOM killer purposes. 14722 // It's placed in a sched group based on the nature of the 14723 // broadcast as reflected by which queue it's active in. 14724 adj = ProcessList.FOREGROUND_APP_ADJ; 14725 schedGroup = (queue == mFgBroadcastQueue) 14726 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14727 app.adjType = "broadcast"; 14728 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14729 } else if (app.executingServices.size() > 0) { 14730 // An app that is currently executing a service callback also 14731 // counts as being in the foreground. 14732 adj = ProcessList.FOREGROUND_APP_ADJ; 14733 schedGroup = app.execServicesFg ? 14734 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14735 app.adjType = "exec-service"; 14736 procState = ActivityManager.PROCESS_STATE_SERVICE; 14737 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14738 } else { 14739 // As far as we know the process is empty. We may change our mind later. 14740 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14741 // At this point we don't actually know the adjustment. Use the cached adj 14742 // value that the caller wants us to. 14743 adj = cachedAdj; 14744 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14745 app.cached = true; 14746 app.empty = true; 14747 app.adjType = "cch-empty"; 14748 } 14749 14750 // Examine all activities if not already foreground. 14751 if (!foregroundActivities && activitiesSize > 0) { 14752 for (int j = 0; j < activitiesSize; j++) { 14753 final ActivityRecord r = app.activities.get(j); 14754 if (r.app != app) { 14755 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14756 + app + "?!?"); 14757 continue; 14758 } 14759 if (r.visible) { 14760 // App has a visible activity; only upgrade adjustment. 14761 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14762 adj = ProcessList.VISIBLE_APP_ADJ; 14763 app.adjType = "visible"; 14764 } 14765 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14766 procState = ActivityManager.PROCESS_STATE_TOP; 14767 } 14768 schedGroup = Process.THREAD_GROUP_DEFAULT; 14769 app.cached = false; 14770 app.empty = false; 14771 foregroundActivities = true; 14772 break; 14773 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14774 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14775 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14776 app.adjType = "pausing"; 14777 } 14778 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14779 procState = ActivityManager.PROCESS_STATE_TOP; 14780 } 14781 schedGroup = Process.THREAD_GROUP_DEFAULT; 14782 app.cached = false; 14783 app.empty = false; 14784 foregroundActivities = true; 14785 } else if (r.state == ActivityState.STOPPING) { 14786 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14787 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14788 app.adjType = "stopping"; 14789 } 14790 // For the process state, we will at this point consider the 14791 // process to be cached. It will be cached either as an activity 14792 // or empty depending on whether the activity is finishing. We do 14793 // this so that we can treat the process as cached for purposes of 14794 // memory trimming (determing current memory level, trim command to 14795 // send to process) since there can be an arbitrary number of stopping 14796 // processes and they should soon all go into the cached state. 14797 if (!r.finishing) { 14798 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14799 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14800 } 14801 } 14802 app.cached = false; 14803 app.empty = false; 14804 foregroundActivities = true; 14805 } else { 14806 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14807 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14808 app.adjType = "cch-act"; 14809 } 14810 } 14811 } 14812 } 14813 14814 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14815 if (app.foregroundServices) { 14816 // The user is aware of this app, so make it visible. 14817 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14818 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14819 app.cached = false; 14820 app.adjType = "fg-service"; 14821 schedGroup = Process.THREAD_GROUP_DEFAULT; 14822 } else if (app.forcingToForeground != null) { 14823 // The user is aware of this app, so make it visible. 14824 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14825 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14826 app.cached = false; 14827 app.adjType = "force-fg"; 14828 app.adjSource = app.forcingToForeground; 14829 schedGroup = Process.THREAD_GROUP_DEFAULT; 14830 } 14831 } 14832 14833 if (app.foregroundServices) { 14834 interesting = true; 14835 } 14836 14837 if (app == mHeavyWeightProcess) { 14838 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14839 // We don't want to kill the current heavy-weight process. 14840 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14841 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14842 app.cached = false; 14843 app.adjType = "heavy"; 14844 } 14845 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14846 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14847 } 14848 } 14849 14850 if (app == mHomeProcess) { 14851 if (adj > ProcessList.HOME_APP_ADJ) { 14852 // This process is hosting what we currently consider to be the 14853 // home app, so we don't want to let it go into the background. 14854 adj = ProcessList.HOME_APP_ADJ; 14855 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14856 app.cached = false; 14857 app.adjType = "home"; 14858 } 14859 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14860 procState = ActivityManager.PROCESS_STATE_HOME; 14861 } 14862 } 14863 14864 if (app == mPreviousProcess && app.activities.size() > 0) { 14865 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14866 // This was the previous process that showed UI to the user. 14867 // We want to try to keep it around more aggressively, to give 14868 // a good experience around switching between two apps. 14869 adj = ProcessList.PREVIOUS_APP_ADJ; 14870 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14871 app.cached = false; 14872 app.adjType = "previous"; 14873 } 14874 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14875 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14876 } 14877 } 14878 14879 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14880 + " reason=" + app.adjType); 14881 14882 // By default, we use the computed adjustment. It may be changed if 14883 // there are applications dependent on our services or providers, but 14884 // this gives us a baseline and makes sure we don't get into an 14885 // infinite recursion. 14886 app.adjSeq = mAdjSeq; 14887 app.curRawAdj = adj; 14888 app.hasStartedServices = false; 14889 14890 if (mBackupTarget != null && app == mBackupTarget.app) { 14891 // If possible we want to avoid killing apps while they're being backed up 14892 if (adj > ProcessList.BACKUP_APP_ADJ) { 14893 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14894 adj = ProcessList.BACKUP_APP_ADJ; 14895 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14896 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14897 } 14898 app.adjType = "backup"; 14899 app.cached = false; 14900 } 14901 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14902 procState = ActivityManager.PROCESS_STATE_BACKUP; 14903 } 14904 } 14905 14906 boolean mayBeTop = false; 14907 14908 for (int is = app.services.size()-1; 14909 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14910 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14911 || procState > ActivityManager.PROCESS_STATE_TOP); 14912 is--) { 14913 ServiceRecord s = app.services.valueAt(is); 14914 if (s.startRequested) { 14915 app.hasStartedServices = true; 14916 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14917 procState = ActivityManager.PROCESS_STATE_SERVICE; 14918 } 14919 if (app.hasShownUi && app != mHomeProcess) { 14920 // If this process has shown some UI, let it immediately 14921 // go to the LRU list because it may be pretty heavy with 14922 // UI stuff. We'll tag it with a label just to help 14923 // debug and understand what is going on. 14924 if (adj > ProcessList.SERVICE_ADJ) { 14925 app.adjType = "cch-started-ui-services"; 14926 } 14927 } else { 14928 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14929 // This service has seen some activity within 14930 // recent memory, so we will keep its process ahead 14931 // of the background processes. 14932 if (adj > ProcessList.SERVICE_ADJ) { 14933 adj = ProcessList.SERVICE_ADJ; 14934 app.adjType = "started-services"; 14935 app.cached = false; 14936 } 14937 } 14938 // If we have let the service slide into the background 14939 // state, still have some text describing what it is doing 14940 // even though the service no longer has an impact. 14941 if (adj > ProcessList.SERVICE_ADJ) { 14942 app.adjType = "cch-started-services"; 14943 } 14944 } 14945 // Don't kill this process because it is doing work; it 14946 // has said it is doing work. 14947 app.keeping = true; 14948 } 14949 for (int conni = s.connections.size()-1; 14950 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14951 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14952 || procState > ActivityManager.PROCESS_STATE_TOP); 14953 conni--) { 14954 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14955 for (int i = 0; 14956 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14957 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14958 || procState > ActivityManager.PROCESS_STATE_TOP); 14959 i++) { 14960 // XXX should compute this based on the max of 14961 // all connected clients. 14962 ConnectionRecord cr = clist.get(i); 14963 if (cr.binding.client == app) { 14964 // Binding to ourself is not interesting. 14965 continue; 14966 } 14967 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14968 ProcessRecord client = cr.binding.client; 14969 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14970 TOP_APP, doingAll, now); 14971 int clientProcState = client.curProcState; 14972 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14973 // If the other app is cached for any reason, for purposes here 14974 // we are going to consider it empty. The specific cached state 14975 // doesn't propagate except under certain conditions. 14976 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14977 } 14978 String adjType = null; 14979 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14980 // Not doing bind OOM management, so treat 14981 // this guy more like a started service. 14982 if (app.hasShownUi && app != mHomeProcess) { 14983 // If this process has shown some UI, let it immediately 14984 // go to the LRU list because it may be pretty heavy with 14985 // UI stuff. We'll tag it with a label just to help 14986 // debug and understand what is going on. 14987 if (adj > clientAdj) { 14988 adjType = "cch-bound-ui-services"; 14989 } 14990 app.cached = false; 14991 clientAdj = adj; 14992 clientProcState = procState; 14993 } else { 14994 if (now >= (s.lastActivity 14995 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14996 // This service has not seen activity within 14997 // recent memory, so allow it to drop to the 14998 // LRU list if there is no other reason to keep 14999 // it around. We'll also tag it with a label just 15000 // to help debug and undertand what is going on. 15001 if (adj > clientAdj) { 15002 adjType = "cch-bound-services"; 15003 } 15004 clientAdj = adj; 15005 } 15006 } 15007 } 15008 if (adj > clientAdj) { 15009 // If this process has recently shown UI, and 15010 // the process that is binding to it is less 15011 // important than being visible, then we don't 15012 // care about the binding as much as we care 15013 // about letting this process get into the LRU 15014 // list to be killed and restarted if needed for 15015 // memory. 15016 if (app.hasShownUi && app != mHomeProcess 15017 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15018 adjType = "cch-bound-ui-services"; 15019 } else { 15020 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15021 |Context.BIND_IMPORTANT)) != 0) { 15022 adj = clientAdj; 15023 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15024 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15025 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15026 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15027 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15028 adj = clientAdj; 15029 } else { 15030 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15031 adj = ProcessList.VISIBLE_APP_ADJ; 15032 } 15033 } 15034 if (!client.cached) { 15035 app.cached = false; 15036 } 15037 if (client.keeping) { 15038 app.keeping = true; 15039 } 15040 adjType = "service"; 15041 } 15042 } 15043 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15044 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15045 schedGroup = Process.THREAD_GROUP_DEFAULT; 15046 } 15047 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15048 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15049 // Special handling of clients who are in the top state. 15050 // We *may* want to consider this process to be in the 15051 // top state as well, but only if there is not another 15052 // reason for it to be running. Being on the top is a 15053 // special state, meaning you are specifically running 15054 // for the current top app. If the process is already 15055 // running in the background for some other reason, it 15056 // is more important to continue considering it to be 15057 // in the background state. 15058 mayBeTop = true; 15059 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15060 } else { 15061 // Special handling for above-top states (persistent 15062 // processes). These should not bring the current process 15063 // into the top state, since they are not on top. Instead 15064 // give them the best state after that. 15065 clientProcState = 15066 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15067 } 15068 } 15069 } else { 15070 if (clientProcState < 15071 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15072 clientProcState = 15073 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15074 } 15075 } 15076 if (procState > clientProcState) { 15077 procState = clientProcState; 15078 } 15079 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15080 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15081 app.pendingUiClean = true; 15082 } 15083 if (adjType != null) { 15084 app.adjType = adjType; 15085 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15086 .REASON_SERVICE_IN_USE; 15087 app.adjSource = cr.binding.client; 15088 app.adjSourceOom = clientAdj; 15089 app.adjTarget = s.name; 15090 } 15091 } 15092 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15093 app.treatLikeActivity = true; 15094 } 15095 final ActivityRecord a = cr.activity; 15096 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15097 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15098 (a.visible || a.state == ActivityState.RESUMED 15099 || a.state == ActivityState.PAUSING)) { 15100 adj = ProcessList.FOREGROUND_APP_ADJ; 15101 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15102 schedGroup = Process.THREAD_GROUP_DEFAULT; 15103 } 15104 app.cached = false; 15105 app.adjType = "service"; 15106 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15107 .REASON_SERVICE_IN_USE; 15108 app.adjSource = a; 15109 app.adjSourceOom = adj; 15110 app.adjTarget = s.name; 15111 } 15112 } 15113 } 15114 } 15115 } 15116 15117 for (int provi = app.pubProviders.size()-1; 15118 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15119 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15120 || procState > ActivityManager.PROCESS_STATE_TOP); 15121 provi--) { 15122 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15123 for (int i = cpr.connections.size()-1; 15124 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15125 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15126 || procState > ActivityManager.PROCESS_STATE_TOP); 15127 i--) { 15128 ContentProviderConnection conn = cpr.connections.get(i); 15129 ProcessRecord client = conn.client; 15130 if (client == app) { 15131 // Being our own client is not interesting. 15132 continue; 15133 } 15134 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15135 int clientProcState = client.curProcState; 15136 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15137 // If the other app is cached for any reason, for purposes here 15138 // we are going to consider it empty. 15139 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15140 } 15141 if (adj > clientAdj) { 15142 if (app.hasShownUi && app != mHomeProcess 15143 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15144 app.adjType = "cch-ui-provider"; 15145 } else { 15146 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15147 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15148 app.adjType = "provider"; 15149 } 15150 app.cached &= client.cached; 15151 app.keeping |= client.keeping; 15152 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15153 .REASON_PROVIDER_IN_USE; 15154 app.adjSource = client; 15155 app.adjSourceOom = clientAdj; 15156 app.adjTarget = cpr.name; 15157 } 15158 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15159 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15160 // Special handling of clients who are in the top state. 15161 // We *may* want to consider this process to be in the 15162 // top state as well, but only if there is not another 15163 // reason for it to be running. Being on the top is a 15164 // special state, meaning you are specifically running 15165 // for the current top app. If the process is already 15166 // running in the background for some other reason, it 15167 // is more important to continue considering it to be 15168 // in the background state. 15169 mayBeTop = true; 15170 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15171 } else { 15172 // Special handling for above-top states (persistent 15173 // processes). These should not bring the current process 15174 // into the top state, since they are not on top. Instead 15175 // give them the best state after that. 15176 clientProcState = 15177 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15178 } 15179 } 15180 if (procState > clientProcState) { 15181 procState = clientProcState; 15182 } 15183 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15184 schedGroup = Process.THREAD_GROUP_DEFAULT; 15185 } 15186 } 15187 // If the provider has external (non-framework) process 15188 // dependencies, ensure that its adjustment is at least 15189 // FOREGROUND_APP_ADJ. 15190 if (cpr.hasExternalProcessHandles()) { 15191 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15192 adj = ProcessList.FOREGROUND_APP_ADJ; 15193 schedGroup = Process.THREAD_GROUP_DEFAULT; 15194 app.cached = false; 15195 app.keeping = true; 15196 app.adjType = "provider"; 15197 app.adjTarget = cpr.name; 15198 } 15199 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15200 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15201 } 15202 } 15203 } 15204 15205 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15206 // A client of one of our services or providers is in the top state. We 15207 // *may* want to be in the top state, but not if we are already running in 15208 // the background for some other reason. For the decision here, we are going 15209 // to pick out a few specific states that we want to remain in when a client 15210 // is top (states that tend to be longer-term) and otherwise allow it to go 15211 // to the top state. 15212 switch (procState) { 15213 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15214 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15215 case ActivityManager.PROCESS_STATE_SERVICE: 15216 // These all are longer-term states, so pull them up to the top 15217 // of the background states, but not all the way to the top state. 15218 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15219 break; 15220 default: 15221 // Otherwise, top is a better choice, so take it. 15222 procState = ActivityManager.PROCESS_STATE_TOP; 15223 break; 15224 } 15225 } 15226 15227 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15228 if (app.hasClientActivities) { 15229 // This is a cached process, but with client activities. Mark it so. 15230 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15231 app.adjType = "cch-client-act"; 15232 } else if (app.treatLikeActivity) { 15233 // This is a cached process, but somebody wants us to treat it like it has 15234 // an activity, okay! 15235 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15236 app.adjType = "cch-as-act"; 15237 } 15238 } 15239 15240 if (adj == ProcessList.SERVICE_ADJ) { 15241 if (doingAll) { 15242 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15243 mNewNumServiceProcs++; 15244 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15245 if (!app.serviceb) { 15246 // This service isn't far enough down on the LRU list to 15247 // normally be a B service, but if we are low on RAM and it 15248 // is large we want to force it down since we would prefer to 15249 // keep launcher over it. 15250 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15251 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15252 app.serviceHighRam = true; 15253 app.serviceb = true; 15254 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15255 } else { 15256 mNewNumAServiceProcs++; 15257 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15258 } 15259 } else { 15260 app.serviceHighRam = false; 15261 } 15262 } 15263 if (app.serviceb) { 15264 adj = ProcessList.SERVICE_B_ADJ; 15265 } 15266 } 15267 15268 app.curRawAdj = adj; 15269 15270 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15271 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15272 if (adj > app.maxAdj) { 15273 adj = app.maxAdj; 15274 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15275 schedGroup = Process.THREAD_GROUP_DEFAULT; 15276 } 15277 } 15278 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15279 app.keeping = true; 15280 } 15281 15282 // Do final modification to adj. Everything we do between here and applying 15283 // the final setAdj must be done in this function, because we will also use 15284 // it when computing the final cached adj later. Note that we don't need to 15285 // worry about this for max adj above, since max adj will always be used to 15286 // keep it out of the cached vaues. 15287 app.curAdj = app.modifyRawOomAdj(adj); 15288 app.curSchedGroup = schedGroup; 15289 app.curProcState = procState; 15290 app.foregroundActivities = foregroundActivities; 15291 15292 return app.curRawAdj; 15293 } 15294 15295 /** 15296 * Schedule PSS collection of a process. 15297 */ 15298 void requestPssLocked(ProcessRecord proc, int procState) { 15299 if (mPendingPssProcesses.contains(proc)) { 15300 return; 15301 } 15302 if (mPendingPssProcesses.size() == 0) { 15303 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15304 } 15305 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15306 proc.pssProcState = procState; 15307 mPendingPssProcesses.add(proc); 15308 } 15309 15310 /** 15311 * Schedule PSS collection of all processes. 15312 */ 15313 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15314 if (!always) { 15315 if (now < (mLastFullPssTime + 15316 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15317 return; 15318 } 15319 } 15320 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15321 mLastFullPssTime = now; 15322 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15323 mPendingPssProcesses.clear(); 15324 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15325 ProcessRecord app = mLruProcesses.get(i); 15326 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15327 app.pssProcState = app.setProcState; 15328 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15329 isSleeping(), now); 15330 mPendingPssProcesses.add(app); 15331 } 15332 } 15333 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15334 } 15335 15336 /** 15337 * Ask a given process to GC right now. 15338 */ 15339 final void performAppGcLocked(ProcessRecord app) { 15340 try { 15341 app.lastRequestedGc = SystemClock.uptimeMillis(); 15342 if (app.thread != null) { 15343 if (app.reportLowMemory) { 15344 app.reportLowMemory = false; 15345 app.thread.scheduleLowMemory(); 15346 } else { 15347 app.thread.processInBackground(); 15348 } 15349 } 15350 } catch (Exception e) { 15351 // whatever. 15352 } 15353 } 15354 15355 /** 15356 * Returns true if things are idle enough to perform GCs. 15357 */ 15358 private final boolean canGcNowLocked() { 15359 boolean processingBroadcasts = false; 15360 for (BroadcastQueue q : mBroadcastQueues) { 15361 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15362 processingBroadcasts = true; 15363 } 15364 } 15365 return !processingBroadcasts 15366 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15367 } 15368 15369 /** 15370 * Perform GCs on all processes that are waiting for it, but only 15371 * if things are idle. 15372 */ 15373 final void performAppGcsLocked() { 15374 final int N = mProcessesToGc.size(); 15375 if (N <= 0) { 15376 return; 15377 } 15378 if (canGcNowLocked()) { 15379 while (mProcessesToGc.size() > 0) { 15380 ProcessRecord proc = mProcessesToGc.remove(0); 15381 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15382 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15383 <= SystemClock.uptimeMillis()) { 15384 // To avoid spamming the system, we will GC processes one 15385 // at a time, waiting a few seconds between each. 15386 performAppGcLocked(proc); 15387 scheduleAppGcsLocked(); 15388 return; 15389 } else { 15390 // It hasn't been long enough since we last GCed this 15391 // process... put it in the list to wait for its time. 15392 addProcessToGcListLocked(proc); 15393 break; 15394 } 15395 } 15396 } 15397 15398 scheduleAppGcsLocked(); 15399 } 15400 } 15401 15402 /** 15403 * If all looks good, perform GCs on all processes waiting for them. 15404 */ 15405 final void performAppGcsIfAppropriateLocked() { 15406 if (canGcNowLocked()) { 15407 performAppGcsLocked(); 15408 return; 15409 } 15410 // Still not idle, wait some more. 15411 scheduleAppGcsLocked(); 15412 } 15413 15414 /** 15415 * Schedule the execution of all pending app GCs. 15416 */ 15417 final void scheduleAppGcsLocked() { 15418 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15419 15420 if (mProcessesToGc.size() > 0) { 15421 // Schedule a GC for the time to the next process. 15422 ProcessRecord proc = mProcessesToGc.get(0); 15423 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15424 15425 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15426 long now = SystemClock.uptimeMillis(); 15427 if (when < (now+GC_TIMEOUT)) { 15428 when = now + GC_TIMEOUT; 15429 } 15430 mHandler.sendMessageAtTime(msg, when); 15431 } 15432 } 15433 15434 /** 15435 * Add a process to the array of processes waiting to be GCed. Keeps the 15436 * list in sorted order by the last GC time. The process can't already be 15437 * on the list. 15438 */ 15439 final void addProcessToGcListLocked(ProcessRecord proc) { 15440 boolean added = false; 15441 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15442 if (mProcessesToGc.get(i).lastRequestedGc < 15443 proc.lastRequestedGc) { 15444 added = true; 15445 mProcessesToGc.add(i+1, proc); 15446 break; 15447 } 15448 } 15449 if (!added) { 15450 mProcessesToGc.add(0, proc); 15451 } 15452 } 15453 15454 /** 15455 * Set up to ask a process to GC itself. This will either do it 15456 * immediately, or put it on the list of processes to gc the next 15457 * time things are idle. 15458 */ 15459 final void scheduleAppGcLocked(ProcessRecord app) { 15460 long now = SystemClock.uptimeMillis(); 15461 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15462 return; 15463 } 15464 if (!mProcessesToGc.contains(app)) { 15465 addProcessToGcListLocked(app); 15466 scheduleAppGcsLocked(); 15467 } 15468 } 15469 15470 final void checkExcessivePowerUsageLocked(boolean doKills) { 15471 updateCpuStatsNow(); 15472 15473 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15474 boolean doWakeKills = doKills; 15475 boolean doCpuKills = doKills; 15476 if (mLastPowerCheckRealtime == 0) { 15477 doWakeKills = false; 15478 } 15479 if (mLastPowerCheckUptime == 0) { 15480 doCpuKills = false; 15481 } 15482 if (stats.isScreenOn()) { 15483 doWakeKills = false; 15484 } 15485 final long curRealtime = SystemClock.elapsedRealtime(); 15486 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15487 final long curUptime = SystemClock.uptimeMillis(); 15488 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15489 mLastPowerCheckRealtime = curRealtime; 15490 mLastPowerCheckUptime = curUptime; 15491 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15492 doWakeKills = false; 15493 } 15494 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15495 doCpuKills = false; 15496 } 15497 int i = mLruProcesses.size(); 15498 while (i > 0) { 15499 i--; 15500 ProcessRecord app = mLruProcesses.get(i); 15501 if (!app.keeping) { 15502 long wtime; 15503 synchronized (stats) { 15504 wtime = stats.getProcessWakeTime(app.info.uid, 15505 app.pid, curRealtime); 15506 } 15507 long wtimeUsed = wtime - app.lastWakeTime; 15508 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15509 if (DEBUG_POWER) { 15510 StringBuilder sb = new StringBuilder(128); 15511 sb.append("Wake for "); 15512 app.toShortString(sb); 15513 sb.append(": over "); 15514 TimeUtils.formatDuration(realtimeSince, sb); 15515 sb.append(" used "); 15516 TimeUtils.formatDuration(wtimeUsed, sb); 15517 sb.append(" ("); 15518 sb.append((wtimeUsed*100)/realtimeSince); 15519 sb.append("%)"); 15520 Slog.i(TAG, sb.toString()); 15521 sb.setLength(0); 15522 sb.append("CPU for "); 15523 app.toShortString(sb); 15524 sb.append(": over "); 15525 TimeUtils.formatDuration(uptimeSince, sb); 15526 sb.append(" used "); 15527 TimeUtils.formatDuration(cputimeUsed, sb); 15528 sb.append(" ("); 15529 sb.append((cputimeUsed*100)/uptimeSince); 15530 sb.append("%)"); 15531 Slog.i(TAG, sb.toString()); 15532 } 15533 // If a process has held a wake lock for more 15534 // than 50% of the time during this period, 15535 // that sounds bad. Kill! 15536 if (doWakeKills && realtimeSince > 0 15537 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15538 synchronized (stats) { 15539 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15540 realtimeSince, wtimeUsed); 15541 } 15542 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15543 + " during " + realtimeSince); 15544 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15545 } else if (doCpuKills && uptimeSince > 0 15546 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15547 synchronized (stats) { 15548 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15549 uptimeSince, cputimeUsed); 15550 } 15551 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15552 + " during " + uptimeSince); 15553 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15554 } else { 15555 app.lastWakeTime = wtime; 15556 app.lastCpuTime = app.curCpuTime; 15557 } 15558 } 15559 } 15560 } 15561 15562 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15563 ProcessRecord TOP_APP, boolean doingAll, long now) { 15564 boolean success = true; 15565 15566 if (app.curRawAdj != app.setRawAdj) { 15567 if (wasKeeping && !app.keeping) { 15568 // This app is no longer something we want to keep. Note 15569 // its current wake lock time to later know to kill it if 15570 // it is not behaving well. 15571 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15572 synchronized (stats) { 15573 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15574 app.pid, SystemClock.elapsedRealtime()); 15575 } 15576 app.lastCpuTime = app.curCpuTime; 15577 } 15578 15579 app.setRawAdj = app.curRawAdj; 15580 } 15581 15582 int changes = 0; 15583 15584 if (app.curAdj != app.setAdj) { 15585 ProcessList.setOomAdj(app.pid, app.curAdj); 15586 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15587 TAG, "Set " + app.pid + " " + app.processName + 15588 " adj " + app.curAdj + ": " + app.adjType); 15589 app.setAdj = app.curAdj; 15590 } 15591 15592 if (app.setSchedGroup != app.curSchedGroup) { 15593 app.setSchedGroup = app.curSchedGroup; 15594 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15595 "Setting process group of " + app.processName 15596 + " to " + app.curSchedGroup); 15597 if (app.waitingToKill != null && 15598 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15599 killUnneededProcessLocked(app, app.waitingToKill); 15600 success = false; 15601 } else { 15602 if (true) { 15603 long oldId = Binder.clearCallingIdentity(); 15604 try { 15605 Process.setProcessGroup(app.pid, app.curSchedGroup); 15606 } catch (Exception e) { 15607 Slog.w(TAG, "Failed setting process group of " + app.pid 15608 + " to " + app.curSchedGroup); 15609 e.printStackTrace(); 15610 } finally { 15611 Binder.restoreCallingIdentity(oldId); 15612 } 15613 } else { 15614 if (app.thread != null) { 15615 try { 15616 app.thread.setSchedulingGroup(app.curSchedGroup); 15617 } catch (RemoteException e) { 15618 } 15619 } 15620 } 15621 Process.setSwappiness(app.pid, 15622 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15623 } 15624 } 15625 if (app.repForegroundActivities != app.foregroundActivities) { 15626 app.repForegroundActivities = app.foregroundActivities; 15627 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15628 } 15629 if (app.repProcState != app.curProcState) { 15630 app.repProcState = app.curProcState; 15631 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15632 if (app.thread != null) { 15633 try { 15634 if (false) { 15635 //RuntimeException h = new RuntimeException("here"); 15636 Slog.i(TAG, "Sending new process state " + app.repProcState 15637 + " to " + app /*, h*/); 15638 } 15639 app.thread.setProcessState(app.repProcState); 15640 } catch (RemoteException e) { 15641 } 15642 } 15643 } 15644 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15645 app.setProcState)) { 15646 app.lastStateTime = now; 15647 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15648 isSleeping(), now); 15649 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15650 + ProcessList.makeProcStateString(app.setProcState) + " to " 15651 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15652 + (app.nextPssTime-now) + ": " + app); 15653 } else { 15654 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15655 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15656 requestPssLocked(app, app.setProcState); 15657 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15658 isSleeping(), now); 15659 } else if (false && DEBUG_PSS) { 15660 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15661 } 15662 } 15663 if (app.setProcState != app.curProcState) { 15664 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15665 "Proc state change of " + app.processName 15666 + " to " + app.curProcState); 15667 app.setProcState = app.curProcState; 15668 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15669 app.notCachedSinceIdle = false; 15670 } 15671 if (!doingAll) { 15672 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15673 } else { 15674 app.procStateChanged = true; 15675 } 15676 } 15677 15678 if (changes != 0) { 15679 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15680 int i = mPendingProcessChanges.size()-1; 15681 ProcessChangeItem item = null; 15682 while (i >= 0) { 15683 item = mPendingProcessChanges.get(i); 15684 if (item.pid == app.pid) { 15685 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15686 break; 15687 } 15688 i--; 15689 } 15690 if (i < 0) { 15691 // No existing item in pending changes; need a new one. 15692 final int NA = mAvailProcessChanges.size(); 15693 if (NA > 0) { 15694 item = mAvailProcessChanges.remove(NA-1); 15695 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15696 } else { 15697 item = new ProcessChangeItem(); 15698 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15699 } 15700 item.changes = 0; 15701 item.pid = app.pid; 15702 item.uid = app.info.uid; 15703 if (mPendingProcessChanges.size() == 0) { 15704 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15705 "*** Enqueueing dispatch processes changed!"); 15706 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15707 } 15708 mPendingProcessChanges.add(item); 15709 } 15710 item.changes |= changes; 15711 item.processState = app.repProcState; 15712 item.foregroundActivities = app.repForegroundActivities; 15713 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15714 + Integer.toHexString(System.identityHashCode(item)) 15715 + " " + app.toShortString() + ": changes=" + item.changes 15716 + " procState=" + item.processState 15717 + " foreground=" + item.foregroundActivities 15718 + " type=" + app.adjType + " source=" + app.adjSource 15719 + " target=" + app.adjTarget); 15720 } 15721 15722 return success; 15723 } 15724 15725 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15726 if (proc.thread != null && proc.baseProcessTracker != null) { 15727 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15728 } 15729 } 15730 15731 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15732 ProcessRecord TOP_APP, boolean doingAll, long now) { 15733 if (app.thread == null) { 15734 return false; 15735 } 15736 15737 final boolean wasKeeping = app.keeping; 15738 15739 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15740 15741 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15742 } 15743 15744 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15745 boolean oomAdj) { 15746 if (isForeground != proc.foregroundServices) { 15747 proc.foregroundServices = isForeground; 15748 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15749 proc.info.uid); 15750 if (isForeground) { 15751 if (curProcs == null) { 15752 curProcs = new ArrayList<ProcessRecord>(); 15753 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15754 } 15755 if (!curProcs.contains(proc)) { 15756 curProcs.add(proc); 15757 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15758 proc.info.packageName, proc.info.uid); 15759 } 15760 } else { 15761 if (curProcs != null) { 15762 if (curProcs.remove(proc)) { 15763 mBatteryStatsService.noteEvent( 15764 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15765 proc.info.packageName, proc.info.uid); 15766 if (curProcs.size() <= 0) { 15767 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15768 } 15769 } 15770 } 15771 } 15772 if (oomAdj) { 15773 updateOomAdjLocked(); 15774 } 15775 } 15776 } 15777 15778 private final ActivityRecord resumedAppLocked() { 15779 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15780 String pkg; 15781 int uid; 15782 if (act != null && !act.sleeping) { 15783 pkg = act.packageName; 15784 uid = act.info.applicationInfo.uid; 15785 } else { 15786 pkg = null; 15787 uid = -1; 15788 } 15789 // Has the UID or resumed package name changed? 15790 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15791 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15792 if (mCurResumedPackage != null) { 15793 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15794 mCurResumedPackage, mCurResumedUid); 15795 } 15796 mCurResumedPackage = pkg; 15797 mCurResumedUid = uid; 15798 if (mCurResumedPackage != null) { 15799 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15800 mCurResumedPackage, mCurResumedUid); 15801 } 15802 } 15803 return act; 15804 } 15805 15806 final boolean updateOomAdjLocked(ProcessRecord app) { 15807 final ActivityRecord TOP_ACT = resumedAppLocked(); 15808 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15809 final boolean wasCached = app.cached; 15810 15811 mAdjSeq++; 15812 15813 // This is the desired cached adjusment we want to tell it to use. 15814 // If our app is currently cached, we know it, and that is it. Otherwise, 15815 // we don't know it yet, and it needs to now be cached we will then 15816 // need to do a complete oom adj. 15817 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15818 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15819 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15820 SystemClock.uptimeMillis()); 15821 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15822 // Changed to/from cached state, so apps after it in the LRU 15823 // list may also be changed. 15824 updateOomAdjLocked(); 15825 } 15826 return success; 15827 } 15828 15829 final void updateOomAdjLocked() { 15830 final ActivityRecord TOP_ACT = resumedAppLocked(); 15831 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15832 final long now = SystemClock.uptimeMillis(); 15833 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15834 final int N = mLruProcesses.size(); 15835 15836 if (false) { 15837 RuntimeException e = new RuntimeException(); 15838 e.fillInStackTrace(); 15839 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15840 } 15841 15842 mAdjSeq++; 15843 mNewNumServiceProcs = 0; 15844 mNewNumAServiceProcs = 0; 15845 15846 final int emptyProcessLimit; 15847 final int cachedProcessLimit; 15848 if (mProcessLimit <= 0) { 15849 emptyProcessLimit = cachedProcessLimit = 0; 15850 } else if (mProcessLimit == 1) { 15851 emptyProcessLimit = 1; 15852 cachedProcessLimit = 0; 15853 } else { 15854 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15855 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15856 } 15857 15858 // Let's determine how many processes we have running vs. 15859 // how many slots we have for background processes; we may want 15860 // to put multiple processes in a slot of there are enough of 15861 // them. 15862 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15863 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15864 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15865 if (numEmptyProcs > cachedProcessLimit) { 15866 // If there are more empty processes than our limit on cached 15867 // processes, then use the cached process limit for the factor. 15868 // This ensures that the really old empty processes get pushed 15869 // down to the bottom, so if we are running low on memory we will 15870 // have a better chance at keeping around more cached processes 15871 // instead of a gazillion empty processes. 15872 numEmptyProcs = cachedProcessLimit; 15873 } 15874 int emptyFactor = numEmptyProcs/numSlots; 15875 if (emptyFactor < 1) emptyFactor = 1; 15876 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15877 if (cachedFactor < 1) cachedFactor = 1; 15878 int stepCached = 0; 15879 int stepEmpty = 0; 15880 int numCached = 0; 15881 int numEmpty = 0; 15882 int numTrimming = 0; 15883 15884 mNumNonCachedProcs = 0; 15885 mNumCachedHiddenProcs = 0; 15886 15887 // First update the OOM adjustment for each of the 15888 // application processes based on their current state. 15889 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15890 int nextCachedAdj = curCachedAdj+1; 15891 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15892 int nextEmptyAdj = curEmptyAdj+2; 15893 for (int i=N-1; i>=0; i--) { 15894 ProcessRecord app = mLruProcesses.get(i); 15895 if (!app.killedByAm && app.thread != null) { 15896 app.procStateChanged = false; 15897 final boolean wasKeeping = app.keeping; 15898 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15899 15900 // If we haven't yet assigned the final cached adj 15901 // to the process, do that now. 15902 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15903 switch (app.curProcState) { 15904 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15905 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15906 // This process is a cached process holding activities... 15907 // assign it the next cached value for that type, and then 15908 // step that cached level. 15909 app.curRawAdj = curCachedAdj; 15910 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15911 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15912 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15913 + ")"); 15914 if (curCachedAdj != nextCachedAdj) { 15915 stepCached++; 15916 if (stepCached >= cachedFactor) { 15917 stepCached = 0; 15918 curCachedAdj = nextCachedAdj; 15919 nextCachedAdj += 2; 15920 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15921 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15922 } 15923 } 15924 } 15925 break; 15926 default: 15927 // For everything else, assign next empty cached process 15928 // level and bump that up. Note that this means that 15929 // long-running services that have dropped down to the 15930 // cached level will be treated as empty (since their process 15931 // state is still as a service), which is what we want. 15932 app.curRawAdj = curEmptyAdj; 15933 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15934 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15935 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15936 + ")"); 15937 if (curEmptyAdj != nextEmptyAdj) { 15938 stepEmpty++; 15939 if (stepEmpty >= emptyFactor) { 15940 stepEmpty = 0; 15941 curEmptyAdj = nextEmptyAdj; 15942 nextEmptyAdj += 2; 15943 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15944 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15945 } 15946 } 15947 } 15948 break; 15949 } 15950 } 15951 15952 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15953 15954 // Count the number of process types. 15955 switch (app.curProcState) { 15956 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15957 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15958 mNumCachedHiddenProcs++; 15959 numCached++; 15960 if (numCached > cachedProcessLimit) { 15961 killUnneededProcessLocked(app, "cached #" + numCached); 15962 } 15963 break; 15964 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15965 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15966 && app.lastActivityTime < oldTime) { 15967 killUnneededProcessLocked(app, "empty for " 15968 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15969 / 1000) + "s"); 15970 } else { 15971 numEmpty++; 15972 if (numEmpty > emptyProcessLimit) { 15973 killUnneededProcessLocked(app, "empty #" + numEmpty); 15974 } 15975 } 15976 break; 15977 default: 15978 mNumNonCachedProcs++; 15979 break; 15980 } 15981 15982 if (app.isolated && app.services.size() <= 0) { 15983 // If this is an isolated process, and there are no 15984 // services running in it, then the process is no longer 15985 // needed. We agressively kill these because we can by 15986 // definition not re-use the same process again, and it is 15987 // good to avoid having whatever code was running in them 15988 // left sitting around after no longer needed. 15989 killUnneededProcessLocked(app, "isolated not needed"); 15990 } 15991 15992 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15993 && !app.killedByAm) { 15994 numTrimming++; 15995 } 15996 } 15997 } 15998 15999 mNumServiceProcs = mNewNumServiceProcs; 16000 16001 // Now determine the memory trimming level of background processes. 16002 // Unfortunately we need to start at the back of the list to do this 16003 // properly. We only do this if the number of background apps we 16004 // are managing to keep around is less than half the maximum we desire; 16005 // if we are keeping a good number around, we'll let them use whatever 16006 // memory they want. 16007 final int numCachedAndEmpty = numCached + numEmpty; 16008 int memFactor; 16009 if (numCached <= ProcessList.TRIM_CACHED_APPS 16010 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16011 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16012 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16013 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16014 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16015 } else { 16016 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16017 } 16018 } else { 16019 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16020 } 16021 // We always allow the memory level to go up (better). We only allow it to go 16022 // down if we are in a state where that is allowed, *and* the total number of processes 16023 // has gone down since last time. 16024 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16025 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16026 + " last=" + mLastNumProcesses); 16027 if (memFactor > mLastMemoryLevel) { 16028 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16029 memFactor = mLastMemoryLevel; 16030 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16031 } 16032 } 16033 mLastMemoryLevel = memFactor; 16034 mLastNumProcesses = mLruProcesses.size(); 16035 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16036 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16037 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16038 if (mLowRamStartTime == 0) { 16039 mLowRamStartTime = now; 16040 } 16041 int step = 0; 16042 int fgTrimLevel; 16043 switch (memFactor) { 16044 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16045 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16046 break; 16047 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16048 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16049 break; 16050 default: 16051 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16052 break; 16053 } 16054 int factor = numTrimming/3; 16055 int minFactor = 2; 16056 if (mHomeProcess != null) minFactor++; 16057 if (mPreviousProcess != null) minFactor++; 16058 if (factor < minFactor) factor = minFactor; 16059 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16060 for (int i=N-1; i>=0; i--) { 16061 ProcessRecord app = mLruProcesses.get(i); 16062 if (allChanged || app.procStateChanged) { 16063 setProcessTrackerState(app, trackerMemFactor, now); 16064 app.procStateChanged = false; 16065 } 16066 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16067 && !app.killedByAm) { 16068 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16069 try { 16070 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16071 "Trimming memory of " + app.processName 16072 + " to " + curLevel); 16073 app.thread.scheduleTrimMemory(curLevel); 16074 } catch (RemoteException e) { 16075 } 16076 if (false) { 16077 // For now we won't do this; our memory trimming seems 16078 // to be good enough at this point that destroying 16079 // activities causes more harm than good. 16080 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16081 && app != mHomeProcess && app != mPreviousProcess) { 16082 // Need to do this on its own message because the stack may not 16083 // be in a consistent state at this point. 16084 // For these apps we will also finish their activities 16085 // to help them free memory. 16086 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16087 } 16088 } 16089 } 16090 app.trimMemoryLevel = curLevel; 16091 step++; 16092 if (step >= factor) { 16093 step = 0; 16094 switch (curLevel) { 16095 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16096 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16097 break; 16098 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16099 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16100 break; 16101 } 16102 } 16103 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16104 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16105 && app.thread != null) { 16106 try { 16107 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16108 "Trimming memory of heavy-weight " + app.processName 16109 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16110 app.thread.scheduleTrimMemory( 16111 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16112 } catch (RemoteException e) { 16113 } 16114 } 16115 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16116 } else { 16117 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16118 || app.systemNoUi) && app.pendingUiClean) { 16119 // If this application is now in the background and it 16120 // had done UI, then give it the special trim level to 16121 // have it free UI resources. 16122 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16123 if (app.trimMemoryLevel < level && app.thread != null) { 16124 try { 16125 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16126 "Trimming memory of bg-ui " + app.processName 16127 + " to " + level); 16128 app.thread.scheduleTrimMemory(level); 16129 } catch (RemoteException e) { 16130 } 16131 } 16132 app.pendingUiClean = false; 16133 } 16134 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16135 try { 16136 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16137 "Trimming memory of fg " + app.processName 16138 + " to " + fgTrimLevel); 16139 app.thread.scheduleTrimMemory(fgTrimLevel); 16140 } catch (RemoteException e) { 16141 } 16142 } 16143 app.trimMemoryLevel = fgTrimLevel; 16144 } 16145 } 16146 } else { 16147 if (mLowRamStartTime != 0) { 16148 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16149 mLowRamStartTime = 0; 16150 } 16151 for (int i=N-1; i>=0; i--) { 16152 ProcessRecord app = mLruProcesses.get(i); 16153 if (allChanged || app.procStateChanged) { 16154 setProcessTrackerState(app, trackerMemFactor, now); 16155 app.procStateChanged = false; 16156 } 16157 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16158 || app.systemNoUi) && app.pendingUiClean) { 16159 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16160 && app.thread != null) { 16161 try { 16162 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16163 "Trimming memory of ui hidden " + app.processName 16164 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16165 app.thread.scheduleTrimMemory( 16166 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16167 } catch (RemoteException e) { 16168 } 16169 } 16170 app.pendingUiClean = false; 16171 } 16172 app.trimMemoryLevel = 0; 16173 } 16174 } 16175 16176 if (mAlwaysFinishActivities) { 16177 // Need to do this on its own message because the stack may not 16178 // be in a consistent state at this point. 16179 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16180 } 16181 16182 if (allChanged) { 16183 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16184 } 16185 16186 if (mProcessStats.shouldWriteNowLocked(now)) { 16187 mHandler.post(new Runnable() { 16188 @Override public void run() { 16189 synchronized (ActivityManagerService.this) { 16190 mProcessStats.writeStateAsyncLocked(); 16191 } 16192 } 16193 }); 16194 } 16195 16196 if (DEBUG_OOM_ADJ) { 16197 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16198 } 16199 } 16200 16201 final void trimApplications() { 16202 synchronized (this) { 16203 int i; 16204 16205 // First remove any unused application processes whose package 16206 // has been removed. 16207 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16208 final ProcessRecord app = mRemovedProcesses.get(i); 16209 if (app.activities.size() == 0 16210 && app.curReceiver == null && app.services.size() == 0) { 16211 Slog.i( 16212 TAG, "Exiting empty application process " 16213 + app.processName + " (" 16214 + (app.thread != null ? app.thread.asBinder() : null) 16215 + ")\n"); 16216 if (app.pid > 0 && app.pid != MY_PID) { 16217 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16218 app.processName, app.setAdj, "empty"); 16219 app.killedByAm = true; 16220 Process.killProcessQuiet(app.pid); 16221 } else { 16222 try { 16223 app.thread.scheduleExit(); 16224 } catch (Exception e) { 16225 // Ignore exceptions. 16226 } 16227 } 16228 cleanUpApplicationRecordLocked(app, false, true, -1); 16229 mRemovedProcesses.remove(i); 16230 16231 if (app.persistent) { 16232 if (app.persistent) { 16233 addAppLocked(app.info, false); 16234 } 16235 } 16236 } 16237 } 16238 16239 // Now update the oom adj for all processes. 16240 updateOomAdjLocked(); 16241 } 16242 } 16243 16244 /** This method sends the specified signal to each of the persistent apps */ 16245 public void signalPersistentProcesses(int sig) throws RemoteException { 16246 if (sig != Process.SIGNAL_USR1) { 16247 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16248 } 16249 16250 synchronized (this) { 16251 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16252 != PackageManager.PERMISSION_GRANTED) { 16253 throw new SecurityException("Requires permission " 16254 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16255 } 16256 16257 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16258 ProcessRecord r = mLruProcesses.get(i); 16259 if (r.thread != null && r.persistent) { 16260 Process.sendSignal(r.pid, sig); 16261 } 16262 } 16263 } 16264 } 16265 16266 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16267 if (proc == null || proc == mProfileProc) { 16268 proc = mProfileProc; 16269 path = mProfileFile; 16270 profileType = mProfileType; 16271 clearProfilerLocked(); 16272 } 16273 if (proc == null) { 16274 return; 16275 } 16276 try { 16277 proc.thread.profilerControl(false, path, null, profileType); 16278 } catch (RemoteException e) { 16279 throw new IllegalStateException("Process disappeared"); 16280 } 16281 } 16282 16283 private void clearProfilerLocked() { 16284 if (mProfileFd != null) { 16285 try { 16286 mProfileFd.close(); 16287 } catch (IOException e) { 16288 } 16289 } 16290 mProfileApp = null; 16291 mProfileProc = null; 16292 mProfileFile = null; 16293 mProfileType = 0; 16294 mAutoStopProfiler = false; 16295 } 16296 16297 public boolean profileControl(String process, int userId, boolean start, 16298 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16299 16300 try { 16301 synchronized (this) { 16302 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16303 // its own permission. 16304 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16305 != PackageManager.PERMISSION_GRANTED) { 16306 throw new SecurityException("Requires permission " 16307 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16308 } 16309 16310 if (start && fd == null) { 16311 throw new IllegalArgumentException("null fd"); 16312 } 16313 16314 ProcessRecord proc = null; 16315 if (process != null) { 16316 proc = findProcessLocked(process, userId, "profileControl"); 16317 } 16318 16319 if (start && (proc == null || proc.thread == null)) { 16320 throw new IllegalArgumentException("Unknown process: " + process); 16321 } 16322 16323 if (start) { 16324 stopProfilerLocked(null, null, 0); 16325 setProfileApp(proc.info, proc.processName, path, fd, false); 16326 mProfileProc = proc; 16327 mProfileType = profileType; 16328 try { 16329 fd = fd.dup(); 16330 } catch (IOException e) { 16331 fd = null; 16332 } 16333 proc.thread.profilerControl(start, path, fd, profileType); 16334 fd = null; 16335 mProfileFd = null; 16336 } else { 16337 stopProfilerLocked(proc, path, profileType); 16338 if (fd != null) { 16339 try { 16340 fd.close(); 16341 } catch (IOException e) { 16342 } 16343 } 16344 } 16345 16346 return true; 16347 } 16348 } catch (RemoteException e) { 16349 throw new IllegalStateException("Process disappeared"); 16350 } finally { 16351 if (fd != null) { 16352 try { 16353 fd.close(); 16354 } catch (IOException e) { 16355 } 16356 } 16357 } 16358 } 16359 16360 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16361 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16362 userId, true, true, callName, null); 16363 ProcessRecord proc = null; 16364 try { 16365 int pid = Integer.parseInt(process); 16366 synchronized (mPidsSelfLocked) { 16367 proc = mPidsSelfLocked.get(pid); 16368 } 16369 } catch (NumberFormatException e) { 16370 } 16371 16372 if (proc == null) { 16373 ArrayMap<String, SparseArray<ProcessRecord>> all 16374 = mProcessNames.getMap(); 16375 SparseArray<ProcessRecord> procs = all.get(process); 16376 if (procs != null && procs.size() > 0) { 16377 proc = procs.valueAt(0); 16378 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16379 for (int i=1; i<procs.size(); i++) { 16380 ProcessRecord thisProc = procs.valueAt(i); 16381 if (thisProc.userId == userId) { 16382 proc = thisProc; 16383 break; 16384 } 16385 } 16386 } 16387 } 16388 } 16389 16390 return proc; 16391 } 16392 16393 public boolean dumpHeap(String process, int userId, boolean managed, 16394 String path, ParcelFileDescriptor fd) throws RemoteException { 16395 16396 try { 16397 synchronized (this) { 16398 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16399 // its own permission (same as profileControl). 16400 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16401 != PackageManager.PERMISSION_GRANTED) { 16402 throw new SecurityException("Requires permission " 16403 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16404 } 16405 16406 if (fd == null) { 16407 throw new IllegalArgumentException("null fd"); 16408 } 16409 16410 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16411 if (proc == null || proc.thread == null) { 16412 throw new IllegalArgumentException("Unknown process: " + process); 16413 } 16414 16415 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16416 if (!isDebuggable) { 16417 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16418 throw new SecurityException("Process not debuggable: " + proc); 16419 } 16420 } 16421 16422 proc.thread.dumpHeap(managed, path, fd); 16423 fd = null; 16424 return true; 16425 } 16426 } catch (RemoteException e) { 16427 throw new IllegalStateException("Process disappeared"); 16428 } finally { 16429 if (fd != null) { 16430 try { 16431 fd.close(); 16432 } catch (IOException e) { 16433 } 16434 } 16435 } 16436 } 16437 16438 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16439 public void monitor() { 16440 synchronized (this) { } 16441 } 16442 16443 void onCoreSettingsChange(Bundle settings) { 16444 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16445 ProcessRecord processRecord = mLruProcesses.get(i); 16446 try { 16447 if (processRecord.thread != null) { 16448 processRecord.thread.setCoreSettings(settings); 16449 } 16450 } catch (RemoteException re) { 16451 /* ignore */ 16452 } 16453 } 16454 } 16455 16456 // Multi-user methods 16457 16458 /** 16459 * Start user, if its not already running, but don't bring it to foreground. 16460 */ 16461 @Override 16462 public boolean startUserInBackground(final int userId) { 16463 return startUser(userId, /* foreground */ false); 16464 } 16465 16466 /** 16467 * Refreshes the list of users related to the current user when either a 16468 * user switch happens or when a new related user is started in the 16469 * background. 16470 */ 16471 private void updateCurrentProfileIdsLocked() { 16472 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16473 mCurrentUserId, false /* enabledOnly */); 16474 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16475 for (int i = 0; i < currentProfileIds.length; i++) { 16476 currentProfileIds[i] = profiles.get(i).id; 16477 } 16478 mCurrentProfileIds = currentProfileIds; 16479 } 16480 16481 private Set getProfileIdsLocked(int userId) { 16482 Set userIds = new HashSet<Integer>(); 16483 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16484 userId, false /* enabledOnly */); 16485 for (UserInfo user : profiles) { 16486 userIds.add(Integer.valueOf(user.id)); 16487 } 16488 return userIds; 16489 } 16490 16491 @Override 16492 public boolean switchUser(final int userId) { 16493 return startUser(userId, /* foregound */ true); 16494 } 16495 16496 private boolean startUser(final int userId, boolean foreground) { 16497 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16498 != PackageManager.PERMISSION_GRANTED) { 16499 String msg = "Permission Denial: switchUser() from pid=" 16500 + Binder.getCallingPid() 16501 + ", uid=" + Binder.getCallingUid() 16502 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16503 Slog.w(TAG, msg); 16504 throw new SecurityException(msg); 16505 } 16506 16507 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16508 16509 final long ident = Binder.clearCallingIdentity(); 16510 try { 16511 synchronized (this) { 16512 final int oldUserId = mCurrentUserId; 16513 if (oldUserId == userId) { 16514 return true; 16515 } 16516 16517 mStackSupervisor.setLockTaskModeLocked(null); 16518 16519 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16520 if (userInfo == null) { 16521 Slog.w(TAG, "No user info for user #" + userId); 16522 return false; 16523 } 16524 16525 if (foreground) { 16526 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16527 R.anim.screen_user_enter); 16528 } 16529 16530 boolean needStart = false; 16531 16532 // If the user we are switching to is not currently started, then 16533 // we need to start it now. 16534 if (mStartedUsers.get(userId) == null) { 16535 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16536 updateStartedUserArrayLocked(); 16537 needStart = true; 16538 } 16539 16540 final Integer userIdInt = Integer.valueOf(userId); 16541 mUserLru.remove(userIdInt); 16542 mUserLru.add(userIdInt); 16543 16544 if (foreground) { 16545 mCurrentUserId = userId; 16546 updateCurrentProfileIdsLocked(); 16547 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16548 // Once the internal notion of the active user has switched, we lock the device 16549 // with the option to show the user switcher on the keyguard. 16550 mWindowManager.lockNow(null); 16551 } else { 16552 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16553 updateCurrentProfileIdsLocked(); 16554 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16555 mUserLru.remove(currentUserIdInt); 16556 mUserLru.add(currentUserIdInt); 16557 } 16558 16559 final UserStartedState uss = mStartedUsers.get(userId); 16560 16561 // Make sure user is in the started state. If it is currently 16562 // stopping, we need to knock that off. 16563 if (uss.mState == UserStartedState.STATE_STOPPING) { 16564 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16565 // so we can just fairly silently bring the user back from 16566 // the almost-dead. 16567 uss.mState = UserStartedState.STATE_RUNNING; 16568 updateStartedUserArrayLocked(); 16569 needStart = true; 16570 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16571 // This means ACTION_SHUTDOWN has been sent, so we will 16572 // need to treat this as a new boot of the user. 16573 uss.mState = UserStartedState.STATE_BOOTING; 16574 updateStartedUserArrayLocked(); 16575 needStart = true; 16576 } 16577 16578 if (uss.mState == UserStartedState.STATE_BOOTING) { 16579 // Booting up a new user, need to tell system services about it. 16580 // Note that this is on the same handler as scheduling of broadcasts, 16581 // which is important because it needs to go first. 16582 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16583 } 16584 16585 if (foreground) { 16586 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16587 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16588 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16589 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16590 oldUserId, userId, uss)); 16591 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16592 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16593 } 16594 16595 if (needStart) { 16596 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16597 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16598 | Intent.FLAG_RECEIVER_FOREGROUND); 16599 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16600 broadcastIntentLocked(null, null, intent, 16601 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16602 false, false, MY_PID, Process.SYSTEM_UID, userId); 16603 } 16604 16605 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16606 if (userId != UserHandle.USER_OWNER) { 16607 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16608 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16609 broadcastIntentLocked(null, null, intent, null, 16610 new IIntentReceiver.Stub() { 16611 public void performReceive(Intent intent, int resultCode, 16612 String data, Bundle extras, boolean ordered, 16613 boolean sticky, int sendingUser) { 16614 userInitialized(uss, userId); 16615 } 16616 }, 0, null, null, null, AppOpsManager.OP_NONE, 16617 true, false, MY_PID, Process.SYSTEM_UID, 16618 userId); 16619 uss.initializing = true; 16620 } else { 16621 getUserManagerLocked().makeInitialized(userInfo.id); 16622 } 16623 } 16624 16625 if (foreground) { 16626 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16627 if (homeInFront) { 16628 startHomeActivityLocked(userId); 16629 } else { 16630 mStackSupervisor.resumeTopActivitiesLocked(); 16631 } 16632 EventLogTags.writeAmSwitchUser(userId); 16633 getUserManagerLocked().userForeground(userId); 16634 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16635 } else { 16636 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16637 } 16638 16639 if (needStart) { 16640 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16641 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16642 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16643 broadcastIntentLocked(null, null, intent, 16644 null, new IIntentReceiver.Stub() { 16645 @Override 16646 public void performReceive(Intent intent, int resultCode, String data, 16647 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16648 throws RemoteException { 16649 } 16650 }, 0, null, null, 16651 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16652 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16653 } 16654 } 16655 } finally { 16656 Binder.restoreCallingIdentity(ident); 16657 } 16658 16659 return true; 16660 } 16661 16662 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16663 long ident = Binder.clearCallingIdentity(); 16664 try { 16665 Intent intent; 16666 if (oldUserId >= 0) { 16667 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16668 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16669 | Intent.FLAG_RECEIVER_FOREGROUND); 16670 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16671 broadcastIntentLocked(null, null, intent, 16672 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16673 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16674 } 16675 if (newUserId >= 0) { 16676 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16677 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16678 | Intent.FLAG_RECEIVER_FOREGROUND); 16679 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16680 broadcastIntentLocked(null, null, intent, 16681 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16682 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16683 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16684 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16685 | Intent.FLAG_RECEIVER_FOREGROUND); 16686 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16687 broadcastIntentLocked(null, null, intent, 16688 null, null, 0, null, null, 16689 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16690 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16691 } 16692 } finally { 16693 Binder.restoreCallingIdentity(ident); 16694 } 16695 } 16696 16697 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16698 final int newUserId) { 16699 final int N = mUserSwitchObservers.beginBroadcast(); 16700 if (N > 0) { 16701 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16702 int mCount = 0; 16703 @Override 16704 public void sendResult(Bundle data) throws RemoteException { 16705 synchronized (ActivityManagerService.this) { 16706 if (mCurUserSwitchCallback == this) { 16707 mCount++; 16708 if (mCount == N) { 16709 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16710 } 16711 } 16712 } 16713 } 16714 }; 16715 synchronized (this) { 16716 uss.switching = true; 16717 mCurUserSwitchCallback = callback; 16718 } 16719 for (int i=0; i<N; i++) { 16720 try { 16721 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16722 newUserId, callback); 16723 } catch (RemoteException e) { 16724 } 16725 } 16726 } else { 16727 synchronized (this) { 16728 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16729 } 16730 } 16731 mUserSwitchObservers.finishBroadcast(); 16732 } 16733 16734 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16735 synchronized (this) { 16736 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16737 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16738 } 16739 } 16740 16741 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16742 mCurUserSwitchCallback = null; 16743 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16744 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16745 oldUserId, newUserId, uss)); 16746 } 16747 16748 void userInitialized(UserStartedState uss, int newUserId) { 16749 completeSwitchAndInitalize(uss, newUserId, true, false); 16750 } 16751 16752 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16753 completeSwitchAndInitalize(uss, newUserId, false, true); 16754 } 16755 16756 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16757 boolean clearInitializing, boolean clearSwitching) { 16758 boolean unfrozen = false; 16759 synchronized (this) { 16760 if (clearInitializing) { 16761 uss.initializing = false; 16762 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16763 } 16764 if (clearSwitching) { 16765 uss.switching = false; 16766 } 16767 if (!uss.switching && !uss.initializing) { 16768 mWindowManager.stopFreezingScreen(); 16769 unfrozen = true; 16770 } 16771 } 16772 if (unfrozen) { 16773 final int N = mUserSwitchObservers.beginBroadcast(); 16774 for (int i=0; i<N; i++) { 16775 try { 16776 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16777 } catch (RemoteException e) { 16778 } 16779 } 16780 mUserSwitchObservers.finishBroadcast(); 16781 } 16782 } 16783 16784 void scheduleStartProfilesLocked() { 16785 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16786 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16787 DateUtils.SECOND_IN_MILLIS); 16788 } 16789 } 16790 16791 void startProfilesLocked() { 16792 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16793 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16794 mCurrentUserId, false /* enabledOnly */); 16795 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16796 for (UserInfo user : profiles) { 16797 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16798 && user.id != mCurrentUserId) { 16799 toStart.add(user); 16800 } 16801 } 16802 final int n = toStart.size(); 16803 int i = 0; 16804 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16805 startUserInBackground(toStart.get(i).id); 16806 } 16807 if (i < n) { 16808 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16809 } 16810 } 16811 16812 void finishUserBoot(UserStartedState uss) { 16813 synchronized (this) { 16814 if (uss.mState == UserStartedState.STATE_BOOTING 16815 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16816 uss.mState = UserStartedState.STATE_RUNNING; 16817 final int userId = uss.mHandle.getIdentifier(); 16818 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16819 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16820 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16821 broadcastIntentLocked(null, null, intent, 16822 null, null, 0, null, null, 16823 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16824 true, false, MY_PID, Process.SYSTEM_UID, userId); 16825 } 16826 } 16827 } 16828 16829 void finishUserSwitch(UserStartedState uss) { 16830 synchronized (this) { 16831 finishUserBoot(uss); 16832 16833 startProfilesLocked(); 16834 16835 int num = mUserLru.size(); 16836 int i = 0; 16837 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16838 Integer oldUserId = mUserLru.get(i); 16839 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16840 if (oldUss == null) { 16841 // Shouldn't happen, but be sane if it does. 16842 mUserLru.remove(i); 16843 num--; 16844 continue; 16845 } 16846 if (oldUss.mState == UserStartedState.STATE_STOPPING 16847 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16848 // This user is already stopping, doesn't count. 16849 num--; 16850 i++; 16851 continue; 16852 } 16853 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16854 // Owner and current can't be stopped, but count as running. 16855 i++; 16856 continue; 16857 } 16858 // This is a user to be stopped. 16859 stopUserLocked(oldUserId, null); 16860 num--; 16861 i++; 16862 } 16863 } 16864 } 16865 16866 @Override 16867 public int stopUser(final int userId, final IStopUserCallback callback) { 16868 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16869 != PackageManager.PERMISSION_GRANTED) { 16870 String msg = "Permission Denial: switchUser() from pid=" 16871 + Binder.getCallingPid() 16872 + ", uid=" + Binder.getCallingUid() 16873 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16874 Slog.w(TAG, msg); 16875 throw new SecurityException(msg); 16876 } 16877 if (userId <= 0) { 16878 throw new IllegalArgumentException("Can't stop primary user " + userId); 16879 } 16880 synchronized (this) { 16881 return stopUserLocked(userId, callback); 16882 } 16883 } 16884 16885 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16886 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16887 if (mCurrentUserId == userId) { 16888 return ActivityManager.USER_OP_IS_CURRENT; 16889 } 16890 16891 final UserStartedState uss = mStartedUsers.get(userId); 16892 if (uss == null) { 16893 // User is not started, nothing to do... but we do need to 16894 // callback if requested. 16895 if (callback != null) { 16896 mHandler.post(new Runnable() { 16897 @Override 16898 public void run() { 16899 try { 16900 callback.userStopped(userId); 16901 } catch (RemoteException e) { 16902 } 16903 } 16904 }); 16905 } 16906 return ActivityManager.USER_OP_SUCCESS; 16907 } 16908 16909 if (callback != null) { 16910 uss.mStopCallbacks.add(callback); 16911 } 16912 16913 if (uss.mState != UserStartedState.STATE_STOPPING 16914 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16915 uss.mState = UserStartedState.STATE_STOPPING; 16916 updateStartedUserArrayLocked(); 16917 16918 long ident = Binder.clearCallingIdentity(); 16919 try { 16920 // We are going to broadcast ACTION_USER_STOPPING and then 16921 // once that is done send a final ACTION_SHUTDOWN and then 16922 // stop the user. 16923 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16924 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16925 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16926 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16927 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16928 // This is the result receiver for the final shutdown broadcast. 16929 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16930 @Override 16931 public void performReceive(Intent intent, int resultCode, String data, 16932 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16933 finishUserStop(uss); 16934 } 16935 }; 16936 // This is the result receiver for the initial stopping broadcast. 16937 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16938 @Override 16939 public void performReceive(Intent intent, int resultCode, String data, 16940 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16941 // On to the next. 16942 synchronized (ActivityManagerService.this) { 16943 if (uss.mState != UserStartedState.STATE_STOPPING) { 16944 // Whoops, we are being started back up. Abort, abort! 16945 return; 16946 } 16947 uss.mState = UserStartedState.STATE_SHUTDOWN; 16948 } 16949 mSystemServiceManager.stopUser(userId); 16950 broadcastIntentLocked(null, null, shutdownIntent, 16951 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16952 true, false, MY_PID, Process.SYSTEM_UID, userId); 16953 } 16954 }; 16955 // Kick things off. 16956 broadcastIntentLocked(null, null, stoppingIntent, 16957 null, stoppingReceiver, 0, null, null, 16958 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16959 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16960 } finally { 16961 Binder.restoreCallingIdentity(ident); 16962 } 16963 } 16964 16965 return ActivityManager.USER_OP_SUCCESS; 16966 } 16967 16968 void finishUserStop(UserStartedState uss) { 16969 final int userId = uss.mHandle.getIdentifier(); 16970 boolean stopped; 16971 ArrayList<IStopUserCallback> callbacks; 16972 synchronized (this) { 16973 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16974 if (mStartedUsers.get(userId) != uss) { 16975 stopped = false; 16976 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16977 stopped = false; 16978 } else { 16979 stopped = true; 16980 // User can no longer run. 16981 mStartedUsers.remove(userId); 16982 mUserLru.remove(Integer.valueOf(userId)); 16983 updateStartedUserArrayLocked(); 16984 16985 // Clean up all state and processes associated with the user. 16986 // Kill all the processes for the user. 16987 forceStopUserLocked(userId, "finish user"); 16988 } 16989 } 16990 16991 for (int i=0; i<callbacks.size(); i++) { 16992 try { 16993 if (stopped) callbacks.get(i).userStopped(userId); 16994 else callbacks.get(i).userStopAborted(userId); 16995 } catch (RemoteException e) { 16996 } 16997 } 16998 16999 if (stopped) { 17000 mSystemServiceManager.cleanupUser(userId); 17001 synchronized (this) { 17002 mStackSupervisor.removeUserLocked(userId); 17003 } 17004 } 17005 } 17006 17007 @Override 17008 public UserInfo getCurrentUser() { 17009 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17010 != PackageManager.PERMISSION_GRANTED) && ( 17011 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17012 != PackageManager.PERMISSION_GRANTED)) { 17013 String msg = "Permission Denial: getCurrentUser() from pid=" 17014 + Binder.getCallingPid() 17015 + ", uid=" + Binder.getCallingUid() 17016 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17017 Slog.w(TAG, msg); 17018 throw new SecurityException(msg); 17019 } 17020 synchronized (this) { 17021 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17022 } 17023 } 17024 17025 int getCurrentUserIdLocked() { 17026 return mCurrentUserId; 17027 } 17028 17029 @Override 17030 public boolean isUserRunning(int userId, boolean orStopped) { 17031 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17032 != PackageManager.PERMISSION_GRANTED) { 17033 String msg = "Permission Denial: isUserRunning() from pid=" 17034 + Binder.getCallingPid() 17035 + ", uid=" + Binder.getCallingUid() 17036 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17037 Slog.w(TAG, msg); 17038 throw new SecurityException(msg); 17039 } 17040 synchronized (this) { 17041 return isUserRunningLocked(userId, orStopped); 17042 } 17043 } 17044 17045 boolean isUserRunningLocked(int userId, boolean orStopped) { 17046 UserStartedState state = mStartedUsers.get(userId); 17047 if (state == null) { 17048 return false; 17049 } 17050 if (orStopped) { 17051 return true; 17052 } 17053 return state.mState != UserStartedState.STATE_STOPPING 17054 && state.mState != UserStartedState.STATE_SHUTDOWN; 17055 } 17056 17057 @Override 17058 public int[] getRunningUserIds() { 17059 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17060 != PackageManager.PERMISSION_GRANTED) { 17061 String msg = "Permission Denial: isUserRunning() from pid=" 17062 + Binder.getCallingPid() 17063 + ", uid=" + Binder.getCallingUid() 17064 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17065 Slog.w(TAG, msg); 17066 throw new SecurityException(msg); 17067 } 17068 synchronized (this) { 17069 return mStartedUserArray; 17070 } 17071 } 17072 17073 private void updateStartedUserArrayLocked() { 17074 int num = 0; 17075 for (int i=0; i<mStartedUsers.size(); i++) { 17076 UserStartedState uss = mStartedUsers.valueAt(i); 17077 // This list does not include stopping users. 17078 if (uss.mState != UserStartedState.STATE_STOPPING 17079 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17080 num++; 17081 } 17082 } 17083 mStartedUserArray = new int[num]; 17084 num = 0; 17085 for (int i=0; i<mStartedUsers.size(); i++) { 17086 UserStartedState uss = mStartedUsers.valueAt(i); 17087 if (uss.mState != UserStartedState.STATE_STOPPING 17088 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17089 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17090 num++; 17091 } 17092 } 17093 } 17094 17095 @Override 17096 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17097 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17098 != PackageManager.PERMISSION_GRANTED) { 17099 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17100 + Binder.getCallingPid() 17101 + ", uid=" + Binder.getCallingUid() 17102 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17103 Slog.w(TAG, msg); 17104 throw new SecurityException(msg); 17105 } 17106 17107 mUserSwitchObservers.register(observer); 17108 } 17109 17110 @Override 17111 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17112 mUserSwitchObservers.unregister(observer); 17113 } 17114 17115 private boolean userExists(int userId) { 17116 if (userId == 0) { 17117 return true; 17118 } 17119 UserManagerService ums = getUserManagerLocked(); 17120 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17121 } 17122 17123 int[] getUsersLocked() { 17124 UserManagerService ums = getUserManagerLocked(); 17125 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17126 } 17127 17128 UserManagerService getUserManagerLocked() { 17129 if (mUserManager == null) { 17130 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17131 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17132 } 17133 return mUserManager; 17134 } 17135 17136 private int applyUserId(int uid, int userId) { 17137 return UserHandle.getUid(userId, uid); 17138 } 17139 17140 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17141 if (info == null) return null; 17142 ApplicationInfo newInfo = new ApplicationInfo(info); 17143 newInfo.uid = applyUserId(info.uid, userId); 17144 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17145 + info.packageName; 17146 return newInfo; 17147 } 17148 17149 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17150 if (aInfo == null 17151 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17152 return aInfo; 17153 } 17154 17155 ActivityInfo info = new ActivityInfo(aInfo); 17156 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17157 return info; 17158 } 17159 17160 private final class LocalService extends ActivityManagerInternal { 17161 @Override 17162 public void goingToSleep() { 17163 ActivityManagerService.this.goingToSleep(); 17164 } 17165 17166 @Override 17167 public void wakingUp() { 17168 ActivityManagerService.this.wakingUp(); 17169 } 17170 } 17171 17172 /** 17173 * An implementation of IAppTask, that allows an app to manage its own tasks via 17174 * {@link android.app.ActivityManager#AppTask}. We keep track of the callingUid to ensure that 17175 * only the process that calls getAppTasks() can call the AppTask methods. 17176 */ 17177 class AppTaskImpl extends IAppTask.Stub { 17178 private int mTaskId; 17179 private int mCallingUid; 17180 17181 public AppTaskImpl(int taskId, int callingUid) { 17182 mTaskId = taskId; 17183 mCallingUid = callingUid; 17184 } 17185 17186 @Override 17187 public void finishAndRemoveTask() { 17188 // Ensure that we are called from the same process that created this AppTask 17189 if (mCallingUid != Binder.getCallingUid()) { 17190 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17191 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17192 return; 17193 } 17194 17195 synchronized (ActivityManagerService.this) { 17196 long origId = Binder.clearCallingIdentity(); 17197 try { 17198 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17199 if (tr != null) { 17200 // Only kill the process if we are not a new document 17201 int flags = tr.getBaseIntent().getFlags(); 17202 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == 17203 Intent.FLAG_ACTIVITY_NEW_DOCUMENT; 17204 removeTaskByIdLocked(mTaskId, 17205 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0); 17206 } 17207 } finally { 17208 Binder.restoreCallingIdentity(origId); 17209 } 17210 } 17211 } 17212 17213 @Override 17214 public ActivityManager.RecentTaskInfo getTaskInfo() { 17215 // Ensure that we are called from the same process that created this AppTask 17216 if (mCallingUid != Binder.getCallingUid()) { 17217 Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid 17218 + " does not match caller of getAppTasks(): " + Binder.getCallingUid()); 17219 return null; 17220 } 17221 17222 synchronized (ActivityManagerService.this) { 17223 long origId = Binder.clearCallingIdentity(); 17224 try { 17225 TaskRecord tr = recentTaskForIdLocked(mTaskId); 17226 if (tr != null) { 17227 return createRecentTaskInfoFromTaskRecord(tr); 17228 } 17229 } finally { 17230 Binder.restoreCallingIdentity(origId); 17231 } 17232 return null; 17233 } 17234 } 17235 } 17236} 17237