ActivityManagerService.java revision 684bf34ee8acc41931fac23762b13e14a22011db
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.appwidget.AppWidgetManager; 36import android.graphics.Rect; 37import android.os.BatteryStats; 38import android.service.voice.IVoiceInteractionSession; 39import android.util.ArrayMap; 40 41import com.android.internal.R; 42import com.android.internal.annotations.GuardedBy; 43import com.android.internal.app.IAppOpsService; 44import com.android.internal.app.IVoiceInteractor; 45import com.android.internal.app.ProcessMap; 46import com.android.internal.app.ProcessStats; 47import com.android.internal.content.PackageMonitor; 48import com.android.internal.os.BackgroundThread; 49import com.android.internal.os.BatteryStatsImpl; 50import com.android.internal.os.ProcessCpuTracker; 51import com.android.internal.os.TransferPipe; 52import com.android.internal.os.Zygote; 53import com.android.internal.util.FastPrintWriter; 54import com.android.internal.util.FastXmlSerializer; 55import com.android.internal.util.MemInfoReader; 56import com.android.internal.util.Preconditions; 57import com.android.server.AppOpsService; 58import com.android.server.AttributeCache; 59import com.android.server.IntentResolver; 60import com.android.server.LocalServices; 61import com.android.server.ServiceThread; 62import com.android.server.SystemService; 63import com.android.server.SystemServiceManager; 64import com.android.server.Watchdog; 65import com.android.server.am.ActivityStack.ActivityState; 66import com.android.server.firewall.IntentFirewall; 67import com.android.server.pm.UserManagerService; 68import com.android.server.wm.AppTransition; 69import com.android.server.wm.WindowManagerService; 70import com.google.android.collect.Lists; 71import com.google.android.collect.Maps; 72 73import libcore.io.IoUtils; 74 75import org.xmlpull.v1.XmlPullParser; 76import org.xmlpull.v1.XmlPullParserException; 77import org.xmlpull.v1.XmlSerializer; 78 79import android.app.Activity; 80import android.app.ActivityManager; 81import android.app.ActivityManager.RunningTaskInfo; 82import android.app.ActivityManager.StackInfo; 83import android.app.ActivityManagerInternal; 84import android.app.ActivityManagerNative; 85import android.app.ActivityOptions; 86import android.app.ActivityThread; 87import android.app.AlertDialog; 88import android.app.AppGlobals; 89import android.app.ApplicationErrorReport; 90import android.app.Dialog; 91import android.app.IActivityController; 92import android.app.IApplicationThread; 93import android.app.IInstrumentationWatcher; 94import android.app.INotificationManager; 95import android.app.IProcessObserver; 96import android.app.IServiceConnection; 97import android.app.IStopUserCallback; 98import android.app.IThumbnailReceiver; 99import android.app.IUiAutomationConnection; 100import android.app.IUserSwitchObserver; 101import android.app.Instrumentation; 102import android.app.Notification; 103import android.app.NotificationManager; 104import android.app.PendingIntent; 105import android.app.backup.IBackupManager; 106import android.content.ActivityNotFoundException; 107import android.content.BroadcastReceiver; 108import android.content.ClipData; 109import android.content.ComponentCallbacks2; 110import android.content.ComponentName; 111import android.content.ContentProvider; 112import android.content.ContentResolver; 113import android.content.Context; 114import android.content.DialogInterface; 115import android.content.IContentProvider; 116import android.content.IIntentReceiver; 117import android.content.IIntentSender; 118import android.content.Intent; 119import android.content.IntentFilter; 120import android.content.IntentSender; 121import android.content.pm.ActivityInfo; 122import android.content.pm.ApplicationInfo; 123import android.content.pm.ConfigurationInfo; 124import android.content.pm.IPackageDataObserver; 125import android.content.pm.IPackageManager; 126import android.content.pm.InstrumentationInfo; 127import android.content.pm.PackageInfo; 128import android.content.pm.PackageManager; 129import android.content.pm.ParceledListSlice; 130import android.content.pm.UserInfo; 131import android.content.pm.PackageManager.NameNotFoundException; 132import android.content.pm.PathPermission; 133import android.content.pm.ProviderInfo; 134import android.content.pm.ResolveInfo; 135import android.content.pm.ServiceInfo; 136import android.content.res.CompatibilityInfo; 137import android.content.res.Configuration; 138import android.graphics.Bitmap; 139import android.net.Proxy; 140import android.net.ProxyProperties; 141import android.net.Uri; 142import android.os.Binder; 143import android.os.Build; 144import android.os.Bundle; 145import android.os.Debug; 146import android.os.DropBoxManager; 147import android.os.Environment; 148import android.os.FactoryTest; 149import android.os.FileObserver; 150import android.os.FileUtils; 151import android.os.Handler; 152import android.os.IBinder; 153import android.os.IPermissionController; 154import android.os.IRemoteCallback; 155import android.os.IUserManager; 156import android.os.Looper; 157import android.os.Message; 158import android.os.Parcel; 159import android.os.ParcelFileDescriptor; 160import android.os.Process; 161import android.os.RemoteCallbackList; 162import android.os.RemoteException; 163import android.os.SELinux; 164import android.os.ServiceManager; 165import android.os.StrictMode; 166import android.os.SystemClock; 167import android.os.SystemProperties; 168import android.os.UpdateLock; 169import android.os.UserHandle; 170import android.provider.Settings; 171import android.text.format.DateUtils; 172import android.text.format.Time; 173import android.util.AtomicFile; 174import android.util.EventLog; 175import android.util.Log; 176import android.util.Pair; 177import android.util.PrintWriterPrinter; 178import android.util.Slog; 179import android.util.SparseArray; 180import android.util.TimeUtils; 181import android.util.Xml; 182import android.view.Gravity; 183import android.view.LayoutInflater; 184import android.view.View; 185import android.view.WindowManager; 186 187import java.io.BufferedInputStream; 188import java.io.BufferedOutputStream; 189import java.io.DataInputStream; 190import java.io.DataOutputStream; 191import java.io.File; 192import java.io.FileDescriptor; 193import java.io.FileInputStream; 194import java.io.FileNotFoundException; 195import java.io.FileOutputStream; 196import java.io.IOException; 197import java.io.InputStreamReader; 198import java.io.PrintWriter; 199import java.io.StringWriter; 200import java.lang.ref.WeakReference; 201import java.util.ArrayList; 202import java.util.Arrays; 203import java.util.Collections; 204import java.util.Comparator; 205import java.util.HashMap; 206import java.util.HashSet; 207import java.util.Iterator; 208import java.util.List; 209import java.util.Locale; 210import java.util.Map; 211import java.util.Set; 212import java.util.concurrent.atomic.AtomicBoolean; 213import java.util.concurrent.atomic.AtomicLong; 214 215public final class ActivityManagerService extends ActivityManagerNative 216 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 217 private static final String USER_DATA_DIR = "/data/user/"; 218 static final String TAG = "ActivityManager"; 219 static final String TAG_MU = "ActivityManagerServiceMU"; 220 static final boolean DEBUG = false; 221 static final boolean localLOGV = DEBUG; 222 static final boolean DEBUG_BACKUP = localLOGV || false; 223 static final boolean DEBUG_BROADCAST = localLOGV || false; 224 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 226 static final boolean DEBUG_CLEANUP = localLOGV || false; 227 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 228 static final boolean DEBUG_FOCUS = false; 229 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 230 static final boolean DEBUG_MU = localLOGV || false; 231 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 232 static final boolean DEBUG_LRU = localLOGV || false; 233 static final boolean DEBUG_PAUSE = localLOGV || false; 234 static final boolean DEBUG_POWER = localLOGV || false; 235 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 236 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 237 static final boolean DEBUG_PROCESSES = localLOGV || false; 238 static final boolean DEBUG_PROVIDER = localLOGV || false; 239 static final boolean DEBUG_RESULTS = localLOGV || false; 240 static final boolean DEBUG_SERVICE = localLOGV || false; 241 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 242 static final boolean DEBUG_STACK = localLOGV || false; 243 static final boolean DEBUG_SWITCH = localLOGV || false; 244 static final boolean DEBUG_TASKS = localLOGV || false; 245 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 246 static final boolean DEBUG_TRANSITION = localLOGV || false; 247 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 248 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 249 static final boolean DEBUG_VISBILITY = localLOGV || false; 250 static final boolean DEBUG_PSS = localLOGV || false; 251 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 252 static final boolean VALIDATE_TOKENS = false; 253 static final boolean SHOW_ACTIVITY_START_TIME = true; 254 255 // Control over CPU and battery monitoring. 256 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 257 static final boolean MONITOR_CPU_USAGE = true; 258 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 259 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 260 static final boolean MONITOR_THREAD_CPU_USAGE = false; 261 262 // The flags that are set for all calls we make to the package manager. 263 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 264 265 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 266 267 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 268 269 // Maximum number of recent tasks that we can remember. 270 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 271 272 // Amount of time after a call to stopAppSwitches() during which we will 273 // prevent further untrusted switches from happening. 274 static final long APP_SWITCH_DELAY_TIME = 5*1000; 275 276 // How long we wait for a launched process to attach to the activity manager 277 // before we decide it's never going to come up for real. 278 static final int PROC_START_TIMEOUT = 10*1000; 279 280 // How long we wait for a launched process to attach to the activity manager 281 // before we decide it's never going to come up for real, when the process was 282 // started with a wrapper for instrumentation (such as Valgrind) because it 283 // could take much longer than usual. 284 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 285 286 // How long to wait after going idle before forcing apps to GC. 287 static final int GC_TIMEOUT = 5*1000; 288 289 // The minimum amount of time between successive GC requests for a process. 290 static final int GC_MIN_INTERVAL = 60*1000; 291 292 // The minimum amount of time between successive PSS requests for a process. 293 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 294 295 // The minimum amount of time between successive PSS requests for a process 296 // when the request is due to the memory state being lowered. 297 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 298 299 // The rate at which we check for apps using excessive power -- 15 mins. 300 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 301 302 // The minimum sample duration we will allow before deciding we have 303 // enough data on wake locks to start killing things. 304 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 305 306 // The minimum sample duration we will allow before deciding we have 307 // enough data on CPU usage to start killing things. 308 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 309 310 // How long we allow a receiver to run before giving up on it. 311 static final int BROADCAST_FG_TIMEOUT = 10*1000; 312 static final int BROADCAST_BG_TIMEOUT = 60*1000; 313 314 // How long we wait until we timeout on key dispatching. 315 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 316 317 // How long we wait until we timeout on key dispatching during instrumentation. 318 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 319 320 // Amount of time we wait for observers to handle a user switch before 321 // giving up on them and unfreezing the screen. 322 static final int USER_SWITCH_TIMEOUT = 2*1000; 323 324 // Maximum number of users we allow to be running at a time. 325 static final int MAX_RUNNING_USERS = 3; 326 327 // How long to wait in getAssistContextExtras for the activity and foreground services 328 // to respond with the result. 329 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 330 331 // Maximum number of persisted Uri grants a package is allowed 332 static final int MAX_PERSISTED_URI_GRANTS = 128; 333 334 static final int MY_PID = Process.myPid(); 335 336 static final String[] EMPTY_STRING_ARRAY = new String[0]; 337 338 // How many bytes to write into the dropbox log before truncating 339 static final int DROPBOX_MAX_SIZE = 256 * 1024; 340 341 /** All system services */ 342 SystemServiceManager mSystemServiceManager; 343 344 /** Run all ActivityStacks through this */ 345 ActivityStackSupervisor mStackSupervisor; 346 347 public IntentFirewall mIntentFirewall; 348 349 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 350 // default actuion automatically. Important for devices without direct input 351 // devices. 352 private boolean mShowDialogs = true; 353 354 /** 355 * Description of a request to start a new activity, which has been held 356 * due to app switches being disabled. 357 */ 358 static class PendingActivityLaunch { 359 final ActivityRecord r; 360 final ActivityRecord sourceRecord; 361 final int startFlags; 362 final ActivityStack stack; 363 364 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 365 int _startFlags, ActivityStack _stack) { 366 r = _r; 367 sourceRecord = _sourceRecord; 368 startFlags = _startFlags; 369 stack = _stack; 370 } 371 } 372 373 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 374 = new ArrayList<PendingActivityLaunch>(); 375 376 BroadcastQueue mFgBroadcastQueue; 377 BroadcastQueue mBgBroadcastQueue; 378 // Convenient for easy iteration over the queues. Foreground is first 379 // so that dispatch of foreground broadcasts gets precedence. 380 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 381 382 BroadcastQueue broadcastQueueForIntent(Intent intent) { 383 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 384 if (DEBUG_BACKGROUND_BROADCAST) { 385 Slog.i(TAG, "Broadcast intent " + intent + " on " 386 + (isFg ? "foreground" : "background") 387 + " queue"); 388 } 389 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 390 } 391 392 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 393 for (BroadcastQueue queue : mBroadcastQueues) { 394 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 395 if (r != null) { 396 return r; 397 } 398 } 399 return null; 400 } 401 402 /** 403 * Activity we have told the window manager to have key focus. 404 */ 405 ActivityRecord mFocusedActivity = null; 406 407 /** 408 * List of intents that were used to start the most recent tasks. 409 */ 410 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 411 412 public class PendingAssistExtras extends Binder implements Runnable { 413 public final ActivityRecord activity; 414 public boolean haveResult = false; 415 public Bundle result = null; 416 public PendingAssistExtras(ActivityRecord _activity) { 417 activity = _activity; 418 } 419 @Override 420 public void run() { 421 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 422 synchronized (this) { 423 haveResult = true; 424 notifyAll(); 425 } 426 } 427 } 428 429 final ArrayList<PendingAssistExtras> mPendingAssistExtras 430 = new ArrayList<PendingAssistExtras>(); 431 432 /** 433 * Process management. 434 */ 435 final ProcessList mProcessList = new ProcessList(); 436 437 /** 438 * All of the applications we currently have running organized by name. 439 * The keys are strings of the application package name (as 440 * returned by the package manager), and the keys are ApplicationRecord 441 * objects. 442 */ 443 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 444 445 /** 446 * Tracking long-term execution of processes to look for abuse and other 447 * bad app behavior. 448 */ 449 final ProcessStatsService mProcessStats; 450 451 /** 452 * The currently running isolated processes. 453 */ 454 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 455 456 /** 457 * Counter for assigning isolated process uids, to avoid frequently reusing the 458 * same ones. 459 */ 460 int mNextIsolatedProcessUid = 0; 461 462 /** 463 * The currently running heavy-weight process, if any. 464 */ 465 ProcessRecord mHeavyWeightProcess = null; 466 467 /** 468 * The last time that various processes have crashed. 469 */ 470 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 471 472 /** 473 * Information about a process that is currently marked as bad. 474 */ 475 static final class BadProcessInfo { 476 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 477 this.time = time; 478 this.shortMsg = shortMsg; 479 this.longMsg = longMsg; 480 this.stack = stack; 481 } 482 483 final long time; 484 final String shortMsg; 485 final String longMsg; 486 final String stack; 487 } 488 489 /** 490 * Set of applications that we consider to be bad, and will reject 491 * incoming broadcasts from (which the user has no control over). 492 * Processes are added to this set when they have crashed twice within 493 * a minimum amount of time; they are removed from it when they are 494 * later restarted (hopefully due to some user action). The value is the 495 * time it was added to the list. 496 */ 497 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 498 499 /** 500 * All of the processes we currently have running organized by pid. 501 * The keys are the pid running the application. 502 * 503 * <p>NOTE: This object is protected by its own lock, NOT the global 504 * activity manager lock! 505 */ 506 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 507 508 /** 509 * All of the processes that have been forced to be foreground. The key 510 * is the pid of the caller who requested it (we hold a death 511 * link on it). 512 */ 513 abstract class ForegroundToken implements IBinder.DeathRecipient { 514 int pid; 515 IBinder token; 516 } 517 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 518 519 /** 520 * List of records for processes that someone had tried to start before the 521 * system was ready. We don't start them at that point, but ensure they 522 * are started by the time booting is complete. 523 */ 524 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of persistent applications that are in the process 528 * of being started. 529 */ 530 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Processes that are being forcibly torn down. 534 */ 535 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 536 537 /** 538 * List of running applications, sorted by recent usage. 539 * The first entry in the list is the least recently used. 540 */ 541 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 542 543 /** 544 * Where in mLruProcesses that the processes hosting activities start. 545 */ 546 int mLruProcessActivityStart = 0; 547 548 /** 549 * Where in mLruProcesses that the processes hosting services start. 550 * This is after (lower index) than mLruProcessesActivityStart. 551 */ 552 int mLruProcessServiceStart = 0; 553 554 /** 555 * List of processes that should gc as soon as things are idle. 556 */ 557 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 558 559 /** 560 * Processes we want to collect PSS data from. 561 */ 562 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 563 564 /** 565 * Last time we requested PSS data of all processes. 566 */ 567 long mLastFullPssTime = SystemClock.uptimeMillis(); 568 569 /** 570 * This is the process holding what we currently consider to be 571 * the "home" activity. 572 */ 573 ProcessRecord mHomeProcess; 574 575 /** 576 * This is the process holding the activity the user last visited that 577 * is in a different process from the one they are currently in. 578 */ 579 ProcessRecord mPreviousProcess; 580 581 /** 582 * The time at which the previous process was last visible. 583 */ 584 long mPreviousProcessVisibleTime; 585 586 /** 587 * Which uses have been started, so are allowed to run code. 588 */ 589 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 590 591 /** 592 * LRU list of history of current users. Most recently current is at the end. 593 */ 594 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 595 596 /** 597 * Constant array of the users that are currently started. 598 */ 599 int[] mStartedUserArray = new int[] { 0 }; 600 601 /** 602 * Registered observers of the user switching mechanics. 603 */ 604 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 605 = new RemoteCallbackList<IUserSwitchObserver>(); 606 607 /** 608 * Currently active user switch. 609 */ 610 Object mCurUserSwitchCallback; 611 612 /** 613 * Packages that the user has asked to have run in screen size 614 * compatibility mode instead of filling the screen. 615 */ 616 final CompatModePackages mCompatModePackages; 617 618 /** 619 * Set of IntentSenderRecord objects that are currently active. 620 */ 621 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 622 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 623 624 /** 625 * Fingerprints (hashCode()) of stack traces that we've 626 * already logged DropBox entries for. Guarded by itself. If 627 * something (rogue user app) forces this over 628 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 629 */ 630 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 631 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 632 633 /** 634 * Strict Mode background batched logging state. 635 * 636 * The string buffer is guarded by itself, and its lock is also 637 * used to determine if another batched write is already 638 * in-flight. 639 */ 640 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 641 642 /** 643 * Keeps track of all IIntentReceivers that have been registered for 644 * broadcasts. Hash keys are the receiver IBinder, hash value is 645 * a ReceiverList. 646 */ 647 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 648 new HashMap<IBinder, ReceiverList>(); 649 650 /** 651 * Resolver for broadcast intents to registered receivers. 652 * Holds BroadcastFilter (subclass of IntentFilter). 653 */ 654 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 655 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 656 @Override 657 protected boolean allowFilterResult( 658 BroadcastFilter filter, List<BroadcastFilter> dest) { 659 IBinder target = filter.receiverList.receiver.asBinder(); 660 for (int i=dest.size()-1; i>=0; i--) { 661 if (dest.get(i).receiverList.receiver.asBinder() == target) { 662 return false; 663 } 664 } 665 return true; 666 } 667 668 @Override 669 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 670 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 671 || userId == filter.owningUserId) { 672 return super.newResult(filter, match, userId); 673 } 674 return null; 675 } 676 677 @Override 678 protected BroadcastFilter[] newArray(int size) { 679 return new BroadcastFilter[size]; 680 } 681 682 @Override 683 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 684 return packageName.equals(filter.packageName); 685 } 686 }; 687 688 /** 689 * State of all active sticky broadcasts per user. Keys are the action of the 690 * sticky Intent, values are an ArrayList of all broadcasted intents with 691 * that action (which should usually be one). The SparseArray is keyed 692 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 693 * for stickies that are sent to all users. 694 */ 695 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 696 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 697 698 final ActiveServices mServices; 699 700 /** 701 * Backup/restore process management 702 */ 703 String mBackupAppName = null; 704 BackupRecord mBackupTarget = null; 705 706 /** 707 * List of PendingThumbnailsRecord objects of clients who are still 708 * waiting to receive all of the thumbnails for a task. 709 */ 710 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 711 new ArrayList<PendingThumbnailsRecord>(); 712 713 final ProviderMap mProviderMap; 714 715 /** 716 * List of content providers who have clients waiting for them. The 717 * application is currently being launched and the provider will be 718 * removed from this list once it is published. 719 */ 720 final ArrayList<ContentProviderRecord> mLaunchingProviders 721 = new ArrayList<ContentProviderRecord>(); 722 723 /** 724 * File storing persisted {@link #mGrantedUriPermissions}. 725 */ 726 private final AtomicFile mGrantFile; 727 728 /** XML constants used in {@link #mGrantFile} */ 729 private static final String TAG_URI_GRANTS = "uri-grants"; 730 private static final String TAG_URI_GRANT = "uri-grant"; 731 private static final String ATTR_USER_HANDLE = "userHandle"; 732 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 733 private static final String ATTR_TARGET_PKG = "targetPkg"; 734 private static final String ATTR_URI = "uri"; 735 private static final String ATTR_MODE_FLAGS = "modeFlags"; 736 private static final String ATTR_CREATED_TIME = "createdTime"; 737 private static final String ATTR_PREFIX = "prefix"; 738 739 /** 740 * Global set of specific {@link Uri} permissions that have been granted. 741 * This optimized lookup structure maps from {@link UriPermission#targetUid} 742 * to {@link UriPermission#uri} to {@link UriPermission}. 743 */ 744 @GuardedBy("this") 745 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 746 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 747 748 public static class GrantUri { 749 public final Uri uri; 750 public final boolean prefix; 751 752 public GrantUri(Uri uri, boolean prefix) { 753 this.uri = uri; 754 this.prefix = prefix; 755 } 756 757 @Override 758 public int hashCode() { 759 return toString().hashCode(); 760 } 761 762 @Override 763 public boolean equals(Object o) { 764 if (o instanceof GrantUri) { 765 GrantUri other = (GrantUri) o; 766 return uri.equals(other.uri) && prefix == other.prefix; 767 } 768 return false; 769 } 770 771 @Override 772 public String toString() { 773 if (prefix) { 774 return uri.toString() + " [prefix]"; 775 } else { 776 return uri.toString(); 777 } 778 } 779 } 780 781 CoreSettingsObserver mCoreSettingsObserver; 782 783 /** 784 * Thread-local storage used to carry caller permissions over through 785 * indirect content-provider access. 786 */ 787 private class Identity { 788 public int pid; 789 public int uid; 790 791 Identity(int _pid, int _uid) { 792 pid = _pid; 793 uid = _uid; 794 } 795 } 796 797 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 798 799 /** 800 * All information we have collected about the runtime performance of 801 * any user id that can impact battery performance. 802 */ 803 final BatteryStatsService mBatteryStatsService; 804 805 /** 806 * Information about component usage 807 */ 808 final UsageStatsService mUsageStatsService; 809 810 /** 811 * Information about and control over application operations 812 */ 813 final AppOpsService mAppOpsService; 814 815 /** 816 * Current configuration information. HistoryRecord objects are given 817 * a reference to this object to indicate which configuration they are 818 * currently running in, so this object must be kept immutable. 819 */ 820 Configuration mConfiguration = new Configuration(); 821 822 /** 823 * Current sequencing integer of the configuration, for skipping old 824 * configurations. 825 */ 826 int mConfigurationSeq = 0; 827 828 /** 829 * Hardware-reported OpenGLES version. 830 */ 831 final int GL_ES_VERSION; 832 833 /** 834 * List of initialization arguments to pass to all processes when binding applications to them. 835 * For example, references to the commonly used services. 836 */ 837 HashMap<String, IBinder> mAppBindArgs; 838 839 /** 840 * Temporary to avoid allocations. Protected by main lock. 841 */ 842 final StringBuilder mStringBuilder = new StringBuilder(256); 843 844 /** 845 * Used to control how we initialize the service. 846 */ 847 ComponentName mTopComponent; 848 String mTopAction = Intent.ACTION_MAIN; 849 String mTopData; 850 boolean mProcessesReady = false; 851 boolean mSystemReady = false; 852 boolean mBooting = false; 853 boolean mWaitingUpdate = false; 854 boolean mDidUpdate = false; 855 boolean mOnBattery = false; 856 boolean mLaunchWarningShown = false; 857 858 Context mContext; 859 860 int mFactoryTest; 861 862 boolean mCheckedForSetup; 863 864 /** 865 * The time at which we will allow normal application switches again, 866 * after a call to {@link #stopAppSwitches()}. 867 */ 868 long mAppSwitchesAllowedTime; 869 870 /** 871 * This is set to true after the first switch after mAppSwitchesAllowedTime 872 * is set; any switches after that will clear the time. 873 */ 874 boolean mDidAppSwitch; 875 876 /** 877 * Last time (in realtime) at which we checked for power usage. 878 */ 879 long mLastPowerCheckRealtime; 880 881 /** 882 * Last time (in uptime) at which we checked for power usage. 883 */ 884 long mLastPowerCheckUptime; 885 886 /** 887 * Set while we are wanting to sleep, to prevent any 888 * activities from being started/resumed. 889 */ 890 private boolean mSleeping = false; 891 892 /** 893 * Set while we are running a voice interaction. This overrides 894 * sleeping while it is active. 895 */ 896 private boolean mRunningVoice = false; 897 898 /** 899 * State of external calls telling us if the device is asleep. 900 */ 901 private boolean mWentToSleep = false; 902 903 /** 904 * State of external call telling us if the lock screen is shown. 905 */ 906 private boolean mLockScreenShown = false; 907 908 /** 909 * Set if we are shutting down the system, similar to sleeping. 910 */ 911 boolean mShuttingDown = false; 912 913 /** 914 * Current sequence id for oom_adj computation traversal. 915 */ 916 int mAdjSeq = 0; 917 918 /** 919 * Current sequence id for process LRU updating. 920 */ 921 int mLruSeq = 0; 922 923 /** 924 * Keep track of the non-cached/empty process we last found, to help 925 * determine how to distribute cached/empty processes next time. 926 */ 927 int mNumNonCachedProcs = 0; 928 929 /** 930 * Keep track of the number of cached hidden procs, to balance oom adj 931 * distribution between those and empty procs. 932 */ 933 int mNumCachedHiddenProcs = 0; 934 935 /** 936 * Keep track of the number of service processes we last found, to 937 * determine on the next iteration which should be B services. 938 */ 939 int mNumServiceProcs = 0; 940 int mNewNumAServiceProcs = 0; 941 int mNewNumServiceProcs = 0; 942 943 /** 944 * Allow the current computed overall memory level of the system to go down? 945 * This is set to false when we are killing processes for reasons other than 946 * memory management, so that the now smaller process list will not be taken as 947 * an indication that memory is tighter. 948 */ 949 boolean mAllowLowerMemLevel = false; 950 951 /** 952 * The last computed memory level, for holding when we are in a state that 953 * processes are going away for other reasons. 954 */ 955 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 956 957 /** 958 * The last total number of process we have, to determine if changes actually look 959 * like a shrinking number of process due to lower RAM. 960 */ 961 int mLastNumProcesses; 962 963 /** 964 * The uptime of the last time we performed idle maintenance. 965 */ 966 long mLastIdleTime = SystemClock.uptimeMillis(); 967 968 /** 969 * Total time spent with RAM that has been added in the past since the last idle time. 970 */ 971 long mLowRamTimeSinceLastIdle = 0; 972 973 /** 974 * If RAM is currently low, when that horrible situation started. 975 */ 976 long mLowRamStartTime = 0; 977 978 /** 979 * For reporting to battery stats the current top application. 980 */ 981 private String mCurResumedPackage = null; 982 private int mCurResumedUid = -1; 983 984 /** 985 * For reporting to battery stats the apps currently running foreground 986 * service. The ProcessMap is package/uid tuples; each of these contain 987 * an array of the currently foreground processes. 988 */ 989 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 990 = new ProcessMap<ArrayList<ProcessRecord>>(); 991 992 /** 993 * This is set if we had to do a delayed dexopt of an app before launching 994 * it, to increasing the ANR timeouts in that case. 995 */ 996 boolean mDidDexOpt; 997 998 /** 999 * Set if the systemServer made a call to enterSafeMode. 1000 */ 1001 boolean mSafeMode; 1002 1003 String mDebugApp = null; 1004 boolean mWaitForDebugger = false; 1005 boolean mDebugTransient = false; 1006 String mOrigDebugApp = null; 1007 boolean mOrigWaitForDebugger = false; 1008 boolean mAlwaysFinishActivities = false; 1009 IActivityController mController = null; 1010 String mProfileApp = null; 1011 ProcessRecord mProfileProc = null; 1012 String mProfileFile; 1013 ParcelFileDescriptor mProfileFd; 1014 int mProfileType = 0; 1015 boolean mAutoStopProfiler = false; 1016 String mOpenGlTraceApp = null; 1017 1018 static class ProcessChangeItem { 1019 static final int CHANGE_ACTIVITIES = 1<<0; 1020 static final int CHANGE_PROCESS_STATE = 1<<1; 1021 int changes; 1022 int uid; 1023 int pid; 1024 int processState; 1025 boolean foregroundActivities; 1026 } 1027 1028 final RemoteCallbackList<IProcessObserver> mProcessObservers 1029 = new RemoteCallbackList<IProcessObserver>(); 1030 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1031 1032 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1033 = new ArrayList<ProcessChangeItem>(); 1034 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1035 = new ArrayList<ProcessChangeItem>(); 1036 1037 /** 1038 * Runtime CPU use collection thread. This object's lock is used to 1039 * protect all related state. 1040 */ 1041 final Thread mProcessCpuThread; 1042 1043 /** 1044 * Used to collect process stats when showing not responding dialog. 1045 * Protected by mProcessCpuThread. 1046 */ 1047 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1048 MONITOR_THREAD_CPU_USAGE); 1049 final AtomicLong mLastCpuTime = new AtomicLong(0); 1050 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1051 1052 long mLastWriteTime = 0; 1053 1054 /** 1055 * Used to retain an update lock when the foreground activity is in 1056 * immersive mode. 1057 */ 1058 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1059 1060 /** 1061 * Set to true after the system has finished booting. 1062 */ 1063 boolean mBooted = false; 1064 1065 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1066 int mProcessLimitOverride = -1; 1067 1068 WindowManagerService mWindowManager; 1069 1070 final ActivityThread mSystemThread; 1071 1072 int mCurrentUserId = 0; 1073 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1074 private UserManagerService mUserManager; 1075 1076 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1077 final ProcessRecord mApp; 1078 final int mPid; 1079 final IApplicationThread mAppThread; 1080 1081 AppDeathRecipient(ProcessRecord app, int pid, 1082 IApplicationThread thread) { 1083 if (localLOGV) Slog.v( 1084 TAG, "New death recipient " + this 1085 + " for thread " + thread.asBinder()); 1086 mApp = app; 1087 mPid = pid; 1088 mAppThread = thread; 1089 } 1090 1091 @Override 1092 public void binderDied() { 1093 if (localLOGV) Slog.v( 1094 TAG, "Death received in " + this 1095 + " for thread " + mAppThread.asBinder()); 1096 synchronized(ActivityManagerService.this) { 1097 appDiedLocked(mApp, mPid, mAppThread); 1098 } 1099 } 1100 } 1101 1102 static final int SHOW_ERROR_MSG = 1; 1103 static final int SHOW_NOT_RESPONDING_MSG = 2; 1104 static final int SHOW_FACTORY_ERROR_MSG = 3; 1105 static final int UPDATE_CONFIGURATION_MSG = 4; 1106 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1107 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1108 static final int SERVICE_TIMEOUT_MSG = 12; 1109 static final int UPDATE_TIME_ZONE = 13; 1110 static final int SHOW_UID_ERROR_MSG = 14; 1111 static final int IM_FEELING_LUCKY_MSG = 15; 1112 static final int PROC_START_TIMEOUT_MSG = 20; 1113 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1114 static final int KILL_APPLICATION_MSG = 22; 1115 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1116 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1117 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1118 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1119 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1120 static final int CLEAR_DNS_CACHE_MSG = 28; 1121 static final int UPDATE_HTTP_PROXY_MSG = 29; 1122 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1123 static final int DISPATCH_PROCESSES_CHANGED = 31; 1124 static final int DISPATCH_PROCESS_DIED = 32; 1125 static final int REPORT_MEM_USAGE_MSG = 33; 1126 static final int REPORT_USER_SWITCH_MSG = 34; 1127 static final int CONTINUE_USER_SWITCH_MSG = 35; 1128 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1129 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1130 static final int PERSIST_URI_GRANTS_MSG = 38; 1131 static final int REQUEST_ALL_PSS_MSG = 39; 1132 static final int START_PROFILES_MSG = 40; 1133 static final int UPDATE_TIME = 41; 1134 static final int SYSTEM_USER_START_MSG = 42; 1135 static final int SYSTEM_USER_CURRENT_MSG = 43; 1136 1137 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1138 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1139 static final int FIRST_COMPAT_MODE_MSG = 300; 1140 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1141 1142 AlertDialog mUidAlert; 1143 CompatModeDialog mCompatModeDialog; 1144 long mLastMemUsageReportTime = 0; 1145 1146 /** 1147 * Flag whether the current user is a "monkey", i.e. whether 1148 * the UI is driven by a UI automation tool. 1149 */ 1150 private boolean mUserIsMonkey; 1151 1152 final ServiceThread mHandlerThread; 1153 final MainHandler mHandler; 1154 1155 final class MainHandler extends Handler { 1156 public MainHandler(Looper looper) { 1157 super(looper, null, true); 1158 } 1159 1160 @Override 1161 public void handleMessage(Message msg) { 1162 switch (msg.what) { 1163 case SHOW_ERROR_MSG: { 1164 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1165 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1166 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1167 synchronized (ActivityManagerService.this) { 1168 ProcessRecord proc = (ProcessRecord)data.get("app"); 1169 AppErrorResult res = (AppErrorResult) data.get("result"); 1170 if (proc != null && proc.crashDialog != null) { 1171 Slog.e(TAG, "App already has crash dialog: " + proc); 1172 if (res != null) { 1173 res.set(0); 1174 } 1175 return; 1176 } 1177 if (!showBackground && UserHandle.getAppId(proc.uid) 1178 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1179 && proc.pid != MY_PID) { 1180 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1181 if (res != null) { 1182 res.set(0); 1183 } 1184 return; 1185 } 1186 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1187 Dialog d = new AppErrorDialog(mContext, 1188 ActivityManagerService.this, res, proc); 1189 d.show(); 1190 proc.crashDialog = d; 1191 } else { 1192 // The device is asleep, so just pretend that the user 1193 // saw a crash dialog and hit "force quit". 1194 if (res != null) { 1195 res.set(0); 1196 } 1197 } 1198 } 1199 1200 ensureBootCompleted(); 1201 } break; 1202 case SHOW_NOT_RESPONDING_MSG: { 1203 synchronized (ActivityManagerService.this) { 1204 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1205 ProcessRecord proc = (ProcessRecord)data.get("app"); 1206 if (proc != null && proc.anrDialog != null) { 1207 Slog.e(TAG, "App already has anr dialog: " + proc); 1208 return; 1209 } 1210 1211 Intent intent = new Intent("android.intent.action.ANR"); 1212 if (!mProcessesReady) { 1213 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1214 | Intent.FLAG_RECEIVER_FOREGROUND); 1215 } 1216 broadcastIntentLocked(null, null, intent, 1217 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1218 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1219 1220 if (mShowDialogs) { 1221 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1222 mContext, proc, (ActivityRecord)data.get("activity"), 1223 msg.arg1 != 0); 1224 d.show(); 1225 proc.anrDialog = d; 1226 } else { 1227 // Just kill the app if there is no dialog to be shown. 1228 killAppAtUsersRequest(proc, null); 1229 } 1230 } 1231 1232 ensureBootCompleted(); 1233 } break; 1234 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1235 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1236 synchronized (ActivityManagerService.this) { 1237 ProcessRecord proc = (ProcessRecord) data.get("app"); 1238 if (proc == null) { 1239 Slog.e(TAG, "App not found when showing strict mode dialog."); 1240 break; 1241 } 1242 if (proc.crashDialog != null) { 1243 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1244 return; 1245 } 1246 AppErrorResult res = (AppErrorResult) data.get("result"); 1247 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1248 Dialog d = new StrictModeViolationDialog(mContext, 1249 ActivityManagerService.this, res, proc); 1250 d.show(); 1251 proc.crashDialog = d; 1252 } else { 1253 // The device is asleep, so just pretend that the user 1254 // saw a crash dialog and hit "force quit". 1255 res.set(0); 1256 } 1257 } 1258 ensureBootCompleted(); 1259 } break; 1260 case SHOW_FACTORY_ERROR_MSG: { 1261 Dialog d = new FactoryErrorDialog( 1262 mContext, msg.getData().getCharSequence("msg")); 1263 d.show(); 1264 ensureBootCompleted(); 1265 } break; 1266 case UPDATE_CONFIGURATION_MSG: { 1267 final ContentResolver resolver = mContext.getContentResolver(); 1268 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1269 } break; 1270 case GC_BACKGROUND_PROCESSES_MSG: { 1271 synchronized (ActivityManagerService.this) { 1272 performAppGcsIfAppropriateLocked(); 1273 } 1274 } break; 1275 case WAIT_FOR_DEBUGGER_MSG: { 1276 synchronized (ActivityManagerService.this) { 1277 ProcessRecord app = (ProcessRecord)msg.obj; 1278 if (msg.arg1 != 0) { 1279 if (!app.waitedForDebugger) { 1280 Dialog d = new AppWaitingForDebuggerDialog( 1281 ActivityManagerService.this, 1282 mContext, app); 1283 app.waitDialog = d; 1284 app.waitedForDebugger = true; 1285 d.show(); 1286 } 1287 } else { 1288 if (app.waitDialog != null) { 1289 app.waitDialog.dismiss(); 1290 app.waitDialog = null; 1291 } 1292 } 1293 } 1294 } break; 1295 case SERVICE_TIMEOUT_MSG: { 1296 if (mDidDexOpt) { 1297 mDidDexOpt = false; 1298 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1299 nmsg.obj = msg.obj; 1300 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1301 return; 1302 } 1303 mServices.serviceTimeout((ProcessRecord)msg.obj); 1304 } break; 1305 case UPDATE_TIME_ZONE: { 1306 synchronized (ActivityManagerService.this) { 1307 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1308 ProcessRecord r = mLruProcesses.get(i); 1309 if (r.thread != null) { 1310 try { 1311 r.thread.updateTimeZone(); 1312 } catch (RemoteException ex) { 1313 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1314 } 1315 } 1316 } 1317 } 1318 } break; 1319 case CLEAR_DNS_CACHE_MSG: { 1320 synchronized (ActivityManagerService.this) { 1321 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1322 ProcessRecord r = mLruProcesses.get(i); 1323 if (r.thread != null) { 1324 try { 1325 r.thread.clearDnsCache(); 1326 } catch (RemoteException ex) { 1327 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1328 } 1329 } 1330 } 1331 } 1332 } break; 1333 case UPDATE_HTTP_PROXY_MSG: { 1334 ProxyProperties proxy = (ProxyProperties)msg.obj; 1335 String host = ""; 1336 String port = ""; 1337 String exclList = ""; 1338 String pacFileUrl = null; 1339 if (proxy != null) { 1340 host = proxy.getHost(); 1341 port = Integer.toString(proxy.getPort()); 1342 exclList = proxy.getExclusionList(); 1343 pacFileUrl = proxy.getPacFileUrl(); 1344 } 1345 synchronized (ActivityManagerService.this) { 1346 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1347 ProcessRecord r = mLruProcesses.get(i); 1348 if (r.thread != null) { 1349 try { 1350 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1351 } catch (RemoteException ex) { 1352 Slog.w(TAG, "Failed to update http proxy for: " + 1353 r.info.processName); 1354 } 1355 } 1356 } 1357 } 1358 } break; 1359 case SHOW_UID_ERROR_MSG: { 1360 String title = "System UIDs Inconsistent"; 1361 String text = "UIDs on the system are inconsistent, you need to wipe your" 1362 + " data partition or your device will be unstable."; 1363 Log.e(TAG, title + ": " + text); 1364 if (mShowDialogs) { 1365 // XXX This is a temporary dialog, no need to localize. 1366 AlertDialog d = new BaseErrorDialog(mContext); 1367 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1368 d.setCancelable(false); 1369 d.setTitle(title); 1370 d.setMessage(text); 1371 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1372 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1373 mUidAlert = d; 1374 d.show(); 1375 } 1376 } break; 1377 case IM_FEELING_LUCKY_MSG: { 1378 if (mUidAlert != null) { 1379 mUidAlert.dismiss(); 1380 mUidAlert = null; 1381 } 1382 } break; 1383 case PROC_START_TIMEOUT_MSG: { 1384 if (mDidDexOpt) { 1385 mDidDexOpt = false; 1386 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1387 nmsg.obj = msg.obj; 1388 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1389 return; 1390 } 1391 ProcessRecord app = (ProcessRecord)msg.obj; 1392 synchronized (ActivityManagerService.this) { 1393 processStartTimedOutLocked(app); 1394 } 1395 } break; 1396 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1397 synchronized (ActivityManagerService.this) { 1398 doPendingActivityLaunchesLocked(true); 1399 } 1400 } break; 1401 case KILL_APPLICATION_MSG: { 1402 synchronized (ActivityManagerService.this) { 1403 int appid = msg.arg1; 1404 boolean restart = (msg.arg2 == 1); 1405 Bundle bundle = (Bundle)msg.obj; 1406 String pkg = bundle.getString("pkg"); 1407 String reason = bundle.getString("reason"); 1408 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1409 false, UserHandle.USER_ALL, reason); 1410 } 1411 } break; 1412 case FINALIZE_PENDING_INTENT_MSG: { 1413 ((PendingIntentRecord)msg.obj).completeFinalize(); 1414 } break; 1415 case POST_HEAVY_NOTIFICATION_MSG: { 1416 INotificationManager inm = NotificationManager.getService(); 1417 if (inm == null) { 1418 return; 1419 } 1420 1421 ActivityRecord root = (ActivityRecord)msg.obj; 1422 ProcessRecord process = root.app; 1423 if (process == null) { 1424 return; 1425 } 1426 1427 try { 1428 Context context = mContext.createPackageContext(process.info.packageName, 0); 1429 String text = mContext.getString(R.string.heavy_weight_notification, 1430 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1431 Notification notification = new Notification(); 1432 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1433 notification.when = 0; 1434 notification.flags = Notification.FLAG_ONGOING_EVENT; 1435 notification.tickerText = text; 1436 notification.defaults = 0; // please be quiet 1437 notification.sound = null; 1438 notification.vibrate = null; 1439 notification.setLatestEventInfo(context, text, 1440 mContext.getText(R.string.heavy_weight_notification_detail), 1441 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1442 PendingIntent.FLAG_CANCEL_CURRENT, null, 1443 new UserHandle(root.userId))); 1444 1445 try { 1446 int[] outId = new int[1]; 1447 inm.enqueueNotificationWithTag("android", "android", null, 1448 R.string.heavy_weight_notification, 1449 notification, outId, root.userId); 1450 } catch (RuntimeException e) { 1451 Slog.w(ActivityManagerService.TAG, 1452 "Error showing notification for heavy-weight app", e); 1453 } catch (RemoteException e) { 1454 } 1455 } catch (NameNotFoundException e) { 1456 Slog.w(TAG, "Unable to create context for heavy notification", e); 1457 } 1458 } break; 1459 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1460 INotificationManager inm = NotificationManager.getService(); 1461 if (inm == null) { 1462 return; 1463 } 1464 try { 1465 inm.cancelNotificationWithTag("android", null, 1466 R.string.heavy_weight_notification, msg.arg1); 1467 } catch (RuntimeException e) { 1468 Slog.w(ActivityManagerService.TAG, 1469 "Error canceling notification for service", e); 1470 } catch (RemoteException e) { 1471 } 1472 } break; 1473 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1474 synchronized (ActivityManagerService.this) { 1475 checkExcessivePowerUsageLocked(true); 1476 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1477 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1478 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1479 } 1480 } break; 1481 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1482 synchronized (ActivityManagerService.this) { 1483 ActivityRecord ar = (ActivityRecord)msg.obj; 1484 if (mCompatModeDialog != null) { 1485 if (mCompatModeDialog.mAppInfo.packageName.equals( 1486 ar.info.applicationInfo.packageName)) { 1487 return; 1488 } 1489 mCompatModeDialog.dismiss(); 1490 mCompatModeDialog = null; 1491 } 1492 if (ar != null && false) { 1493 if (mCompatModePackages.getPackageAskCompatModeLocked( 1494 ar.packageName)) { 1495 int mode = mCompatModePackages.computeCompatModeLocked( 1496 ar.info.applicationInfo); 1497 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1498 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1499 mCompatModeDialog = new CompatModeDialog( 1500 ActivityManagerService.this, mContext, 1501 ar.info.applicationInfo); 1502 mCompatModeDialog.show(); 1503 } 1504 } 1505 } 1506 } 1507 break; 1508 } 1509 case DISPATCH_PROCESSES_CHANGED: { 1510 dispatchProcessesChanged(); 1511 break; 1512 } 1513 case DISPATCH_PROCESS_DIED: { 1514 final int pid = msg.arg1; 1515 final int uid = msg.arg2; 1516 dispatchProcessDied(pid, uid); 1517 break; 1518 } 1519 case REPORT_MEM_USAGE_MSG: { 1520 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1521 Thread thread = new Thread() { 1522 @Override public void run() { 1523 final SparseArray<ProcessMemInfo> infoMap 1524 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1525 for (int i=0, N=memInfos.size(); i<N; i++) { 1526 ProcessMemInfo mi = memInfos.get(i); 1527 infoMap.put(mi.pid, mi); 1528 } 1529 updateCpuStatsNow(); 1530 synchronized (mProcessCpuThread) { 1531 final int N = mProcessCpuTracker.countStats(); 1532 for (int i=0; i<N; i++) { 1533 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1534 if (st.vsize > 0) { 1535 long pss = Debug.getPss(st.pid, null); 1536 if (pss > 0) { 1537 if (infoMap.indexOfKey(st.pid) < 0) { 1538 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1539 ProcessList.NATIVE_ADJ, -1, "native", null); 1540 mi.pss = pss; 1541 memInfos.add(mi); 1542 } 1543 } 1544 } 1545 } 1546 } 1547 1548 long totalPss = 0; 1549 for (int i=0, N=memInfos.size(); i<N; i++) { 1550 ProcessMemInfo mi = memInfos.get(i); 1551 if (mi.pss == 0) { 1552 mi.pss = Debug.getPss(mi.pid, null); 1553 } 1554 totalPss += mi.pss; 1555 } 1556 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1557 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1558 if (lhs.oomAdj != rhs.oomAdj) { 1559 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1560 } 1561 if (lhs.pss != rhs.pss) { 1562 return lhs.pss < rhs.pss ? 1 : -1; 1563 } 1564 return 0; 1565 } 1566 }); 1567 1568 StringBuilder tag = new StringBuilder(128); 1569 StringBuilder stack = new StringBuilder(128); 1570 tag.append("Low on memory -- "); 1571 appendMemBucket(tag, totalPss, "total", false); 1572 appendMemBucket(stack, totalPss, "total", true); 1573 1574 StringBuilder logBuilder = new StringBuilder(1024); 1575 logBuilder.append("Low on memory:\n"); 1576 1577 boolean firstLine = true; 1578 int lastOomAdj = Integer.MIN_VALUE; 1579 for (int i=0, N=memInfos.size(); i<N; i++) { 1580 ProcessMemInfo mi = memInfos.get(i); 1581 1582 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1583 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1584 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1585 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1586 if (lastOomAdj != mi.oomAdj) { 1587 lastOomAdj = mi.oomAdj; 1588 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1589 tag.append(" / "); 1590 } 1591 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1592 if (firstLine) { 1593 stack.append(":"); 1594 firstLine = false; 1595 } 1596 stack.append("\n\t at "); 1597 } else { 1598 stack.append("$"); 1599 } 1600 } else { 1601 tag.append(" "); 1602 stack.append("$"); 1603 } 1604 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1605 appendMemBucket(tag, mi.pss, mi.name, false); 1606 } 1607 appendMemBucket(stack, mi.pss, mi.name, true); 1608 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1609 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1610 stack.append("("); 1611 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1612 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1613 stack.append(DUMP_MEM_OOM_LABEL[k]); 1614 stack.append(":"); 1615 stack.append(DUMP_MEM_OOM_ADJ[k]); 1616 } 1617 } 1618 stack.append(")"); 1619 } 1620 } 1621 1622 logBuilder.append(" "); 1623 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1624 logBuilder.append(' '); 1625 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1626 logBuilder.append(' '); 1627 ProcessList.appendRamKb(logBuilder, mi.pss); 1628 logBuilder.append(" kB: "); 1629 logBuilder.append(mi.name); 1630 logBuilder.append(" ("); 1631 logBuilder.append(mi.pid); 1632 logBuilder.append(") "); 1633 logBuilder.append(mi.adjType); 1634 logBuilder.append('\n'); 1635 if (mi.adjReason != null) { 1636 logBuilder.append(" "); 1637 logBuilder.append(mi.adjReason); 1638 logBuilder.append('\n'); 1639 } 1640 } 1641 1642 logBuilder.append(" "); 1643 ProcessList.appendRamKb(logBuilder, totalPss); 1644 logBuilder.append(" kB: TOTAL\n"); 1645 1646 long[] infos = new long[Debug.MEMINFO_COUNT]; 1647 Debug.getMemInfo(infos); 1648 logBuilder.append(" MemInfo: "); 1649 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1650 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1651 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1652 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1653 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1654 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1655 logBuilder.append(" ZRAM: "); 1656 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1657 logBuilder.append(" kB RAM, "); 1658 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1659 logBuilder.append(" kB swap total, "); 1660 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1661 logBuilder.append(" kB swap free\n"); 1662 } 1663 Slog.i(TAG, logBuilder.toString()); 1664 1665 StringBuilder dropBuilder = new StringBuilder(1024); 1666 /* 1667 StringWriter oomSw = new StringWriter(); 1668 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1669 StringWriter catSw = new StringWriter(); 1670 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1671 String[] emptyArgs = new String[] { }; 1672 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1673 oomPw.flush(); 1674 String oomString = oomSw.toString(); 1675 */ 1676 dropBuilder.append(stack); 1677 dropBuilder.append('\n'); 1678 dropBuilder.append('\n'); 1679 dropBuilder.append(logBuilder); 1680 dropBuilder.append('\n'); 1681 /* 1682 dropBuilder.append(oomString); 1683 dropBuilder.append('\n'); 1684 */ 1685 StringWriter catSw = new StringWriter(); 1686 synchronized (ActivityManagerService.this) { 1687 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1688 String[] emptyArgs = new String[] { }; 1689 catPw.println(); 1690 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1691 catPw.println(); 1692 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1693 false, false, null); 1694 catPw.println(); 1695 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1696 catPw.flush(); 1697 } 1698 dropBuilder.append(catSw.toString()); 1699 addErrorToDropBox("lowmem", null, "system_server", null, 1700 null, tag.toString(), dropBuilder.toString(), null, null); 1701 //Slog.i(TAG, "Sent to dropbox:"); 1702 //Slog.i(TAG, dropBuilder.toString()); 1703 synchronized (ActivityManagerService.this) { 1704 long now = SystemClock.uptimeMillis(); 1705 if (mLastMemUsageReportTime < now) { 1706 mLastMemUsageReportTime = now; 1707 } 1708 } 1709 } 1710 }; 1711 thread.start(); 1712 break; 1713 } 1714 case REPORT_USER_SWITCH_MSG: { 1715 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1716 break; 1717 } 1718 case CONTINUE_USER_SWITCH_MSG: { 1719 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1720 break; 1721 } 1722 case USER_SWITCH_TIMEOUT_MSG: { 1723 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1724 break; 1725 } 1726 case IMMERSIVE_MODE_LOCK_MSG: { 1727 final boolean nextState = (msg.arg1 != 0); 1728 if (mUpdateLock.isHeld() != nextState) { 1729 if (DEBUG_IMMERSIVE) { 1730 final ActivityRecord r = (ActivityRecord) msg.obj; 1731 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1732 } 1733 if (nextState) { 1734 mUpdateLock.acquire(); 1735 } else { 1736 mUpdateLock.release(); 1737 } 1738 } 1739 break; 1740 } 1741 case PERSIST_URI_GRANTS_MSG: { 1742 writeGrantedUriPermissions(); 1743 break; 1744 } 1745 case REQUEST_ALL_PSS_MSG: { 1746 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1747 break; 1748 } 1749 case START_PROFILES_MSG: { 1750 synchronized (ActivityManagerService.this) { 1751 startProfilesLocked(); 1752 } 1753 break; 1754 } 1755 case UPDATE_TIME: { 1756 synchronized (ActivityManagerService.this) { 1757 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1758 ProcessRecord r = mLruProcesses.get(i); 1759 if (r.thread != null) { 1760 try { 1761 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1762 } catch (RemoteException ex) { 1763 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1764 } 1765 } 1766 } 1767 } 1768 break; 1769 } 1770 case SYSTEM_USER_START_MSG: { 1771 mSystemServiceManager.startUser(msg.arg1); 1772 break; 1773 } 1774 case SYSTEM_USER_CURRENT_MSG: { 1775 mSystemServiceManager.switchUser(msg.arg1); 1776 break; 1777 } 1778 } 1779 } 1780 }; 1781 1782 static final int COLLECT_PSS_BG_MSG = 1; 1783 1784 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1785 @Override 1786 public void handleMessage(Message msg) { 1787 switch (msg.what) { 1788 case COLLECT_PSS_BG_MSG: { 1789 int i=0, num=0; 1790 long start = SystemClock.uptimeMillis(); 1791 long[] tmp = new long[1]; 1792 do { 1793 ProcessRecord proc; 1794 int procState; 1795 int pid; 1796 synchronized (ActivityManagerService.this) { 1797 if (i >= mPendingPssProcesses.size()) { 1798 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1799 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1800 mPendingPssProcesses.clear(); 1801 return; 1802 } 1803 proc = mPendingPssProcesses.get(i); 1804 procState = proc.pssProcState; 1805 if (proc.thread != null && procState == proc.setProcState) { 1806 pid = proc.pid; 1807 } else { 1808 proc = null; 1809 pid = 0; 1810 } 1811 i++; 1812 } 1813 if (proc != null) { 1814 long pss = Debug.getPss(pid, tmp); 1815 synchronized (ActivityManagerService.this) { 1816 if (proc.thread != null && proc.setProcState == procState 1817 && proc.pid == pid) { 1818 num++; 1819 proc.lastPssTime = SystemClock.uptimeMillis(); 1820 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1821 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1822 + ": " + pss + " lastPss=" + proc.lastPss 1823 + " state=" + ProcessList.makeProcStateString(procState)); 1824 if (proc.initialIdlePss == 0) { 1825 proc.initialIdlePss = pss; 1826 } 1827 proc.lastPss = pss; 1828 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1829 proc.lastCachedPss = pss; 1830 } 1831 } 1832 } 1833 } 1834 } while (true); 1835 } 1836 } 1837 } 1838 }; 1839 1840 /** 1841 * Monitor for package changes and update our internal state. 1842 */ 1843 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1844 @Override 1845 public void onPackageRemoved(String packageName, int uid) { 1846 // Remove all tasks with activities in the specified package from the list of recent tasks 1847 synchronized (ActivityManagerService.this) { 1848 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1849 TaskRecord tr = mRecentTasks.get(i); 1850 ComponentName cn = tr.intent.getComponent(); 1851 if (cn != null && cn.getPackageName().equals(packageName)) { 1852 // If the package name matches, remove the task and kill the process 1853 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1854 } 1855 } 1856 } 1857 } 1858 1859 @Override 1860 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1861 final PackageManager pm = mContext.getPackageManager(); 1862 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1863 new ArrayList<Pair<Intent, Integer>>(); 1864 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1865 // Copy the list of recent tasks so that we don't hold onto the lock on 1866 // ActivityManagerService for long periods while checking if components exist. 1867 synchronized (ActivityManagerService.this) { 1868 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1869 TaskRecord tr = mRecentTasks.get(i); 1870 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1871 } 1872 } 1873 // Check the recent tasks and filter out all tasks with components that no longer exist. 1874 Intent tmpI = new Intent(); 1875 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1876 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1877 ComponentName cn = p.first.getComponent(); 1878 if (cn != null && cn.getPackageName().equals(packageName)) { 1879 try { 1880 // Add the task to the list to remove if the component no longer exists 1881 tmpI.setComponent(cn); 1882 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1883 tasksToRemove.add(p.second); 1884 } 1885 } catch (Exception e) {} 1886 } 1887 } 1888 // Prune all the tasks with removed components from the list of recent tasks 1889 synchronized (ActivityManagerService.this) { 1890 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1891 // Remove the task but don't kill the process (since other components in that 1892 // package may still be running and in the background) 1893 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1894 } 1895 } 1896 return true; 1897 } 1898 1899 @Override 1900 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1901 // Force stop the specified packages 1902 if (packages != null) { 1903 for (String pkg : packages) { 1904 synchronized (ActivityManagerService.this) { 1905 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1906 "finished booting")) { 1907 return true; 1908 } 1909 } 1910 } 1911 } 1912 return false; 1913 } 1914 }; 1915 1916 public void setSystemProcess() { 1917 try { 1918 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1919 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1920 ServiceManager.addService("meminfo", new MemBinder(this)); 1921 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1922 ServiceManager.addService("dbinfo", new DbBinder(this)); 1923 if (MONITOR_CPU_USAGE) { 1924 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1925 } 1926 ServiceManager.addService("permission", new PermissionController(this)); 1927 1928 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1929 "android", STOCK_PM_FLAGS); 1930 mSystemThread.installSystemApplicationInfo(info); 1931 1932 synchronized (this) { 1933 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1934 app.persistent = true; 1935 app.pid = MY_PID; 1936 app.maxAdj = ProcessList.SYSTEM_ADJ; 1937 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1938 mProcessNames.put(app.processName, app.uid, app); 1939 synchronized (mPidsSelfLocked) { 1940 mPidsSelfLocked.put(app.pid, app); 1941 } 1942 updateLruProcessLocked(app, false, null); 1943 updateOomAdjLocked(); 1944 } 1945 } catch (PackageManager.NameNotFoundException e) { 1946 throw new RuntimeException( 1947 "Unable to find android system package", e); 1948 } 1949 } 1950 1951 public void setWindowManager(WindowManagerService wm) { 1952 mWindowManager = wm; 1953 mStackSupervisor.setWindowManager(wm); 1954 } 1955 1956 public void startObservingNativeCrashes() { 1957 final NativeCrashListener ncl = new NativeCrashListener(this); 1958 ncl.start(); 1959 } 1960 1961 public IAppOpsService getAppOpsService() { 1962 return mAppOpsService; 1963 } 1964 1965 static class MemBinder extends Binder { 1966 ActivityManagerService mActivityManagerService; 1967 MemBinder(ActivityManagerService activityManagerService) { 1968 mActivityManagerService = activityManagerService; 1969 } 1970 1971 @Override 1972 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1973 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1974 != PackageManager.PERMISSION_GRANTED) { 1975 pw.println("Permission Denial: can't dump meminfo from from pid=" 1976 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1977 + " without permission " + android.Manifest.permission.DUMP); 1978 return; 1979 } 1980 1981 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1982 } 1983 } 1984 1985 static class GraphicsBinder extends Binder { 1986 ActivityManagerService mActivityManagerService; 1987 GraphicsBinder(ActivityManagerService activityManagerService) { 1988 mActivityManagerService = activityManagerService; 1989 } 1990 1991 @Override 1992 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1993 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1994 != PackageManager.PERMISSION_GRANTED) { 1995 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1996 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1997 + " without permission " + android.Manifest.permission.DUMP); 1998 return; 1999 } 2000 2001 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 2002 } 2003 } 2004 2005 static class DbBinder extends Binder { 2006 ActivityManagerService mActivityManagerService; 2007 DbBinder(ActivityManagerService activityManagerService) { 2008 mActivityManagerService = activityManagerService; 2009 } 2010 2011 @Override 2012 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2013 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2014 != PackageManager.PERMISSION_GRANTED) { 2015 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2016 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2017 + " without permission " + android.Manifest.permission.DUMP); 2018 return; 2019 } 2020 2021 mActivityManagerService.dumpDbInfo(fd, pw, args); 2022 } 2023 } 2024 2025 static class CpuBinder extends Binder { 2026 ActivityManagerService mActivityManagerService; 2027 CpuBinder(ActivityManagerService activityManagerService) { 2028 mActivityManagerService = activityManagerService; 2029 } 2030 2031 @Override 2032 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2033 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2034 != PackageManager.PERMISSION_GRANTED) { 2035 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2036 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2037 + " without permission " + android.Manifest.permission.DUMP); 2038 return; 2039 } 2040 2041 synchronized (mActivityManagerService.mProcessCpuThread) { 2042 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2043 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2044 SystemClock.uptimeMillis())); 2045 } 2046 } 2047 } 2048 2049 public static final class Lifecycle extends SystemService { 2050 private final ActivityManagerService mService; 2051 2052 public Lifecycle(Context context) { 2053 super(context); 2054 mService = new ActivityManagerService(context); 2055 } 2056 2057 @Override 2058 public void onStart() { 2059 mService.start(); 2060 } 2061 2062 public ActivityManagerService getService() { 2063 return mService; 2064 } 2065 } 2066 2067 // Note: This method is invoked on the main thread but may need to attach various 2068 // handlers to other threads. So take care to be explicit about the looper. 2069 public ActivityManagerService(Context systemContext) { 2070 mContext = systemContext; 2071 mFactoryTest = FactoryTest.getMode(); 2072 mSystemThread = ActivityThread.currentActivityThread(); 2073 2074 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2075 2076 mHandlerThread = new ServiceThread(TAG, 2077 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2078 mHandlerThread.start(); 2079 mHandler = new MainHandler(mHandlerThread.getLooper()); 2080 2081 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2082 "foreground", BROADCAST_FG_TIMEOUT, false); 2083 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2084 "background", BROADCAST_BG_TIMEOUT, true); 2085 mBroadcastQueues[0] = mFgBroadcastQueue; 2086 mBroadcastQueues[1] = mBgBroadcastQueue; 2087 2088 mServices = new ActiveServices(this); 2089 mProviderMap = new ProviderMap(this); 2090 2091 // TODO: Move creation of battery stats service outside of activity manager service. 2092 File dataDir = Environment.getDataDirectory(); 2093 File systemDir = new File(dataDir, "system"); 2094 systemDir.mkdirs(); 2095 mBatteryStatsService = new BatteryStatsService(new File( 2096 systemDir, "batterystats.bin").toString(), mHandler); 2097 mBatteryStatsService.getActiveStatistics().readLocked(); 2098 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2099 mOnBattery = DEBUG_POWER ? true 2100 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2101 mBatteryStatsService.getActiveStatistics().setCallback(this); 2102 2103 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2104 2105 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2106 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2107 2108 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2109 2110 // User 0 is the first and only user that runs at boot. 2111 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2112 mUserLru.add(Integer.valueOf(0)); 2113 updateStartedUserArrayLocked(); 2114 2115 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2116 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2117 2118 mConfiguration.setToDefaults(); 2119 mConfiguration.setLocale(Locale.getDefault()); 2120 2121 mConfigurationSeq = mConfiguration.seq = 1; 2122 mProcessCpuTracker.init(); 2123 2124 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2125 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2126 mStackSupervisor = new ActivityStackSupervisor(this); 2127 2128 mProcessCpuThread = new Thread("CpuTracker") { 2129 @Override 2130 public void run() { 2131 while (true) { 2132 try { 2133 try { 2134 synchronized(this) { 2135 final long now = SystemClock.uptimeMillis(); 2136 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2137 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2138 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2139 // + ", write delay=" + nextWriteDelay); 2140 if (nextWriteDelay < nextCpuDelay) { 2141 nextCpuDelay = nextWriteDelay; 2142 } 2143 if (nextCpuDelay > 0) { 2144 mProcessCpuMutexFree.set(true); 2145 this.wait(nextCpuDelay); 2146 } 2147 } 2148 } catch (InterruptedException e) { 2149 } 2150 updateCpuStatsNow(); 2151 } catch (Exception e) { 2152 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2153 } 2154 } 2155 } 2156 }; 2157 2158 Watchdog.getInstance().addMonitor(this); 2159 Watchdog.getInstance().addThread(mHandler); 2160 } 2161 2162 public void setSystemServiceManager(SystemServiceManager mgr) { 2163 mSystemServiceManager = mgr; 2164 } 2165 2166 private void start() { 2167 mProcessCpuThread.start(); 2168 2169 mBatteryStatsService.publish(mContext); 2170 mUsageStatsService.publish(mContext); 2171 mAppOpsService.publish(mContext); 2172 2173 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2174 } 2175 2176 @Override 2177 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2178 throws RemoteException { 2179 if (code == SYSPROPS_TRANSACTION) { 2180 // We need to tell all apps about the system property change. 2181 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2182 synchronized(this) { 2183 final int NP = mProcessNames.getMap().size(); 2184 for (int ip=0; ip<NP; ip++) { 2185 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2186 final int NA = apps.size(); 2187 for (int ia=0; ia<NA; ia++) { 2188 ProcessRecord app = apps.valueAt(ia); 2189 if (app.thread != null) { 2190 procs.add(app.thread.asBinder()); 2191 } 2192 } 2193 } 2194 } 2195 2196 int N = procs.size(); 2197 for (int i=0; i<N; i++) { 2198 Parcel data2 = Parcel.obtain(); 2199 try { 2200 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2201 } catch (RemoteException e) { 2202 } 2203 data2.recycle(); 2204 } 2205 } 2206 try { 2207 return super.onTransact(code, data, reply, flags); 2208 } catch (RuntimeException e) { 2209 // The activity manager only throws security exceptions, so let's 2210 // log all others. 2211 if (!(e instanceof SecurityException)) { 2212 Slog.wtf(TAG, "Activity Manager Crash", e); 2213 } 2214 throw e; 2215 } 2216 } 2217 2218 void updateCpuStats() { 2219 final long now = SystemClock.uptimeMillis(); 2220 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2221 return; 2222 } 2223 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2224 synchronized (mProcessCpuThread) { 2225 mProcessCpuThread.notify(); 2226 } 2227 } 2228 } 2229 2230 void updateCpuStatsNow() { 2231 synchronized (mProcessCpuThread) { 2232 mProcessCpuMutexFree.set(false); 2233 final long now = SystemClock.uptimeMillis(); 2234 boolean haveNewCpuStats = false; 2235 2236 if (MONITOR_CPU_USAGE && 2237 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2238 mLastCpuTime.set(now); 2239 haveNewCpuStats = true; 2240 mProcessCpuTracker.update(); 2241 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2242 //Slog.i(TAG, "Total CPU usage: " 2243 // + mProcessCpu.getTotalCpuPercent() + "%"); 2244 2245 // Slog the cpu usage if the property is set. 2246 if ("true".equals(SystemProperties.get("events.cpu"))) { 2247 int user = mProcessCpuTracker.getLastUserTime(); 2248 int system = mProcessCpuTracker.getLastSystemTime(); 2249 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2250 int irq = mProcessCpuTracker.getLastIrqTime(); 2251 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2252 int idle = mProcessCpuTracker.getLastIdleTime(); 2253 2254 int total = user + system + iowait + irq + softIrq + idle; 2255 if (total == 0) total = 1; 2256 2257 EventLog.writeEvent(EventLogTags.CPU, 2258 ((user+system+iowait+irq+softIrq) * 100) / total, 2259 (user * 100) / total, 2260 (system * 100) / total, 2261 (iowait * 100) / total, 2262 (irq * 100) / total, 2263 (softIrq * 100) / total); 2264 } 2265 } 2266 2267 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2268 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2269 synchronized(bstats) { 2270 synchronized(mPidsSelfLocked) { 2271 if (haveNewCpuStats) { 2272 if (mOnBattery) { 2273 int perc = bstats.startAddingCpuLocked(); 2274 int totalUTime = 0; 2275 int totalSTime = 0; 2276 final int N = mProcessCpuTracker.countStats(); 2277 for (int i=0; i<N; i++) { 2278 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2279 if (!st.working) { 2280 continue; 2281 } 2282 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2283 int otherUTime = (st.rel_utime*perc)/100; 2284 int otherSTime = (st.rel_stime*perc)/100; 2285 totalUTime += otherUTime; 2286 totalSTime += otherSTime; 2287 if (pr != null) { 2288 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2289 if (ps == null || !ps.isActive()) { 2290 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2291 pr.info.uid, pr.processName); 2292 } 2293 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2294 st.rel_stime-otherSTime); 2295 ps.addSpeedStepTimes(cpuSpeedTimes); 2296 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2297 } else { 2298 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2299 if (ps == null || !ps.isActive()) { 2300 st.batteryStats = ps = bstats.getProcessStatsLocked( 2301 bstats.mapUid(st.uid), st.name); 2302 } 2303 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2304 st.rel_stime-otherSTime); 2305 ps.addSpeedStepTimes(cpuSpeedTimes); 2306 } 2307 } 2308 bstats.finishAddingCpuLocked(perc, totalUTime, 2309 totalSTime, cpuSpeedTimes); 2310 } 2311 } 2312 } 2313 2314 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2315 mLastWriteTime = now; 2316 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2317 } 2318 } 2319 } 2320 } 2321 2322 @Override 2323 public void batteryNeedsCpuUpdate() { 2324 updateCpuStatsNow(); 2325 } 2326 2327 @Override 2328 public void batteryPowerChanged(boolean onBattery) { 2329 // When plugging in, update the CPU stats first before changing 2330 // the plug state. 2331 updateCpuStatsNow(); 2332 synchronized (this) { 2333 synchronized(mPidsSelfLocked) { 2334 mOnBattery = DEBUG_POWER ? true : onBattery; 2335 } 2336 } 2337 } 2338 2339 /** 2340 * Initialize the application bind args. These are passed to each 2341 * process when the bindApplication() IPC is sent to the process. They're 2342 * lazily setup to make sure the services are running when they're asked for. 2343 */ 2344 private HashMap<String, IBinder> getCommonServicesLocked() { 2345 if (mAppBindArgs == null) { 2346 mAppBindArgs = new HashMap<String, IBinder>(); 2347 2348 // Setup the application init args 2349 mAppBindArgs.put("package", ServiceManager.getService("package")); 2350 mAppBindArgs.put("window", ServiceManager.getService("window")); 2351 mAppBindArgs.put(Context.ALARM_SERVICE, 2352 ServiceManager.getService(Context.ALARM_SERVICE)); 2353 } 2354 return mAppBindArgs; 2355 } 2356 2357 final void setFocusedActivityLocked(ActivityRecord r) { 2358 if (mFocusedActivity != r) { 2359 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2360 mFocusedActivity = r; 2361 if (r.task != null && r.task.voiceInteractor != null) { 2362 startRunningVoiceLocked(); 2363 } else { 2364 finishRunningVoiceLocked(); 2365 } 2366 mStackSupervisor.setFocusedStack(r); 2367 if (r != null) { 2368 mWindowManager.setFocusedApp(r.appToken, true); 2369 } 2370 applyUpdateLockStateLocked(r); 2371 } 2372 } 2373 2374 final void clearFocusedActivity(ActivityRecord r) { 2375 if (mFocusedActivity == r) { 2376 mFocusedActivity = null; 2377 } 2378 } 2379 2380 @Override 2381 public void setFocusedStack(int stackId) { 2382 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2383 synchronized (ActivityManagerService.this) { 2384 ActivityStack stack = mStackSupervisor.getStack(stackId); 2385 if (stack != null) { 2386 ActivityRecord r = stack.topRunningActivityLocked(null); 2387 if (r != null) { 2388 setFocusedActivityLocked(r); 2389 } 2390 } 2391 } 2392 } 2393 2394 @Override 2395 public void notifyActivityDrawn(IBinder token) { 2396 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2397 synchronized (this) { 2398 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2399 if (r != null) { 2400 r.task.stack.notifyActivityDrawnLocked(r); 2401 } 2402 } 2403 } 2404 2405 final void applyUpdateLockStateLocked(ActivityRecord r) { 2406 // Modifications to the UpdateLock state are done on our handler, outside 2407 // the activity manager's locks. The new state is determined based on the 2408 // state *now* of the relevant activity record. The object is passed to 2409 // the handler solely for logging detail, not to be consulted/modified. 2410 final boolean nextState = r != null && r.immersive; 2411 mHandler.sendMessage( 2412 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2413 } 2414 2415 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2416 Message msg = Message.obtain(); 2417 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2418 msg.obj = r.task.askedCompatMode ? null : r; 2419 mHandler.sendMessage(msg); 2420 } 2421 2422 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2423 String what, Object obj, ProcessRecord srcApp) { 2424 app.lastActivityTime = now; 2425 2426 if (app.activities.size() > 0) { 2427 // Don't want to touch dependent processes that are hosting activities. 2428 return index; 2429 } 2430 2431 int lrui = mLruProcesses.lastIndexOf(app); 2432 if (lrui < 0) { 2433 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2434 + what + " " + obj + " from " + srcApp); 2435 return index; 2436 } 2437 2438 if (lrui >= index) { 2439 // Don't want to cause this to move dependent processes *back* in the 2440 // list as if they were less frequently used. 2441 return index; 2442 } 2443 2444 if (lrui >= mLruProcessActivityStart) { 2445 // Don't want to touch dependent processes that are hosting activities. 2446 return index; 2447 } 2448 2449 mLruProcesses.remove(lrui); 2450 if (index > 0) { 2451 index--; 2452 } 2453 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2454 + " in LRU list: " + app); 2455 mLruProcesses.add(index, app); 2456 return index; 2457 } 2458 2459 final void removeLruProcessLocked(ProcessRecord app) { 2460 int lrui = mLruProcesses.lastIndexOf(app); 2461 if (lrui >= 0) { 2462 if (lrui <= mLruProcessActivityStart) { 2463 mLruProcessActivityStart--; 2464 } 2465 if (lrui <= mLruProcessServiceStart) { 2466 mLruProcessServiceStart--; 2467 } 2468 mLruProcesses.remove(lrui); 2469 } 2470 } 2471 2472 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2473 ProcessRecord client) { 2474 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2475 || app.treatLikeActivity; 2476 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2477 if (!activityChange && hasActivity) { 2478 // The process has activities, so we are only allowing activity-based adjustments 2479 // to move it. It should be kept in the front of the list with other 2480 // processes that have activities, and we don't want those to change their 2481 // order except due to activity operations. 2482 return; 2483 } 2484 2485 mLruSeq++; 2486 final long now = SystemClock.uptimeMillis(); 2487 app.lastActivityTime = now; 2488 2489 // First a quick reject: if the app is already at the position we will 2490 // put it, then there is nothing to do. 2491 if (hasActivity) { 2492 final int N = mLruProcesses.size(); 2493 if (N > 0 && mLruProcesses.get(N-1) == app) { 2494 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2495 return; 2496 } 2497 } else { 2498 if (mLruProcessServiceStart > 0 2499 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2500 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2501 return; 2502 } 2503 } 2504 2505 int lrui = mLruProcesses.lastIndexOf(app); 2506 2507 if (app.persistent && lrui >= 0) { 2508 // We don't care about the position of persistent processes, as long as 2509 // they are in the list. 2510 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2511 return; 2512 } 2513 2514 /* In progress: compute new position first, so we can avoid doing work 2515 if the process is not actually going to move. Not yet working. 2516 int addIndex; 2517 int nextIndex; 2518 boolean inActivity = false, inService = false; 2519 if (hasActivity) { 2520 // Process has activities, put it at the very tipsy-top. 2521 addIndex = mLruProcesses.size(); 2522 nextIndex = mLruProcessServiceStart; 2523 inActivity = true; 2524 } else if (hasService) { 2525 // Process has services, put it at the top of the service list. 2526 addIndex = mLruProcessActivityStart; 2527 nextIndex = mLruProcessServiceStart; 2528 inActivity = true; 2529 inService = true; 2530 } else { 2531 // Process not otherwise of interest, it goes to the top of the non-service area. 2532 addIndex = mLruProcessServiceStart; 2533 if (client != null) { 2534 int clientIndex = mLruProcesses.lastIndexOf(client); 2535 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2536 + app); 2537 if (clientIndex >= 0 && addIndex > clientIndex) { 2538 addIndex = clientIndex; 2539 } 2540 } 2541 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2542 } 2543 2544 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2545 + mLruProcessActivityStart + "): " + app); 2546 */ 2547 2548 if (lrui >= 0) { 2549 if (lrui < mLruProcessActivityStart) { 2550 mLruProcessActivityStart--; 2551 } 2552 if (lrui < mLruProcessServiceStart) { 2553 mLruProcessServiceStart--; 2554 } 2555 /* 2556 if (addIndex > lrui) { 2557 addIndex--; 2558 } 2559 if (nextIndex > lrui) { 2560 nextIndex--; 2561 } 2562 */ 2563 mLruProcesses.remove(lrui); 2564 } 2565 2566 /* 2567 mLruProcesses.add(addIndex, app); 2568 if (inActivity) { 2569 mLruProcessActivityStart++; 2570 } 2571 if (inService) { 2572 mLruProcessActivityStart++; 2573 } 2574 */ 2575 2576 int nextIndex; 2577 if (hasActivity) { 2578 final int N = mLruProcesses.size(); 2579 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2580 // Process doesn't have activities, but has clients with 2581 // activities... move it up, but one below the top (the top 2582 // should always have a real activity). 2583 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2584 mLruProcesses.add(N-1, app); 2585 // To keep it from spamming the LRU list (by making a bunch of clients), 2586 // we will push down any other entries owned by the app. 2587 final int uid = app.info.uid; 2588 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2589 ProcessRecord subProc = mLruProcesses.get(i); 2590 if (subProc.info.uid == uid) { 2591 // We want to push this one down the list. If the process after 2592 // it is for the same uid, however, don't do so, because we don't 2593 // want them internally to be re-ordered. 2594 if (mLruProcesses.get(i-1).info.uid != uid) { 2595 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2596 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2597 ProcessRecord tmp = mLruProcesses.get(i); 2598 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2599 mLruProcesses.set(i-1, tmp); 2600 i--; 2601 } 2602 } else { 2603 // A gap, we can stop here. 2604 break; 2605 } 2606 } 2607 } else { 2608 // Process has activities, put it at the very tipsy-top. 2609 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2610 mLruProcesses.add(app); 2611 } 2612 nextIndex = mLruProcessServiceStart; 2613 } else if (hasService) { 2614 // Process has services, put it at the top of the service list. 2615 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2616 mLruProcesses.add(mLruProcessActivityStart, app); 2617 nextIndex = mLruProcessServiceStart; 2618 mLruProcessActivityStart++; 2619 } else { 2620 // Process not otherwise of interest, it goes to the top of the non-service area. 2621 int index = mLruProcessServiceStart; 2622 if (client != null) { 2623 // If there is a client, don't allow the process to be moved up higher 2624 // in the list than that client. 2625 int clientIndex = mLruProcesses.lastIndexOf(client); 2626 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2627 + " when updating " + app); 2628 if (clientIndex <= lrui) { 2629 // Don't allow the client index restriction to push it down farther in the 2630 // list than it already is. 2631 clientIndex = lrui; 2632 } 2633 if (clientIndex >= 0 && index > clientIndex) { 2634 index = clientIndex; 2635 } 2636 } 2637 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2638 mLruProcesses.add(index, app); 2639 nextIndex = index-1; 2640 mLruProcessActivityStart++; 2641 mLruProcessServiceStart++; 2642 } 2643 2644 // If the app is currently using a content provider or service, 2645 // bump those processes as well. 2646 for (int j=app.connections.size()-1; j>=0; j--) { 2647 ConnectionRecord cr = app.connections.valueAt(j); 2648 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2649 && cr.binding.service.app != null 2650 && cr.binding.service.app.lruSeq != mLruSeq 2651 && !cr.binding.service.app.persistent) { 2652 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2653 "service connection", cr, app); 2654 } 2655 } 2656 for (int j=app.conProviders.size()-1; j>=0; j--) { 2657 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2658 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2659 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2660 "provider reference", cpr, app); 2661 } 2662 } 2663 } 2664 2665 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2666 if (uid == Process.SYSTEM_UID) { 2667 // The system gets to run in any process. If there are multiple 2668 // processes with the same uid, just pick the first (this 2669 // should never happen). 2670 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2671 if (procs == null) return null; 2672 final int N = procs.size(); 2673 for (int i = 0; i < N; i++) { 2674 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2675 } 2676 } 2677 ProcessRecord proc = mProcessNames.get(processName, uid); 2678 if (false && proc != null && !keepIfLarge 2679 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2680 && proc.lastCachedPss >= 4000) { 2681 // Turn this condition on to cause killing to happen regularly, for testing. 2682 if (proc.baseProcessTracker != null) { 2683 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2684 } 2685 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2686 + "k from cached"); 2687 } else if (proc != null && !keepIfLarge 2688 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2689 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2690 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2691 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2692 if (proc.baseProcessTracker != null) { 2693 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2694 } 2695 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2696 + "k from cached"); 2697 } 2698 } 2699 return proc; 2700 } 2701 2702 void ensurePackageDexOpt(String packageName) { 2703 IPackageManager pm = AppGlobals.getPackageManager(); 2704 try { 2705 if (pm.performDexOpt(packageName)) { 2706 mDidDexOpt = true; 2707 } 2708 } catch (RemoteException e) { 2709 } 2710 } 2711 2712 boolean isNextTransitionForward() { 2713 int transit = mWindowManager.getPendingAppTransition(); 2714 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2715 || transit == AppTransition.TRANSIT_TASK_OPEN 2716 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2717 } 2718 2719 final ProcessRecord startProcessLocked(String processName, 2720 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2721 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2722 boolean isolated, boolean keepIfLarge) { 2723 ProcessRecord app; 2724 if (!isolated) { 2725 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2726 } else { 2727 // If this is an isolated process, it can't re-use an existing process. 2728 app = null; 2729 } 2730 // We don't have to do anything more if: 2731 // (1) There is an existing application record; and 2732 // (2) The caller doesn't think it is dead, OR there is no thread 2733 // object attached to it so we know it couldn't have crashed; and 2734 // (3) There is a pid assigned to it, so it is either starting or 2735 // already running. 2736 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2737 + " app=" + app + " knownToBeDead=" + knownToBeDead 2738 + " thread=" + (app != null ? app.thread : null) 2739 + " pid=" + (app != null ? app.pid : -1)); 2740 if (app != null && app.pid > 0) { 2741 if (!knownToBeDead || app.thread == null) { 2742 // We already have the app running, or are waiting for it to 2743 // come up (we have a pid but not yet its thread), so keep it. 2744 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2745 // If this is a new package in the process, add the package to the list 2746 app.addPackage(info.packageName, mProcessStats); 2747 return app; 2748 } 2749 2750 // An application record is attached to a previous process, 2751 // clean it up now. 2752 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2753 handleAppDiedLocked(app, true, true); 2754 } 2755 2756 String hostingNameStr = hostingName != null 2757 ? hostingName.flattenToShortString() : null; 2758 2759 if (!isolated) { 2760 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2761 // If we are in the background, then check to see if this process 2762 // is bad. If so, we will just silently fail. 2763 if (mBadProcesses.get(info.processName, info.uid) != null) { 2764 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2765 + "/" + info.processName); 2766 return null; 2767 } 2768 } else { 2769 // When the user is explicitly starting a process, then clear its 2770 // crash count so that we won't make it bad until they see at 2771 // least one crash dialog again, and make the process good again 2772 // if it had been bad. 2773 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2774 + "/" + info.processName); 2775 mProcessCrashTimes.remove(info.processName, info.uid); 2776 if (mBadProcesses.get(info.processName, info.uid) != null) { 2777 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2778 UserHandle.getUserId(info.uid), info.uid, 2779 info.processName); 2780 mBadProcesses.remove(info.processName, info.uid); 2781 if (app != null) { 2782 app.bad = false; 2783 } 2784 } 2785 } 2786 } 2787 2788 if (app == null) { 2789 app = newProcessRecordLocked(info, processName, isolated); 2790 if (app == null) { 2791 Slog.w(TAG, "Failed making new process record for " 2792 + processName + "/" + info.uid + " isolated=" + isolated); 2793 return null; 2794 } 2795 mProcessNames.put(processName, app.uid, app); 2796 if (isolated) { 2797 mIsolatedProcesses.put(app.uid, app); 2798 } 2799 } else { 2800 // If this is a new package in the process, add the package to the list 2801 app.addPackage(info.packageName, mProcessStats); 2802 } 2803 2804 // If the system is not ready yet, then hold off on starting this 2805 // process until it is. 2806 if (!mProcessesReady 2807 && !isAllowedWhileBooting(info) 2808 && !allowWhileBooting) { 2809 if (!mProcessesOnHold.contains(app)) { 2810 mProcessesOnHold.add(app); 2811 } 2812 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2813 return app; 2814 } 2815 2816 startProcessLocked(app, hostingType, hostingNameStr); 2817 return (app.pid != 0) ? app : null; 2818 } 2819 2820 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2821 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2822 } 2823 2824 private final void startProcessLocked(ProcessRecord app, 2825 String hostingType, String hostingNameStr) { 2826 if (app.pid > 0 && app.pid != MY_PID) { 2827 synchronized (mPidsSelfLocked) { 2828 mPidsSelfLocked.remove(app.pid); 2829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2830 } 2831 app.setPid(0); 2832 } 2833 2834 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2835 "startProcessLocked removing on hold: " + app); 2836 mProcessesOnHold.remove(app); 2837 2838 updateCpuStats(); 2839 2840 try { 2841 int uid = app.uid; 2842 2843 int[] gids = null; 2844 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2845 if (!app.isolated) { 2846 int[] permGids = null; 2847 try { 2848 final PackageManager pm = mContext.getPackageManager(); 2849 permGids = pm.getPackageGids(app.info.packageName); 2850 2851 if (Environment.isExternalStorageEmulated()) { 2852 if (pm.checkPermission( 2853 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2854 app.info.packageName) == PERMISSION_GRANTED) { 2855 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2856 } else { 2857 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2858 } 2859 } 2860 } catch (PackageManager.NameNotFoundException e) { 2861 Slog.w(TAG, "Unable to retrieve gids", e); 2862 } 2863 2864 /* 2865 * Add shared application GID so applications can share some 2866 * resources like shared libraries 2867 */ 2868 if (permGids == null) { 2869 gids = new int[1]; 2870 } else { 2871 gids = new int[permGids.length + 1]; 2872 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2873 } 2874 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2875 } 2876 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2877 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2878 && mTopComponent != null 2879 && app.processName.equals(mTopComponent.getPackageName())) { 2880 uid = 0; 2881 } 2882 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2883 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2884 uid = 0; 2885 } 2886 } 2887 int debugFlags = 0; 2888 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2889 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2890 // Also turn on CheckJNI for debuggable apps. It's quite 2891 // awkward to turn on otherwise. 2892 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2893 } 2894 // Run the app in safe mode if its manifest requests so or the 2895 // system is booted in safe mode. 2896 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2897 mSafeMode == true) { 2898 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2899 } 2900 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2901 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2902 } 2903 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2904 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2905 } 2906 if ("1".equals(SystemProperties.get("debug.assert"))) { 2907 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2908 } 2909 2910 String requiredAbi = app.info.requiredCpuAbi; 2911 if (requiredAbi == null) { 2912 requiredAbi = Build.SUPPORTED_ABIS[0]; 2913 } 2914 2915 // Start the process. It will either succeed and return a result containing 2916 // the PID of the new process, or else throw a RuntimeException. 2917 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2918 app.processName, uid, uid, gids, debugFlags, mountExternal, 2919 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2920 2921 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2922 synchronized (bs) { 2923 if (bs.isOnBattery()) { 2924 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2925 } 2926 } 2927 2928 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2929 UserHandle.getUserId(uid), startResult.pid, uid, 2930 app.processName, hostingType, 2931 hostingNameStr != null ? hostingNameStr : ""); 2932 2933 if (app.persistent) { 2934 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2935 } 2936 2937 StringBuilder buf = mStringBuilder; 2938 buf.setLength(0); 2939 buf.append("Start proc "); 2940 buf.append(app.processName); 2941 buf.append(" for "); 2942 buf.append(hostingType); 2943 if (hostingNameStr != null) { 2944 buf.append(" "); 2945 buf.append(hostingNameStr); 2946 } 2947 buf.append(": pid="); 2948 buf.append(startResult.pid); 2949 buf.append(" uid="); 2950 buf.append(uid); 2951 buf.append(" gids={"); 2952 if (gids != null) { 2953 for (int gi=0; gi<gids.length; gi++) { 2954 if (gi != 0) buf.append(", "); 2955 buf.append(gids[gi]); 2956 2957 } 2958 } 2959 buf.append("}"); 2960 Slog.i(TAG, buf.toString()); 2961 app.setPid(startResult.pid); 2962 app.usingWrapper = startResult.usingWrapper; 2963 app.removed = false; 2964 synchronized (mPidsSelfLocked) { 2965 this.mPidsSelfLocked.put(startResult.pid, app); 2966 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2967 msg.obj = app; 2968 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2969 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2970 } 2971 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2972 app.processName, app.info.uid); 2973 if (app.isolated) { 2974 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2975 } 2976 } catch (RuntimeException e) { 2977 // XXX do better error recovery. 2978 app.setPid(0); 2979 Slog.e(TAG, "Failure starting process " + app.processName, e); 2980 } 2981 } 2982 2983 void updateUsageStats(ActivityRecord component, boolean resumed) { 2984 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2985 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2986 if (resumed) { 2987 mUsageStatsService.noteResumeComponent(component.realActivity); 2988 synchronized (stats) { 2989 stats.noteActivityResumedLocked(component.app.uid); 2990 } 2991 } else { 2992 mUsageStatsService.notePauseComponent(component.realActivity); 2993 synchronized (stats) { 2994 stats.noteActivityPausedLocked(component.app.uid); 2995 } 2996 } 2997 } 2998 2999 Intent getHomeIntent() { 3000 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 3001 intent.setComponent(mTopComponent); 3002 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 3003 intent.addCategory(Intent.CATEGORY_HOME); 3004 } 3005 return intent; 3006 } 3007 3008 boolean startHomeActivityLocked(int userId) { 3009 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3010 && mTopAction == null) { 3011 // We are running in factory test mode, but unable to find 3012 // the factory test app, so just sit around displaying the 3013 // error message and don't try to start anything. 3014 return false; 3015 } 3016 Intent intent = getHomeIntent(); 3017 ActivityInfo aInfo = 3018 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3019 if (aInfo != null) { 3020 intent.setComponent(new ComponentName( 3021 aInfo.applicationInfo.packageName, aInfo.name)); 3022 // Don't do this if the home app is currently being 3023 // instrumented. 3024 aInfo = new ActivityInfo(aInfo); 3025 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3026 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3027 aInfo.applicationInfo.uid, true); 3028 if (app == null || app.instrumentationClass == null) { 3029 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3030 mStackSupervisor.startHomeActivity(intent, aInfo); 3031 } 3032 } 3033 3034 return true; 3035 } 3036 3037 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3038 ActivityInfo ai = null; 3039 ComponentName comp = intent.getComponent(); 3040 try { 3041 if (comp != null) { 3042 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3043 } else { 3044 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3045 intent, 3046 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3047 flags, userId); 3048 3049 if (info != null) { 3050 ai = info.activityInfo; 3051 } 3052 } 3053 } catch (RemoteException e) { 3054 // ignore 3055 } 3056 3057 return ai; 3058 } 3059 3060 /** 3061 * Starts the "new version setup screen" if appropriate. 3062 */ 3063 void startSetupActivityLocked() { 3064 // Only do this once per boot. 3065 if (mCheckedForSetup) { 3066 return; 3067 } 3068 3069 // We will show this screen if the current one is a different 3070 // version than the last one shown, and we are not running in 3071 // low-level factory test mode. 3072 final ContentResolver resolver = mContext.getContentResolver(); 3073 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3074 Settings.Global.getInt(resolver, 3075 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3076 mCheckedForSetup = true; 3077 3078 // See if we should be showing the platform update setup UI. 3079 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3080 List<ResolveInfo> ris = mContext.getPackageManager() 3081 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3082 3083 // We don't allow third party apps to replace this. 3084 ResolveInfo ri = null; 3085 for (int i=0; ris != null && i<ris.size(); i++) { 3086 if ((ris.get(i).activityInfo.applicationInfo.flags 3087 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3088 ri = ris.get(i); 3089 break; 3090 } 3091 } 3092 3093 if (ri != null) { 3094 String vers = ri.activityInfo.metaData != null 3095 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3096 : null; 3097 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3098 vers = ri.activityInfo.applicationInfo.metaData.getString( 3099 Intent.METADATA_SETUP_VERSION); 3100 } 3101 String lastVers = Settings.Secure.getString( 3102 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3103 if (vers != null && !vers.equals(lastVers)) { 3104 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3105 intent.setComponent(new ComponentName( 3106 ri.activityInfo.packageName, ri.activityInfo.name)); 3107 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3108 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3109 } 3110 } 3111 } 3112 } 3113 3114 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3115 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3116 } 3117 3118 void enforceNotIsolatedCaller(String caller) { 3119 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3120 throw new SecurityException("Isolated process not allowed to call " + caller); 3121 } 3122 } 3123 3124 @Override 3125 public int getFrontActivityScreenCompatMode() { 3126 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3127 synchronized (this) { 3128 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3129 } 3130 } 3131 3132 @Override 3133 public void setFrontActivityScreenCompatMode(int mode) { 3134 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3135 "setFrontActivityScreenCompatMode"); 3136 synchronized (this) { 3137 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3138 } 3139 } 3140 3141 @Override 3142 public int getPackageScreenCompatMode(String packageName) { 3143 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3144 synchronized (this) { 3145 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3146 } 3147 } 3148 3149 @Override 3150 public void setPackageScreenCompatMode(String packageName, int mode) { 3151 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3152 "setPackageScreenCompatMode"); 3153 synchronized (this) { 3154 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3155 } 3156 } 3157 3158 @Override 3159 public boolean getPackageAskScreenCompat(String packageName) { 3160 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3161 synchronized (this) { 3162 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3163 } 3164 } 3165 3166 @Override 3167 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3168 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3169 "setPackageAskScreenCompat"); 3170 synchronized (this) { 3171 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3172 } 3173 } 3174 3175 private void dispatchProcessesChanged() { 3176 int N; 3177 synchronized (this) { 3178 N = mPendingProcessChanges.size(); 3179 if (mActiveProcessChanges.length < N) { 3180 mActiveProcessChanges = new ProcessChangeItem[N]; 3181 } 3182 mPendingProcessChanges.toArray(mActiveProcessChanges); 3183 mAvailProcessChanges.addAll(mPendingProcessChanges); 3184 mPendingProcessChanges.clear(); 3185 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3186 } 3187 3188 int i = mProcessObservers.beginBroadcast(); 3189 while (i > 0) { 3190 i--; 3191 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3192 if (observer != null) { 3193 try { 3194 for (int j=0; j<N; j++) { 3195 ProcessChangeItem item = mActiveProcessChanges[j]; 3196 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3197 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3198 + item.pid + " uid=" + item.uid + ": " 3199 + item.foregroundActivities); 3200 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3201 item.foregroundActivities); 3202 } 3203 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3204 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3205 + item.pid + " uid=" + item.uid + ": " + item.processState); 3206 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3207 } 3208 } 3209 } catch (RemoteException e) { 3210 } 3211 } 3212 } 3213 mProcessObservers.finishBroadcast(); 3214 } 3215 3216 private void dispatchProcessDied(int pid, int uid) { 3217 int i = mProcessObservers.beginBroadcast(); 3218 while (i > 0) { 3219 i--; 3220 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3221 if (observer != null) { 3222 try { 3223 observer.onProcessDied(pid, uid); 3224 } catch (RemoteException e) { 3225 } 3226 } 3227 } 3228 mProcessObservers.finishBroadcast(); 3229 } 3230 3231 final void doPendingActivityLaunchesLocked(boolean doResume) { 3232 final int N = mPendingActivityLaunches.size(); 3233 if (N <= 0) { 3234 return; 3235 } 3236 for (int i=0; i<N; i++) { 3237 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3238 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3239 doResume && i == (N-1), null); 3240 } 3241 mPendingActivityLaunches.clear(); 3242 } 3243 3244 @Override 3245 public final int startActivity(IApplicationThread caller, String callingPackage, 3246 Intent intent, String resolvedType, IBinder resultTo, 3247 String resultWho, int requestCode, int startFlags, 3248 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3249 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3250 resultWho, requestCode, 3251 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3252 } 3253 3254 @Override 3255 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3256 Intent intent, String resolvedType, IBinder resultTo, 3257 String resultWho, int requestCode, int startFlags, 3258 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3259 enforceNotIsolatedCaller("startActivity"); 3260 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3261 false, true, "startActivity", null); 3262 // TODO: Switch to user app stacks here. 3263 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3264 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3265 null, null, options, userId, null); 3266 } 3267 3268 @Override 3269 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3270 Intent intent, String resolvedType, IBinder resultTo, 3271 String resultWho, int requestCode, int startFlags, String profileFile, 3272 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3273 enforceNotIsolatedCaller("startActivityAndWait"); 3274 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3275 false, true, "startActivityAndWait", null); 3276 WaitResult res = new WaitResult(); 3277 // TODO: Switch to user app stacks here. 3278 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3279 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3280 res, null, options, UserHandle.getCallingUserId(), null); 3281 return res; 3282 } 3283 3284 @Override 3285 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3286 Intent intent, String resolvedType, IBinder resultTo, 3287 String resultWho, int requestCode, int startFlags, Configuration config, 3288 Bundle options, int userId) { 3289 enforceNotIsolatedCaller("startActivityWithConfig"); 3290 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3291 false, true, "startActivityWithConfig", null); 3292 // TODO: Switch to user app stacks here. 3293 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3294 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3295 null, null, null, config, options, userId, null); 3296 return ret; 3297 } 3298 3299 @Override 3300 public int startActivityIntentSender(IApplicationThread caller, 3301 IntentSender intent, Intent fillInIntent, String resolvedType, 3302 IBinder resultTo, String resultWho, int requestCode, 3303 int flagsMask, int flagsValues, Bundle options) { 3304 enforceNotIsolatedCaller("startActivityIntentSender"); 3305 // Refuse possible leaked file descriptors 3306 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3307 throw new IllegalArgumentException("File descriptors passed in Intent"); 3308 } 3309 3310 IIntentSender sender = intent.getTarget(); 3311 if (!(sender instanceof PendingIntentRecord)) { 3312 throw new IllegalArgumentException("Bad PendingIntent object"); 3313 } 3314 3315 PendingIntentRecord pir = (PendingIntentRecord)sender; 3316 3317 synchronized (this) { 3318 // If this is coming from the currently resumed activity, it is 3319 // effectively saying that app switches are allowed at this point. 3320 final ActivityStack stack = getFocusedStack(); 3321 if (stack.mResumedActivity != null && 3322 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3323 mAppSwitchesAllowedTime = 0; 3324 } 3325 } 3326 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3327 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3328 return ret; 3329 } 3330 3331 @Override 3332 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3333 Intent intent, String resolvedType, IVoiceInteractionSession session, 3334 IVoiceInteractor interactor, int startFlags, String profileFile, 3335 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3336 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3337 != PackageManager.PERMISSION_GRANTED) { 3338 String msg = "Permission Denial: startVoiceActivity() from pid=" 3339 + Binder.getCallingPid() 3340 + ", uid=" + Binder.getCallingUid() 3341 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3342 Slog.w(TAG, msg); 3343 throw new SecurityException(msg); 3344 } 3345 if (session == null || interactor == null) { 3346 throw new NullPointerException("null session or interactor"); 3347 } 3348 userId = handleIncomingUser(callingPid, callingUid, userId, 3349 false, true, "startVoiceActivity", null); 3350 // TODO: Switch to user app stacks here. 3351 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3352 resolvedType, session, interactor, null, null, 0, startFlags, 3353 profileFile, profileFd, null, null, options, userId, null); 3354 } 3355 3356 @Override 3357 public boolean startNextMatchingActivity(IBinder callingActivity, 3358 Intent intent, Bundle options) { 3359 // Refuse possible leaked file descriptors 3360 if (intent != null && intent.hasFileDescriptors() == true) { 3361 throw new IllegalArgumentException("File descriptors passed in Intent"); 3362 } 3363 3364 synchronized (this) { 3365 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3366 if (r == null) { 3367 ActivityOptions.abort(options); 3368 return false; 3369 } 3370 if (r.app == null || r.app.thread == null) { 3371 // The caller is not running... d'oh! 3372 ActivityOptions.abort(options); 3373 return false; 3374 } 3375 intent = new Intent(intent); 3376 // The caller is not allowed to change the data. 3377 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3378 // And we are resetting to find the next component... 3379 intent.setComponent(null); 3380 3381 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3382 3383 ActivityInfo aInfo = null; 3384 try { 3385 List<ResolveInfo> resolves = 3386 AppGlobals.getPackageManager().queryIntentActivities( 3387 intent, r.resolvedType, 3388 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3389 UserHandle.getCallingUserId()); 3390 3391 // Look for the original activity in the list... 3392 final int N = resolves != null ? resolves.size() : 0; 3393 for (int i=0; i<N; i++) { 3394 ResolveInfo rInfo = resolves.get(i); 3395 if (rInfo.activityInfo.packageName.equals(r.packageName) 3396 && rInfo.activityInfo.name.equals(r.info.name)) { 3397 // We found the current one... the next matching is 3398 // after it. 3399 i++; 3400 if (i<N) { 3401 aInfo = resolves.get(i).activityInfo; 3402 } 3403 if (debug) { 3404 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3405 + "/" + r.info.name); 3406 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3407 + "/" + aInfo.name); 3408 } 3409 break; 3410 } 3411 } 3412 } catch (RemoteException e) { 3413 } 3414 3415 if (aInfo == null) { 3416 // Nobody who is next! 3417 ActivityOptions.abort(options); 3418 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3419 return false; 3420 } 3421 3422 intent.setComponent(new ComponentName( 3423 aInfo.applicationInfo.packageName, aInfo.name)); 3424 intent.setFlags(intent.getFlags()&~( 3425 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3426 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3427 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3428 Intent.FLAG_ACTIVITY_NEW_TASK)); 3429 3430 // Okay now we need to start the new activity, replacing the 3431 // currently running activity. This is a little tricky because 3432 // we want to start the new one as if the current one is finished, 3433 // but not finish the current one first so that there is no flicker. 3434 // And thus... 3435 final boolean wasFinishing = r.finishing; 3436 r.finishing = true; 3437 3438 // Propagate reply information over to the new activity. 3439 final ActivityRecord resultTo = r.resultTo; 3440 final String resultWho = r.resultWho; 3441 final int requestCode = r.requestCode; 3442 r.resultTo = null; 3443 if (resultTo != null) { 3444 resultTo.removeResultsLocked(r, resultWho, requestCode); 3445 } 3446 3447 final long origId = Binder.clearCallingIdentity(); 3448 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3449 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3450 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3451 options, false, null, null); 3452 Binder.restoreCallingIdentity(origId); 3453 3454 r.finishing = wasFinishing; 3455 if (res != ActivityManager.START_SUCCESS) { 3456 return false; 3457 } 3458 return true; 3459 } 3460 } 3461 3462 final int startActivityInPackage(int uid, String callingPackage, 3463 Intent intent, String resolvedType, IBinder resultTo, 3464 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3465 IActivityContainer container) { 3466 3467 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3468 false, true, "startActivityInPackage", null); 3469 3470 // TODO: Switch to user app stacks here. 3471 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3472 null, null, resultTo, resultWho, requestCode, startFlags, 3473 null, null, null, null, options, userId, container); 3474 return ret; 3475 } 3476 3477 @Override 3478 public final int startActivities(IApplicationThread caller, String callingPackage, 3479 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3480 int userId) { 3481 enforceNotIsolatedCaller("startActivities"); 3482 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3483 false, true, "startActivity", null); 3484 // TODO: Switch to user app stacks here. 3485 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3486 resolvedTypes, resultTo, options, userId); 3487 return ret; 3488 } 3489 3490 final int startActivitiesInPackage(int uid, String callingPackage, 3491 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3492 Bundle options, int userId) { 3493 3494 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3495 false, true, "startActivityInPackage", null); 3496 // TODO: Switch to user app stacks here. 3497 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3498 resultTo, options, userId); 3499 return ret; 3500 } 3501 3502 final void addRecentTaskLocked(TaskRecord task) { 3503 int N = mRecentTasks.size(); 3504 // Quick case: check if the top-most recent task is the same. 3505 if (N > 0 && mRecentTasks.get(0) == task) { 3506 return; 3507 } 3508 // Another quick case: never add voice sessions. 3509 if (task.voiceSession != null) { 3510 return; 3511 } 3512 // Remove any existing entries that are the same kind of task. 3513 final Intent intent = task.intent; 3514 final boolean document = intent != null && intent.isDocument(); 3515 for (int i=0; i<N; i++) { 3516 TaskRecord tr = mRecentTasks.get(i); 3517 if (task != tr) { 3518 if (task.userId != tr.userId) { 3519 continue; 3520 } 3521 final Intent trIntent = tr.intent; 3522 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3523 (intent == null || !intent.filterEquals(trIntent))) { 3524 continue; 3525 } 3526 if (document || trIntent != null && trIntent.isDocument()) { 3527 // Document tasks do not match other tasks. 3528 continue; 3529 } 3530 } 3531 3532 // Either task and tr are the same or, their affinities match or their intents match 3533 // and neither of them is a document. 3534 tr.disposeThumbnail(); 3535 mRecentTasks.remove(i); 3536 i--; 3537 N--; 3538 if (task.intent == null) { 3539 // If the new recent task we are adding is not fully 3540 // specified, then replace it with the existing recent task. 3541 task = tr; 3542 } 3543 } 3544 if (N >= MAX_RECENT_TASKS) { 3545 mRecentTasks.remove(N-1).disposeThumbnail(); 3546 } 3547 mRecentTasks.add(0, task); 3548 } 3549 3550 @Override 3551 public void reportActivityFullyDrawn(IBinder token) { 3552 synchronized (this) { 3553 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3554 if (r == null) { 3555 return; 3556 } 3557 r.reportFullyDrawnLocked(); 3558 } 3559 } 3560 3561 @Override 3562 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3563 synchronized (this) { 3564 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3565 if (r == null) { 3566 return; 3567 } 3568 final long origId = Binder.clearCallingIdentity(); 3569 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3570 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3571 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3572 if (config != null) { 3573 r.frozenBeforeDestroy = true; 3574 if (!updateConfigurationLocked(config, r, false, false)) { 3575 mStackSupervisor.resumeTopActivitiesLocked(); 3576 } 3577 } 3578 Binder.restoreCallingIdentity(origId); 3579 } 3580 } 3581 3582 @Override 3583 public int getRequestedOrientation(IBinder token) { 3584 synchronized (this) { 3585 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3586 if (r == null) { 3587 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3588 } 3589 return mWindowManager.getAppOrientation(r.appToken); 3590 } 3591 } 3592 3593 /** 3594 * This is the internal entry point for handling Activity.finish(). 3595 * 3596 * @param token The Binder token referencing the Activity we want to finish. 3597 * @param resultCode Result code, if any, from this Activity. 3598 * @param resultData Result data (Intent), if any, from this Activity. 3599 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3600 * the root Activity in the task. 3601 * 3602 * @return Returns true if the activity successfully finished, or false if it is still running. 3603 */ 3604 @Override 3605 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3606 boolean finishTask) { 3607 // Refuse possible leaked file descriptors 3608 if (resultData != null && resultData.hasFileDescriptors() == true) { 3609 throw new IllegalArgumentException("File descriptors passed in Intent"); 3610 } 3611 3612 synchronized(this) { 3613 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3614 if (r == null) { 3615 return true; 3616 } 3617 // Keep track of the root activity of the task before we finish it 3618 TaskRecord tr = r.task; 3619 ActivityRecord rootR = tr.getRootActivity(); 3620 if (mController != null) { 3621 // Find the first activity that is not finishing. 3622 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3623 if (next != null) { 3624 // ask watcher if this is allowed 3625 boolean resumeOK = true; 3626 try { 3627 resumeOK = mController.activityResuming(next.packageName); 3628 } catch (RemoteException e) { 3629 mController = null; 3630 Watchdog.getInstance().setActivityController(null); 3631 } 3632 3633 if (!resumeOK) { 3634 return false; 3635 } 3636 } 3637 } 3638 final long origId = Binder.clearCallingIdentity(); 3639 try { 3640 boolean res; 3641 if (finishTask && r == rootR) { 3642 // If requested, remove the task that is associated to this activity only if it 3643 // was the root activity in the task. The result code and data is ignored because 3644 // we don't support returning them across task boundaries. 3645 res = removeTaskByIdLocked(tr.taskId, 0); 3646 } else { 3647 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3648 resultData, "app-request", true); 3649 } 3650 return res; 3651 } finally { 3652 Binder.restoreCallingIdentity(origId); 3653 } 3654 } 3655 } 3656 3657 @Override 3658 public final void finishHeavyWeightApp() { 3659 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3660 != PackageManager.PERMISSION_GRANTED) { 3661 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3662 + Binder.getCallingPid() 3663 + ", uid=" + Binder.getCallingUid() 3664 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3665 Slog.w(TAG, msg); 3666 throw new SecurityException(msg); 3667 } 3668 3669 synchronized(this) { 3670 if (mHeavyWeightProcess == null) { 3671 return; 3672 } 3673 3674 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3675 mHeavyWeightProcess.activities); 3676 for (int i=0; i<activities.size(); i++) { 3677 ActivityRecord r = activities.get(i); 3678 if (!r.finishing) { 3679 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3680 null, "finish-heavy", true); 3681 } 3682 } 3683 3684 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3685 mHeavyWeightProcess.userId, 0)); 3686 mHeavyWeightProcess = null; 3687 } 3688 } 3689 3690 @Override 3691 public void crashApplication(int uid, int initialPid, String packageName, 3692 String message) { 3693 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3694 != PackageManager.PERMISSION_GRANTED) { 3695 String msg = "Permission Denial: crashApplication() from pid=" 3696 + Binder.getCallingPid() 3697 + ", uid=" + Binder.getCallingUid() 3698 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3699 Slog.w(TAG, msg); 3700 throw new SecurityException(msg); 3701 } 3702 3703 synchronized(this) { 3704 ProcessRecord proc = null; 3705 3706 // Figure out which process to kill. We don't trust that initialPid 3707 // still has any relation to current pids, so must scan through the 3708 // list. 3709 synchronized (mPidsSelfLocked) { 3710 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3711 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3712 if (p.uid != uid) { 3713 continue; 3714 } 3715 if (p.pid == initialPid) { 3716 proc = p; 3717 break; 3718 } 3719 if (p.pkgList.containsKey(packageName)) { 3720 proc = p; 3721 } 3722 } 3723 } 3724 3725 if (proc == null) { 3726 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3727 + " initialPid=" + initialPid 3728 + " packageName=" + packageName); 3729 return; 3730 } 3731 3732 if (proc.thread != null) { 3733 if (proc.pid == Process.myPid()) { 3734 Log.w(TAG, "crashApplication: trying to crash self!"); 3735 return; 3736 } 3737 long ident = Binder.clearCallingIdentity(); 3738 try { 3739 proc.thread.scheduleCrash(message); 3740 } catch (RemoteException e) { 3741 } 3742 Binder.restoreCallingIdentity(ident); 3743 } 3744 } 3745 } 3746 3747 @Override 3748 public final void finishSubActivity(IBinder token, String resultWho, 3749 int requestCode) { 3750 synchronized(this) { 3751 final long origId = Binder.clearCallingIdentity(); 3752 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3753 if (r != null) { 3754 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3755 } 3756 Binder.restoreCallingIdentity(origId); 3757 } 3758 } 3759 3760 @Override 3761 public boolean finishActivityAffinity(IBinder token) { 3762 synchronized(this) { 3763 final long origId = Binder.clearCallingIdentity(); 3764 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3765 boolean res = false; 3766 if (r != null) { 3767 res = r.task.stack.finishActivityAffinityLocked(r); 3768 } 3769 Binder.restoreCallingIdentity(origId); 3770 return res; 3771 } 3772 } 3773 3774 @Override 3775 public boolean willActivityBeVisible(IBinder token) { 3776 synchronized(this) { 3777 ActivityStack stack = ActivityRecord.getStackLocked(token); 3778 if (stack != null) { 3779 return stack.willActivityBeVisibleLocked(token); 3780 } 3781 return false; 3782 } 3783 } 3784 3785 @Override 3786 public void overridePendingTransition(IBinder token, String packageName, 3787 int enterAnim, int exitAnim) { 3788 synchronized(this) { 3789 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3790 if (self == null) { 3791 return; 3792 } 3793 3794 final long origId = Binder.clearCallingIdentity(); 3795 3796 if (self.state == ActivityState.RESUMED 3797 || self.state == ActivityState.PAUSING) { 3798 mWindowManager.overridePendingAppTransition(packageName, 3799 enterAnim, exitAnim, null); 3800 } 3801 3802 Binder.restoreCallingIdentity(origId); 3803 } 3804 } 3805 3806 /** 3807 * Main function for removing an existing process from the activity manager 3808 * as a result of that process going away. Clears out all connections 3809 * to the process. 3810 */ 3811 private final void handleAppDiedLocked(ProcessRecord app, 3812 boolean restarting, boolean allowRestart) { 3813 int pid = app.pid; 3814 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3815 if (!restarting) { 3816 removeLruProcessLocked(app); 3817 if (pid > 0) { 3818 ProcessList.remove(pid); 3819 } 3820 } 3821 3822 if (mProfileProc == app) { 3823 clearProfilerLocked(); 3824 } 3825 3826 // Remove this application's activities from active lists. 3827 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3828 3829 app.activities.clear(); 3830 3831 if (app.instrumentationClass != null) { 3832 Slog.w(TAG, "Crash of app " + app.processName 3833 + " running instrumentation " + app.instrumentationClass); 3834 Bundle info = new Bundle(); 3835 info.putString("shortMsg", "Process crashed."); 3836 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3837 } 3838 3839 if (!restarting) { 3840 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3841 // If there was nothing to resume, and we are not already 3842 // restarting this process, but there is a visible activity that 3843 // is hosted by the process... then make sure all visible 3844 // activities are running, taking care of restarting this 3845 // process. 3846 if (hasVisibleActivities) { 3847 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3848 } 3849 } 3850 } 3851 } 3852 3853 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3854 IBinder threadBinder = thread.asBinder(); 3855 // Find the application record. 3856 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3857 ProcessRecord rec = mLruProcesses.get(i); 3858 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3859 return i; 3860 } 3861 } 3862 return -1; 3863 } 3864 3865 final ProcessRecord getRecordForAppLocked( 3866 IApplicationThread thread) { 3867 if (thread == null) { 3868 return null; 3869 } 3870 3871 int appIndex = getLRURecordIndexForAppLocked(thread); 3872 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3873 } 3874 3875 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3876 // If there are no longer any background processes running, 3877 // and the app that died was not running instrumentation, 3878 // then tell everyone we are now low on memory. 3879 boolean haveBg = false; 3880 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3881 ProcessRecord rec = mLruProcesses.get(i); 3882 if (rec.thread != null 3883 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3884 haveBg = true; 3885 break; 3886 } 3887 } 3888 3889 if (!haveBg) { 3890 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3891 if (doReport) { 3892 long now = SystemClock.uptimeMillis(); 3893 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3894 doReport = false; 3895 } else { 3896 mLastMemUsageReportTime = now; 3897 } 3898 } 3899 final ArrayList<ProcessMemInfo> memInfos 3900 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3901 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3902 long now = SystemClock.uptimeMillis(); 3903 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3904 ProcessRecord rec = mLruProcesses.get(i); 3905 if (rec == dyingProc || rec.thread == null) { 3906 continue; 3907 } 3908 if (doReport) { 3909 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3910 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3911 } 3912 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3913 // The low memory report is overriding any current 3914 // state for a GC request. Make sure to do 3915 // heavy/important/visible/foreground processes first. 3916 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3917 rec.lastRequestedGc = 0; 3918 } else { 3919 rec.lastRequestedGc = rec.lastLowMemory; 3920 } 3921 rec.reportLowMemory = true; 3922 rec.lastLowMemory = now; 3923 mProcessesToGc.remove(rec); 3924 addProcessToGcListLocked(rec); 3925 } 3926 } 3927 if (doReport) { 3928 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3929 mHandler.sendMessage(msg); 3930 } 3931 scheduleAppGcsLocked(); 3932 } 3933 } 3934 3935 final void appDiedLocked(ProcessRecord app, int pid, 3936 IApplicationThread thread) { 3937 3938 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3939 synchronized (stats) { 3940 stats.noteProcessDiedLocked(app.info.uid, pid); 3941 } 3942 3943 // Clean up already done if the process has been re-started. 3944 if (app.pid == pid && app.thread != null && 3945 app.thread.asBinder() == thread.asBinder()) { 3946 boolean doLowMem = app.instrumentationClass == null; 3947 boolean doOomAdj = doLowMem; 3948 if (!app.killedByAm) { 3949 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3950 + ") has died."); 3951 mAllowLowerMemLevel = true; 3952 } else { 3953 // Note that we always want to do oom adj to update our state with the 3954 // new number of procs. 3955 mAllowLowerMemLevel = false; 3956 doLowMem = false; 3957 } 3958 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3959 if (DEBUG_CLEANUP) Slog.v( 3960 TAG, "Dying app: " + app + ", pid: " + pid 3961 + ", thread: " + thread.asBinder()); 3962 handleAppDiedLocked(app, false, true); 3963 3964 if (doOomAdj) { 3965 updateOomAdjLocked(); 3966 } 3967 if (doLowMem) { 3968 doLowMemReportIfNeededLocked(app); 3969 } 3970 } else if (app.pid != pid) { 3971 // A new process has already been started. 3972 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3973 + ") has died and restarted (pid " + app.pid + ")."); 3974 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3975 } else if (DEBUG_PROCESSES) { 3976 Slog.d(TAG, "Received spurious death notification for thread " 3977 + thread.asBinder()); 3978 } 3979 } 3980 3981 /** 3982 * If a stack trace dump file is configured, dump process stack traces. 3983 * @param clearTraces causes the dump file to be erased prior to the new 3984 * traces being written, if true; when false, the new traces will be 3985 * appended to any existing file content. 3986 * @param firstPids of dalvik VM processes to dump stack traces for first 3987 * @param lastPids of dalvik VM processes to dump stack traces for last 3988 * @param nativeProcs optional list of native process names to dump stack crawls 3989 * @return file containing stack traces, or null if no dump file is configured 3990 */ 3991 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3992 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3993 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3994 if (tracesPath == null || tracesPath.length() == 0) { 3995 return null; 3996 } 3997 3998 File tracesFile = new File(tracesPath); 3999 try { 4000 File tracesDir = tracesFile.getParentFile(); 4001 if (!tracesDir.exists()) { 4002 tracesFile.mkdirs(); 4003 if (!SELinux.restorecon(tracesDir)) { 4004 return null; 4005 } 4006 } 4007 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4008 4009 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4010 tracesFile.createNewFile(); 4011 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4012 } catch (IOException e) { 4013 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4014 return null; 4015 } 4016 4017 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4018 return tracesFile; 4019 } 4020 4021 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4022 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4023 // Use a FileObserver to detect when traces finish writing. 4024 // The order of traces is considered important to maintain for legibility. 4025 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4026 @Override 4027 public synchronized void onEvent(int event, String path) { notify(); } 4028 }; 4029 4030 try { 4031 observer.startWatching(); 4032 4033 // First collect all of the stacks of the most important pids. 4034 if (firstPids != null) { 4035 try { 4036 int num = firstPids.size(); 4037 for (int i = 0; i < num; i++) { 4038 synchronized (observer) { 4039 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4040 observer.wait(200); // Wait for write-close, give up after 200msec 4041 } 4042 } 4043 } catch (InterruptedException e) { 4044 Log.wtf(TAG, e); 4045 } 4046 } 4047 4048 // Next collect the stacks of the native pids 4049 if (nativeProcs != null) { 4050 int[] pids = Process.getPidsForCommands(nativeProcs); 4051 if (pids != null) { 4052 for (int pid : pids) { 4053 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4054 } 4055 } 4056 } 4057 4058 // Lastly, measure CPU usage. 4059 if (processCpuTracker != null) { 4060 processCpuTracker.init(); 4061 System.gc(); 4062 processCpuTracker.update(); 4063 try { 4064 synchronized (processCpuTracker) { 4065 processCpuTracker.wait(500); // measure over 1/2 second. 4066 } 4067 } catch (InterruptedException e) { 4068 } 4069 processCpuTracker.update(); 4070 4071 // We'll take the stack crawls of just the top apps using CPU. 4072 final int N = processCpuTracker.countWorkingStats(); 4073 int numProcs = 0; 4074 for (int i=0; i<N && numProcs<5; i++) { 4075 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4076 if (lastPids.indexOfKey(stats.pid) >= 0) { 4077 numProcs++; 4078 try { 4079 synchronized (observer) { 4080 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4081 observer.wait(200); // Wait for write-close, give up after 200msec 4082 } 4083 } catch (InterruptedException e) { 4084 Log.wtf(TAG, e); 4085 } 4086 4087 } 4088 } 4089 } 4090 } finally { 4091 observer.stopWatching(); 4092 } 4093 } 4094 4095 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4096 if (true || IS_USER_BUILD) { 4097 return; 4098 } 4099 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4100 if (tracesPath == null || tracesPath.length() == 0) { 4101 return; 4102 } 4103 4104 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4105 StrictMode.allowThreadDiskWrites(); 4106 try { 4107 final File tracesFile = new File(tracesPath); 4108 final File tracesDir = tracesFile.getParentFile(); 4109 final File tracesTmp = new File(tracesDir, "__tmp__"); 4110 try { 4111 if (!tracesDir.exists()) { 4112 tracesFile.mkdirs(); 4113 if (!SELinux.restorecon(tracesDir.getPath())) { 4114 return; 4115 } 4116 } 4117 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4118 4119 if (tracesFile.exists()) { 4120 tracesTmp.delete(); 4121 tracesFile.renameTo(tracesTmp); 4122 } 4123 StringBuilder sb = new StringBuilder(); 4124 Time tobj = new Time(); 4125 tobj.set(System.currentTimeMillis()); 4126 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4127 sb.append(": "); 4128 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4129 sb.append(" since "); 4130 sb.append(msg); 4131 FileOutputStream fos = new FileOutputStream(tracesFile); 4132 fos.write(sb.toString().getBytes()); 4133 if (app == null) { 4134 fos.write("\n*** No application process!".getBytes()); 4135 } 4136 fos.close(); 4137 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4138 } catch (IOException e) { 4139 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4140 return; 4141 } 4142 4143 if (app != null) { 4144 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4145 firstPids.add(app.pid); 4146 dumpStackTraces(tracesPath, firstPids, null, null, null); 4147 } 4148 4149 File lastTracesFile = null; 4150 File curTracesFile = null; 4151 for (int i=9; i>=0; i--) { 4152 String name = String.format(Locale.US, "slow%02d.txt", i); 4153 curTracesFile = new File(tracesDir, name); 4154 if (curTracesFile.exists()) { 4155 if (lastTracesFile != null) { 4156 curTracesFile.renameTo(lastTracesFile); 4157 } else { 4158 curTracesFile.delete(); 4159 } 4160 } 4161 lastTracesFile = curTracesFile; 4162 } 4163 tracesFile.renameTo(curTracesFile); 4164 if (tracesTmp.exists()) { 4165 tracesTmp.renameTo(tracesFile); 4166 } 4167 } finally { 4168 StrictMode.setThreadPolicy(oldPolicy); 4169 } 4170 } 4171 4172 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4173 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4174 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4175 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4176 4177 if (mController != null) { 4178 try { 4179 // 0 == continue, -1 = kill process immediately 4180 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4181 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4182 } catch (RemoteException e) { 4183 mController = null; 4184 Watchdog.getInstance().setActivityController(null); 4185 } 4186 } 4187 4188 long anrTime = SystemClock.uptimeMillis(); 4189 if (MONITOR_CPU_USAGE) { 4190 updateCpuStatsNow(); 4191 } 4192 4193 synchronized (this) { 4194 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4195 if (mShuttingDown) { 4196 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4197 return; 4198 } else if (app.notResponding) { 4199 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4200 return; 4201 } else if (app.crashing) { 4202 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4203 return; 4204 } 4205 4206 // In case we come through here for the same app before completing 4207 // this one, mark as anring now so we will bail out. 4208 app.notResponding = true; 4209 4210 // Log the ANR to the event log. 4211 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4212 app.processName, app.info.flags, annotation); 4213 4214 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4215 firstPids.add(app.pid); 4216 4217 int parentPid = app.pid; 4218 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4219 if (parentPid != app.pid) firstPids.add(parentPid); 4220 4221 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4222 4223 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4224 ProcessRecord r = mLruProcesses.get(i); 4225 if (r != null && r.thread != null) { 4226 int pid = r.pid; 4227 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4228 if (r.persistent) { 4229 firstPids.add(pid); 4230 } else { 4231 lastPids.put(pid, Boolean.TRUE); 4232 } 4233 } 4234 } 4235 } 4236 } 4237 4238 // Log the ANR to the main log. 4239 StringBuilder info = new StringBuilder(); 4240 info.setLength(0); 4241 info.append("ANR in ").append(app.processName); 4242 if (activity != null && activity.shortComponentName != null) { 4243 info.append(" (").append(activity.shortComponentName).append(")"); 4244 } 4245 info.append("\n"); 4246 info.append("PID: ").append(app.pid).append("\n"); 4247 if (annotation != null) { 4248 info.append("Reason: ").append(annotation).append("\n"); 4249 } 4250 if (parent != null && parent != activity) { 4251 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4252 } 4253 4254 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4255 4256 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4257 NATIVE_STACKS_OF_INTEREST); 4258 4259 String cpuInfo = null; 4260 if (MONITOR_CPU_USAGE) { 4261 updateCpuStatsNow(); 4262 synchronized (mProcessCpuThread) { 4263 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4264 } 4265 info.append(processCpuTracker.printCurrentLoad()); 4266 info.append(cpuInfo); 4267 } 4268 4269 info.append(processCpuTracker.printCurrentState(anrTime)); 4270 4271 Slog.e(TAG, info.toString()); 4272 if (tracesFile == null) { 4273 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4274 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4275 } 4276 4277 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4278 cpuInfo, tracesFile, null); 4279 4280 if (mController != null) { 4281 try { 4282 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4283 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4284 if (res != 0) { 4285 if (res < 0 && app.pid != MY_PID) { 4286 Process.killProcess(app.pid); 4287 } else { 4288 synchronized (this) { 4289 mServices.scheduleServiceTimeoutLocked(app); 4290 } 4291 } 4292 return; 4293 } 4294 } catch (RemoteException e) { 4295 mController = null; 4296 Watchdog.getInstance().setActivityController(null); 4297 } 4298 } 4299 4300 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4301 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4302 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4303 4304 synchronized (this) { 4305 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4306 killUnneededProcessLocked(app, "background ANR"); 4307 return; 4308 } 4309 4310 // Set the app's notResponding state, and look up the errorReportReceiver 4311 makeAppNotRespondingLocked(app, 4312 activity != null ? activity.shortComponentName : null, 4313 annotation != null ? "ANR " + annotation : "ANR", 4314 info.toString()); 4315 4316 // Bring up the infamous App Not Responding dialog 4317 Message msg = Message.obtain(); 4318 HashMap<String, Object> map = new HashMap<String, Object>(); 4319 msg.what = SHOW_NOT_RESPONDING_MSG; 4320 msg.obj = map; 4321 msg.arg1 = aboveSystem ? 1 : 0; 4322 map.put("app", app); 4323 if (activity != null) { 4324 map.put("activity", activity); 4325 } 4326 4327 mHandler.sendMessage(msg); 4328 } 4329 } 4330 4331 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4332 if (!mLaunchWarningShown) { 4333 mLaunchWarningShown = true; 4334 mHandler.post(new Runnable() { 4335 @Override 4336 public void run() { 4337 synchronized (ActivityManagerService.this) { 4338 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4339 d.show(); 4340 mHandler.postDelayed(new Runnable() { 4341 @Override 4342 public void run() { 4343 synchronized (ActivityManagerService.this) { 4344 d.dismiss(); 4345 mLaunchWarningShown = false; 4346 } 4347 } 4348 }, 4000); 4349 } 4350 } 4351 }); 4352 } 4353 } 4354 4355 @Override 4356 public boolean clearApplicationUserData(final String packageName, 4357 final IPackageDataObserver observer, int userId) { 4358 enforceNotIsolatedCaller("clearApplicationUserData"); 4359 int uid = Binder.getCallingUid(); 4360 int pid = Binder.getCallingPid(); 4361 userId = handleIncomingUser(pid, uid, 4362 userId, false, true, "clearApplicationUserData", null); 4363 long callingId = Binder.clearCallingIdentity(); 4364 try { 4365 IPackageManager pm = AppGlobals.getPackageManager(); 4366 int pkgUid = -1; 4367 synchronized(this) { 4368 try { 4369 pkgUid = pm.getPackageUid(packageName, userId); 4370 } catch (RemoteException e) { 4371 } 4372 if (pkgUid == -1) { 4373 Slog.w(TAG, "Invalid packageName: " + packageName); 4374 if (observer != null) { 4375 try { 4376 observer.onRemoveCompleted(packageName, false); 4377 } catch (RemoteException e) { 4378 Slog.i(TAG, "Observer no longer exists."); 4379 } 4380 } 4381 return false; 4382 } 4383 if (uid == pkgUid || checkComponentPermission( 4384 android.Manifest.permission.CLEAR_APP_USER_DATA, 4385 pid, uid, -1, true) 4386 == PackageManager.PERMISSION_GRANTED) { 4387 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4388 } else { 4389 throw new SecurityException("PID " + pid + " does not have permission " 4390 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4391 + " of package " + packageName); 4392 } 4393 } 4394 4395 try { 4396 // Clear application user data 4397 pm.clearApplicationUserData(packageName, observer, userId); 4398 4399 // Remove all permissions granted from/to this package 4400 removeUriPermissionsForPackageLocked(packageName, userId, true); 4401 4402 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4403 Uri.fromParts("package", packageName, null)); 4404 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4405 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4406 null, null, 0, null, null, null, false, false, userId); 4407 } catch (RemoteException e) { 4408 } 4409 } finally { 4410 Binder.restoreCallingIdentity(callingId); 4411 } 4412 return true; 4413 } 4414 4415 @Override 4416 public void killBackgroundProcesses(final String packageName, int userId) { 4417 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4418 != PackageManager.PERMISSION_GRANTED && 4419 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4420 != PackageManager.PERMISSION_GRANTED) { 4421 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4422 + Binder.getCallingPid() 4423 + ", uid=" + Binder.getCallingUid() 4424 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4425 Slog.w(TAG, msg); 4426 throw new SecurityException(msg); 4427 } 4428 4429 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4430 userId, true, true, "killBackgroundProcesses", null); 4431 long callingId = Binder.clearCallingIdentity(); 4432 try { 4433 IPackageManager pm = AppGlobals.getPackageManager(); 4434 synchronized(this) { 4435 int appId = -1; 4436 try { 4437 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4438 } catch (RemoteException e) { 4439 } 4440 if (appId == -1) { 4441 Slog.w(TAG, "Invalid packageName: " + packageName); 4442 return; 4443 } 4444 killPackageProcessesLocked(packageName, appId, userId, 4445 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4446 } 4447 } finally { 4448 Binder.restoreCallingIdentity(callingId); 4449 } 4450 } 4451 4452 @Override 4453 public void killAllBackgroundProcesses() { 4454 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4455 != PackageManager.PERMISSION_GRANTED) { 4456 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4457 + Binder.getCallingPid() 4458 + ", uid=" + Binder.getCallingUid() 4459 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4460 Slog.w(TAG, msg); 4461 throw new SecurityException(msg); 4462 } 4463 4464 long callingId = Binder.clearCallingIdentity(); 4465 try { 4466 synchronized(this) { 4467 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4468 final int NP = mProcessNames.getMap().size(); 4469 for (int ip=0; ip<NP; ip++) { 4470 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4471 final int NA = apps.size(); 4472 for (int ia=0; ia<NA; ia++) { 4473 ProcessRecord app = apps.valueAt(ia); 4474 if (app.persistent) { 4475 // we don't kill persistent processes 4476 continue; 4477 } 4478 if (app.removed) { 4479 procs.add(app); 4480 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4481 app.removed = true; 4482 procs.add(app); 4483 } 4484 } 4485 } 4486 4487 int N = procs.size(); 4488 for (int i=0; i<N; i++) { 4489 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4490 } 4491 mAllowLowerMemLevel = true; 4492 updateOomAdjLocked(); 4493 doLowMemReportIfNeededLocked(null); 4494 } 4495 } finally { 4496 Binder.restoreCallingIdentity(callingId); 4497 } 4498 } 4499 4500 @Override 4501 public void forceStopPackage(final String packageName, int userId) { 4502 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4503 != PackageManager.PERMISSION_GRANTED) { 4504 String msg = "Permission Denial: forceStopPackage() from pid=" 4505 + Binder.getCallingPid() 4506 + ", uid=" + Binder.getCallingUid() 4507 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4508 Slog.w(TAG, msg); 4509 throw new SecurityException(msg); 4510 } 4511 final int callingPid = Binder.getCallingPid(); 4512 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4513 userId, true, true, "forceStopPackage", null); 4514 long callingId = Binder.clearCallingIdentity(); 4515 try { 4516 IPackageManager pm = AppGlobals.getPackageManager(); 4517 synchronized(this) { 4518 int[] users = userId == UserHandle.USER_ALL 4519 ? getUsersLocked() : new int[] { userId }; 4520 for (int user : users) { 4521 int pkgUid = -1; 4522 try { 4523 pkgUid = pm.getPackageUid(packageName, user); 4524 } catch (RemoteException e) { 4525 } 4526 if (pkgUid == -1) { 4527 Slog.w(TAG, "Invalid packageName: " + packageName); 4528 continue; 4529 } 4530 try { 4531 pm.setPackageStoppedState(packageName, true, user); 4532 } catch (RemoteException e) { 4533 } catch (IllegalArgumentException e) { 4534 Slog.w(TAG, "Failed trying to unstop package " 4535 + packageName + ": " + e); 4536 } 4537 if (isUserRunningLocked(user, false)) { 4538 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4539 } 4540 } 4541 } 4542 } finally { 4543 Binder.restoreCallingIdentity(callingId); 4544 } 4545 } 4546 4547 /* 4548 * The pkg name and app id have to be specified. 4549 */ 4550 @Override 4551 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4552 if (pkg == null) { 4553 return; 4554 } 4555 // Make sure the uid is valid. 4556 if (appid < 0) { 4557 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4558 return; 4559 } 4560 int callerUid = Binder.getCallingUid(); 4561 // Only the system server can kill an application 4562 if (callerUid == Process.SYSTEM_UID) { 4563 // Post an aysnc message to kill the application 4564 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4565 msg.arg1 = appid; 4566 msg.arg2 = 0; 4567 Bundle bundle = new Bundle(); 4568 bundle.putString("pkg", pkg); 4569 bundle.putString("reason", reason); 4570 msg.obj = bundle; 4571 mHandler.sendMessage(msg); 4572 } else { 4573 throw new SecurityException(callerUid + " cannot kill pkg: " + 4574 pkg); 4575 } 4576 } 4577 4578 @Override 4579 public void closeSystemDialogs(String reason) { 4580 enforceNotIsolatedCaller("closeSystemDialogs"); 4581 4582 final int pid = Binder.getCallingPid(); 4583 final int uid = Binder.getCallingUid(); 4584 final long origId = Binder.clearCallingIdentity(); 4585 try { 4586 synchronized (this) { 4587 // Only allow this from foreground processes, so that background 4588 // applications can't abuse it to prevent system UI from being shown. 4589 if (uid >= Process.FIRST_APPLICATION_UID) { 4590 ProcessRecord proc; 4591 synchronized (mPidsSelfLocked) { 4592 proc = mPidsSelfLocked.get(pid); 4593 } 4594 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4595 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4596 + " from background process " + proc); 4597 return; 4598 } 4599 } 4600 closeSystemDialogsLocked(reason); 4601 } 4602 } finally { 4603 Binder.restoreCallingIdentity(origId); 4604 } 4605 } 4606 4607 void closeSystemDialogsLocked(String reason) { 4608 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4609 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4610 | Intent.FLAG_RECEIVER_FOREGROUND); 4611 if (reason != null) { 4612 intent.putExtra("reason", reason); 4613 } 4614 mWindowManager.closeSystemDialogs(reason); 4615 4616 mStackSupervisor.closeSystemDialogsLocked(); 4617 4618 broadcastIntentLocked(null, null, intent, null, 4619 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4620 Process.SYSTEM_UID, UserHandle.USER_ALL); 4621 } 4622 4623 @Override 4624 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4625 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4626 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4627 for (int i=pids.length-1; i>=0; i--) { 4628 ProcessRecord proc; 4629 int oomAdj; 4630 synchronized (this) { 4631 synchronized (mPidsSelfLocked) { 4632 proc = mPidsSelfLocked.get(pids[i]); 4633 oomAdj = proc != null ? proc.setAdj : 0; 4634 } 4635 } 4636 infos[i] = new Debug.MemoryInfo(); 4637 Debug.getMemoryInfo(pids[i], infos[i]); 4638 if (proc != null) { 4639 synchronized (this) { 4640 if (proc.thread != null && proc.setAdj == oomAdj) { 4641 // Record this for posterity if the process has been stable. 4642 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4643 infos[i].getTotalUss(), false, proc.pkgList); 4644 } 4645 } 4646 } 4647 } 4648 return infos; 4649 } 4650 4651 @Override 4652 public long[] getProcessPss(int[] pids) { 4653 enforceNotIsolatedCaller("getProcessPss"); 4654 long[] pss = new long[pids.length]; 4655 for (int i=pids.length-1; i>=0; i--) { 4656 ProcessRecord proc; 4657 int oomAdj; 4658 synchronized (this) { 4659 synchronized (mPidsSelfLocked) { 4660 proc = mPidsSelfLocked.get(pids[i]); 4661 oomAdj = proc != null ? proc.setAdj : 0; 4662 } 4663 } 4664 long[] tmpUss = new long[1]; 4665 pss[i] = Debug.getPss(pids[i], tmpUss); 4666 if (proc != null) { 4667 synchronized (this) { 4668 if (proc.thread != null && proc.setAdj == oomAdj) { 4669 // Record this for posterity if the process has been stable. 4670 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4671 } 4672 } 4673 } 4674 } 4675 return pss; 4676 } 4677 4678 @Override 4679 public void killApplicationProcess(String processName, int uid) { 4680 if (processName == null) { 4681 return; 4682 } 4683 4684 int callerUid = Binder.getCallingUid(); 4685 // Only the system server can kill an application 4686 if (callerUid == Process.SYSTEM_UID) { 4687 synchronized (this) { 4688 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4689 if (app != null && app.thread != null) { 4690 try { 4691 app.thread.scheduleSuicide(); 4692 } catch (RemoteException e) { 4693 // If the other end already died, then our work here is done. 4694 } 4695 } else { 4696 Slog.w(TAG, "Process/uid not found attempting kill of " 4697 + processName + " / " + uid); 4698 } 4699 } 4700 } else { 4701 throw new SecurityException(callerUid + " cannot kill app process: " + 4702 processName); 4703 } 4704 } 4705 4706 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4707 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4708 false, true, false, false, UserHandle.getUserId(uid), reason); 4709 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4710 Uri.fromParts("package", packageName, null)); 4711 if (!mProcessesReady) { 4712 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4713 | Intent.FLAG_RECEIVER_FOREGROUND); 4714 } 4715 intent.putExtra(Intent.EXTRA_UID, uid); 4716 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4717 broadcastIntentLocked(null, null, intent, 4718 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4719 false, false, 4720 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4721 } 4722 4723 private void forceStopUserLocked(int userId, String reason) { 4724 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4725 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4726 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4727 | Intent.FLAG_RECEIVER_FOREGROUND); 4728 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4729 broadcastIntentLocked(null, null, intent, 4730 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4731 false, false, 4732 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4733 } 4734 4735 private final boolean killPackageProcessesLocked(String packageName, int appId, 4736 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4737 boolean doit, boolean evenPersistent, String reason) { 4738 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4739 4740 // Remove all processes this package may have touched: all with the 4741 // same UID (except for the system or root user), and all whose name 4742 // matches the package name. 4743 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4744 final int NP = mProcessNames.getMap().size(); 4745 for (int ip=0; ip<NP; ip++) { 4746 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4747 final int NA = apps.size(); 4748 for (int ia=0; ia<NA; ia++) { 4749 ProcessRecord app = apps.valueAt(ia); 4750 if (app.persistent && !evenPersistent) { 4751 // we don't kill persistent processes 4752 continue; 4753 } 4754 if (app.removed) { 4755 if (doit) { 4756 procs.add(app); 4757 } 4758 continue; 4759 } 4760 4761 // Skip process if it doesn't meet our oom adj requirement. 4762 if (app.setAdj < minOomAdj) { 4763 continue; 4764 } 4765 4766 // If no package is specified, we call all processes under the 4767 // give user id. 4768 if (packageName == null) { 4769 if (app.userId != userId) { 4770 continue; 4771 } 4772 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4773 continue; 4774 } 4775 // Package has been specified, we want to hit all processes 4776 // that match it. We need to qualify this by the processes 4777 // that are running under the specified app and user ID. 4778 } else { 4779 if (UserHandle.getAppId(app.uid) != appId) { 4780 continue; 4781 } 4782 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4783 continue; 4784 } 4785 if (!app.pkgList.containsKey(packageName)) { 4786 continue; 4787 } 4788 } 4789 4790 // Process has passed all conditions, kill it! 4791 if (!doit) { 4792 return true; 4793 } 4794 app.removed = true; 4795 procs.add(app); 4796 } 4797 } 4798 4799 int N = procs.size(); 4800 for (int i=0; i<N; i++) { 4801 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4802 } 4803 updateOomAdjLocked(); 4804 return N > 0; 4805 } 4806 4807 private final boolean forceStopPackageLocked(String name, int appId, 4808 boolean callerWillRestart, boolean purgeCache, boolean doit, 4809 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4810 int i; 4811 int N; 4812 4813 if (userId == UserHandle.USER_ALL && name == null) { 4814 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4815 } 4816 4817 if (appId < 0 && name != null) { 4818 try { 4819 appId = UserHandle.getAppId( 4820 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4821 } catch (RemoteException e) { 4822 } 4823 } 4824 4825 if (doit) { 4826 if (name != null) { 4827 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4828 + " user=" + userId + ": " + reason); 4829 } else { 4830 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4831 } 4832 4833 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4834 for (int ip=pmap.size()-1; ip>=0; ip--) { 4835 SparseArray<Long> ba = pmap.valueAt(ip); 4836 for (i=ba.size()-1; i>=0; i--) { 4837 boolean remove = false; 4838 final int entUid = ba.keyAt(i); 4839 if (name != null) { 4840 if (userId == UserHandle.USER_ALL) { 4841 if (UserHandle.getAppId(entUid) == appId) { 4842 remove = true; 4843 } 4844 } else { 4845 if (entUid == UserHandle.getUid(userId, appId)) { 4846 remove = true; 4847 } 4848 } 4849 } else if (UserHandle.getUserId(entUid) == userId) { 4850 remove = true; 4851 } 4852 if (remove) { 4853 ba.removeAt(i); 4854 } 4855 } 4856 if (ba.size() == 0) { 4857 pmap.removeAt(ip); 4858 } 4859 } 4860 } 4861 4862 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4863 -100, callerWillRestart, true, doit, evenPersistent, 4864 name == null ? ("stop user " + userId) : ("stop " + name)); 4865 4866 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4867 if (!doit) { 4868 return true; 4869 } 4870 didSomething = true; 4871 } 4872 4873 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4874 if (!doit) { 4875 return true; 4876 } 4877 didSomething = true; 4878 } 4879 4880 if (name == null) { 4881 // Remove all sticky broadcasts from this user. 4882 mStickyBroadcasts.remove(userId); 4883 } 4884 4885 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4886 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4887 userId, providers)) { 4888 if (!doit) { 4889 return true; 4890 } 4891 didSomething = true; 4892 } 4893 N = providers.size(); 4894 for (i=0; i<N; i++) { 4895 removeDyingProviderLocked(null, providers.get(i), true); 4896 } 4897 4898 // Remove transient permissions granted from/to this package/user 4899 removeUriPermissionsForPackageLocked(name, userId, false); 4900 4901 if (name == null || uninstalling) { 4902 // Remove pending intents. For now we only do this when force 4903 // stopping users, because we have some problems when doing this 4904 // for packages -- app widgets are not currently cleaned up for 4905 // such packages, so they can be left with bad pending intents. 4906 if (mIntentSenderRecords.size() > 0) { 4907 Iterator<WeakReference<PendingIntentRecord>> it 4908 = mIntentSenderRecords.values().iterator(); 4909 while (it.hasNext()) { 4910 WeakReference<PendingIntentRecord> wpir = it.next(); 4911 if (wpir == null) { 4912 it.remove(); 4913 continue; 4914 } 4915 PendingIntentRecord pir = wpir.get(); 4916 if (pir == null) { 4917 it.remove(); 4918 continue; 4919 } 4920 if (name == null) { 4921 // Stopping user, remove all objects for the user. 4922 if (pir.key.userId != userId) { 4923 // Not the same user, skip it. 4924 continue; 4925 } 4926 } else { 4927 if (UserHandle.getAppId(pir.uid) != appId) { 4928 // Different app id, skip it. 4929 continue; 4930 } 4931 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4932 // Different user, skip it. 4933 continue; 4934 } 4935 if (!pir.key.packageName.equals(name)) { 4936 // Different package, skip it. 4937 continue; 4938 } 4939 } 4940 if (!doit) { 4941 return true; 4942 } 4943 didSomething = true; 4944 it.remove(); 4945 pir.canceled = true; 4946 if (pir.key.activity != null) { 4947 pir.key.activity.pendingResults.remove(pir.ref); 4948 } 4949 } 4950 } 4951 } 4952 4953 if (doit) { 4954 if (purgeCache && name != null) { 4955 AttributeCache ac = AttributeCache.instance(); 4956 if (ac != null) { 4957 ac.removePackage(name); 4958 } 4959 } 4960 if (mBooted) { 4961 mStackSupervisor.resumeTopActivitiesLocked(); 4962 mStackSupervisor.scheduleIdleLocked(); 4963 } 4964 } 4965 4966 return didSomething; 4967 } 4968 4969 private final boolean removeProcessLocked(ProcessRecord app, 4970 boolean callerWillRestart, boolean allowRestart, String reason) { 4971 final String name = app.processName; 4972 final int uid = app.uid; 4973 if (DEBUG_PROCESSES) Slog.d( 4974 TAG, "Force removing proc " + app.toShortString() + " (" + name 4975 + "/" + uid + ")"); 4976 4977 mProcessNames.remove(name, uid); 4978 mIsolatedProcesses.remove(app.uid); 4979 if (mHeavyWeightProcess == app) { 4980 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4981 mHeavyWeightProcess.userId, 0)); 4982 mHeavyWeightProcess = null; 4983 } 4984 boolean needRestart = false; 4985 if (app.pid > 0 && app.pid != MY_PID) { 4986 int pid = app.pid; 4987 synchronized (mPidsSelfLocked) { 4988 mPidsSelfLocked.remove(pid); 4989 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4990 } 4991 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4992 app.processName, app.info.uid); 4993 if (app.isolated) { 4994 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4995 } 4996 killUnneededProcessLocked(app, reason); 4997 handleAppDiedLocked(app, true, allowRestart); 4998 removeLruProcessLocked(app); 4999 5000 if (app.persistent && !app.isolated) { 5001 if (!callerWillRestart) { 5002 addAppLocked(app.info, false); 5003 } else { 5004 needRestart = true; 5005 } 5006 } 5007 } else { 5008 mRemovedProcesses.add(app); 5009 } 5010 5011 return needRestart; 5012 } 5013 5014 private final void processStartTimedOutLocked(ProcessRecord app) { 5015 final int pid = app.pid; 5016 boolean gone = false; 5017 synchronized (mPidsSelfLocked) { 5018 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5019 if (knownApp != null && knownApp.thread == null) { 5020 mPidsSelfLocked.remove(pid); 5021 gone = true; 5022 } 5023 } 5024 5025 if (gone) { 5026 Slog.w(TAG, "Process " + app + " failed to attach"); 5027 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5028 pid, app.uid, app.processName); 5029 mProcessNames.remove(app.processName, app.uid); 5030 mIsolatedProcesses.remove(app.uid); 5031 if (mHeavyWeightProcess == app) { 5032 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5033 mHeavyWeightProcess.userId, 0)); 5034 mHeavyWeightProcess = null; 5035 } 5036 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5037 app.processName, app.info.uid); 5038 if (app.isolated) { 5039 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5040 } 5041 // Take care of any launching providers waiting for this process. 5042 checkAppInLaunchingProvidersLocked(app, true); 5043 // Take care of any services that are waiting for the process. 5044 mServices.processStartTimedOutLocked(app); 5045 killUnneededProcessLocked(app, "start timeout"); 5046 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5047 Slog.w(TAG, "Unattached app died before backup, skipping"); 5048 try { 5049 IBackupManager bm = IBackupManager.Stub.asInterface( 5050 ServiceManager.getService(Context.BACKUP_SERVICE)); 5051 bm.agentDisconnected(app.info.packageName); 5052 } catch (RemoteException e) { 5053 // Can't happen; the backup manager is local 5054 } 5055 } 5056 if (isPendingBroadcastProcessLocked(pid)) { 5057 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5058 skipPendingBroadcastLocked(pid); 5059 } 5060 } else { 5061 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5062 } 5063 } 5064 5065 private final boolean attachApplicationLocked(IApplicationThread thread, 5066 int pid) { 5067 5068 // Find the application record that is being attached... either via 5069 // the pid if we are running in multiple processes, or just pull the 5070 // next app record if we are emulating process with anonymous threads. 5071 ProcessRecord app; 5072 if (pid != MY_PID && pid >= 0) { 5073 synchronized (mPidsSelfLocked) { 5074 app = mPidsSelfLocked.get(pid); 5075 } 5076 } else { 5077 app = null; 5078 } 5079 5080 if (app == null) { 5081 Slog.w(TAG, "No pending application record for pid " + pid 5082 + " (IApplicationThread " + thread + "); dropping process"); 5083 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5084 if (pid > 0 && pid != MY_PID) { 5085 Process.killProcessQuiet(pid); 5086 } else { 5087 try { 5088 thread.scheduleExit(); 5089 } catch (Exception e) { 5090 // Ignore exceptions. 5091 } 5092 } 5093 return false; 5094 } 5095 5096 // If this application record is still attached to a previous 5097 // process, clean it up now. 5098 if (app.thread != null) { 5099 handleAppDiedLocked(app, true, true); 5100 } 5101 5102 // Tell the process all about itself. 5103 5104 if (localLOGV) Slog.v( 5105 TAG, "Binding process pid " + pid + " to record " + app); 5106 5107 final String processName = app.processName; 5108 try { 5109 AppDeathRecipient adr = new AppDeathRecipient( 5110 app, pid, thread); 5111 thread.asBinder().linkToDeath(adr, 0); 5112 app.deathRecipient = adr; 5113 } catch (RemoteException e) { 5114 app.resetPackageList(mProcessStats); 5115 startProcessLocked(app, "link fail", processName); 5116 return false; 5117 } 5118 5119 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5120 5121 app.makeActive(thread, mProcessStats); 5122 app.curAdj = app.setAdj = -100; 5123 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5124 app.forcingToForeground = null; 5125 updateProcessForegroundLocked(app, false, false); 5126 app.hasShownUi = false; 5127 app.debugging = false; 5128 app.cached = false; 5129 5130 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5131 5132 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5133 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5134 5135 if (!normalMode) { 5136 Slog.i(TAG, "Launching preboot mode app: " + app); 5137 } 5138 5139 if (localLOGV) Slog.v( 5140 TAG, "New app record " + app 5141 + " thread=" + thread.asBinder() + " pid=" + pid); 5142 try { 5143 int testMode = IApplicationThread.DEBUG_OFF; 5144 if (mDebugApp != null && mDebugApp.equals(processName)) { 5145 testMode = mWaitForDebugger 5146 ? IApplicationThread.DEBUG_WAIT 5147 : IApplicationThread.DEBUG_ON; 5148 app.debugging = true; 5149 if (mDebugTransient) { 5150 mDebugApp = mOrigDebugApp; 5151 mWaitForDebugger = mOrigWaitForDebugger; 5152 } 5153 } 5154 String profileFile = app.instrumentationProfileFile; 5155 ParcelFileDescriptor profileFd = null; 5156 boolean profileAutoStop = false; 5157 if (mProfileApp != null && mProfileApp.equals(processName)) { 5158 mProfileProc = app; 5159 profileFile = mProfileFile; 5160 profileFd = mProfileFd; 5161 profileAutoStop = mAutoStopProfiler; 5162 } 5163 boolean enableOpenGlTrace = false; 5164 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5165 enableOpenGlTrace = true; 5166 mOpenGlTraceApp = null; 5167 } 5168 5169 // If the app is being launched for restore or full backup, set it up specially 5170 boolean isRestrictedBackupMode = false; 5171 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5172 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5173 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5174 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5175 } 5176 5177 ensurePackageDexOpt(app.instrumentationInfo != null 5178 ? app.instrumentationInfo.packageName 5179 : app.info.packageName); 5180 if (app.instrumentationClass != null) { 5181 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5182 } 5183 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5184 + processName + " with config " + mConfiguration); 5185 ApplicationInfo appInfo = app.instrumentationInfo != null 5186 ? app.instrumentationInfo : app.info; 5187 app.compat = compatibilityInfoForPackageLocked(appInfo); 5188 if (profileFd != null) { 5189 profileFd = profileFd.dup(); 5190 } 5191 thread.bindApplication(processName, appInfo, providers, 5192 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5193 app.instrumentationArguments, app.instrumentationWatcher, 5194 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5195 isRestrictedBackupMode || !normalMode, app.persistent, 5196 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5197 mCoreSettingsObserver.getCoreSettingsLocked()); 5198 updateLruProcessLocked(app, false, null); 5199 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5200 } catch (Exception e) { 5201 // todo: Yikes! What should we do? For now we will try to 5202 // start another process, but that could easily get us in 5203 // an infinite loop of restarting processes... 5204 Slog.w(TAG, "Exception thrown during bind!", e); 5205 5206 app.resetPackageList(mProcessStats); 5207 app.unlinkDeathRecipient(); 5208 startProcessLocked(app, "bind fail", processName); 5209 return false; 5210 } 5211 5212 // Remove this record from the list of starting applications. 5213 mPersistentStartingProcesses.remove(app); 5214 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5215 "Attach application locked removing on hold: " + app); 5216 mProcessesOnHold.remove(app); 5217 5218 boolean badApp = false; 5219 boolean didSomething = false; 5220 5221 // See if the top visible activity is waiting to run in this process... 5222 if (normalMode) { 5223 try { 5224 if (mStackSupervisor.attachApplicationLocked(app)) { 5225 didSomething = true; 5226 } 5227 } catch (Exception e) { 5228 badApp = true; 5229 } 5230 } 5231 5232 // Find any services that should be running in this process... 5233 if (!badApp) { 5234 try { 5235 didSomething |= mServices.attachApplicationLocked(app, processName); 5236 } catch (Exception e) { 5237 badApp = true; 5238 } 5239 } 5240 5241 // Check if a next-broadcast receiver is in this process... 5242 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5243 try { 5244 didSomething |= sendPendingBroadcastsLocked(app); 5245 } catch (Exception e) { 5246 // If the app died trying to launch the receiver we declare it 'bad' 5247 badApp = true; 5248 } 5249 } 5250 5251 // Check whether the next backup agent is in this process... 5252 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5253 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5254 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5255 try { 5256 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5257 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5258 mBackupTarget.backupMode); 5259 } catch (Exception e) { 5260 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5261 e.printStackTrace(); 5262 } 5263 } 5264 5265 if (badApp) { 5266 // todo: Also need to kill application to deal with all 5267 // kinds of exceptions. 5268 handleAppDiedLocked(app, false, true); 5269 return false; 5270 } 5271 5272 if (!didSomething) { 5273 updateOomAdjLocked(); 5274 } 5275 5276 return true; 5277 } 5278 5279 @Override 5280 public final void attachApplication(IApplicationThread thread) { 5281 synchronized (this) { 5282 int callingPid = Binder.getCallingPid(); 5283 final long origId = Binder.clearCallingIdentity(); 5284 attachApplicationLocked(thread, callingPid); 5285 Binder.restoreCallingIdentity(origId); 5286 } 5287 } 5288 5289 @Override 5290 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5291 final long origId = Binder.clearCallingIdentity(); 5292 synchronized (this) { 5293 ActivityStack stack = ActivityRecord.getStackLocked(token); 5294 if (stack != null) { 5295 ActivityRecord r = 5296 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5297 if (stopProfiling) { 5298 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5299 try { 5300 mProfileFd.close(); 5301 } catch (IOException e) { 5302 } 5303 clearProfilerLocked(); 5304 } 5305 } 5306 } 5307 } 5308 Binder.restoreCallingIdentity(origId); 5309 } 5310 5311 void enableScreenAfterBoot() { 5312 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5313 SystemClock.uptimeMillis()); 5314 mWindowManager.enableScreenAfterBoot(); 5315 5316 synchronized (this) { 5317 updateEventDispatchingLocked(); 5318 } 5319 } 5320 5321 @Override 5322 public void showBootMessage(final CharSequence msg, final boolean always) { 5323 enforceNotIsolatedCaller("showBootMessage"); 5324 mWindowManager.showBootMessage(msg, always); 5325 } 5326 5327 @Override 5328 public void dismissKeyguardOnNextActivity() { 5329 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5330 final long token = Binder.clearCallingIdentity(); 5331 try { 5332 synchronized (this) { 5333 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5334 if (mLockScreenShown) { 5335 mLockScreenShown = false; 5336 comeOutOfSleepIfNeededLocked(); 5337 } 5338 mStackSupervisor.setDismissKeyguard(true); 5339 } 5340 } finally { 5341 Binder.restoreCallingIdentity(token); 5342 } 5343 } 5344 5345 final void finishBooting() { 5346 // Register receivers to handle package update events 5347 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5348 5349 synchronized (this) { 5350 // Ensure that any processes we had put on hold are now started 5351 // up. 5352 final int NP = mProcessesOnHold.size(); 5353 if (NP > 0) { 5354 ArrayList<ProcessRecord> procs = 5355 new ArrayList<ProcessRecord>(mProcessesOnHold); 5356 for (int ip=0; ip<NP; ip++) { 5357 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5358 + procs.get(ip)); 5359 startProcessLocked(procs.get(ip), "on-hold", null); 5360 } 5361 } 5362 5363 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5364 // Start looking for apps that are abusing wake locks. 5365 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5366 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5367 // Tell anyone interested that we are done booting! 5368 SystemProperties.set("sys.boot_completed", "1"); 5369 SystemProperties.set("dev.bootcomplete", "1"); 5370 for (int i=0; i<mStartedUsers.size(); i++) { 5371 UserStartedState uss = mStartedUsers.valueAt(i); 5372 if (uss.mState == UserStartedState.STATE_BOOTING) { 5373 uss.mState = UserStartedState.STATE_RUNNING; 5374 final int userId = mStartedUsers.keyAt(i); 5375 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5376 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5377 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5378 broadcastIntentLocked(null, null, intent, null, 5379 new IIntentReceiver.Stub() { 5380 @Override 5381 public void performReceive(Intent intent, int resultCode, 5382 String data, Bundle extras, boolean ordered, 5383 boolean sticky, int sendingUser) { 5384 synchronized (ActivityManagerService.this) { 5385 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5386 true, false); 5387 } 5388 } 5389 }, 5390 0, null, null, 5391 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5392 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5393 userId); 5394 } 5395 } 5396 scheduleStartProfilesLocked(); 5397 } 5398 } 5399 } 5400 5401 final void ensureBootCompleted() { 5402 boolean booting; 5403 boolean enableScreen; 5404 synchronized (this) { 5405 booting = mBooting; 5406 mBooting = false; 5407 enableScreen = !mBooted; 5408 mBooted = true; 5409 } 5410 5411 if (booting) { 5412 finishBooting(); 5413 } 5414 5415 if (enableScreen) { 5416 enableScreenAfterBoot(); 5417 } 5418 } 5419 5420 @Override 5421 public final void activityResumed(IBinder token) { 5422 final long origId = Binder.clearCallingIdentity(); 5423 synchronized(this) { 5424 ActivityStack stack = ActivityRecord.getStackLocked(token); 5425 if (stack != null) { 5426 ActivityRecord.activityResumedLocked(token); 5427 } 5428 } 5429 Binder.restoreCallingIdentity(origId); 5430 } 5431 5432 @Override 5433 public final void activityPaused(IBinder token) { 5434 final long origId = Binder.clearCallingIdentity(); 5435 synchronized(this) { 5436 ActivityStack stack = ActivityRecord.getStackLocked(token); 5437 if (stack != null) { 5438 stack.activityPausedLocked(token, false); 5439 } 5440 } 5441 Binder.restoreCallingIdentity(origId); 5442 } 5443 5444 @Override 5445 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5446 CharSequence description) { 5447 if (localLOGV) Slog.v( 5448 TAG, "Activity stopped: token=" + token); 5449 5450 // Refuse possible leaked file descriptors 5451 if (icicle != null && icicle.hasFileDescriptors()) { 5452 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5453 } 5454 5455 ActivityRecord r = null; 5456 5457 final long origId = Binder.clearCallingIdentity(); 5458 5459 synchronized (this) { 5460 r = ActivityRecord.isInStackLocked(token); 5461 if (r != null) { 5462 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5463 } 5464 } 5465 5466 if (r != null) { 5467 sendPendingThumbnail(r, null, null, null, false); 5468 } 5469 5470 trimApplications(); 5471 5472 Binder.restoreCallingIdentity(origId); 5473 } 5474 5475 @Override 5476 public final void activityDestroyed(IBinder token) { 5477 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5478 synchronized (this) { 5479 ActivityStack stack = ActivityRecord.getStackLocked(token); 5480 if (stack != null) { 5481 stack.activityDestroyedLocked(token); 5482 } 5483 } 5484 } 5485 5486 @Override 5487 public String getCallingPackage(IBinder token) { 5488 synchronized (this) { 5489 ActivityRecord r = getCallingRecordLocked(token); 5490 return r != null ? r.info.packageName : null; 5491 } 5492 } 5493 5494 @Override 5495 public ComponentName getCallingActivity(IBinder token) { 5496 synchronized (this) { 5497 ActivityRecord r = getCallingRecordLocked(token); 5498 return r != null ? r.intent.getComponent() : null; 5499 } 5500 } 5501 5502 private ActivityRecord getCallingRecordLocked(IBinder token) { 5503 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5504 if (r == null) { 5505 return null; 5506 } 5507 return r.resultTo; 5508 } 5509 5510 @Override 5511 public ComponentName getActivityClassForToken(IBinder token) { 5512 synchronized(this) { 5513 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5514 if (r == null) { 5515 return null; 5516 } 5517 return r.intent.getComponent(); 5518 } 5519 } 5520 5521 @Override 5522 public String getPackageForToken(IBinder token) { 5523 synchronized(this) { 5524 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5525 if (r == null) { 5526 return null; 5527 } 5528 return r.packageName; 5529 } 5530 } 5531 5532 @Override 5533 public IIntentSender getIntentSender(int type, 5534 String packageName, IBinder token, String resultWho, 5535 int requestCode, Intent[] intents, String[] resolvedTypes, 5536 int flags, Bundle options, int userId) { 5537 enforceNotIsolatedCaller("getIntentSender"); 5538 // Refuse possible leaked file descriptors 5539 if (intents != null) { 5540 if (intents.length < 1) { 5541 throw new IllegalArgumentException("Intents array length must be >= 1"); 5542 } 5543 for (int i=0; i<intents.length; i++) { 5544 Intent intent = intents[i]; 5545 if (intent != null) { 5546 if (intent.hasFileDescriptors()) { 5547 throw new IllegalArgumentException("File descriptors passed in Intent"); 5548 } 5549 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5550 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5551 throw new IllegalArgumentException( 5552 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5553 } 5554 intents[i] = new Intent(intent); 5555 } 5556 } 5557 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5558 throw new IllegalArgumentException( 5559 "Intent array length does not match resolvedTypes length"); 5560 } 5561 } 5562 if (options != null) { 5563 if (options.hasFileDescriptors()) { 5564 throw new IllegalArgumentException("File descriptors passed in options"); 5565 } 5566 } 5567 5568 synchronized(this) { 5569 int callingUid = Binder.getCallingUid(); 5570 int origUserId = userId; 5571 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5572 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5573 "getIntentSender", null); 5574 if (origUserId == UserHandle.USER_CURRENT) { 5575 // We don't want to evaluate this until the pending intent is 5576 // actually executed. However, we do want to always do the 5577 // security checking for it above. 5578 userId = UserHandle.USER_CURRENT; 5579 } 5580 try { 5581 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5582 int uid = AppGlobals.getPackageManager() 5583 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5584 if (!UserHandle.isSameApp(callingUid, uid)) { 5585 String msg = "Permission Denial: getIntentSender() from pid=" 5586 + Binder.getCallingPid() 5587 + ", uid=" + Binder.getCallingUid() 5588 + ", (need uid=" + uid + ")" 5589 + " is not allowed to send as package " + packageName; 5590 Slog.w(TAG, msg); 5591 throw new SecurityException(msg); 5592 } 5593 } 5594 5595 return getIntentSenderLocked(type, packageName, callingUid, userId, 5596 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5597 5598 } catch (RemoteException e) { 5599 throw new SecurityException(e); 5600 } 5601 } 5602 } 5603 5604 IIntentSender getIntentSenderLocked(int type, String packageName, 5605 int callingUid, int userId, IBinder token, String resultWho, 5606 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5607 Bundle options) { 5608 if (DEBUG_MU) 5609 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5610 ActivityRecord activity = null; 5611 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5612 activity = ActivityRecord.isInStackLocked(token); 5613 if (activity == null) { 5614 return null; 5615 } 5616 if (activity.finishing) { 5617 return null; 5618 } 5619 } 5620 5621 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5622 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5623 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5624 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5625 |PendingIntent.FLAG_UPDATE_CURRENT); 5626 5627 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5628 type, packageName, activity, resultWho, 5629 requestCode, intents, resolvedTypes, flags, options, userId); 5630 WeakReference<PendingIntentRecord> ref; 5631 ref = mIntentSenderRecords.get(key); 5632 PendingIntentRecord rec = ref != null ? ref.get() : null; 5633 if (rec != null) { 5634 if (!cancelCurrent) { 5635 if (updateCurrent) { 5636 if (rec.key.requestIntent != null) { 5637 rec.key.requestIntent.replaceExtras(intents != null ? 5638 intents[intents.length - 1] : null); 5639 } 5640 if (intents != null) { 5641 intents[intents.length-1] = rec.key.requestIntent; 5642 rec.key.allIntents = intents; 5643 rec.key.allResolvedTypes = resolvedTypes; 5644 } else { 5645 rec.key.allIntents = null; 5646 rec.key.allResolvedTypes = null; 5647 } 5648 } 5649 return rec; 5650 } 5651 rec.canceled = true; 5652 mIntentSenderRecords.remove(key); 5653 } 5654 if (noCreate) { 5655 return rec; 5656 } 5657 rec = new PendingIntentRecord(this, key, callingUid); 5658 mIntentSenderRecords.put(key, rec.ref); 5659 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5660 if (activity.pendingResults == null) { 5661 activity.pendingResults 5662 = new HashSet<WeakReference<PendingIntentRecord>>(); 5663 } 5664 activity.pendingResults.add(rec.ref); 5665 } 5666 return rec; 5667 } 5668 5669 @Override 5670 public void cancelIntentSender(IIntentSender sender) { 5671 if (!(sender instanceof PendingIntentRecord)) { 5672 return; 5673 } 5674 synchronized(this) { 5675 PendingIntentRecord rec = (PendingIntentRecord)sender; 5676 try { 5677 int uid = AppGlobals.getPackageManager() 5678 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5679 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5680 String msg = "Permission Denial: cancelIntentSender() from pid=" 5681 + Binder.getCallingPid() 5682 + ", uid=" + Binder.getCallingUid() 5683 + " is not allowed to cancel packges " 5684 + rec.key.packageName; 5685 Slog.w(TAG, msg); 5686 throw new SecurityException(msg); 5687 } 5688 } catch (RemoteException e) { 5689 throw new SecurityException(e); 5690 } 5691 cancelIntentSenderLocked(rec, true); 5692 } 5693 } 5694 5695 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5696 rec.canceled = true; 5697 mIntentSenderRecords.remove(rec.key); 5698 if (cleanActivity && rec.key.activity != null) { 5699 rec.key.activity.pendingResults.remove(rec.ref); 5700 } 5701 } 5702 5703 @Override 5704 public String getPackageForIntentSender(IIntentSender pendingResult) { 5705 if (!(pendingResult instanceof PendingIntentRecord)) { 5706 return null; 5707 } 5708 try { 5709 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5710 return res.key.packageName; 5711 } catch (ClassCastException e) { 5712 } 5713 return null; 5714 } 5715 5716 @Override 5717 public int getUidForIntentSender(IIntentSender sender) { 5718 if (sender instanceof PendingIntentRecord) { 5719 try { 5720 PendingIntentRecord res = (PendingIntentRecord)sender; 5721 return res.uid; 5722 } catch (ClassCastException e) { 5723 } 5724 } 5725 return -1; 5726 } 5727 5728 @Override 5729 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5730 if (!(pendingResult instanceof PendingIntentRecord)) { 5731 return false; 5732 } 5733 try { 5734 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5735 if (res.key.allIntents == null) { 5736 return false; 5737 } 5738 for (int i=0; i<res.key.allIntents.length; i++) { 5739 Intent intent = res.key.allIntents[i]; 5740 if (intent.getPackage() != null && intent.getComponent() != null) { 5741 return false; 5742 } 5743 } 5744 return true; 5745 } catch (ClassCastException e) { 5746 } 5747 return false; 5748 } 5749 5750 @Override 5751 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5752 if (!(pendingResult instanceof PendingIntentRecord)) { 5753 return false; 5754 } 5755 try { 5756 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5757 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5758 return true; 5759 } 5760 return false; 5761 } catch (ClassCastException e) { 5762 } 5763 return false; 5764 } 5765 5766 @Override 5767 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5768 if (!(pendingResult instanceof PendingIntentRecord)) { 5769 return null; 5770 } 5771 try { 5772 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5773 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5774 } catch (ClassCastException e) { 5775 } 5776 return null; 5777 } 5778 5779 @Override 5780 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5781 if (!(pendingResult instanceof PendingIntentRecord)) { 5782 return null; 5783 } 5784 try { 5785 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5786 Intent intent = res.key.requestIntent; 5787 if (intent != null) { 5788 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5789 || res.lastTagPrefix.equals(prefix))) { 5790 return res.lastTag; 5791 } 5792 res.lastTagPrefix = prefix; 5793 StringBuilder sb = new StringBuilder(128); 5794 if (prefix != null) { 5795 sb.append(prefix); 5796 } 5797 if (intent.getAction() != null) { 5798 sb.append(intent.getAction()); 5799 } else if (intent.getComponent() != null) { 5800 intent.getComponent().appendShortString(sb); 5801 } else { 5802 sb.append("?"); 5803 } 5804 return res.lastTag = sb.toString(); 5805 } 5806 } catch (ClassCastException e) { 5807 } 5808 return null; 5809 } 5810 5811 @Override 5812 public void setProcessLimit(int max) { 5813 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5814 "setProcessLimit()"); 5815 synchronized (this) { 5816 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5817 mProcessLimitOverride = max; 5818 } 5819 trimApplications(); 5820 } 5821 5822 @Override 5823 public int getProcessLimit() { 5824 synchronized (this) { 5825 return mProcessLimitOverride; 5826 } 5827 } 5828 5829 void foregroundTokenDied(ForegroundToken token) { 5830 synchronized (ActivityManagerService.this) { 5831 synchronized (mPidsSelfLocked) { 5832 ForegroundToken cur 5833 = mForegroundProcesses.get(token.pid); 5834 if (cur != token) { 5835 return; 5836 } 5837 mForegroundProcesses.remove(token.pid); 5838 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5839 if (pr == null) { 5840 return; 5841 } 5842 pr.forcingToForeground = null; 5843 updateProcessForegroundLocked(pr, false, false); 5844 } 5845 updateOomAdjLocked(); 5846 } 5847 } 5848 5849 @Override 5850 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5851 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5852 "setProcessForeground()"); 5853 synchronized(this) { 5854 boolean changed = false; 5855 5856 synchronized (mPidsSelfLocked) { 5857 ProcessRecord pr = mPidsSelfLocked.get(pid); 5858 if (pr == null && isForeground) { 5859 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5860 return; 5861 } 5862 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5863 if (oldToken != null) { 5864 oldToken.token.unlinkToDeath(oldToken, 0); 5865 mForegroundProcesses.remove(pid); 5866 if (pr != null) { 5867 pr.forcingToForeground = null; 5868 } 5869 changed = true; 5870 } 5871 if (isForeground && token != null) { 5872 ForegroundToken newToken = new ForegroundToken() { 5873 @Override 5874 public void binderDied() { 5875 foregroundTokenDied(this); 5876 } 5877 }; 5878 newToken.pid = pid; 5879 newToken.token = token; 5880 try { 5881 token.linkToDeath(newToken, 0); 5882 mForegroundProcesses.put(pid, newToken); 5883 pr.forcingToForeground = token; 5884 changed = true; 5885 } catch (RemoteException e) { 5886 // If the process died while doing this, we will later 5887 // do the cleanup with the process death link. 5888 } 5889 } 5890 } 5891 5892 if (changed) { 5893 updateOomAdjLocked(); 5894 } 5895 } 5896 } 5897 5898 // ========================================================= 5899 // PERMISSIONS 5900 // ========================================================= 5901 5902 static class PermissionController extends IPermissionController.Stub { 5903 ActivityManagerService mActivityManagerService; 5904 PermissionController(ActivityManagerService activityManagerService) { 5905 mActivityManagerService = activityManagerService; 5906 } 5907 5908 @Override 5909 public boolean checkPermission(String permission, int pid, int uid) { 5910 return mActivityManagerService.checkPermission(permission, pid, 5911 uid) == PackageManager.PERMISSION_GRANTED; 5912 } 5913 } 5914 5915 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5916 @Override 5917 public int checkComponentPermission(String permission, int pid, int uid, 5918 int owningUid, boolean exported) { 5919 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5920 owningUid, exported); 5921 } 5922 5923 @Override 5924 public Object getAMSLock() { 5925 return ActivityManagerService.this; 5926 } 5927 } 5928 5929 /** 5930 * This can be called with or without the global lock held. 5931 */ 5932 int checkComponentPermission(String permission, int pid, int uid, 5933 int owningUid, boolean exported) { 5934 // We might be performing an operation on behalf of an indirect binder 5935 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5936 // client identity accordingly before proceeding. 5937 Identity tlsIdentity = sCallerIdentity.get(); 5938 if (tlsIdentity != null) { 5939 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5940 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5941 uid = tlsIdentity.uid; 5942 pid = tlsIdentity.pid; 5943 } 5944 5945 if (pid == MY_PID) { 5946 return PackageManager.PERMISSION_GRANTED; 5947 } 5948 5949 return ActivityManager.checkComponentPermission(permission, uid, 5950 owningUid, exported); 5951 } 5952 5953 /** 5954 * As the only public entry point for permissions checking, this method 5955 * can enforce the semantic that requesting a check on a null global 5956 * permission is automatically denied. (Internally a null permission 5957 * string is used when calling {@link #checkComponentPermission} in cases 5958 * when only uid-based security is needed.) 5959 * 5960 * This can be called with or without the global lock held. 5961 */ 5962 @Override 5963 public int checkPermission(String permission, int pid, int uid) { 5964 if (permission == null) { 5965 return PackageManager.PERMISSION_DENIED; 5966 } 5967 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5968 } 5969 5970 /** 5971 * Binder IPC calls go through the public entry point. 5972 * This can be called with or without the global lock held. 5973 */ 5974 int checkCallingPermission(String permission) { 5975 return checkPermission(permission, 5976 Binder.getCallingPid(), 5977 UserHandle.getAppId(Binder.getCallingUid())); 5978 } 5979 5980 /** 5981 * This can be called with or without the global lock held. 5982 */ 5983 void enforceCallingPermission(String permission, String func) { 5984 if (checkCallingPermission(permission) 5985 == PackageManager.PERMISSION_GRANTED) { 5986 return; 5987 } 5988 5989 String msg = "Permission Denial: " + func + " from pid=" 5990 + Binder.getCallingPid() 5991 + ", uid=" + Binder.getCallingUid() 5992 + " requires " + permission; 5993 Slog.w(TAG, msg); 5994 throw new SecurityException(msg); 5995 } 5996 5997 /** 5998 * Determine if UID is holding permissions required to access {@link Uri} in 5999 * the given {@link ProviderInfo}. Final permission checking is always done 6000 * in {@link ContentProvider}. 6001 */ 6002 private final boolean checkHoldingPermissionsLocked( 6003 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 6004 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6005 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 6006 6007 if (pi.applicationInfo.uid == uid) { 6008 return true; 6009 } else if (!pi.exported) { 6010 return false; 6011 } 6012 6013 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6014 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6015 try { 6016 // check if target holds top-level <provider> permissions 6017 if (!readMet && pi.readPermission != null 6018 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6019 readMet = true; 6020 } 6021 if (!writeMet && pi.writePermission != null 6022 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6023 writeMet = true; 6024 } 6025 6026 // track if unprotected read/write is allowed; any denied 6027 // <path-permission> below removes this ability 6028 boolean allowDefaultRead = pi.readPermission == null; 6029 boolean allowDefaultWrite = pi.writePermission == null; 6030 6031 // check if target holds any <path-permission> that match uri 6032 final PathPermission[] pps = pi.pathPermissions; 6033 if (pps != null) { 6034 final String path = uri.getPath(); 6035 int i = pps.length; 6036 while (i > 0 && (!readMet || !writeMet)) { 6037 i--; 6038 PathPermission pp = pps[i]; 6039 if (pp.match(path)) { 6040 if (!readMet) { 6041 final String pprperm = pp.getReadPermission(); 6042 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6043 + pprperm + " for " + pp.getPath() 6044 + ": match=" + pp.match(path) 6045 + " check=" + pm.checkUidPermission(pprperm, uid)); 6046 if (pprperm != null) { 6047 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6048 readMet = true; 6049 } else { 6050 allowDefaultRead = false; 6051 } 6052 } 6053 } 6054 if (!writeMet) { 6055 final String ppwperm = pp.getWritePermission(); 6056 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6057 + ppwperm + " for " + pp.getPath() 6058 + ": match=" + pp.match(path) 6059 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6060 if (ppwperm != null) { 6061 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6062 writeMet = true; 6063 } else { 6064 allowDefaultWrite = false; 6065 } 6066 } 6067 } 6068 } 6069 } 6070 } 6071 6072 // grant unprotected <provider> read/write, if not blocked by 6073 // <path-permission> above 6074 if (allowDefaultRead) readMet = true; 6075 if (allowDefaultWrite) writeMet = true; 6076 6077 } catch (RemoteException e) { 6078 return false; 6079 } 6080 6081 return readMet && writeMet; 6082 } 6083 6084 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6085 ProviderInfo pi = null; 6086 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6087 if (cpr != null) { 6088 pi = cpr.info; 6089 } else { 6090 try { 6091 pi = AppGlobals.getPackageManager().resolveContentProvider( 6092 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6093 } catch (RemoteException ex) { 6094 } 6095 } 6096 return pi; 6097 } 6098 6099 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6100 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6101 if (targetUris != null) { 6102 return targetUris.get(uri); 6103 } 6104 return null; 6105 } 6106 6107 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6108 String targetPkg, int targetUid, GrantUri uri) { 6109 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6110 if (targetUris == null) { 6111 targetUris = Maps.newArrayMap(); 6112 mGrantedUriPermissions.put(targetUid, targetUris); 6113 } 6114 6115 UriPermission perm = targetUris.get(uri); 6116 if (perm == null) { 6117 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6118 targetUris.put(uri, perm); 6119 } 6120 6121 return perm; 6122 } 6123 6124 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6125 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6126 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6127 : UriPermission.STRENGTH_OWNED; 6128 6129 // Root gets to do everything. 6130 if (uid == 0) { 6131 return true; 6132 } 6133 6134 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6135 if (perms == null) return false; 6136 6137 // First look for exact match 6138 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6139 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6140 return true; 6141 } 6142 6143 // No exact match, look for prefixes 6144 final int N = perms.size(); 6145 for (int i = 0; i < N; i++) { 6146 final UriPermission perm = perms.valueAt(i); 6147 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6148 && perm.getStrength(modeFlags) >= minStrength) { 6149 return true; 6150 } 6151 } 6152 6153 return false; 6154 } 6155 6156 @Override 6157 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6158 enforceNotIsolatedCaller("checkUriPermission"); 6159 6160 // Another redirected-binder-call permissions check as in 6161 // {@link checkComponentPermission}. 6162 Identity tlsIdentity = sCallerIdentity.get(); 6163 if (tlsIdentity != null) { 6164 uid = tlsIdentity.uid; 6165 pid = tlsIdentity.pid; 6166 } 6167 6168 // Our own process gets to do everything. 6169 if (pid == MY_PID) { 6170 return PackageManager.PERMISSION_GRANTED; 6171 } 6172 synchronized (this) { 6173 return checkUriPermissionLocked(uri, uid, modeFlags) 6174 ? PackageManager.PERMISSION_GRANTED 6175 : PackageManager.PERMISSION_DENIED; 6176 } 6177 } 6178 6179 /** 6180 * Check if the targetPkg can be granted permission to access uri by 6181 * the callingUid using the given modeFlags. Throws a security exception 6182 * if callingUid is not allowed to do this. Returns the uid of the target 6183 * if the URI permission grant should be performed; returns -1 if it is not 6184 * needed (for example targetPkg already has permission to access the URI). 6185 * If you already know the uid of the target, you can supply it in 6186 * lastTargetUid else set that to -1. 6187 */ 6188 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6189 Uri uri, final int modeFlags, int lastTargetUid) { 6190 if (!Intent.isAccessUriMode(modeFlags)) { 6191 return -1; 6192 } 6193 6194 if (targetPkg != null) { 6195 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6196 "Checking grant " + targetPkg + " permission to " + uri); 6197 } 6198 6199 final IPackageManager pm = AppGlobals.getPackageManager(); 6200 6201 // If this is not a content: uri, we can't do anything with it. 6202 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6203 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6204 "Can't grant URI permission for non-content URI: " + uri); 6205 return -1; 6206 } 6207 6208 final String authority = uri.getAuthority(); 6209 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6210 if (pi == null) { 6211 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6212 return -1; 6213 } 6214 6215 int targetUid = lastTargetUid; 6216 if (targetUid < 0 && targetPkg != null) { 6217 try { 6218 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6219 if (targetUid < 0) { 6220 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6221 "Can't grant URI permission no uid for: " + targetPkg); 6222 return -1; 6223 } 6224 } catch (RemoteException ex) { 6225 return -1; 6226 } 6227 } 6228 6229 if (targetUid >= 0) { 6230 // First... does the target actually need this permission? 6231 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6232 // No need to grant the target this permission. 6233 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6234 "Target " + targetPkg + " already has full permission to " + uri); 6235 return -1; 6236 } 6237 } else { 6238 // First... there is no target package, so can anyone access it? 6239 boolean allowed = pi.exported; 6240 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6241 if (pi.readPermission != null) { 6242 allowed = false; 6243 } 6244 } 6245 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6246 if (pi.writePermission != null) { 6247 allowed = false; 6248 } 6249 } 6250 if (allowed) { 6251 return -1; 6252 } 6253 } 6254 6255 // Second... is the provider allowing granting of URI permissions? 6256 if (!pi.grantUriPermissions) { 6257 throw new SecurityException("Provider " + pi.packageName 6258 + "/" + pi.name 6259 + " does not allow granting of Uri permissions (uri " 6260 + uri + ")"); 6261 } 6262 if (pi.uriPermissionPatterns != null) { 6263 final int N = pi.uriPermissionPatterns.length; 6264 boolean allowed = false; 6265 for (int i=0; i<N; i++) { 6266 if (pi.uriPermissionPatterns[i] != null 6267 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6268 allowed = true; 6269 break; 6270 } 6271 } 6272 if (!allowed) { 6273 throw new SecurityException("Provider " + pi.packageName 6274 + "/" + pi.name 6275 + " does not allow granting of permission to path of Uri " 6276 + uri); 6277 } 6278 } 6279 6280 // Third... does the caller itself have permission to access 6281 // this uri? 6282 if (callingUid != Process.myUid()) { 6283 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6284 // Require they hold a strong enough Uri permission 6285 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6286 throw new SecurityException("Uid " + callingUid 6287 + " does not have permission to uri " + uri); 6288 } 6289 } 6290 } 6291 6292 return targetUid; 6293 } 6294 6295 @Override 6296 public int checkGrantUriPermission(int callingUid, String targetPkg, 6297 Uri uri, final int modeFlags) { 6298 enforceNotIsolatedCaller("checkGrantUriPermission"); 6299 synchronized(this) { 6300 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6301 } 6302 } 6303 6304 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6305 final int modeFlags, UriPermissionOwner owner) { 6306 if (!Intent.isAccessUriMode(modeFlags)) { 6307 return; 6308 } 6309 6310 // So here we are: the caller has the assumed permission 6311 // to the uri, and the target doesn't. Let's now give this to 6312 // the target. 6313 6314 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6315 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6316 6317 final String authority = uri.getAuthority(); 6318 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6319 if (pi == null) { 6320 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6321 return; 6322 } 6323 6324 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6325 final UriPermission perm = findOrCreateUriPermissionLocked( 6326 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6327 perm.grantModes(modeFlags, owner); 6328 } 6329 6330 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6331 final int modeFlags, UriPermissionOwner owner) { 6332 if (targetPkg == null) { 6333 throw new NullPointerException("targetPkg"); 6334 } 6335 6336 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6337 if (targetUid < 0) { 6338 return; 6339 } 6340 6341 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6342 } 6343 6344 static class NeededUriGrants extends ArrayList<Uri> { 6345 final String targetPkg; 6346 final int targetUid; 6347 final int flags; 6348 6349 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6350 this.targetPkg = targetPkg; 6351 this.targetUid = targetUid; 6352 this.flags = flags; 6353 } 6354 } 6355 6356 /** 6357 * Like checkGrantUriPermissionLocked, but takes an Intent. 6358 */ 6359 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6360 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6361 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6362 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6363 + " clip=" + (intent != null ? intent.getClipData() : null) 6364 + " from " + intent + "; flags=0x" 6365 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6366 6367 if (targetPkg == null) { 6368 throw new NullPointerException("targetPkg"); 6369 } 6370 6371 if (intent == null) { 6372 return null; 6373 } 6374 Uri data = intent.getData(); 6375 ClipData clip = intent.getClipData(); 6376 if (data == null && clip == null) { 6377 return null; 6378 } 6379 6380 if (data != null) { 6381 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6382 mode, needed != null ? needed.targetUid : -1); 6383 if (targetUid > 0) { 6384 if (needed == null) { 6385 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6386 } 6387 needed.add(data); 6388 } 6389 } 6390 if (clip != null) { 6391 for (int i=0; i<clip.getItemCount(); i++) { 6392 Uri uri = clip.getItemAt(i).getUri(); 6393 if (uri != null) { 6394 int targetUid = -1; 6395 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6396 mode, needed != null ? needed.targetUid : -1); 6397 if (targetUid > 0) { 6398 if (needed == null) { 6399 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6400 } 6401 needed.add(uri); 6402 } 6403 } else { 6404 Intent clipIntent = clip.getItemAt(i).getIntent(); 6405 if (clipIntent != null) { 6406 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6407 callingUid, targetPkg, clipIntent, mode, needed); 6408 if (newNeeded != null) { 6409 needed = newNeeded; 6410 } 6411 } 6412 } 6413 } 6414 } 6415 6416 return needed; 6417 } 6418 6419 /** 6420 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6421 */ 6422 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6423 UriPermissionOwner owner) { 6424 if (needed != null) { 6425 for (int i=0; i<needed.size(); i++) { 6426 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6427 needed.get(i), needed.flags, owner); 6428 } 6429 } 6430 } 6431 6432 void grantUriPermissionFromIntentLocked(int callingUid, 6433 String targetPkg, Intent intent, UriPermissionOwner owner) { 6434 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6435 intent, intent != null ? intent.getFlags() : 0, null); 6436 if (needed == null) { 6437 return; 6438 } 6439 6440 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6441 } 6442 6443 @Override 6444 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6445 Uri uri, final int modeFlags) { 6446 enforceNotIsolatedCaller("grantUriPermission"); 6447 synchronized(this) { 6448 final ProcessRecord r = getRecordForAppLocked(caller); 6449 if (r == null) { 6450 throw new SecurityException("Unable to find app for caller " 6451 + caller 6452 + " when granting permission to uri " + uri); 6453 } 6454 if (targetPkg == null) { 6455 throw new IllegalArgumentException("null target"); 6456 } 6457 if (uri == null) { 6458 throw new IllegalArgumentException("null uri"); 6459 } 6460 6461 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6462 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6463 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6464 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6465 6466 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6467 } 6468 } 6469 6470 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6471 if (perm.modeFlags == 0) { 6472 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6473 perm.targetUid); 6474 if (perms != null) { 6475 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6476 "Removing " + perm.targetUid + " permission to " + perm.uri); 6477 6478 perms.remove(perm.uri); 6479 if (perms.isEmpty()) { 6480 mGrantedUriPermissions.remove(perm.targetUid); 6481 } 6482 } 6483 } 6484 } 6485 6486 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6487 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6488 6489 final IPackageManager pm = AppGlobals.getPackageManager(); 6490 final String authority = uri.getAuthority(); 6491 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6492 if (pi == null) { 6493 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6494 return; 6495 } 6496 6497 // Does the caller have this permission on the URI? 6498 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6499 // Right now, if you are not the original owner of the permission, 6500 // you are not allowed to revoke it. 6501 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6502 throw new SecurityException("Uid " + callingUid 6503 + " does not have permission to uri " + uri); 6504 //} 6505 } 6506 6507 boolean persistChanged = false; 6508 6509 // Go through all of the permissions and remove any that match. 6510 int N = mGrantedUriPermissions.size(); 6511 for (int i = 0; i < N; i++) { 6512 final int targetUid = mGrantedUriPermissions.keyAt(i); 6513 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6514 6515 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6516 final UriPermission perm = it.next(); 6517 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6518 if (DEBUG_URI_PERMISSION) 6519 Slog.v(TAG, 6520 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6521 persistChanged |= perm.revokeModes( 6522 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6523 if (perm.modeFlags == 0) { 6524 it.remove(); 6525 } 6526 } 6527 } 6528 6529 if (perms.isEmpty()) { 6530 mGrantedUriPermissions.remove(targetUid); 6531 N--; 6532 i--; 6533 } 6534 } 6535 6536 if (persistChanged) { 6537 schedulePersistUriGrants(); 6538 } 6539 } 6540 6541 @Override 6542 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6543 final int modeFlags) { 6544 enforceNotIsolatedCaller("revokeUriPermission"); 6545 synchronized(this) { 6546 final ProcessRecord r = getRecordForAppLocked(caller); 6547 if (r == null) { 6548 throw new SecurityException("Unable to find app for caller " 6549 + caller 6550 + " when revoking permission to uri " + uri); 6551 } 6552 if (uri == null) { 6553 Slog.w(TAG, "revokeUriPermission: null uri"); 6554 return; 6555 } 6556 6557 if (!Intent.isAccessUriMode(modeFlags)) { 6558 return; 6559 } 6560 6561 final IPackageManager pm = AppGlobals.getPackageManager(); 6562 final String authority = uri.getAuthority(); 6563 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6564 if (pi == null) { 6565 Slog.w(TAG, "No content provider found for permission revoke: " 6566 + uri.toSafeString()); 6567 return; 6568 } 6569 6570 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6571 } 6572 } 6573 6574 /** 6575 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6576 * given package. 6577 * 6578 * @param packageName Package name to match, or {@code null} to apply to all 6579 * packages. 6580 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6581 * to all users. 6582 * @param persistable If persistable grants should be removed. 6583 */ 6584 private void removeUriPermissionsForPackageLocked( 6585 String packageName, int userHandle, boolean persistable) { 6586 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6587 throw new IllegalArgumentException("Must narrow by either package or user"); 6588 } 6589 6590 boolean persistChanged = false; 6591 6592 int N = mGrantedUriPermissions.size(); 6593 for (int i = 0; i < N; i++) { 6594 final int targetUid = mGrantedUriPermissions.keyAt(i); 6595 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6596 6597 // Only inspect grants matching user 6598 if (userHandle == UserHandle.USER_ALL 6599 || userHandle == UserHandle.getUserId(targetUid)) { 6600 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6601 final UriPermission perm = it.next(); 6602 6603 // Only inspect grants matching package 6604 if (packageName == null || perm.sourcePkg.equals(packageName) 6605 || perm.targetPkg.equals(packageName)) { 6606 persistChanged |= perm.revokeModes( 6607 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6608 6609 // Only remove when no modes remain; any persisted grants 6610 // will keep this alive. 6611 if (perm.modeFlags == 0) { 6612 it.remove(); 6613 } 6614 } 6615 } 6616 6617 if (perms.isEmpty()) { 6618 mGrantedUriPermissions.remove(targetUid); 6619 N--; 6620 i--; 6621 } 6622 } 6623 } 6624 6625 if (persistChanged) { 6626 schedulePersistUriGrants(); 6627 } 6628 } 6629 6630 @Override 6631 public IBinder newUriPermissionOwner(String name) { 6632 enforceNotIsolatedCaller("newUriPermissionOwner"); 6633 synchronized(this) { 6634 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6635 return owner.getExternalTokenLocked(); 6636 } 6637 } 6638 6639 @Override 6640 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6641 Uri uri, final int modeFlags) { 6642 synchronized(this) { 6643 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6644 if (owner == null) { 6645 throw new IllegalArgumentException("Unknown owner: " + token); 6646 } 6647 if (fromUid != Binder.getCallingUid()) { 6648 if (Binder.getCallingUid() != Process.myUid()) { 6649 // Only system code can grant URI permissions on behalf 6650 // of other users. 6651 throw new SecurityException("nice try"); 6652 } 6653 } 6654 if (targetPkg == null) { 6655 throw new IllegalArgumentException("null target"); 6656 } 6657 if (uri == null) { 6658 throw new IllegalArgumentException("null uri"); 6659 } 6660 6661 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6662 } 6663 } 6664 6665 @Override 6666 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6667 synchronized(this) { 6668 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6669 if (owner == null) { 6670 throw new IllegalArgumentException("Unknown owner: " + token); 6671 } 6672 6673 if (uri == null) { 6674 owner.removeUriPermissionsLocked(mode); 6675 } else { 6676 owner.removeUriPermissionLocked(uri, mode); 6677 } 6678 } 6679 } 6680 6681 private void schedulePersistUriGrants() { 6682 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6683 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6684 10 * DateUtils.SECOND_IN_MILLIS); 6685 } 6686 } 6687 6688 private void writeGrantedUriPermissions() { 6689 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6690 6691 // Snapshot permissions so we can persist without lock 6692 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6693 synchronized (this) { 6694 final int size = mGrantedUriPermissions.size(); 6695 for (int i = 0; i < size; i++) { 6696 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6697 for (UriPermission perm : perms.values()) { 6698 if (perm.persistedModeFlags != 0) { 6699 persist.add(perm.snapshot()); 6700 } 6701 } 6702 } 6703 } 6704 6705 FileOutputStream fos = null; 6706 try { 6707 fos = mGrantFile.startWrite(); 6708 6709 XmlSerializer out = new FastXmlSerializer(); 6710 out.setOutput(fos, "utf-8"); 6711 out.startDocument(null, true); 6712 out.startTag(null, TAG_URI_GRANTS); 6713 for (UriPermission.Snapshot perm : persist) { 6714 out.startTag(null, TAG_URI_GRANT); 6715 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6716 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6717 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6718 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6719 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6720 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6721 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6722 out.endTag(null, TAG_URI_GRANT); 6723 } 6724 out.endTag(null, TAG_URI_GRANTS); 6725 out.endDocument(); 6726 6727 mGrantFile.finishWrite(fos); 6728 } catch (IOException e) { 6729 if (fos != null) { 6730 mGrantFile.failWrite(fos); 6731 } 6732 } 6733 } 6734 6735 private void readGrantedUriPermissionsLocked() { 6736 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6737 6738 final long now = System.currentTimeMillis(); 6739 6740 FileInputStream fis = null; 6741 try { 6742 fis = mGrantFile.openRead(); 6743 final XmlPullParser in = Xml.newPullParser(); 6744 in.setInput(fis, null); 6745 6746 int type; 6747 while ((type = in.next()) != END_DOCUMENT) { 6748 final String tag = in.getName(); 6749 if (type == START_TAG) { 6750 if (TAG_URI_GRANT.equals(tag)) { 6751 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6752 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6753 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6754 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6755 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6756 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6757 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6758 6759 // Sanity check that provider still belongs to source package 6760 final ProviderInfo pi = getProviderInfoLocked( 6761 uri.getAuthority(), userHandle); 6762 if (pi != null && sourcePkg.equals(pi.packageName)) { 6763 int targetUid = -1; 6764 try { 6765 targetUid = AppGlobals.getPackageManager() 6766 .getPackageUid(targetPkg, userHandle); 6767 } catch (RemoteException e) { 6768 } 6769 if (targetUid != -1) { 6770 final UriPermission perm = findOrCreateUriPermissionLocked( 6771 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6772 perm.initPersistedModes(modeFlags, createdTime); 6773 } 6774 } else { 6775 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6776 + " but instead found " + pi); 6777 } 6778 } 6779 } 6780 } 6781 } catch (FileNotFoundException e) { 6782 // Missing grants is okay 6783 } catch (IOException e) { 6784 Log.wtf(TAG, "Failed reading Uri grants", e); 6785 } catch (XmlPullParserException e) { 6786 Log.wtf(TAG, "Failed reading Uri grants", e); 6787 } finally { 6788 IoUtils.closeQuietly(fis); 6789 } 6790 } 6791 6792 @Override 6793 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6794 enforceNotIsolatedCaller("takePersistableUriPermission"); 6795 6796 Preconditions.checkFlagsArgument(modeFlags, 6797 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6798 6799 synchronized (this) { 6800 final int callingUid = Binder.getCallingUid(); 6801 boolean persistChanged = false; 6802 6803 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6804 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6805 6806 final boolean exactValid = (exactPerm != null) 6807 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6808 final boolean prefixValid = (prefixPerm != null) 6809 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6810 6811 if (!(exactValid || prefixValid)) { 6812 throw new SecurityException("No persistable permission grants found for UID " 6813 + callingUid + " and Uri " + uri.toSafeString()); 6814 } 6815 6816 if (exactValid) { 6817 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6818 } 6819 if (prefixValid) { 6820 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6821 } 6822 6823 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6824 6825 if (persistChanged) { 6826 schedulePersistUriGrants(); 6827 } 6828 } 6829 } 6830 6831 @Override 6832 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6833 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6834 6835 Preconditions.checkFlagsArgument(modeFlags, 6836 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6837 6838 synchronized (this) { 6839 final int callingUid = Binder.getCallingUid(); 6840 boolean persistChanged = false; 6841 6842 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6843 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6844 if (exactPerm == null && prefixPerm == null) { 6845 throw new SecurityException("No permission grants found for UID " + callingUid 6846 + " and Uri " + uri.toSafeString()); 6847 } 6848 6849 if (exactPerm != null) { 6850 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6851 removeUriPermissionIfNeededLocked(exactPerm); 6852 } 6853 if (prefixPerm != null) { 6854 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6855 removeUriPermissionIfNeededLocked(prefixPerm); 6856 } 6857 6858 if (persistChanged) { 6859 schedulePersistUriGrants(); 6860 } 6861 } 6862 } 6863 6864 /** 6865 * Prune any older {@link UriPermission} for the given UID until outstanding 6866 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6867 * 6868 * @return if any mutations occured that require persisting. 6869 */ 6870 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6871 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6872 if (perms == null) return false; 6873 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6874 6875 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6876 for (UriPermission perm : perms.values()) { 6877 if (perm.persistedModeFlags != 0) { 6878 persisted.add(perm); 6879 } 6880 } 6881 6882 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6883 if (trimCount <= 0) return false; 6884 6885 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6886 for (int i = 0; i < trimCount; i++) { 6887 final UriPermission perm = persisted.get(i); 6888 6889 if (DEBUG_URI_PERMISSION) { 6890 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6891 } 6892 6893 perm.releasePersistableModes(~0); 6894 removeUriPermissionIfNeededLocked(perm); 6895 } 6896 6897 return true; 6898 } 6899 6900 @Override 6901 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6902 String packageName, boolean incoming) { 6903 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6904 Preconditions.checkNotNull(packageName, "packageName"); 6905 6906 final int callingUid = Binder.getCallingUid(); 6907 final IPackageManager pm = AppGlobals.getPackageManager(); 6908 try { 6909 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6910 if (packageUid != callingUid) { 6911 throw new SecurityException( 6912 "Package " + packageName + " does not belong to calling UID " + callingUid); 6913 } 6914 } catch (RemoteException e) { 6915 throw new SecurityException("Failed to verify package name ownership"); 6916 } 6917 6918 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6919 synchronized (this) { 6920 if (incoming) { 6921 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6922 callingUid); 6923 if (perms == null) { 6924 Slog.w(TAG, "No permission grants found for " + packageName); 6925 } else { 6926 for (UriPermission perm : perms.values()) { 6927 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6928 result.add(perm.buildPersistedPublicApiObject()); 6929 } 6930 } 6931 } 6932 } else { 6933 final int size = mGrantedUriPermissions.size(); 6934 for (int i = 0; i < size; i++) { 6935 final ArrayMap<GrantUri, UriPermission> perms = 6936 mGrantedUriPermissions.valueAt(i); 6937 for (UriPermission perm : perms.values()) { 6938 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6939 result.add(perm.buildPersistedPublicApiObject()); 6940 } 6941 } 6942 } 6943 } 6944 } 6945 return new ParceledListSlice<android.content.UriPermission>(result); 6946 } 6947 6948 @Override 6949 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6950 synchronized (this) { 6951 ProcessRecord app = 6952 who != null ? getRecordForAppLocked(who) : null; 6953 if (app == null) return; 6954 6955 Message msg = Message.obtain(); 6956 msg.what = WAIT_FOR_DEBUGGER_MSG; 6957 msg.obj = app; 6958 msg.arg1 = waiting ? 1 : 0; 6959 mHandler.sendMessage(msg); 6960 } 6961 } 6962 6963 @Override 6964 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6965 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6966 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6967 outInfo.availMem = Process.getFreeMemory(); 6968 outInfo.totalMem = Process.getTotalMemory(); 6969 outInfo.threshold = homeAppMem; 6970 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6971 outInfo.hiddenAppThreshold = cachedAppMem; 6972 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6973 ProcessList.SERVICE_ADJ); 6974 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6975 ProcessList.VISIBLE_APP_ADJ); 6976 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6977 ProcessList.FOREGROUND_APP_ADJ); 6978 } 6979 6980 // ========================================================= 6981 // TASK MANAGEMENT 6982 // ========================================================= 6983 6984 @Override 6985 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6986 IThumbnailReceiver receiver) { 6987 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6988 6989 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6990 ActivityRecord topRecord = null; 6991 6992 synchronized(this) { 6993 if (localLOGV) Slog.v( 6994 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6995 + ", receiver=" + receiver); 6996 6997 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6998 != PackageManager.PERMISSION_GRANTED) { 6999 if (receiver != null) { 7000 // If the caller wants to wait for pending thumbnails, 7001 // it ain't gonna get them. 7002 try { 7003 receiver.finished(); 7004 } catch (RemoteException ex) { 7005 } 7006 } 7007 String msg = "Permission Denial: getTasks() from pid=" 7008 + Binder.getCallingPid() 7009 + ", uid=" + Binder.getCallingUid() 7010 + " requires " + android.Manifest.permission.GET_TASKS; 7011 Slog.w(TAG, msg); 7012 throw new SecurityException(msg); 7013 } 7014 7015 // TODO: Improve with MRU list from all ActivityStacks. 7016 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 7017 7018 if (!pending.pendingRecords.isEmpty()) { 7019 mPendingThumbnails.add(pending); 7020 } 7021 } 7022 7023 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 7024 7025 if (topRecord != null) { 7026 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 7027 try { 7028 IApplicationThread topThumbnail = topRecord.app.thread; 7029 topThumbnail.requestThumbnail(topRecord.appToken); 7030 } catch (Exception e) { 7031 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 7032 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 7033 } 7034 } 7035 7036 if (pending.pendingRecords.isEmpty() && receiver != null) { 7037 // In this case all thumbnails were available and the client 7038 // is being asked to be told when the remaining ones come in... 7039 // which is unusually, since the top-most currently running 7040 // activity should never have a canned thumbnail! Oh well. 7041 try { 7042 receiver.finished(); 7043 } catch (RemoteException ex) { 7044 } 7045 } 7046 7047 return list; 7048 } 7049 7050 TaskRecord getMostRecentTask() { 7051 return mRecentTasks.get(0); 7052 } 7053 7054 @Override 7055 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7056 int flags, int userId) { 7057 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7058 false, true, "getRecentTasks", null); 7059 7060 synchronized (this) { 7061 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 7062 "getRecentTasks()"); 7063 final boolean detailed = checkCallingPermission( 7064 android.Manifest.permission.GET_DETAILED_TASKS) 7065 == PackageManager.PERMISSION_GRANTED; 7066 7067 IPackageManager pm = AppGlobals.getPackageManager(); 7068 7069 final int N = mRecentTasks.size(); 7070 ArrayList<ActivityManager.RecentTaskInfo> res 7071 = new ArrayList<ActivityManager.RecentTaskInfo>( 7072 maxNum < N ? maxNum : N); 7073 7074 final Set<Integer> includedUsers; 7075 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7076 includedUsers = getProfileIdsLocked(userId); 7077 } else { 7078 includedUsers = new HashSet<Integer>(); 7079 } 7080 includedUsers.add(Integer.valueOf(userId)); 7081 for (int i=0; i<N && maxNum > 0; i++) { 7082 TaskRecord tr = mRecentTasks.get(i); 7083 // Only add calling user or related users recent tasks 7084 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7085 7086 // Return the entry if desired by the caller. We always return 7087 // the first entry, because callers always expect this to be the 7088 // foreground app. We may filter others if the caller has 7089 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7090 // we should exclude the entry. 7091 7092 if (i == 0 7093 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7094 || (tr.intent == null) 7095 || ((tr.intent.getFlags() 7096 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7097 ActivityManager.RecentTaskInfo rti 7098 = new ActivityManager.RecentTaskInfo(); 7099 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7100 rti.persistentId = tr.taskId; 7101 rti.baseIntent = new Intent( 7102 tr.intent != null ? tr.intent : tr.affinityIntent); 7103 if (!detailed) { 7104 rti.baseIntent.replaceExtras((Bundle)null); 7105 } 7106 rti.origActivity = tr.origActivity; 7107 rti.description = tr.lastDescription; 7108 rti.stackId = tr.stack.mStackId; 7109 rti.userId = tr.userId; 7110 7111 // Traverse upwards looking for any break between main task activities and 7112 // utility activities. 7113 final ArrayList<ActivityRecord> activities = tr.mActivities; 7114 int activityNdx; 7115 final int numActivities = activities.size(); 7116 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7117 ++activityNdx) { 7118 final ActivityRecord r = activities.get(activityNdx); 7119 if (r.intent != null && 7120 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7121 != 0) { 7122 break; 7123 } 7124 } 7125 // Traverse downwards starting below break looking for set label and icon. 7126 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7127 final ActivityRecord r = activities.get(activityNdx); 7128 if (r.activityLabel != null || r.activityIcon != null) { 7129 rti.activityLabel = r.activityLabel; 7130 rti.activityIcon = r.activityIcon; 7131 break; 7132 } 7133 } 7134 7135 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7136 // Check whether this activity is currently available. 7137 try { 7138 if (rti.origActivity != null) { 7139 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7140 == null) { 7141 continue; 7142 } 7143 } else if (rti.baseIntent != null) { 7144 if (pm.queryIntentActivities(rti.baseIntent, 7145 null, 0, userId) == null) { 7146 continue; 7147 } 7148 } 7149 } catch (RemoteException e) { 7150 // Will never happen. 7151 } 7152 } 7153 7154 res.add(rti); 7155 maxNum--; 7156 } 7157 } 7158 return res; 7159 } 7160 } 7161 7162 private TaskRecord recentTaskForIdLocked(int id) { 7163 final int N = mRecentTasks.size(); 7164 for (int i=0; i<N; i++) { 7165 TaskRecord tr = mRecentTasks.get(i); 7166 if (tr.taskId == id) { 7167 return tr; 7168 } 7169 } 7170 return null; 7171 } 7172 7173 @Override 7174 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7175 synchronized (this) { 7176 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7177 "getTaskThumbnails()"); 7178 TaskRecord tr = recentTaskForIdLocked(id); 7179 if (tr != null) { 7180 return tr.getTaskThumbnailsLocked(); 7181 } 7182 } 7183 return null; 7184 } 7185 7186 @Override 7187 public Bitmap getTaskTopThumbnail(int id) { 7188 synchronized (this) { 7189 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7190 "getTaskTopThumbnail()"); 7191 TaskRecord tr = recentTaskForIdLocked(id); 7192 if (tr != null) { 7193 return tr.getTaskTopThumbnailLocked(); 7194 } 7195 } 7196 return null; 7197 } 7198 7199 @Override 7200 public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, 7201 Bitmap activityIcon) { 7202 synchronized (this) { 7203 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7204 if (r != null) { 7205 r.activityLabel = activityLabel.toString(); 7206 r.activityIcon = activityIcon; 7207 } 7208 } 7209 } 7210 7211 @Override 7212 public boolean removeSubTask(int taskId, int subTaskIndex) { 7213 synchronized (this) { 7214 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7215 "removeSubTask()"); 7216 long ident = Binder.clearCallingIdentity(); 7217 try { 7218 TaskRecord tr = recentTaskForIdLocked(taskId); 7219 if (tr != null) { 7220 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7221 } 7222 return false; 7223 } finally { 7224 Binder.restoreCallingIdentity(ident); 7225 } 7226 } 7227 } 7228 7229 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7230 if (!pr.killedByAm) { 7231 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7232 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7233 pr.processName, pr.setAdj, reason); 7234 pr.killedByAm = true; 7235 Process.killProcessQuiet(pr.pid); 7236 } 7237 } 7238 7239 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7240 tr.disposeThumbnail(); 7241 mRecentTasks.remove(tr); 7242 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7243 Intent baseIntent = new Intent( 7244 tr.intent != null ? tr.intent : tr.affinityIntent); 7245 ComponentName component = baseIntent.getComponent(); 7246 if (component == null) { 7247 Slog.w(TAG, "Now component for base intent of task: " + tr); 7248 return; 7249 } 7250 7251 // Find any running services associated with this app. 7252 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7253 7254 if (killProcesses) { 7255 // Find any running processes associated with this app. 7256 final String pkg = component.getPackageName(); 7257 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7258 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7259 for (int i=0; i<pmap.size(); i++) { 7260 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7261 for (int j=0; j<uids.size(); j++) { 7262 ProcessRecord proc = uids.valueAt(j); 7263 if (proc.userId != tr.userId) { 7264 continue; 7265 } 7266 if (!proc.pkgList.containsKey(pkg)) { 7267 continue; 7268 } 7269 procs.add(proc); 7270 } 7271 } 7272 7273 // Kill the running processes. 7274 for (int i=0; i<procs.size(); i++) { 7275 ProcessRecord pr = procs.get(i); 7276 if (pr == mHomeProcess) { 7277 // Don't kill the home process along with tasks from the same package. 7278 continue; 7279 } 7280 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7281 killUnneededProcessLocked(pr, "remove task"); 7282 } else { 7283 pr.waitingToKill = "remove task"; 7284 } 7285 } 7286 } 7287 } 7288 7289 /** 7290 * Removes the task with the specified task id. 7291 * 7292 * @param taskId Identifier of the task to be removed. 7293 * @param flags Additional operational flags. May be 0 or 7294 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7295 * @return Returns true if the given task was found and removed. 7296 */ 7297 private boolean removeTaskByIdLocked(int taskId, int flags) { 7298 TaskRecord tr = recentTaskForIdLocked(taskId); 7299 if (tr != null) { 7300 tr.removeTaskActivitiesLocked(-1, false); 7301 cleanUpRemovedTaskLocked(tr, flags); 7302 return true; 7303 } 7304 return false; 7305 } 7306 7307 @Override 7308 public boolean removeTask(int taskId, int flags) { 7309 synchronized (this) { 7310 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7311 "removeTask()"); 7312 long ident = Binder.clearCallingIdentity(); 7313 try { 7314 return removeTaskByIdLocked(taskId, flags); 7315 } finally { 7316 Binder.restoreCallingIdentity(ident); 7317 } 7318 } 7319 } 7320 7321 /** 7322 * TODO: Add mController hook 7323 */ 7324 @Override 7325 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7326 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7327 "moveTaskToFront()"); 7328 7329 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7330 synchronized(this) { 7331 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7332 Binder.getCallingUid(), "Task to front")) { 7333 ActivityOptions.abort(options); 7334 return; 7335 } 7336 final long origId = Binder.clearCallingIdentity(); 7337 try { 7338 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7339 if (task == null) { 7340 return; 7341 } 7342 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7343 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7344 return; 7345 } 7346 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7347 } finally { 7348 Binder.restoreCallingIdentity(origId); 7349 } 7350 ActivityOptions.abort(options); 7351 } 7352 } 7353 7354 @Override 7355 public void moveTaskToBack(int taskId) { 7356 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7357 "moveTaskToBack()"); 7358 7359 synchronized(this) { 7360 TaskRecord tr = recentTaskForIdLocked(taskId); 7361 if (tr != null) { 7362 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7363 ActivityStack stack = tr.stack; 7364 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7365 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7366 Binder.getCallingUid(), "Task to back")) { 7367 return; 7368 } 7369 } 7370 final long origId = Binder.clearCallingIdentity(); 7371 try { 7372 stack.moveTaskToBackLocked(taskId, null); 7373 } finally { 7374 Binder.restoreCallingIdentity(origId); 7375 } 7376 } 7377 } 7378 } 7379 7380 /** 7381 * Moves an activity, and all of the other activities within the same task, to the bottom 7382 * of the history stack. The activity's order within the task is unchanged. 7383 * 7384 * @param token A reference to the activity we wish to move 7385 * @param nonRoot If false then this only works if the activity is the root 7386 * of a task; if true it will work for any activity in a task. 7387 * @return Returns true if the move completed, false if not. 7388 */ 7389 @Override 7390 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7391 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7392 synchronized(this) { 7393 final long origId = Binder.clearCallingIdentity(); 7394 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7395 if (taskId >= 0) { 7396 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7397 } 7398 Binder.restoreCallingIdentity(origId); 7399 } 7400 return false; 7401 } 7402 7403 @Override 7404 public void moveTaskBackwards(int task) { 7405 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7406 "moveTaskBackwards()"); 7407 7408 synchronized(this) { 7409 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7410 Binder.getCallingUid(), "Task backwards")) { 7411 return; 7412 } 7413 final long origId = Binder.clearCallingIdentity(); 7414 moveTaskBackwardsLocked(task); 7415 Binder.restoreCallingIdentity(origId); 7416 } 7417 } 7418 7419 private final void moveTaskBackwardsLocked(int task) { 7420 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7421 } 7422 7423 @Override 7424 public IBinder getHomeActivityToken() throws RemoteException { 7425 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7426 "getHomeActivityToken()"); 7427 synchronized (this) { 7428 return mStackSupervisor.getHomeActivityToken(); 7429 } 7430 } 7431 7432 @Override 7433 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7434 IActivityContainerCallback callback) throws RemoteException { 7435 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7436 "createActivityContainer()"); 7437 synchronized (this) { 7438 if (parentActivityToken == null) { 7439 throw new IllegalArgumentException("parent token must not be null"); 7440 } 7441 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7442 if (r == null) { 7443 return null; 7444 } 7445 if (callback == null) { 7446 throw new IllegalArgumentException("callback must not be null"); 7447 } 7448 return mStackSupervisor.createActivityContainer(r, callback); 7449 } 7450 } 7451 7452 @Override 7453 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7454 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7455 "deleteActivityContainer()"); 7456 synchronized (this) { 7457 mStackSupervisor.deleteActivityContainer(container); 7458 } 7459 } 7460 7461 @Override 7462 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7463 throws RemoteException { 7464 synchronized (this) { 7465 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7466 if (stack != null) { 7467 return stack.mActivityContainer; 7468 } 7469 return null; 7470 } 7471 } 7472 7473 @Override 7474 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7475 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7476 "moveTaskToStack()"); 7477 if (stackId == HOME_STACK_ID) { 7478 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7479 new RuntimeException("here").fillInStackTrace()); 7480 } 7481 synchronized (this) { 7482 long ident = Binder.clearCallingIdentity(); 7483 try { 7484 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7485 + stackId + " toTop=" + toTop); 7486 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7487 } finally { 7488 Binder.restoreCallingIdentity(ident); 7489 } 7490 } 7491 } 7492 7493 @Override 7494 public void resizeStack(int stackBoxId, Rect bounds) { 7495 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7496 "resizeStackBox()"); 7497 long ident = Binder.clearCallingIdentity(); 7498 try { 7499 mWindowManager.resizeStack(stackBoxId, bounds); 7500 } finally { 7501 Binder.restoreCallingIdentity(ident); 7502 } 7503 } 7504 7505 @Override 7506 public List<StackInfo> getAllStackInfos() { 7507 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7508 "getAllStackInfos()"); 7509 long ident = Binder.clearCallingIdentity(); 7510 try { 7511 synchronized (this) { 7512 return mStackSupervisor.getAllStackInfosLocked(); 7513 } 7514 } finally { 7515 Binder.restoreCallingIdentity(ident); 7516 } 7517 } 7518 7519 @Override 7520 public StackInfo getStackInfo(int stackId) { 7521 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7522 "getStackInfo()"); 7523 long ident = Binder.clearCallingIdentity(); 7524 try { 7525 synchronized (this) { 7526 return mStackSupervisor.getStackInfoLocked(stackId); 7527 } 7528 } finally { 7529 Binder.restoreCallingIdentity(ident); 7530 } 7531 } 7532 7533 @Override 7534 public boolean isInHomeStack(int taskId) { 7535 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7536 "getStackInfo()"); 7537 long ident = Binder.clearCallingIdentity(); 7538 try { 7539 synchronized (this) { 7540 TaskRecord tr = recentTaskForIdLocked(taskId); 7541 if (tr != null) { 7542 return tr.stack.isHomeStack(); 7543 } 7544 } 7545 } finally { 7546 Binder.restoreCallingIdentity(ident); 7547 } 7548 return false; 7549 } 7550 7551 @Override 7552 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7553 synchronized(this) { 7554 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7555 } 7556 } 7557 7558 private boolean isLockTaskAuthorized(ComponentName name) { 7559// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7560// "startLockTaskMode()"); 7561// DevicePolicyManager dpm = (DevicePolicyManager) 7562// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7563// return dpm != null && dpm.isLockTaskPermitted(name); 7564 return true; 7565 } 7566 7567 private void startLockTaskMode(TaskRecord task) { 7568 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7569 return; 7570 } 7571 long ident = Binder.clearCallingIdentity(); 7572 try { 7573 synchronized (this) { 7574 // Since we lost lock on task, make sure it is still there. 7575 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7576 if (task != null) { 7577 mStackSupervisor.setLockTaskModeLocked(task); 7578 } 7579 } 7580 } finally { 7581 Binder.restoreCallingIdentity(ident); 7582 } 7583 } 7584 7585 @Override 7586 public void startLockTaskMode(int taskId) { 7587 long ident = Binder.clearCallingIdentity(); 7588 try { 7589 final TaskRecord task; 7590 synchronized (this) { 7591 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7592 } 7593 if (task != null) { 7594 startLockTaskMode(task); 7595 } 7596 } finally { 7597 Binder.restoreCallingIdentity(ident); 7598 } 7599 } 7600 7601 @Override 7602 public void startLockTaskMode(IBinder token) { 7603 long ident = Binder.clearCallingIdentity(); 7604 try { 7605 final TaskRecord task; 7606 synchronized (this) { 7607 final ActivityRecord r = ActivityRecord.forToken(token); 7608 if (r == null) { 7609 return; 7610 } 7611 task = r.task; 7612 } 7613 if (task != null) { 7614 startLockTaskMode(task); 7615 } 7616 } finally { 7617 Binder.restoreCallingIdentity(ident); 7618 } 7619 } 7620 7621 @Override 7622 public void stopLockTaskMode() { 7623// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7624// "stopLockTaskMode()"); 7625 synchronized (this) { 7626 mStackSupervisor.setLockTaskModeLocked(null); 7627 } 7628 } 7629 7630 @Override 7631 public boolean isInLockTaskMode() { 7632 synchronized (this) { 7633 return mStackSupervisor.isInLockTaskMode(); 7634 } 7635 } 7636 7637 // ========================================================= 7638 // THUMBNAILS 7639 // ========================================================= 7640 7641 public void reportThumbnail(IBinder token, 7642 Bitmap thumbnail, CharSequence description) { 7643 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7644 final long origId = Binder.clearCallingIdentity(); 7645 sendPendingThumbnail(null, token, thumbnail, description, true); 7646 Binder.restoreCallingIdentity(origId); 7647 } 7648 7649 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7650 Bitmap thumbnail, CharSequence description, boolean always) { 7651 TaskRecord task; 7652 ArrayList<PendingThumbnailsRecord> receivers = null; 7653 7654 //System.out.println("Send pending thumbnail: " + r); 7655 7656 synchronized(this) { 7657 if (r == null) { 7658 r = ActivityRecord.isInStackLocked(token); 7659 if (r == null) { 7660 return; 7661 } 7662 } 7663 if (thumbnail == null && r.thumbHolder != null) { 7664 thumbnail = r.thumbHolder.lastThumbnail; 7665 description = r.thumbHolder.lastDescription; 7666 } 7667 if (thumbnail == null && !always) { 7668 // If there is no thumbnail, and this entry is not actually 7669 // going away, then abort for now and pick up the next 7670 // thumbnail we get. 7671 return; 7672 } 7673 task = r.task; 7674 7675 int N = mPendingThumbnails.size(); 7676 int i=0; 7677 while (i<N) { 7678 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7679 //System.out.println("Looking in " + pr.pendingRecords); 7680 if (pr.pendingRecords.remove(r)) { 7681 if (receivers == null) { 7682 receivers = new ArrayList<PendingThumbnailsRecord>(); 7683 } 7684 receivers.add(pr); 7685 if (pr.pendingRecords.size() == 0) { 7686 pr.finished = true; 7687 mPendingThumbnails.remove(i); 7688 N--; 7689 continue; 7690 } 7691 } 7692 i++; 7693 } 7694 } 7695 7696 if (receivers != null) { 7697 final int N = receivers.size(); 7698 for (int i=0; i<N; i++) { 7699 try { 7700 PendingThumbnailsRecord pr = receivers.get(i); 7701 pr.receiver.newThumbnail( 7702 task != null ? task.taskId : -1, thumbnail, description); 7703 if (pr.finished) { 7704 pr.receiver.finished(); 7705 } 7706 } catch (Exception e) { 7707 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7708 } 7709 } 7710 } 7711 } 7712 7713 // ========================================================= 7714 // CONTENT PROVIDERS 7715 // ========================================================= 7716 7717 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7718 List<ProviderInfo> providers = null; 7719 try { 7720 providers = AppGlobals.getPackageManager(). 7721 queryContentProviders(app.processName, app.uid, 7722 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7723 } catch (RemoteException ex) { 7724 } 7725 if (DEBUG_MU) 7726 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7727 int userId = app.userId; 7728 if (providers != null) { 7729 int N = providers.size(); 7730 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7731 for (int i=0; i<N; i++) { 7732 ProviderInfo cpi = 7733 (ProviderInfo)providers.get(i); 7734 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7735 cpi.name, cpi.flags); 7736 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7737 // This is a singleton provider, but a user besides the 7738 // default user is asking to initialize a process it runs 7739 // in... well, no, it doesn't actually run in this process, 7740 // it runs in the process of the default user. Get rid of it. 7741 providers.remove(i); 7742 N--; 7743 i--; 7744 continue; 7745 } 7746 7747 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7748 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7749 if (cpr == null) { 7750 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7751 mProviderMap.putProviderByClass(comp, cpr); 7752 } 7753 if (DEBUG_MU) 7754 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7755 app.pubProviders.put(cpi.name, cpr); 7756 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7757 // Don't add this if it is a platform component that is marked 7758 // to run in multiple processes, because this is actually 7759 // part of the framework so doesn't make sense to track as a 7760 // separate apk in the process. 7761 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7762 } 7763 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7764 } 7765 } 7766 return providers; 7767 } 7768 7769 /** 7770 * Check if {@link ProcessRecord} has a possible chance at accessing the 7771 * given {@link ProviderInfo}. Final permission checking is always done 7772 * in {@link ContentProvider}. 7773 */ 7774 private final String checkContentProviderPermissionLocked( 7775 ProviderInfo cpi, ProcessRecord r) { 7776 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7777 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7778 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7779 cpi.applicationInfo.uid, cpi.exported) 7780 == PackageManager.PERMISSION_GRANTED) { 7781 return null; 7782 } 7783 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7784 cpi.applicationInfo.uid, cpi.exported) 7785 == PackageManager.PERMISSION_GRANTED) { 7786 return null; 7787 } 7788 7789 PathPermission[] pps = cpi.pathPermissions; 7790 if (pps != null) { 7791 int i = pps.length; 7792 while (i > 0) { 7793 i--; 7794 PathPermission pp = pps[i]; 7795 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7796 cpi.applicationInfo.uid, cpi.exported) 7797 == PackageManager.PERMISSION_GRANTED) { 7798 return null; 7799 } 7800 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7801 cpi.applicationInfo.uid, cpi.exported) 7802 == PackageManager.PERMISSION_GRANTED) { 7803 return null; 7804 } 7805 } 7806 } 7807 7808 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7809 if (perms != null) { 7810 for (GrantUri uri : perms.keySet()) { 7811 if (uri.uri.getAuthority().equals(cpi.authority)) { 7812 return null; 7813 } 7814 } 7815 } 7816 7817 String msg; 7818 if (!cpi.exported) { 7819 msg = "Permission Denial: opening provider " + cpi.name 7820 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7821 + ", uid=" + callingUid + ") that is not exported from uid " 7822 + cpi.applicationInfo.uid; 7823 } else { 7824 msg = "Permission Denial: opening provider " + cpi.name 7825 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7826 + ", uid=" + callingUid + ") requires " 7827 + cpi.readPermission + " or " + cpi.writePermission; 7828 } 7829 Slog.w(TAG, msg); 7830 return msg; 7831 } 7832 7833 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7834 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7835 if (r != null) { 7836 for (int i=0; i<r.conProviders.size(); i++) { 7837 ContentProviderConnection conn = r.conProviders.get(i); 7838 if (conn.provider == cpr) { 7839 if (DEBUG_PROVIDER) Slog.v(TAG, 7840 "Adding provider requested by " 7841 + r.processName + " from process " 7842 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7843 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7844 if (stable) { 7845 conn.stableCount++; 7846 conn.numStableIncs++; 7847 } else { 7848 conn.unstableCount++; 7849 conn.numUnstableIncs++; 7850 } 7851 return conn; 7852 } 7853 } 7854 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7855 if (stable) { 7856 conn.stableCount = 1; 7857 conn.numStableIncs = 1; 7858 } else { 7859 conn.unstableCount = 1; 7860 conn.numUnstableIncs = 1; 7861 } 7862 cpr.connections.add(conn); 7863 r.conProviders.add(conn); 7864 return conn; 7865 } 7866 cpr.addExternalProcessHandleLocked(externalProcessToken); 7867 return null; 7868 } 7869 7870 boolean decProviderCountLocked(ContentProviderConnection conn, 7871 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7872 if (conn != null) { 7873 cpr = conn.provider; 7874 if (DEBUG_PROVIDER) Slog.v(TAG, 7875 "Removing provider requested by " 7876 + conn.client.processName + " from process " 7877 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7878 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7879 if (stable) { 7880 conn.stableCount--; 7881 } else { 7882 conn.unstableCount--; 7883 } 7884 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7885 cpr.connections.remove(conn); 7886 conn.client.conProviders.remove(conn); 7887 return true; 7888 } 7889 return false; 7890 } 7891 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7892 return false; 7893 } 7894 7895 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7896 String name, IBinder token, boolean stable, int userId) { 7897 ContentProviderRecord cpr; 7898 ContentProviderConnection conn = null; 7899 ProviderInfo cpi = null; 7900 7901 synchronized(this) { 7902 ProcessRecord r = null; 7903 if (caller != null) { 7904 r = getRecordForAppLocked(caller); 7905 if (r == null) { 7906 throw new SecurityException( 7907 "Unable to find app for caller " + caller 7908 + " (pid=" + Binder.getCallingPid() 7909 + ") when getting content provider " + name); 7910 } 7911 } 7912 7913 // First check if this content provider has been published... 7914 cpr = mProviderMap.getProviderByName(name, userId); 7915 boolean providerRunning = cpr != null; 7916 if (providerRunning) { 7917 cpi = cpr.info; 7918 String msg; 7919 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7920 throw new SecurityException(msg); 7921 } 7922 7923 if (r != null && cpr.canRunHere(r)) { 7924 // This provider has been published or is in the process 7925 // of being published... but it is also allowed to run 7926 // in the caller's process, so don't make a connection 7927 // and just let the caller instantiate its own instance. 7928 ContentProviderHolder holder = cpr.newHolder(null); 7929 // don't give caller the provider object, it needs 7930 // to make its own. 7931 holder.provider = null; 7932 return holder; 7933 } 7934 7935 final long origId = Binder.clearCallingIdentity(); 7936 7937 // In this case the provider instance already exists, so we can 7938 // return it right away. 7939 conn = incProviderCountLocked(r, cpr, token, stable); 7940 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7941 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7942 // If this is a perceptible app accessing the provider, 7943 // make sure to count it as being accessed and thus 7944 // back up on the LRU list. This is good because 7945 // content providers are often expensive to start. 7946 updateLruProcessLocked(cpr.proc, false, null); 7947 } 7948 } 7949 7950 if (cpr.proc != null) { 7951 if (false) { 7952 if (cpr.name.flattenToShortString().equals( 7953 "com.android.providers.calendar/.CalendarProvider2")) { 7954 Slog.v(TAG, "****************** KILLING " 7955 + cpr.name.flattenToShortString()); 7956 Process.killProcess(cpr.proc.pid); 7957 } 7958 } 7959 boolean success = updateOomAdjLocked(cpr.proc); 7960 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7961 // NOTE: there is still a race here where a signal could be 7962 // pending on the process even though we managed to update its 7963 // adj level. Not sure what to do about this, but at least 7964 // the race is now smaller. 7965 if (!success) { 7966 // Uh oh... it looks like the provider's process 7967 // has been killed on us. We need to wait for a new 7968 // process to be started, and make sure its death 7969 // doesn't kill our process. 7970 Slog.i(TAG, 7971 "Existing provider " + cpr.name.flattenToShortString() 7972 + " is crashing; detaching " + r); 7973 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7974 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7975 if (!lastRef) { 7976 // This wasn't the last ref our process had on 7977 // the provider... we have now been killed, bail. 7978 return null; 7979 } 7980 providerRunning = false; 7981 conn = null; 7982 } 7983 } 7984 7985 Binder.restoreCallingIdentity(origId); 7986 } 7987 7988 boolean singleton; 7989 if (!providerRunning) { 7990 try { 7991 cpi = AppGlobals.getPackageManager(). 7992 resolveContentProvider(name, 7993 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7994 } catch (RemoteException ex) { 7995 } 7996 if (cpi == null) { 7997 return null; 7998 } 7999 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 8000 cpi.name, cpi.flags); 8001 if (singleton) { 8002 userId = 0; 8003 } 8004 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 8005 8006 String msg; 8007 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 8008 throw new SecurityException(msg); 8009 } 8010 8011 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 8012 && !cpi.processName.equals("system")) { 8013 // If this content provider does not run in the system 8014 // process, and the system is not yet ready to run other 8015 // processes, then fail fast instead of hanging. 8016 throw new IllegalArgumentException( 8017 "Attempt to launch content provider before system ready"); 8018 } 8019 8020 // Make sure that the user who owns this provider is started. If not, 8021 // we don't want to allow it to run. 8022 if (mStartedUsers.get(userId) == null) { 8023 Slog.w(TAG, "Unable to launch app " 8024 + cpi.applicationInfo.packageName + "/" 8025 + cpi.applicationInfo.uid + " for provider " 8026 + name + ": user " + userId + " is stopped"); 8027 return null; 8028 } 8029 8030 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 8031 cpr = mProviderMap.getProviderByClass(comp, userId); 8032 final boolean firstClass = cpr == null; 8033 if (firstClass) { 8034 try { 8035 ApplicationInfo ai = 8036 AppGlobals.getPackageManager(). 8037 getApplicationInfo( 8038 cpi.applicationInfo.packageName, 8039 STOCK_PM_FLAGS, userId); 8040 if (ai == null) { 8041 Slog.w(TAG, "No package info for content provider " 8042 + cpi.name); 8043 return null; 8044 } 8045 ai = getAppInfoForUser(ai, userId); 8046 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 8047 } catch (RemoteException ex) { 8048 // pm is in same process, this will never happen. 8049 } 8050 } 8051 8052 if (r != null && cpr.canRunHere(r)) { 8053 // If this is a multiprocess provider, then just return its 8054 // info and allow the caller to instantiate it. Only do 8055 // this if the provider is the same user as the caller's 8056 // process, or can run as root (so can be in any process). 8057 return cpr.newHolder(null); 8058 } 8059 8060 if (DEBUG_PROVIDER) { 8061 RuntimeException e = new RuntimeException("here"); 8062 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 8063 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 8064 } 8065 8066 // This is single process, and our app is now connecting to it. 8067 // See if we are already in the process of launching this 8068 // provider. 8069 final int N = mLaunchingProviders.size(); 8070 int i; 8071 for (i=0; i<N; i++) { 8072 if (mLaunchingProviders.get(i) == cpr) { 8073 break; 8074 } 8075 } 8076 8077 // If the provider is not already being launched, then get it 8078 // started. 8079 if (i >= N) { 8080 final long origId = Binder.clearCallingIdentity(); 8081 8082 try { 8083 // Content provider is now in use, its package can't be stopped. 8084 try { 8085 AppGlobals.getPackageManager().setPackageStoppedState( 8086 cpr.appInfo.packageName, false, userId); 8087 } catch (RemoteException e) { 8088 } catch (IllegalArgumentException e) { 8089 Slog.w(TAG, "Failed trying to unstop package " 8090 + cpr.appInfo.packageName + ": " + e); 8091 } 8092 8093 // Use existing process if already started 8094 ProcessRecord proc = getProcessRecordLocked( 8095 cpi.processName, cpr.appInfo.uid, false); 8096 if (proc != null && proc.thread != null) { 8097 if (DEBUG_PROVIDER) { 8098 Slog.d(TAG, "Installing in existing process " + proc); 8099 } 8100 proc.pubProviders.put(cpi.name, cpr); 8101 try { 8102 proc.thread.scheduleInstallProvider(cpi); 8103 } catch (RemoteException e) { 8104 } 8105 } else { 8106 proc = startProcessLocked(cpi.processName, 8107 cpr.appInfo, false, 0, "content provider", 8108 new ComponentName(cpi.applicationInfo.packageName, 8109 cpi.name), false, false, false); 8110 if (proc == null) { 8111 Slog.w(TAG, "Unable to launch app " 8112 + cpi.applicationInfo.packageName + "/" 8113 + cpi.applicationInfo.uid + " for provider " 8114 + name + ": process is bad"); 8115 return null; 8116 } 8117 } 8118 cpr.launchingApp = proc; 8119 mLaunchingProviders.add(cpr); 8120 } finally { 8121 Binder.restoreCallingIdentity(origId); 8122 } 8123 } 8124 8125 // Make sure the provider is published (the same provider class 8126 // may be published under multiple names). 8127 if (firstClass) { 8128 mProviderMap.putProviderByClass(comp, cpr); 8129 } 8130 8131 mProviderMap.putProviderByName(name, cpr); 8132 conn = incProviderCountLocked(r, cpr, token, stable); 8133 if (conn != null) { 8134 conn.waiting = true; 8135 } 8136 } 8137 } 8138 8139 // Wait for the provider to be published... 8140 synchronized (cpr) { 8141 while (cpr.provider == null) { 8142 if (cpr.launchingApp == null) { 8143 Slog.w(TAG, "Unable to launch app " 8144 + cpi.applicationInfo.packageName + "/" 8145 + cpi.applicationInfo.uid + " for provider " 8146 + name + ": launching app became null"); 8147 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8148 UserHandle.getUserId(cpi.applicationInfo.uid), 8149 cpi.applicationInfo.packageName, 8150 cpi.applicationInfo.uid, name); 8151 return null; 8152 } 8153 try { 8154 if (DEBUG_MU) { 8155 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8156 + cpr.launchingApp); 8157 } 8158 if (conn != null) { 8159 conn.waiting = true; 8160 } 8161 cpr.wait(); 8162 } catch (InterruptedException ex) { 8163 } finally { 8164 if (conn != null) { 8165 conn.waiting = false; 8166 } 8167 } 8168 } 8169 } 8170 return cpr != null ? cpr.newHolder(conn) : null; 8171 } 8172 8173 public final ContentProviderHolder getContentProvider( 8174 IApplicationThread caller, String name, int userId, boolean stable) { 8175 enforceNotIsolatedCaller("getContentProvider"); 8176 if (caller == null) { 8177 String msg = "null IApplicationThread when getting content provider " 8178 + name; 8179 Slog.w(TAG, msg); 8180 throw new SecurityException(msg); 8181 } 8182 8183 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8184 false, true, "getContentProvider", null); 8185 return getContentProviderImpl(caller, name, null, stable, userId); 8186 } 8187 8188 public ContentProviderHolder getContentProviderExternal( 8189 String name, int userId, IBinder token) { 8190 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8191 "Do not have permission in call getContentProviderExternal()"); 8192 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8193 false, true, "getContentProvider", null); 8194 return getContentProviderExternalUnchecked(name, token, userId); 8195 } 8196 8197 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8198 IBinder token, int userId) { 8199 return getContentProviderImpl(null, name, token, true, userId); 8200 } 8201 8202 /** 8203 * Drop a content provider from a ProcessRecord's bookkeeping 8204 */ 8205 public void removeContentProvider(IBinder connection, boolean stable) { 8206 enforceNotIsolatedCaller("removeContentProvider"); 8207 long ident = Binder.clearCallingIdentity(); 8208 try { 8209 synchronized (this) { 8210 ContentProviderConnection conn; 8211 try { 8212 conn = (ContentProviderConnection)connection; 8213 } catch (ClassCastException e) { 8214 String msg ="removeContentProvider: " + connection 8215 + " not a ContentProviderConnection"; 8216 Slog.w(TAG, msg); 8217 throw new IllegalArgumentException(msg); 8218 } 8219 if (conn == null) { 8220 throw new NullPointerException("connection is null"); 8221 } 8222 if (decProviderCountLocked(conn, null, null, stable)) { 8223 updateOomAdjLocked(); 8224 } 8225 } 8226 } finally { 8227 Binder.restoreCallingIdentity(ident); 8228 } 8229 } 8230 8231 public void removeContentProviderExternal(String name, IBinder token) { 8232 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8233 "Do not have permission in call removeContentProviderExternal()"); 8234 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8235 } 8236 8237 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8238 synchronized (this) { 8239 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8240 if(cpr == null) { 8241 //remove from mProvidersByClass 8242 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8243 return; 8244 } 8245 8246 //update content provider record entry info 8247 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8248 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8249 if (localCpr.hasExternalProcessHandles()) { 8250 if (localCpr.removeExternalProcessHandleLocked(token)) { 8251 updateOomAdjLocked(); 8252 } else { 8253 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8254 + " with no external reference for token: " 8255 + token + "."); 8256 } 8257 } else { 8258 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8259 + " with no external references."); 8260 } 8261 } 8262 } 8263 8264 public final void publishContentProviders(IApplicationThread caller, 8265 List<ContentProviderHolder> providers) { 8266 if (providers == null) { 8267 return; 8268 } 8269 8270 enforceNotIsolatedCaller("publishContentProviders"); 8271 synchronized (this) { 8272 final ProcessRecord r = getRecordForAppLocked(caller); 8273 if (DEBUG_MU) 8274 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8275 if (r == null) { 8276 throw new SecurityException( 8277 "Unable to find app for caller " + caller 8278 + " (pid=" + Binder.getCallingPid() 8279 + ") when publishing content providers"); 8280 } 8281 8282 final long origId = Binder.clearCallingIdentity(); 8283 8284 final int N = providers.size(); 8285 for (int i=0; i<N; i++) { 8286 ContentProviderHolder src = providers.get(i); 8287 if (src == null || src.info == null || src.provider == null) { 8288 continue; 8289 } 8290 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8291 if (DEBUG_MU) 8292 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8293 if (dst != null) { 8294 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8295 mProviderMap.putProviderByClass(comp, dst); 8296 String names[] = dst.info.authority.split(";"); 8297 for (int j = 0; j < names.length; j++) { 8298 mProviderMap.putProviderByName(names[j], dst); 8299 } 8300 8301 int NL = mLaunchingProviders.size(); 8302 int j; 8303 for (j=0; j<NL; j++) { 8304 if (mLaunchingProviders.get(j) == dst) { 8305 mLaunchingProviders.remove(j); 8306 j--; 8307 NL--; 8308 } 8309 } 8310 synchronized (dst) { 8311 dst.provider = src.provider; 8312 dst.proc = r; 8313 dst.notifyAll(); 8314 } 8315 updateOomAdjLocked(r); 8316 } 8317 } 8318 8319 Binder.restoreCallingIdentity(origId); 8320 } 8321 } 8322 8323 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 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 synchronized (this) { 8338 if (stable > 0) { 8339 conn.numStableIncs += stable; 8340 } 8341 stable = conn.stableCount + stable; 8342 if (stable < 0) { 8343 throw new IllegalStateException("stableCount < 0: " + stable); 8344 } 8345 8346 if (unstable > 0) { 8347 conn.numUnstableIncs += unstable; 8348 } 8349 unstable = conn.unstableCount + unstable; 8350 if (unstable < 0) { 8351 throw new IllegalStateException("unstableCount < 0: " + unstable); 8352 } 8353 8354 if ((stable+unstable) <= 0) { 8355 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8356 + stable + " unstable=" + unstable); 8357 } 8358 conn.stableCount = stable; 8359 conn.unstableCount = unstable; 8360 return !conn.dead; 8361 } 8362 } 8363 8364 public void unstableProviderDied(IBinder connection) { 8365 ContentProviderConnection conn; 8366 try { 8367 conn = (ContentProviderConnection)connection; 8368 } catch (ClassCastException e) { 8369 String msg ="refContentProvider: " + connection 8370 + " not a ContentProviderConnection"; 8371 Slog.w(TAG, msg); 8372 throw new IllegalArgumentException(msg); 8373 } 8374 if (conn == null) { 8375 throw new NullPointerException("connection is null"); 8376 } 8377 8378 // Safely retrieve the content provider associated with the connection. 8379 IContentProvider provider; 8380 synchronized (this) { 8381 provider = conn.provider.provider; 8382 } 8383 8384 if (provider == null) { 8385 // Um, yeah, we're way ahead of you. 8386 return; 8387 } 8388 8389 // Make sure the caller is being honest with us. 8390 if (provider.asBinder().pingBinder()) { 8391 // Er, no, still looks good to us. 8392 synchronized (this) { 8393 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8394 + " says " + conn + " died, but we don't agree"); 8395 return; 8396 } 8397 } 8398 8399 // Well look at that! It's dead! 8400 synchronized (this) { 8401 if (conn.provider.provider != provider) { 8402 // But something changed... good enough. 8403 return; 8404 } 8405 8406 ProcessRecord proc = conn.provider.proc; 8407 if (proc == null || proc.thread == null) { 8408 // Seems like the process is already cleaned up. 8409 return; 8410 } 8411 8412 // As far as we're concerned, this is just like receiving a 8413 // death notification... just a bit prematurely. 8414 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8415 + ") early provider death"); 8416 final long ident = Binder.clearCallingIdentity(); 8417 try { 8418 appDiedLocked(proc, proc.pid, proc.thread); 8419 } finally { 8420 Binder.restoreCallingIdentity(ident); 8421 } 8422 } 8423 } 8424 8425 @Override 8426 public void appNotRespondingViaProvider(IBinder connection) { 8427 enforceCallingPermission( 8428 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8429 8430 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8431 if (conn == null) { 8432 Slog.w(TAG, "ContentProviderConnection is null"); 8433 return; 8434 } 8435 8436 final ProcessRecord host = conn.provider.proc; 8437 if (host == null) { 8438 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8439 return; 8440 } 8441 8442 final long token = Binder.clearCallingIdentity(); 8443 try { 8444 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8445 } finally { 8446 Binder.restoreCallingIdentity(token); 8447 } 8448 } 8449 8450 public final void installSystemProviders() { 8451 List<ProviderInfo> providers; 8452 synchronized (this) { 8453 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8454 providers = generateApplicationProvidersLocked(app); 8455 if (providers != null) { 8456 for (int i=providers.size()-1; i>=0; i--) { 8457 ProviderInfo pi = (ProviderInfo)providers.get(i); 8458 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8459 Slog.w(TAG, "Not installing system proc provider " + pi.name 8460 + ": not system .apk"); 8461 providers.remove(i); 8462 } 8463 } 8464 } 8465 } 8466 if (providers != null) { 8467 mSystemThread.installSystemProviders(providers); 8468 } 8469 8470 mCoreSettingsObserver = new CoreSettingsObserver(this); 8471 8472 mUsageStatsService.monitorPackages(); 8473 } 8474 8475 /** 8476 * Allows app to retrieve the MIME type of a URI without having permission 8477 * to access its content provider. 8478 * 8479 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8480 * 8481 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8482 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8483 */ 8484 public String getProviderMimeType(Uri uri, int userId) { 8485 enforceNotIsolatedCaller("getProviderMimeType"); 8486 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8487 userId, false, true, "getProviderMimeType", null); 8488 final String name = uri.getAuthority(); 8489 final long ident = Binder.clearCallingIdentity(); 8490 ContentProviderHolder holder = null; 8491 8492 try { 8493 holder = getContentProviderExternalUnchecked(name, null, userId); 8494 if (holder != null) { 8495 return holder.provider.getType(uri); 8496 } 8497 } catch (RemoteException e) { 8498 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8499 return null; 8500 } finally { 8501 if (holder != null) { 8502 removeContentProviderExternalUnchecked(name, null, userId); 8503 } 8504 Binder.restoreCallingIdentity(ident); 8505 } 8506 8507 return null; 8508 } 8509 8510 // ========================================================= 8511 // GLOBAL MANAGEMENT 8512 // ========================================================= 8513 8514 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8515 boolean isolated) { 8516 String proc = customProcess != null ? customProcess : info.processName; 8517 BatteryStatsImpl.Uid.Proc ps = null; 8518 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8519 int uid = info.uid; 8520 if (isolated) { 8521 int userId = UserHandle.getUserId(uid); 8522 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8523 while (true) { 8524 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8525 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8526 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8527 } 8528 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8529 mNextIsolatedProcessUid++; 8530 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8531 // No process for this uid, use it. 8532 break; 8533 } 8534 stepsLeft--; 8535 if (stepsLeft <= 0) { 8536 return null; 8537 } 8538 } 8539 } 8540 return new ProcessRecord(stats, info, proc, uid); 8541 } 8542 8543 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8544 ProcessRecord app; 8545 if (!isolated) { 8546 app = getProcessRecordLocked(info.processName, info.uid, true); 8547 } else { 8548 app = null; 8549 } 8550 8551 if (app == null) { 8552 app = newProcessRecordLocked(info, null, isolated); 8553 mProcessNames.put(info.processName, app.uid, app); 8554 if (isolated) { 8555 mIsolatedProcesses.put(app.uid, app); 8556 } 8557 updateLruProcessLocked(app, false, null); 8558 updateOomAdjLocked(); 8559 } 8560 8561 // This package really, really can not be stopped. 8562 try { 8563 AppGlobals.getPackageManager().setPackageStoppedState( 8564 info.packageName, false, UserHandle.getUserId(app.uid)); 8565 } catch (RemoteException e) { 8566 } catch (IllegalArgumentException e) { 8567 Slog.w(TAG, "Failed trying to unstop package " 8568 + info.packageName + ": " + e); 8569 } 8570 8571 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8572 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8573 app.persistent = true; 8574 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8575 } 8576 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8577 mPersistentStartingProcesses.add(app); 8578 startProcessLocked(app, "added application", app.processName); 8579 } 8580 8581 return app; 8582 } 8583 8584 public void unhandledBack() { 8585 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8586 "unhandledBack()"); 8587 8588 synchronized(this) { 8589 final long origId = Binder.clearCallingIdentity(); 8590 try { 8591 getFocusedStack().unhandledBackLocked(); 8592 } finally { 8593 Binder.restoreCallingIdentity(origId); 8594 } 8595 } 8596 } 8597 8598 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8599 enforceNotIsolatedCaller("openContentUri"); 8600 final int userId = UserHandle.getCallingUserId(); 8601 String name = uri.getAuthority(); 8602 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8603 ParcelFileDescriptor pfd = null; 8604 if (cph != null) { 8605 // We record the binder invoker's uid in thread-local storage before 8606 // going to the content provider to open the file. Later, in the code 8607 // that handles all permissions checks, we look for this uid and use 8608 // that rather than the Activity Manager's own uid. The effect is that 8609 // we do the check against the caller's permissions even though it looks 8610 // to the content provider like the Activity Manager itself is making 8611 // the request. 8612 sCallerIdentity.set(new Identity( 8613 Binder.getCallingPid(), Binder.getCallingUid())); 8614 try { 8615 pfd = cph.provider.openFile(null, uri, "r", null); 8616 } catch (FileNotFoundException e) { 8617 // do nothing; pfd will be returned null 8618 } finally { 8619 // Ensure that whatever happens, we clean up the identity state 8620 sCallerIdentity.remove(); 8621 } 8622 8623 // We've got the fd now, so we're done with the provider. 8624 removeContentProviderExternalUnchecked(name, null, userId); 8625 } else { 8626 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8627 } 8628 return pfd; 8629 } 8630 8631 // Actually is sleeping or shutting down or whatever else in the future 8632 // is an inactive state. 8633 public boolean isSleepingOrShuttingDown() { 8634 return mSleeping || mShuttingDown; 8635 } 8636 8637 public boolean isSleeping() { 8638 return mSleeping; 8639 } 8640 8641 void goingToSleep() { 8642 synchronized(this) { 8643 mWentToSleep = true; 8644 updateEventDispatchingLocked(); 8645 goToSleepIfNeededLocked(); 8646 } 8647 } 8648 8649 void finishRunningVoiceLocked() { 8650 if (mRunningVoice) { 8651 mRunningVoice = false; 8652 goToSleepIfNeededLocked(); 8653 } 8654 } 8655 8656 void goToSleepIfNeededLocked() { 8657 if (mWentToSleep && !mRunningVoice) { 8658 if (!mSleeping) { 8659 mSleeping = true; 8660 mStackSupervisor.goingToSleepLocked(); 8661 8662 // Initialize the wake times of all processes. 8663 checkExcessivePowerUsageLocked(false); 8664 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8665 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8666 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8667 } 8668 } 8669 } 8670 8671 @Override 8672 public boolean shutdown(int timeout) { 8673 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8674 != PackageManager.PERMISSION_GRANTED) { 8675 throw new SecurityException("Requires permission " 8676 + android.Manifest.permission.SHUTDOWN); 8677 } 8678 8679 boolean timedout = false; 8680 8681 synchronized(this) { 8682 mShuttingDown = true; 8683 updateEventDispatchingLocked(); 8684 timedout = mStackSupervisor.shutdownLocked(timeout); 8685 } 8686 8687 mAppOpsService.shutdown(); 8688 mUsageStatsService.shutdown(); 8689 mBatteryStatsService.shutdown(); 8690 synchronized (this) { 8691 mProcessStats.shutdownLocked(); 8692 } 8693 8694 return timedout; 8695 } 8696 8697 public final void activitySlept(IBinder token) { 8698 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8699 8700 final long origId = Binder.clearCallingIdentity(); 8701 8702 synchronized (this) { 8703 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8704 if (r != null) { 8705 mStackSupervisor.activitySleptLocked(r); 8706 } 8707 } 8708 8709 Binder.restoreCallingIdentity(origId); 8710 } 8711 8712 void logLockScreen(String msg) { 8713 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8714 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8715 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8716 mStackSupervisor.mDismissKeyguardOnNextActivity); 8717 } 8718 8719 private void comeOutOfSleepIfNeededLocked() { 8720 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8721 if (mSleeping) { 8722 mSleeping = false; 8723 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8724 } 8725 } 8726 } 8727 8728 void wakingUp() { 8729 synchronized(this) { 8730 mWentToSleep = false; 8731 updateEventDispatchingLocked(); 8732 comeOutOfSleepIfNeededLocked(); 8733 } 8734 } 8735 8736 void startRunningVoiceLocked() { 8737 if (!mRunningVoice) { 8738 mRunningVoice = true; 8739 comeOutOfSleepIfNeededLocked(); 8740 } 8741 } 8742 8743 private void updateEventDispatchingLocked() { 8744 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8745 } 8746 8747 public void setLockScreenShown(boolean shown) { 8748 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8749 != PackageManager.PERMISSION_GRANTED) { 8750 throw new SecurityException("Requires permission " 8751 + android.Manifest.permission.DEVICE_POWER); 8752 } 8753 8754 synchronized(this) { 8755 long ident = Binder.clearCallingIdentity(); 8756 try { 8757 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8758 mLockScreenShown = shown; 8759 comeOutOfSleepIfNeededLocked(); 8760 } finally { 8761 Binder.restoreCallingIdentity(ident); 8762 } 8763 } 8764 } 8765 8766 public void stopAppSwitches() { 8767 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8768 != PackageManager.PERMISSION_GRANTED) { 8769 throw new SecurityException("Requires permission " 8770 + android.Manifest.permission.STOP_APP_SWITCHES); 8771 } 8772 8773 synchronized(this) { 8774 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8775 + APP_SWITCH_DELAY_TIME; 8776 mDidAppSwitch = false; 8777 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8778 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8779 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8780 } 8781 } 8782 8783 public void resumeAppSwitches() { 8784 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8785 != PackageManager.PERMISSION_GRANTED) { 8786 throw new SecurityException("Requires permission " 8787 + android.Manifest.permission.STOP_APP_SWITCHES); 8788 } 8789 8790 synchronized(this) { 8791 // Note that we don't execute any pending app switches... we will 8792 // let those wait until either the timeout, or the next start 8793 // activity request. 8794 mAppSwitchesAllowedTime = 0; 8795 } 8796 } 8797 8798 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8799 String name) { 8800 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8801 return true; 8802 } 8803 8804 final int perm = checkComponentPermission( 8805 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8806 callingUid, -1, true); 8807 if (perm == PackageManager.PERMISSION_GRANTED) { 8808 return true; 8809 } 8810 8811 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8812 return false; 8813 } 8814 8815 public void setDebugApp(String packageName, boolean waitForDebugger, 8816 boolean persistent) { 8817 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8818 "setDebugApp()"); 8819 8820 long ident = Binder.clearCallingIdentity(); 8821 try { 8822 // Note that this is not really thread safe if there are multiple 8823 // callers into it at the same time, but that's not a situation we 8824 // care about. 8825 if (persistent) { 8826 final ContentResolver resolver = mContext.getContentResolver(); 8827 Settings.Global.putString( 8828 resolver, Settings.Global.DEBUG_APP, 8829 packageName); 8830 Settings.Global.putInt( 8831 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8832 waitForDebugger ? 1 : 0); 8833 } 8834 8835 synchronized (this) { 8836 if (!persistent) { 8837 mOrigDebugApp = mDebugApp; 8838 mOrigWaitForDebugger = mWaitForDebugger; 8839 } 8840 mDebugApp = packageName; 8841 mWaitForDebugger = waitForDebugger; 8842 mDebugTransient = !persistent; 8843 if (packageName != null) { 8844 forceStopPackageLocked(packageName, -1, false, false, true, true, 8845 false, UserHandle.USER_ALL, "set debug app"); 8846 } 8847 } 8848 } finally { 8849 Binder.restoreCallingIdentity(ident); 8850 } 8851 } 8852 8853 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8854 synchronized (this) { 8855 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8856 if (!isDebuggable) { 8857 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8858 throw new SecurityException("Process not debuggable: " + app.packageName); 8859 } 8860 } 8861 8862 mOpenGlTraceApp = processName; 8863 } 8864 } 8865 8866 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8867 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8868 synchronized (this) { 8869 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8870 if (!isDebuggable) { 8871 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8872 throw new SecurityException("Process not debuggable: " + app.packageName); 8873 } 8874 } 8875 mProfileApp = processName; 8876 mProfileFile = profileFile; 8877 if (mProfileFd != null) { 8878 try { 8879 mProfileFd.close(); 8880 } catch (IOException e) { 8881 } 8882 mProfileFd = null; 8883 } 8884 mProfileFd = profileFd; 8885 mProfileType = 0; 8886 mAutoStopProfiler = autoStopProfiler; 8887 } 8888 } 8889 8890 @Override 8891 public void setAlwaysFinish(boolean enabled) { 8892 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8893 "setAlwaysFinish()"); 8894 8895 Settings.Global.putInt( 8896 mContext.getContentResolver(), 8897 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8898 8899 synchronized (this) { 8900 mAlwaysFinishActivities = enabled; 8901 } 8902 } 8903 8904 @Override 8905 public void setActivityController(IActivityController controller) { 8906 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8907 "setActivityController()"); 8908 synchronized (this) { 8909 mController = controller; 8910 Watchdog.getInstance().setActivityController(controller); 8911 } 8912 } 8913 8914 @Override 8915 public void setUserIsMonkey(boolean userIsMonkey) { 8916 synchronized (this) { 8917 synchronized (mPidsSelfLocked) { 8918 final int callingPid = Binder.getCallingPid(); 8919 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8920 if (precessRecord == null) { 8921 throw new SecurityException("Unknown process: " + callingPid); 8922 } 8923 if (precessRecord.instrumentationUiAutomationConnection == null) { 8924 throw new SecurityException("Only an instrumentation process " 8925 + "with a UiAutomation can call setUserIsMonkey"); 8926 } 8927 } 8928 mUserIsMonkey = userIsMonkey; 8929 } 8930 } 8931 8932 @Override 8933 public boolean isUserAMonkey() { 8934 synchronized (this) { 8935 // If there is a controller also implies the user is a monkey. 8936 return (mUserIsMonkey || mController != null); 8937 } 8938 } 8939 8940 public void requestBugReport() { 8941 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8942 SystemProperties.set("ctl.start", "bugreport"); 8943 } 8944 8945 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8946 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8947 } 8948 8949 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8950 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8951 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8952 } 8953 return KEY_DISPATCHING_TIMEOUT; 8954 } 8955 8956 @Override 8957 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8958 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8959 != PackageManager.PERMISSION_GRANTED) { 8960 throw new SecurityException("Requires permission " 8961 + android.Manifest.permission.FILTER_EVENTS); 8962 } 8963 ProcessRecord proc; 8964 long timeout; 8965 synchronized (this) { 8966 synchronized (mPidsSelfLocked) { 8967 proc = mPidsSelfLocked.get(pid); 8968 } 8969 timeout = getInputDispatchingTimeoutLocked(proc); 8970 } 8971 8972 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8973 return -1; 8974 } 8975 8976 return timeout; 8977 } 8978 8979 /** 8980 * Handle input dispatching timeouts. 8981 * Returns whether input dispatching should be aborted or not. 8982 */ 8983 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8984 final ActivityRecord activity, final ActivityRecord parent, 8985 final boolean aboveSystem, String reason) { 8986 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8987 != PackageManager.PERMISSION_GRANTED) { 8988 throw new SecurityException("Requires permission " 8989 + android.Manifest.permission.FILTER_EVENTS); 8990 } 8991 8992 final String annotation; 8993 if (reason == null) { 8994 annotation = "Input dispatching timed out"; 8995 } else { 8996 annotation = "Input dispatching timed out (" + reason + ")"; 8997 } 8998 8999 if (proc != null) { 9000 synchronized (this) { 9001 if (proc.debugging) { 9002 return false; 9003 } 9004 9005 if (mDidDexOpt) { 9006 // Give more time since we were dexopting. 9007 mDidDexOpt = false; 9008 return false; 9009 } 9010 9011 if (proc.instrumentationClass != null) { 9012 Bundle info = new Bundle(); 9013 info.putString("shortMsg", "keyDispatchingTimedOut"); 9014 info.putString("longMsg", annotation); 9015 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 9016 return true; 9017 } 9018 } 9019 mHandler.post(new Runnable() { 9020 @Override 9021 public void run() { 9022 appNotResponding(proc, activity, parent, aboveSystem, annotation); 9023 } 9024 }); 9025 } 9026 9027 return true; 9028 } 9029 9030 public Bundle getAssistContextExtras(int requestType) { 9031 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 9032 "getAssistContextExtras()"); 9033 PendingAssistExtras pae; 9034 Bundle extras = new Bundle(); 9035 synchronized (this) { 9036 ActivityRecord activity = getFocusedStack().mResumedActivity; 9037 if (activity == null) { 9038 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 9039 return null; 9040 } 9041 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 9042 if (activity.app == null || activity.app.thread == null) { 9043 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 9044 return extras; 9045 } 9046 if (activity.app.pid == Binder.getCallingPid()) { 9047 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 9048 return extras; 9049 } 9050 pae = new PendingAssistExtras(activity); 9051 try { 9052 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 9053 requestType); 9054 mPendingAssistExtras.add(pae); 9055 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 9056 } catch (RemoteException e) { 9057 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 9058 return extras; 9059 } 9060 } 9061 synchronized (pae) { 9062 while (!pae.haveResult) { 9063 try { 9064 pae.wait(); 9065 } catch (InterruptedException e) { 9066 } 9067 } 9068 if (pae.result != null) { 9069 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 9070 } 9071 } 9072 synchronized (this) { 9073 mPendingAssistExtras.remove(pae); 9074 mHandler.removeCallbacks(pae); 9075 } 9076 return extras; 9077 } 9078 9079 public void reportAssistContextExtras(IBinder token, Bundle extras) { 9080 PendingAssistExtras pae = (PendingAssistExtras)token; 9081 synchronized (pae) { 9082 pae.result = extras; 9083 pae.haveResult = true; 9084 pae.notifyAll(); 9085 } 9086 } 9087 9088 public void registerProcessObserver(IProcessObserver observer) { 9089 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 9090 "registerProcessObserver()"); 9091 synchronized (this) { 9092 mProcessObservers.register(observer); 9093 } 9094 } 9095 9096 @Override 9097 public void unregisterProcessObserver(IProcessObserver observer) { 9098 synchronized (this) { 9099 mProcessObservers.unregister(observer); 9100 } 9101 } 9102 9103 @Override 9104 public boolean convertFromTranslucent(IBinder token) { 9105 final long origId = Binder.clearCallingIdentity(); 9106 try { 9107 synchronized (this) { 9108 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9109 if (r == null) { 9110 return false; 9111 } 9112 if (r.changeWindowTranslucency(true)) { 9113 mWindowManager.setAppFullscreen(token, true); 9114 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9115 return true; 9116 } 9117 return false; 9118 } 9119 } finally { 9120 Binder.restoreCallingIdentity(origId); 9121 } 9122 } 9123 9124 @Override 9125 public boolean convertToTranslucent(IBinder token) { 9126 final long origId = Binder.clearCallingIdentity(); 9127 try { 9128 synchronized (this) { 9129 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9130 if (r == null) { 9131 return false; 9132 } 9133 if (r.changeWindowTranslucency(false)) { 9134 r.task.stack.convertToTranslucent(r); 9135 mWindowManager.setAppFullscreen(token, false); 9136 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9137 return true; 9138 } 9139 return false; 9140 } 9141 } finally { 9142 Binder.restoreCallingIdentity(origId); 9143 } 9144 } 9145 9146 @Override 9147 public void setImmersive(IBinder token, boolean immersive) { 9148 synchronized(this) { 9149 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9150 if (r == null) { 9151 throw new IllegalArgumentException(); 9152 } 9153 r.immersive = immersive; 9154 9155 // update associated state if we're frontmost 9156 if (r == mFocusedActivity) { 9157 if (DEBUG_IMMERSIVE) { 9158 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9159 } 9160 applyUpdateLockStateLocked(r); 9161 } 9162 } 9163 } 9164 9165 @Override 9166 public boolean isImmersive(IBinder token) { 9167 synchronized (this) { 9168 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9169 if (r == null) { 9170 throw new IllegalArgumentException(); 9171 } 9172 return r.immersive; 9173 } 9174 } 9175 9176 public boolean isTopActivityImmersive() { 9177 enforceNotIsolatedCaller("startActivity"); 9178 synchronized (this) { 9179 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9180 return (r != null) ? r.immersive : false; 9181 } 9182 } 9183 9184 public final void enterSafeMode() { 9185 synchronized(this) { 9186 // It only makes sense to do this before the system is ready 9187 // and started launching other packages. 9188 if (!mSystemReady) { 9189 try { 9190 AppGlobals.getPackageManager().enterSafeMode(); 9191 } catch (RemoteException e) { 9192 } 9193 } 9194 9195 mSafeMode = true; 9196 } 9197 } 9198 9199 public final void showSafeModeOverlay() { 9200 View v = LayoutInflater.from(mContext).inflate( 9201 com.android.internal.R.layout.safe_mode, null); 9202 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9203 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9204 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9205 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9206 lp.gravity = Gravity.BOTTOM | Gravity.START; 9207 lp.format = v.getBackground().getOpacity(); 9208 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9209 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9210 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9211 ((WindowManager)mContext.getSystemService( 9212 Context.WINDOW_SERVICE)).addView(v, lp); 9213 } 9214 9215 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9216 if (!(sender instanceof PendingIntentRecord)) { 9217 return; 9218 } 9219 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9220 synchronized (stats) { 9221 if (mBatteryStatsService.isOnBattery()) { 9222 mBatteryStatsService.enforceCallingPermission(); 9223 PendingIntentRecord rec = (PendingIntentRecord)sender; 9224 int MY_UID = Binder.getCallingUid(); 9225 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9226 BatteryStatsImpl.Uid.Pkg pkg = 9227 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9228 sourcePkg != null ? sourcePkg : rec.key.packageName); 9229 pkg.incWakeupsLocked(); 9230 } 9231 } 9232 } 9233 9234 public boolean killPids(int[] pids, String pReason, boolean secure) { 9235 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9236 throw new SecurityException("killPids only available to the system"); 9237 } 9238 String reason = (pReason == null) ? "Unknown" : pReason; 9239 // XXX Note: don't acquire main activity lock here, because the window 9240 // manager calls in with its locks held. 9241 9242 boolean killed = false; 9243 synchronized (mPidsSelfLocked) { 9244 int[] types = new int[pids.length]; 9245 int worstType = 0; 9246 for (int i=0; i<pids.length; i++) { 9247 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9248 if (proc != null) { 9249 int type = proc.setAdj; 9250 types[i] = type; 9251 if (type > worstType) { 9252 worstType = type; 9253 } 9254 } 9255 } 9256 9257 // If the worst oom_adj is somewhere in the cached proc LRU range, 9258 // then constrain it so we will kill all cached procs. 9259 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9260 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9261 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9262 } 9263 9264 // If this is not a secure call, don't let it kill processes that 9265 // are important. 9266 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9267 worstType = ProcessList.SERVICE_ADJ; 9268 } 9269 9270 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9271 for (int i=0; i<pids.length; i++) { 9272 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9273 if (proc == null) { 9274 continue; 9275 } 9276 int adj = proc.setAdj; 9277 if (adj >= worstType && !proc.killedByAm) { 9278 killUnneededProcessLocked(proc, reason); 9279 killed = true; 9280 } 9281 } 9282 } 9283 return killed; 9284 } 9285 9286 @Override 9287 public void killUid(int uid, String reason) { 9288 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9289 throw new SecurityException("killUid only available to the system"); 9290 } 9291 synchronized (this) { 9292 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9293 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9294 reason != null ? reason : "kill uid"); 9295 } 9296 } 9297 9298 @Override 9299 public boolean killProcessesBelowForeground(String reason) { 9300 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9301 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9302 } 9303 9304 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9305 } 9306 9307 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9308 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9309 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9310 } 9311 9312 boolean killed = false; 9313 synchronized (mPidsSelfLocked) { 9314 final int size = mPidsSelfLocked.size(); 9315 for (int i = 0; i < size; i++) { 9316 final int pid = mPidsSelfLocked.keyAt(i); 9317 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9318 if (proc == null) continue; 9319 9320 final int adj = proc.setAdj; 9321 if (adj > belowAdj && !proc.killedByAm) { 9322 killUnneededProcessLocked(proc, reason); 9323 killed = true; 9324 } 9325 } 9326 } 9327 return killed; 9328 } 9329 9330 @Override 9331 public void hang(final IBinder who, boolean allowRestart) { 9332 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9333 != PackageManager.PERMISSION_GRANTED) { 9334 throw new SecurityException("Requires permission " 9335 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9336 } 9337 9338 final IBinder.DeathRecipient death = new DeathRecipient() { 9339 @Override 9340 public void binderDied() { 9341 synchronized (this) { 9342 notifyAll(); 9343 } 9344 } 9345 }; 9346 9347 try { 9348 who.linkToDeath(death, 0); 9349 } catch (RemoteException e) { 9350 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9351 return; 9352 } 9353 9354 synchronized (this) { 9355 Watchdog.getInstance().setAllowRestart(allowRestart); 9356 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9357 synchronized (death) { 9358 while (who.isBinderAlive()) { 9359 try { 9360 death.wait(); 9361 } catch (InterruptedException e) { 9362 } 9363 } 9364 } 9365 Watchdog.getInstance().setAllowRestart(true); 9366 } 9367 } 9368 9369 @Override 9370 public void restart() { 9371 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9372 != PackageManager.PERMISSION_GRANTED) { 9373 throw new SecurityException("Requires permission " 9374 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9375 } 9376 9377 Log.i(TAG, "Sending shutdown broadcast..."); 9378 9379 BroadcastReceiver br = new BroadcastReceiver() { 9380 @Override public void onReceive(Context context, Intent intent) { 9381 // Now the broadcast is done, finish up the low-level shutdown. 9382 Log.i(TAG, "Shutting down activity manager..."); 9383 shutdown(10000); 9384 Log.i(TAG, "Shutdown complete, restarting!"); 9385 Process.killProcess(Process.myPid()); 9386 System.exit(10); 9387 } 9388 }; 9389 9390 // First send the high-level shut down broadcast. 9391 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9392 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9393 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9394 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9395 mContext.sendOrderedBroadcastAsUser(intent, 9396 UserHandle.ALL, null, br, mHandler, 0, null, null); 9397 */ 9398 br.onReceive(mContext, intent); 9399 } 9400 9401 private long getLowRamTimeSinceIdle(long now) { 9402 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9403 } 9404 9405 @Override 9406 public void performIdleMaintenance() { 9407 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9408 != PackageManager.PERMISSION_GRANTED) { 9409 throw new SecurityException("Requires permission " 9410 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9411 } 9412 9413 synchronized (this) { 9414 final long now = SystemClock.uptimeMillis(); 9415 final long timeSinceLastIdle = now - mLastIdleTime; 9416 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9417 mLastIdleTime = now; 9418 mLowRamTimeSinceLastIdle = 0; 9419 if (mLowRamStartTime != 0) { 9420 mLowRamStartTime = now; 9421 } 9422 9423 StringBuilder sb = new StringBuilder(128); 9424 sb.append("Idle maintenance over "); 9425 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9426 sb.append(" low RAM for "); 9427 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9428 Slog.i(TAG, sb.toString()); 9429 9430 // If at least 1/3 of our time since the last idle period has been spent 9431 // with RAM low, then we want to kill processes. 9432 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9433 9434 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9435 ProcessRecord proc = mLruProcesses.get(i); 9436 if (proc.notCachedSinceIdle) { 9437 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9438 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9439 if (doKilling && proc.initialIdlePss != 0 9440 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9441 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9442 + " from " + proc.initialIdlePss + ")"); 9443 } 9444 } 9445 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9446 proc.notCachedSinceIdle = true; 9447 proc.initialIdlePss = 0; 9448 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9449 isSleeping(), now); 9450 } 9451 } 9452 9453 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9454 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9455 } 9456 } 9457 9458 private void retrieveSettings() { 9459 final ContentResolver resolver = mContext.getContentResolver(); 9460 String debugApp = Settings.Global.getString( 9461 resolver, Settings.Global.DEBUG_APP); 9462 boolean waitForDebugger = Settings.Global.getInt( 9463 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9464 boolean alwaysFinishActivities = Settings.Global.getInt( 9465 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9466 boolean forceRtl = Settings.Global.getInt( 9467 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9468 // Transfer any global setting for forcing RTL layout, into a System Property 9469 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9470 9471 Configuration configuration = new Configuration(); 9472 Settings.System.getConfiguration(resolver, configuration); 9473 if (forceRtl) { 9474 // This will take care of setting the correct layout direction flags 9475 configuration.setLayoutDirection(configuration.locale); 9476 } 9477 9478 synchronized (this) { 9479 mDebugApp = mOrigDebugApp = debugApp; 9480 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9481 mAlwaysFinishActivities = alwaysFinishActivities; 9482 // This happens before any activities are started, so we can 9483 // change mConfiguration in-place. 9484 updateConfigurationLocked(configuration, null, false, true); 9485 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9486 } 9487 } 9488 9489 public boolean testIsSystemReady() { 9490 // no need to synchronize(this) just to read & return the value 9491 return mSystemReady; 9492 } 9493 9494 private static File getCalledPreBootReceiversFile() { 9495 File dataDir = Environment.getDataDirectory(); 9496 File systemDir = new File(dataDir, "system"); 9497 File fname = new File(systemDir, "called_pre_boots.dat"); 9498 return fname; 9499 } 9500 9501 static final int LAST_DONE_VERSION = 10000; 9502 9503 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9504 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9505 File file = getCalledPreBootReceiversFile(); 9506 FileInputStream fis = null; 9507 try { 9508 fis = new FileInputStream(file); 9509 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9510 int fvers = dis.readInt(); 9511 if (fvers == LAST_DONE_VERSION) { 9512 String vers = dis.readUTF(); 9513 String codename = dis.readUTF(); 9514 String build = dis.readUTF(); 9515 if (android.os.Build.VERSION.RELEASE.equals(vers) 9516 && android.os.Build.VERSION.CODENAME.equals(codename) 9517 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9518 int num = dis.readInt(); 9519 while (num > 0) { 9520 num--; 9521 String pkg = dis.readUTF(); 9522 String cls = dis.readUTF(); 9523 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9524 } 9525 } 9526 } 9527 } catch (FileNotFoundException e) { 9528 } catch (IOException e) { 9529 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9530 } finally { 9531 if (fis != null) { 9532 try { 9533 fis.close(); 9534 } catch (IOException e) { 9535 } 9536 } 9537 } 9538 return lastDoneReceivers; 9539 } 9540 9541 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9542 File file = getCalledPreBootReceiversFile(); 9543 FileOutputStream fos = null; 9544 DataOutputStream dos = null; 9545 try { 9546 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9547 fos = new FileOutputStream(file); 9548 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9549 dos.writeInt(LAST_DONE_VERSION); 9550 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9551 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9552 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9553 dos.writeInt(list.size()); 9554 for (int i=0; i<list.size(); i++) { 9555 dos.writeUTF(list.get(i).getPackageName()); 9556 dos.writeUTF(list.get(i).getClassName()); 9557 } 9558 } catch (IOException e) { 9559 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9560 file.delete(); 9561 } finally { 9562 FileUtils.sync(fos); 9563 if (dos != null) { 9564 try { 9565 dos.close(); 9566 } catch (IOException e) { 9567 // TODO Auto-generated catch block 9568 e.printStackTrace(); 9569 } 9570 } 9571 } 9572 } 9573 9574 public void systemReady(final Runnable goingCallback) { 9575 synchronized(this) { 9576 if (mSystemReady) { 9577 if (goingCallback != null) goingCallback.run(); 9578 return; 9579 } 9580 9581 // Check to see if there are any update receivers to run. 9582 if (!mDidUpdate) { 9583 if (mWaitingUpdate) { 9584 return; 9585 } 9586 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9587 List<ResolveInfo> ris = null; 9588 try { 9589 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9590 intent, null, 0, 0); 9591 } catch (RemoteException e) { 9592 } 9593 if (ris != null) { 9594 for (int i=ris.size()-1; i>=0; i--) { 9595 if ((ris.get(i).activityInfo.applicationInfo.flags 9596 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9597 ris.remove(i); 9598 } 9599 } 9600 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9601 9602 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9603 9604 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9605 for (int i=0; i<ris.size(); i++) { 9606 ActivityInfo ai = ris.get(i).activityInfo; 9607 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9608 if (lastDoneReceivers.contains(comp)) { 9609 // We already did the pre boot receiver for this app with the current 9610 // platform version, so don't do it again... 9611 ris.remove(i); 9612 i--; 9613 // ...however, do keep it as one that has been done, so we don't 9614 // forget about it when rewriting the file of last done receivers. 9615 doneReceivers.add(comp); 9616 } 9617 } 9618 9619 final int[] users = getUsersLocked(); 9620 for (int i=0; i<ris.size(); i++) { 9621 ActivityInfo ai = ris.get(i).activityInfo; 9622 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9623 doneReceivers.add(comp); 9624 intent.setComponent(comp); 9625 for (int j=0; j<users.length; j++) { 9626 IIntentReceiver finisher = null; 9627 if (i == ris.size()-1 && j == users.length-1) { 9628 finisher = new IIntentReceiver.Stub() { 9629 public void performReceive(Intent intent, int resultCode, 9630 String data, Bundle extras, boolean ordered, 9631 boolean sticky, int sendingUser) { 9632 // The raw IIntentReceiver interface is called 9633 // with the AM lock held, so redispatch to 9634 // execute our code without the lock. 9635 mHandler.post(new Runnable() { 9636 public void run() { 9637 synchronized (ActivityManagerService.this) { 9638 mDidUpdate = true; 9639 } 9640 writeLastDonePreBootReceivers(doneReceivers); 9641 showBootMessage(mContext.getText( 9642 R.string.android_upgrading_complete), 9643 false); 9644 systemReady(goingCallback); 9645 } 9646 }); 9647 } 9648 }; 9649 } 9650 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9651 + " for user " + users[j]); 9652 broadcastIntentLocked(null, null, intent, null, finisher, 9653 0, null, null, null, AppOpsManager.OP_NONE, 9654 true, false, MY_PID, Process.SYSTEM_UID, 9655 users[j]); 9656 if (finisher != null) { 9657 mWaitingUpdate = true; 9658 } 9659 } 9660 } 9661 } 9662 if (mWaitingUpdate) { 9663 return; 9664 } 9665 mDidUpdate = true; 9666 } 9667 9668 mAppOpsService.systemReady(); 9669 mSystemReady = true; 9670 } 9671 9672 ArrayList<ProcessRecord> procsToKill = null; 9673 synchronized(mPidsSelfLocked) { 9674 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9675 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9676 if (!isAllowedWhileBooting(proc.info)){ 9677 if (procsToKill == null) { 9678 procsToKill = new ArrayList<ProcessRecord>(); 9679 } 9680 procsToKill.add(proc); 9681 } 9682 } 9683 } 9684 9685 synchronized(this) { 9686 if (procsToKill != null) { 9687 for (int i=procsToKill.size()-1; i>=0; i--) { 9688 ProcessRecord proc = procsToKill.get(i); 9689 Slog.i(TAG, "Removing system update proc: " + proc); 9690 removeProcessLocked(proc, true, false, "system update done"); 9691 } 9692 } 9693 9694 // Now that we have cleaned up any update processes, we 9695 // are ready to start launching real processes and know that 9696 // we won't trample on them any more. 9697 mProcessesReady = true; 9698 } 9699 9700 Slog.i(TAG, "System now ready"); 9701 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9702 SystemClock.uptimeMillis()); 9703 9704 synchronized(this) { 9705 // Make sure we have no pre-ready processes sitting around. 9706 9707 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9708 ResolveInfo ri = mContext.getPackageManager() 9709 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9710 STOCK_PM_FLAGS); 9711 CharSequence errorMsg = null; 9712 if (ri != null) { 9713 ActivityInfo ai = ri.activityInfo; 9714 ApplicationInfo app = ai.applicationInfo; 9715 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9716 mTopAction = Intent.ACTION_FACTORY_TEST; 9717 mTopData = null; 9718 mTopComponent = new ComponentName(app.packageName, 9719 ai.name); 9720 } else { 9721 errorMsg = mContext.getResources().getText( 9722 com.android.internal.R.string.factorytest_not_system); 9723 } 9724 } else { 9725 errorMsg = mContext.getResources().getText( 9726 com.android.internal.R.string.factorytest_no_action); 9727 } 9728 if (errorMsg != null) { 9729 mTopAction = null; 9730 mTopData = null; 9731 mTopComponent = null; 9732 Message msg = Message.obtain(); 9733 msg.what = SHOW_FACTORY_ERROR_MSG; 9734 msg.getData().putCharSequence("msg", errorMsg); 9735 mHandler.sendMessage(msg); 9736 } 9737 } 9738 } 9739 9740 retrieveSettings(); 9741 9742 synchronized (this) { 9743 readGrantedUriPermissionsLocked(); 9744 } 9745 9746 if (goingCallback != null) goingCallback.run(); 9747 9748 mSystemServiceManager.startUser(mCurrentUserId); 9749 9750 synchronized (this) { 9751 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9752 try { 9753 List apps = AppGlobals.getPackageManager(). 9754 getPersistentApplications(STOCK_PM_FLAGS); 9755 if (apps != null) { 9756 int N = apps.size(); 9757 int i; 9758 for (i=0; i<N; i++) { 9759 ApplicationInfo info 9760 = (ApplicationInfo)apps.get(i); 9761 if (info != null && 9762 !info.packageName.equals("android")) { 9763 addAppLocked(info, false); 9764 } 9765 } 9766 } 9767 } catch (RemoteException ex) { 9768 // pm is in same process, this will never happen. 9769 } 9770 } 9771 9772 // Start up initial activity. 9773 mBooting = true; 9774 9775 try { 9776 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9777 Message msg = Message.obtain(); 9778 msg.what = SHOW_UID_ERROR_MSG; 9779 mHandler.sendMessage(msg); 9780 } 9781 } catch (RemoteException e) { 9782 } 9783 9784 long ident = Binder.clearCallingIdentity(); 9785 try { 9786 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9787 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9788 | Intent.FLAG_RECEIVER_FOREGROUND); 9789 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9790 broadcastIntentLocked(null, null, intent, 9791 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9792 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9793 intent = new Intent(Intent.ACTION_USER_STARTING); 9794 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9795 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9796 broadcastIntentLocked(null, null, intent, 9797 null, new IIntentReceiver.Stub() { 9798 @Override 9799 public void performReceive(Intent intent, int resultCode, String data, 9800 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9801 throws RemoteException { 9802 } 9803 }, 0, null, null, 9804 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9805 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9806 } catch (Throwable t) { 9807 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9808 } finally { 9809 Binder.restoreCallingIdentity(ident); 9810 } 9811 mStackSupervisor.resumeTopActivitiesLocked(); 9812 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9813 } 9814 } 9815 9816 private boolean makeAppCrashingLocked(ProcessRecord app, 9817 String shortMsg, String longMsg, String stackTrace) { 9818 app.crashing = true; 9819 app.crashingReport = generateProcessError(app, 9820 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9821 startAppProblemLocked(app); 9822 app.stopFreezingAllLocked(); 9823 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9824 } 9825 9826 private void makeAppNotRespondingLocked(ProcessRecord app, 9827 String activity, String shortMsg, String longMsg) { 9828 app.notResponding = true; 9829 app.notRespondingReport = generateProcessError(app, 9830 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9831 activity, shortMsg, longMsg, null); 9832 startAppProblemLocked(app); 9833 app.stopFreezingAllLocked(); 9834 } 9835 9836 /** 9837 * Generate a process error record, suitable for attachment to a ProcessRecord. 9838 * 9839 * @param app The ProcessRecord in which the error occurred. 9840 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9841 * ActivityManager.AppErrorStateInfo 9842 * @param activity The activity associated with the crash, if known. 9843 * @param shortMsg Short message describing the crash. 9844 * @param longMsg Long message describing the crash. 9845 * @param stackTrace Full crash stack trace, may be null. 9846 * 9847 * @return Returns a fully-formed AppErrorStateInfo record. 9848 */ 9849 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9850 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9851 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9852 9853 report.condition = condition; 9854 report.processName = app.processName; 9855 report.pid = app.pid; 9856 report.uid = app.info.uid; 9857 report.tag = activity; 9858 report.shortMsg = shortMsg; 9859 report.longMsg = longMsg; 9860 report.stackTrace = stackTrace; 9861 9862 return report; 9863 } 9864 9865 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9866 synchronized (this) { 9867 app.crashing = false; 9868 app.crashingReport = null; 9869 app.notResponding = false; 9870 app.notRespondingReport = null; 9871 if (app.anrDialog == fromDialog) { 9872 app.anrDialog = null; 9873 } 9874 if (app.waitDialog == fromDialog) { 9875 app.waitDialog = null; 9876 } 9877 if (app.pid > 0 && app.pid != MY_PID) { 9878 handleAppCrashLocked(app, null, null, null); 9879 killUnneededProcessLocked(app, "user request after error"); 9880 } 9881 } 9882 } 9883 9884 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9885 String stackTrace) { 9886 long now = SystemClock.uptimeMillis(); 9887 9888 Long crashTime; 9889 if (!app.isolated) { 9890 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9891 } else { 9892 crashTime = null; 9893 } 9894 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9895 // This process loses! 9896 Slog.w(TAG, "Process " + app.info.processName 9897 + " has crashed too many times: killing!"); 9898 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9899 app.userId, app.info.processName, app.uid); 9900 mStackSupervisor.handleAppCrashLocked(app); 9901 if (!app.persistent) { 9902 // We don't want to start this process again until the user 9903 // explicitly does so... but for persistent process, we really 9904 // need to keep it running. If a persistent process is actually 9905 // repeatedly crashing, then badness for everyone. 9906 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9907 app.info.processName); 9908 if (!app.isolated) { 9909 // XXX We don't have a way to mark isolated processes 9910 // as bad, since they don't have a peristent identity. 9911 mBadProcesses.put(app.info.processName, app.uid, 9912 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9913 mProcessCrashTimes.remove(app.info.processName, app.uid); 9914 } 9915 app.bad = true; 9916 app.removed = true; 9917 // Don't let services in this process be restarted and potentially 9918 // annoy the user repeatedly. Unless it is persistent, since those 9919 // processes run critical code. 9920 removeProcessLocked(app, false, false, "crash"); 9921 mStackSupervisor.resumeTopActivitiesLocked(); 9922 return false; 9923 } 9924 mStackSupervisor.resumeTopActivitiesLocked(); 9925 } else { 9926 mStackSupervisor.finishTopRunningActivityLocked(app); 9927 } 9928 9929 // Bump up the crash count of any services currently running in the proc. 9930 for (int i=app.services.size()-1; i>=0; i--) { 9931 // Any services running in the application need to be placed 9932 // back in the pending list. 9933 ServiceRecord sr = app.services.valueAt(i); 9934 sr.crashCount++; 9935 } 9936 9937 // If the crashing process is what we consider to be the "home process" and it has been 9938 // replaced by a third-party app, clear the package preferred activities from packages 9939 // with a home activity running in the process to prevent a repeatedly crashing app 9940 // from blocking the user to manually clear the list. 9941 final ArrayList<ActivityRecord> activities = app.activities; 9942 if (app == mHomeProcess && activities.size() > 0 9943 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9944 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9945 final ActivityRecord r = activities.get(activityNdx); 9946 if (r.isHomeActivity()) { 9947 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9948 try { 9949 ActivityThread.getPackageManager() 9950 .clearPackagePreferredActivities(r.packageName); 9951 } catch (RemoteException c) { 9952 // pm is in same process, this will never happen. 9953 } 9954 } 9955 } 9956 } 9957 9958 if (!app.isolated) { 9959 // XXX Can't keep track of crash times for isolated processes, 9960 // because they don't have a perisistent identity. 9961 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9962 } 9963 9964 return true; 9965 } 9966 9967 void startAppProblemLocked(ProcessRecord app) { 9968 if (app.userId == mCurrentUserId) { 9969 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9970 mContext, app.info.packageName, app.info.flags); 9971 } else { 9972 // If this app is not running under the current user, then we 9973 // can't give it a report button because that would require 9974 // launching the report UI under a different user. 9975 app.errorReportReceiver = null; 9976 } 9977 skipCurrentReceiverLocked(app); 9978 } 9979 9980 void skipCurrentReceiverLocked(ProcessRecord app) { 9981 for (BroadcastQueue queue : mBroadcastQueues) { 9982 queue.skipCurrentReceiverLocked(app); 9983 } 9984 } 9985 9986 /** 9987 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9988 * The application process will exit immediately after this call returns. 9989 * @param app object of the crashing app, null for the system server 9990 * @param crashInfo describing the exception 9991 */ 9992 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9993 ProcessRecord r = findAppProcess(app, "Crash"); 9994 final String processName = app == null ? "system_server" 9995 : (r == null ? "unknown" : r.processName); 9996 9997 handleApplicationCrashInner("crash", r, processName, crashInfo); 9998 } 9999 10000 /* Native crash reporting uses this inner version because it needs to be somewhat 10001 * decoupled from the AM-managed cleanup lifecycle 10002 */ 10003 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 10004 ApplicationErrorReport.CrashInfo crashInfo) { 10005 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 10006 UserHandle.getUserId(Binder.getCallingUid()), processName, 10007 r == null ? -1 : r.info.flags, 10008 crashInfo.exceptionClassName, 10009 crashInfo.exceptionMessage, 10010 crashInfo.throwFileName, 10011 crashInfo.throwLineNumber); 10012 10013 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 10014 10015 crashApplication(r, crashInfo); 10016 } 10017 10018 public void handleApplicationStrictModeViolation( 10019 IBinder app, 10020 int violationMask, 10021 StrictMode.ViolationInfo info) { 10022 ProcessRecord r = findAppProcess(app, "StrictMode"); 10023 if (r == null) { 10024 return; 10025 } 10026 10027 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 10028 Integer stackFingerprint = info.hashCode(); 10029 boolean logIt = true; 10030 synchronized (mAlreadyLoggedViolatedStacks) { 10031 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 10032 logIt = false; 10033 // TODO: sub-sample into EventLog for these, with 10034 // the info.durationMillis? Then we'd get 10035 // the relative pain numbers, without logging all 10036 // the stack traces repeatedly. We'd want to do 10037 // likewise in the client code, which also does 10038 // dup suppression, before the Binder call. 10039 } else { 10040 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 10041 mAlreadyLoggedViolatedStacks.clear(); 10042 } 10043 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 10044 } 10045 } 10046 if (logIt) { 10047 logStrictModeViolationToDropBox(r, info); 10048 } 10049 } 10050 10051 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 10052 AppErrorResult result = new AppErrorResult(); 10053 synchronized (this) { 10054 final long origId = Binder.clearCallingIdentity(); 10055 10056 Message msg = Message.obtain(); 10057 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 10058 HashMap<String, Object> data = new HashMap<String, Object>(); 10059 data.put("result", result); 10060 data.put("app", r); 10061 data.put("violationMask", violationMask); 10062 data.put("info", info); 10063 msg.obj = data; 10064 mHandler.sendMessage(msg); 10065 10066 Binder.restoreCallingIdentity(origId); 10067 } 10068 int res = result.get(); 10069 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 10070 } 10071 } 10072 10073 // Depending on the policy in effect, there could be a bunch of 10074 // these in quick succession so we try to batch these together to 10075 // minimize disk writes, number of dropbox entries, and maximize 10076 // compression, by having more fewer, larger records. 10077 private void logStrictModeViolationToDropBox( 10078 ProcessRecord process, 10079 StrictMode.ViolationInfo info) { 10080 if (info == null) { 10081 return; 10082 } 10083 final boolean isSystemApp = process == null || 10084 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 10085 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 10086 final String processName = process == null ? "unknown" : process.processName; 10087 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 10088 final DropBoxManager dbox = (DropBoxManager) 10089 mContext.getSystemService(Context.DROPBOX_SERVICE); 10090 10091 // Exit early if the dropbox isn't configured to accept this report type. 10092 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10093 10094 boolean bufferWasEmpty; 10095 boolean needsFlush; 10096 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 10097 synchronized (sb) { 10098 bufferWasEmpty = sb.length() == 0; 10099 appendDropBoxProcessHeaders(process, processName, sb); 10100 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10101 sb.append("System-App: ").append(isSystemApp).append("\n"); 10102 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10103 if (info.violationNumThisLoop != 0) { 10104 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10105 } 10106 if (info.numAnimationsRunning != 0) { 10107 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10108 } 10109 if (info.broadcastIntentAction != null) { 10110 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10111 } 10112 if (info.durationMillis != -1) { 10113 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10114 } 10115 if (info.numInstances != -1) { 10116 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10117 } 10118 if (info.tags != null) { 10119 for (String tag : info.tags) { 10120 sb.append("Span-Tag: ").append(tag).append("\n"); 10121 } 10122 } 10123 sb.append("\n"); 10124 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10125 sb.append(info.crashInfo.stackTrace); 10126 } 10127 sb.append("\n"); 10128 10129 // Only buffer up to ~64k. Various logging bits truncate 10130 // things at 128k. 10131 needsFlush = (sb.length() > 64 * 1024); 10132 } 10133 10134 // Flush immediately if the buffer's grown too large, or this 10135 // is a non-system app. Non-system apps are isolated with a 10136 // different tag & policy and not batched. 10137 // 10138 // Batching is useful during internal testing with 10139 // StrictMode settings turned up high. Without batching, 10140 // thousands of separate files could be created on boot. 10141 if (!isSystemApp || needsFlush) { 10142 new Thread("Error dump: " + dropboxTag) { 10143 @Override 10144 public void run() { 10145 String report; 10146 synchronized (sb) { 10147 report = sb.toString(); 10148 sb.delete(0, sb.length()); 10149 sb.trimToSize(); 10150 } 10151 if (report.length() != 0) { 10152 dbox.addText(dropboxTag, report); 10153 } 10154 } 10155 }.start(); 10156 return; 10157 } 10158 10159 // System app batching: 10160 if (!bufferWasEmpty) { 10161 // An existing dropbox-writing thread is outstanding, so 10162 // we don't need to start it up. The existing thread will 10163 // catch the buffer appends we just did. 10164 return; 10165 } 10166 10167 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10168 // (After this point, we shouldn't access AMS internal data structures.) 10169 new Thread("Error dump: " + dropboxTag) { 10170 @Override 10171 public void run() { 10172 // 5 second sleep to let stacks arrive and be batched together 10173 try { 10174 Thread.sleep(5000); // 5 seconds 10175 } catch (InterruptedException e) {} 10176 10177 String errorReport; 10178 synchronized (mStrictModeBuffer) { 10179 errorReport = mStrictModeBuffer.toString(); 10180 if (errorReport.length() == 0) { 10181 return; 10182 } 10183 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10184 mStrictModeBuffer.trimToSize(); 10185 } 10186 dbox.addText(dropboxTag, errorReport); 10187 } 10188 }.start(); 10189 } 10190 10191 /** 10192 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10193 * @param app object of the crashing app, null for the system server 10194 * @param tag reported by the caller 10195 * @param crashInfo describing the context of the error 10196 * @return true if the process should exit immediately (WTF is fatal) 10197 */ 10198 public boolean handleApplicationWtf(IBinder app, String tag, 10199 ApplicationErrorReport.CrashInfo crashInfo) { 10200 ProcessRecord r = findAppProcess(app, "WTF"); 10201 final String processName = app == null ? "system_server" 10202 : (r == null ? "unknown" : r.processName); 10203 10204 EventLog.writeEvent(EventLogTags.AM_WTF, 10205 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10206 processName, 10207 r == null ? -1 : r.info.flags, 10208 tag, crashInfo.exceptionMessage); 10209 10210 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10211 10212 if (r != null && r.pid != Process.myPid() && 10213 Settings.Global.getInt(mContext.getContentResolver(), 10214 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10215 crashApplication(r, crashInfo); 10216 return true; 10217 } else { 10218 return false; 10219 } 10220 } 10221 10222 /** 10223 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10224 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10225 */ 10226 private ProcessRecord findAppProcess(IBinder app, String reason) { 10227 if (app == null) { 10228 return null; 10229 } 10230 10231 synchronized (this) { 10232 final int NP = mProcessNames.getMap().size(); 10233 for (int ip=0; ip<NP; ip++) { 10234 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10235 final int NA = apps.size(); 10236 for (int ia=0; ia<NA; ia++) { 10237 ProcessRecord p = apps.valueAt(ia); 10238 if (p.thread != null && p.thread.asBinder() == app) { 10239 return p; 10240 } 10241 } 10242 } 10243 10244 Slog.w(TAG, "Can't find mystery application for " + reason 10245 + " from pid=" + Binder.getCallingPid() 10246 + " uid=" + Binder.getCallingUid() + ": " + app); 10247 return null; 10248 } 10249 } 10250 10251 /** 10252 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10253 * to append various headers to the dropbox log text. 10254 */ 10255 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10256 StringBuilder sb) { 10257 // Watchdog thread ends up invoking this function (with 10258 // a null ProcessRecord) to add the stack file to dropbox. 10259 // Do not acquire a lock on this (am) in such cases, as it 10260 // could cause a potential deadlock, if and when watchdog 10261 // is invoked due to unavailability of lock on am and it 10262 // would prevent watchdog from killing system_server. 10263 if (process == null) { 10264 sb.append("Process: ").append(processName).append("\n"); 10265 return; 10266 } 10267 // Note: ProcessRecord 'process' is guarded by the service 10268 // instance. (notably process.pkgList, which could otherwise change 10269 // concurrently during execution of this method) 10270 synchronized (this) { 10271 sb.append("Process: ").append(processName).append("\n"); 10272 int flags = process.info.flags; 10273 IPackageManager pm = AppGlobals.getPackageManager(); 10274 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10275 for (int ip=0; ip<process.pkgList.size(); ip++) { 10276 String pkg = process.pkgList.keyAt(ip); 10277 sb.append("Package: ").append(pkg); 10278 try { 10279 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10280 if (pi != null) { 10281 sb.append(" v").append(pi.versionCode); 10282 if (pi.versionName != null) { 10283 sb.append(" (").append(pi.versionName).append(")"); 10284 } 10285 } 10286 } catch (RemoteException e) { 10287 Slog.e(TAG, "Error getting package info: " + pkg, e); 10288 } 10289 sb.append("\n"); 10290 } 10291 } 10292 } 10293 10294 private static String processClass(ProcessRecord process) { 10295 if (process == null || process.pid == MY_PID) { 10296 return "system_server"; 10297 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10298 return "system_app"; 10299 } else { 10300 return "data_app"; 10301 } 10302 } 10303 10304 /** 10305 * Write a description of an error (crash, WTF, ANR) to the drop box. 10306 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10307 * @param process which caused the error, null means the system server 10308 * @param activity which triggered the error, null if unknown 10309 * @param parent activity related to the error, null if unknown 10310 * @param subject line related to the error, null if absent 10311 * @param report in long form describing the error, null if absent 10312 * @param logFile to include in the report, null if none 10313 * @param crashInfo giving an application stack trace, null if absent 10314 */ 10315 public void addErrorToDropBox(String eventType, 10316 ProcessRecord process, String processName, ActivityRecord activity, 10317 ActivityRecord parent, String subject, 10318 final String report, final File logFile, 10319 final ApplicationErrorReport.CrashInfo crashInfo) { 10320 // NOTE -- this must never acquire the ActivityManagerService lock, 10321 // otherwise the watchdog may be prevented from resetting the system. 10322 10323 final String dropboxTag = processClass(process) + "_" + eventType; 10324 final DropBoxManager dbox = (DropBoxManager) 10325 mContext.getSystemService(Context.DROPBOX_SERVICE); 10326 10327 // Exit early if the dropbox isn't configured to accept this report type. 10328 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10329 10330 final StringBuilder sb = new StringBuilder(1024); 10331 appendDropBoxProcessHeaders(process, processName, sb); 10332 if (activity != null) { 10333 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10334 } 10335 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10336 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10337 } 10338 if (parent != null && parent != activity) { 10339 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10340 } 10341 if (subject != null) { 10342 sb.append("Subject: ").append(subject).append("\n"); 10343 } 10344 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10345 if (Debug.isDebuggerConnected()) { 10346 sb.append("Debugger: Connected\n"); 10347 } 10348 sb.append("\n"); 10349 10350 // Do the rest in a worker thread to avoid blocking the caller on I/O 10351 // (After this point, we shouldn't access AMS internal data structures.) 10352 Thread worker = new Thread("Error dump: " + dropboxTag) { 10353 @Override 10354 public void run() { 10355 if (report != null) { 10356 sb.append(report); 10357 } 10358 if (logFile != null) { 10359 try { 10360 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10361 "\n\n[[TRUNCATED]]")); 10362 } catch (IOException e) { 10363 Slog.e(TAG, "Error reading " + logFile, e); 10364 } 10365 } 10366 if (crashInfo != null && crashInfo.stackTrace != null) { 10367 sb.append(crashInfo.stackTrace); 10368 } 10369 10370 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10371 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10372 if (lines > 0) { 10373 sb.append("\n"); 10374 10375 // Merge several logcat streams, and take the last N lines 10376 InputStreamReader input = null; 10377 try { 10378 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10379 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10380 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10381 10382 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10383 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10384 input = new InputStreamReader(logcat.getInputStream()); 10385 10386 int num; 10387 char[] buf = new char[8192]; 10388 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10389 } catch (IOException e) { 10390 Slog.e(TAG, "Error running logcat", e); 10391 } finally { 10392 if (input != null) try { input.close(); } catch (IOException e) {} 10393 } 10394 } 10395 10396 dbox.addText(dropboxTag, sb.toString()); 10397 } 10398 }; 10399 10400 if (process == null) { 10401 // If process is null, we are being called from some internal code 10402 // and may be about to die -- run this synchronously. 10403 worker.run(); 10404 } else { 10405 worker.start(); 10406 } 10407 } 10408 10409 /** 10410 * Bring up the "unexpected error" dialog box for a crashing app. 10411 * Deal with edge cases (intercepts from instrumented applications, 10412 * ActivityController, error intent receivers, that sort of thing). 10413 * @param r the application crashing 10414 * @param crashInfo describing the failure 10415 */ 10416 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10417 long timeMillis = System.currentTimeMillis(); 10418 String shortMsg = crashInfo.exceptionClassName; 10419 String longMsg = crashInfo.exceptionMessage; 10420 String stackTrace = crashInfo.stackTrace; 10421 if (shortMsg != null && longMsg != null) { 10422 longMsg = shortMsg + ": " + longMsg; 10423 } else if (shortMsg != null) { 10424 longMsg = shortMsg; 10425 } 10426 10427 AppErrorResult result = new AppErrorResult(); 10428 synchronized (this) { 10429 if (mController != null) { 10430 try { 10431 String name = r != null ? r.processName : null; 10432 int pid = r != null ? r.pid : Binder.getCallingPid(); 10433 if (!mController.appCrashed(name, pid, 10434 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10435 Slog.w(TAG, "Force-killing crashed app " + name 10436 + " at watcher's request"); 10437 Process.killProcess(pid); 10438 return; 10439 } 10440 } catch (RemoteException e) { 10441 mController = null; 10442 Watchdog.getInstance().setActivityController(null); 10443 } 10444 } 10445 10446 final long origId = Binder.clearCallingIdentity(); 10447 10448 // If this process is running instrumentation, finish it. 10449 if (r != null && r.instrumentationClass != null) { 10450 Slog.w(TAG, "Error in app " + r.processName 10451 + " running instrumentation " + r.instrumentationClass + ":"); 10452 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10453 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10454 Bundle info = new Bundle(); 10455 info.putString("shortMsg", shortMsg); 10456 info.putString("longMsg", longMsg); 10457 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10458 Binder.restoreCallingIdentity(origId); 10459 return; 10460 } 10461 10462 // If we can't identify the process or it's already exceeded its crash quota, 10463 // quit right away without showing a crash dialog. 10464 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10465 Binder.restoreCallingIdentity(origId); 10466 return; 10467 } 10468 10469 Message msg = Message.obtain(); 10470 msg.what = SHOW_ERROR_MSG; 10471 HashMap data = new HashMap(); 10472 data.put("result", result); 10473 data.put("app", r); 10474 msg.obj = data; 10475 mHandler.sendMessage(msg); 10476 10477 Binder.restoreCallingIdentity(origId); 10478 } 10479 10480 int res = result.get(); 10481 10482 Intent appErrorIntent = null; 10483 synchronized (this) { 10484 if (r != null && !r.isolated) { 10485 // XXX Can't keep track of crash time for isolated processes, 10486 // since they don't have a persistent identity. 10487 mProcessCrashTimes.put(r.info.processName, r.uid, 10488 SystemClock.uptimeMillis()); 10489 } 10490 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10491 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10492 } 10493 } 10494 10495 if (appErrorIntent != null) { 10496 try { 10497 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10498 } catch (ActivityNotFoundException e) { 10499 Slog.w(TAG, "bug report receiver dissappeared", e); 10500 } 10501 } 10502 } 10503 10504 Intent createAppErrorIntentLocked(ProcessRecord r, 10505 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10506 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10507 if (report == null) { 10508 return null; 10509 } 10510 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10511 result.setComponent(r.errorReportReceiver); 10512 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10513 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10514 return result; 10515 } 10516 10517 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10518 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10519 if (r.errorReportReceiver == null) { 10520 return null; 10521 } 10522 10523 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10524 return null; 10525 } 10526 10527 ApplicationErrorReport report = new ApplicationErrorReport(); 10528 report.packageName = r.info.packageName; 10529 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10530 report.processName = r.processName; 10531 report.time = timeMillis; 10532 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10533 10534 if (r.crashing || r.forceCrashReport) { 10535 report.type = ApplicationErrorReport.TYPE_CRASH; 10536 report.crashInfo = crashInfo; 10537 } else if (r.notResponding) { 10538 report.type = ApplicationErrorReport.TYPE_ANR; 10539 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10540 10541 report.anrInfo.activity = r.notRespondingReport.tag; 10542 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10543 report.anrInfo.info = r.notRespondingReport.longMsg; 10544 } 10545 10546 return report; 10547 } 10548 10549 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10550 enforceNotIsolatedCaller("getProcessesInErrorState"); 10551 // assume our apps are happy - lazy create the list 10552 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10553 10554 final boolean allUsers = ActivityManager.checkUidPermission( 10555 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10556 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10557 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10558 10559 synchronized (this) { 10560 10561 // iterate across all processes 10562 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10563 ProcessRecord app = mLruProcesses.get(i); 10564 if (!allUsers && app.userId != userId) { 10565 continue; 10566 } 10567 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10568 // This one's in trouble, so we'll generate a report for it 10569 // crashes are higher priority (in case there's a crash *and* an anr) 10570 ActivityManager.ProcessErrorStateInfo report = null; 10571 if (app.crashing) { 10572 report = app.crashingReport; 10573 } else if (app.notResponding) { 10574 report = app.notRespondingReport; 10575 } 10576 10577 if (report != null) { 10578 if (errList == null) { 10579 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10580 } 10581 errList.add(report); 10582 } else { 10583 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10584 " crashing = " + app.crashing + 10585 " notResponding = " + app.notResponding); 10586 } 10587 } 10588 } 10589 } 10590 10591 return errList; 10592 } 10593 10594 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10595 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10596 if (currApp != null) { 10597 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10598 } 10599 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10600 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10601 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10602 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10603 if (currApp != null) { 10604 currApp.lru = 0; 10605 } 10606 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10607 } else if (adj >= ProcessList.SERVICE_ADJ) { 10608 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10609 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10610 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10611 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10612 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10613 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10614 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10615 } else { 10616 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10617 } 10618 } 10619 10620 private void fillInProcMemInfo(ProcessRecord app, 10621 ActivityManager.RunningAppProcessInfo outInfo) { 10622 outInfo.pid = app.pid; 10623 outInfo.uid = app.info.uid; 10624 if (mHeavyWeightProcess == app) { 10625 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10626 } 10627 if (app.persistent) { 10628 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10629 } 10630 if (app.activities.size() > 0) { 10631 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10632 } 10633 outInfo.lastTrimLevel = app.trimMemoryLevel; 10634 int adj = app.curAdj; 10635 outInfo.importance = oomAdjToImportance(adj, outInfo); 10636 outInfo.importanceReasonCode = app.adjTypeCode; 10637 outInfo.processState = app.curProcState; 10638 } 10639 10640 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10641 enforceNotIsolatedCaller("getRunningAppProcesses"); 10642 // Lazy instantiation of list 10643 List<ActivityManager.RunningAppProcessInfo> runList = null; 10644 final boolean allUsers = ActivityManager.checkUidPermission( 10645 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10646 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10647 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10648 synchronized (this) { 10649 // Iterate across all processes 10650 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10651 ProcessRecord app = mLruProcesses.get(i); 10652 if (!allUsers && app.userId != userId) { 10653 continue; 10654 } 10655 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10656 // Generate process state info for running application 10657 ActivityManager.RunningAppProcessInfo currApp = 10658 new ActivityManager.RunningAppProcessInfo(app.processName, 10659 app.pid, app.getPackageList()); 10660 fillInProcMemInfo(app, currApp); 10661 if (app.adjSource instanceof ProcessRecord) { 10662 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10663 currApp.importanceReasonImportance = oomAdjToImportance( 10664 app.adjSourceOom, null); 10665 } else if (app.adjSource instanceof ActivityRecord) { 10666 ActivityRecord r = (ActivityRecord)app.adjSource; 10667 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10668 } 10669 if (app.adjTarget instanceof ComponentName) { 10670 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10671 } 10672 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10673 // + " lru=" + currApp.lru); 10674 if (runList == null) { 10675 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10676 } 10677 runList.add(currApp); 10678 } 10679 } 10680 } 10681 return runList; 10682 } 10683 10684 public List<ApplicationInfo> getRunningExternalApplications() { 10685 enforceNotIsolatedCaller("getRunningExternalApplications"); 10686 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10687 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10688 if (runningApps != null && runningApps.size() > 0) { 10689 Set<String> extList = new HashSet<String>(); 10690 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10691 if (app.pkgList != null) { 10692 for (String pkg : app.pkgList) { 10693 extList.add(pkg); 10694 } 10695 } 10696 } 10697 IPackageManager pm = AppGlobals.getPackageManager(); 10698 for (String pkg : extList) { 10699 try { 10700 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10701 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10702 retList.add(info); 10703 } 10704 } catch (RemoteException e) { 10705 } 10706 } 10707 } 10708 return retList; 10709 } 10710 10711 @Override 10712 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10713 enforceNotIsolatedCaller("getMyMemoryState"); 10714 synchronized (this) { 10715 ProcessRecord proc; 10716 synchronized (mPidsSelfLocked) { 10717 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10718 } 10719 fillInProcMemInfo(proc, outInfo); 10720 } 10721 } 10722 10723 @Override 10724 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10725 if (checkCallingPermission(android.Manifest.permission.DUMP) 10726 != PackageManager.PERMISSION_GRANTED) { 10727 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10728 + Binder.getCallingPid() 10729 + ", uid=" + Binder.getCallingUid() 10730 + " without permission " 10731 + android.Manifest.permission.DUMP); 10732 return; 10733 } 10734 10735 boolean dumpAll = false; 10736 boolean dumpClient = false; 10737 String dumpPackage = null; 10738 10739 int opti = 0; 10740 while (opti < args.length) { 10741 String opt = args[opti]; 10742 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10743 break; 10744 } 10745 opti++; 10746 if ("-a".equals(opt)) { 10747 dumpAll = true; 10748 } else if ("-c".equals(opt)) { 10749 dumpClient = true; 10750 } else if ("-h".equals(opt)) { 10751 pw.println("Activity manager dump options:"); 10752 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10753 pw.println(" cmd may be one of:"); 10754 pw.println(" a[ctivities]: activity stack state"); 10755 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10756 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10757 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10758 pw.println(" o[om]: out of memory management"); 10759 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10760 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10761 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10762 pw.println(" service [COMP_SPEC]: service client-side state"); 10763 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10764 pw.println(" all: dump all activities"); 10765 pw.println(" top: dump the top activity"); 10766 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10767 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10768 pw.println(" a partial substring in a component name, a"); 10769 pw.println(" hex object identifier."); 10770 pw.println(" -a: include all available server state."); 10771 pw.println(" -c: include client state."); 10772 return; 10773 } else { 10774 pw.println("Unknown argument: " + opt + "; use -h for help"); 10775 } 10776 } 10777 10778 long origId = Binder.clearCallingIdentity(); 10779 boolean more = false; 10780 // Is the caller requesting to dump a particular piece of data? 10781 if (opti < args.length) { 10782 String cmd = args[opti]; 10783 opti++; 10784 if ("activities".equals(cmd) || "a".equals(cmd)) { 10785 synchronized (this) { 10786 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10787 } 10788 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10789 String[] newArgs; 10790 String name; 10791 if (opti >= args.length) { 10792 name = null; 10793 newArgs = EMPTY_STRING_ARRAY; 10794 } else { 10795 name = args[opti]; 10796 opti++; 10797 newArgs = new String[args.length - opti]; 10798 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10799 args.length - opti); 10800 } 10801 synchronized (this) { 10802 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10803 } 10804 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10805 String[] newArgs; 10806 String name; 10807 if (opti >= args.length) { 10808 name = null; 10809 newArgs = EMPTY_STRING_ARRAY; 10810 } else { 10811 name = args[opti]; 10812 opti++; 10813 newArgs = new String[args.length - opti]; 10814 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10815 args.length - opti); 10816 } 10817 synchronized (this) { 10818 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10819 } 10820 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10821 String[] newArgs; 10822 String name; 10823 if (opti >= args.length) { 10824 name = null; 10825 newArgs = EMPTY_STRING_ARRAY; 10826 } else { 10827 name = args[opti]; 10828 opti++; 10829 newArgs = new String[args.length - opti]; 10830 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10831 args.length - opti); 10832 } 10833 synchronized (this) { 10834 dumpProcessesLocked(fd, pw, args, opti, true, name); 10835 } 10836 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10837 synchronized (this) { 10838 dumpOomLocked(fd, pw, args, opti, true); 10839 } 10840 } else if ("provider".equals(cmd)) { 10841 String[] newArgs; 10842 String name; 10843 if (opti >= args.length) { 10844 name = null; 10845 newArgs = EMPTY_STRING_ARRAY; 10846 } else { 10847 name = args[opti]; 10848 opti++; 10849 newArgs = new String[args.length - opti]; 10850 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10851 } 10852 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10853 pw.println("No providers match: " + name); 10854 pw.println("Use -h for help."); 10855 } 10856 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10857 synchronized (this) { 10858 dumpProvidersLocked(fd, pw, args, opti, true, null); 10859 } 10860 } else if ("service".equals(cmd)) { 10861 String[] newArgs; 10862 String name; 10863 if (opti >= args.length) { 10864 name = null; 10865 newArgs = EMPTY_STRING_ARRAY; 10866 } else { 10867 name = args[opti]; 10868 opti++; 10869 newArgs = new String[args.length - opti]; 10870 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10871 args.length - opti); 10872 } 10873 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10874 pw.println("No services match: " + name); 10875 pw.println("Use -h for help."); 10876 } 10877 } else if ("package".equals(cmd)) { 10878 String[] newArgs; 10879 if (opti >= args.length) { 10880 pw.println("package: no package name specified"); 10881 pw.println("Use -h for help."); 10882 } else { 10883 dumpPackage = args[opti]; 10884 opti++; 10885 newArgs = new String[args.length - opti]; 10886 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10887 args.length - opti); 10888 args = newArgs; 10889 opti = 0; 10890 more = true; 10891 } 10892 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10893 synchronized (this) { 10894 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10895 } 10896 } else { 10897 // Dumping a single activity? 10898 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10899 pw.println("Bad activity command, or no activities match: " + cmd); 10900 pw.println("Use -h for help."); 10901 } 10902 } 10903 if (!more) { 10904 Binder.restoreCallingIdentity(origId); 10905 return; 10906 } 10907 } 10908 10909 // No piece of data specified, dump everything. 10910 synchronized (this) { 10911 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10912 pw.println(); 10913 if (dumpAll) { 10914 pw.println("-------------------------------------------------------------------------------"); 10915 } 10916 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10917 pw.println(); 10918 if (dumpAll) { 10919 pw.println("-------------------------------------------------------------------------------"); 10920 } 10921 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10922 pw.println(); 10923 if (dumpAll) { 10924 pw.println("-------------------------------------------------------------------------------"); 10925 } 10926 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10927 pw.println(); 10928 if (dumpAll) { 10929 pw.println("-------------------------------------------------------------------------------"); 10930 } 10931 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10932 pw.println(); 10933 if (dumpAll) { 10934 pw.println("-------------------------------------------------------------------------------"); 10935 } 10936 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10937 } 10938 Binder.restoreCallingIdentity(origId); 10939 } 10940 10941 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10942 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10943 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10944 10945 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10946 dumpPackage); 10947 boolean needSep = printedAnything; 10948 10949 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10950 dumpPackage, needSep, " mFocusedActivity: "); 10951 if (printed) { 10952 printedAnything = true; 10953 needSep = false; 10954 } 10955 10956 if (dumpPackage == null) { 10957 if (needSep) { 10958 pw.println(); 10959 } 10960 needSep = true; 10961 printedAnything = true; 10962 mStackSupervisor.dump(pw, " "); 10963 } 10964 10965 if (mRecentTasks.size() > 0) { 10966 boolean printedHeader = false; 10967 10968 final int N = mRecentTasks.size(); 10969 for (int i=0; i<N; i++) { 10970 TaskRecord tr = mRecentTasks.get(i); 10971 if (dumpPackage != null) { 10972 if (tr.realActivity == null || 10973 !dumpPackage.equals(tr.realActivity)) { 10974 continue; 10975 } 10976 } 10977 if (!printedHeader) { 10978 if (needSep) { 10979 pw.println(); 10980 } 10981 pw.println(" Recent tasks:"); 10982 printedHeader = true; 10983 printedAnything = true; 10984 } 10985 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10986 pw.println(tr); 10987 if (dumpAll) { 10988 mRecentTasks.get(i).dump(pw, " "); 10989 } 10990 } 10991 } 10992 10993 if (!printedAnything) { 10994 pw.println(" (nothing)"); 10995 } 10996 } 10997 10998 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10999 int opti, boolean dumpAll, String dumpPackage) { 11000 boolean needSep = false; 11001 boolean printedAnything = false; 11002 int numPers = 0; 11003 11004 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 11005 11006 if (dumpAll) { 11007 final int NP = mProcessNames.getMap().size(); 11008 for (int ip=0; ip<NP; ip++) { 11009 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 11010 final int NA = procs.size(); 11011 for (int ia=0; ia<NA; ia++) { 11012 ProcessRecord r = procs.valueAt(ia); 11013 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11014 continue; 11015 } 11016 if (!needSep) { 11017 pw.println(" All known processes:"); 11018 needSep = true; 11019 printedAnything = true; 11020 } 11021 pw.print(r.persistent ? " *PERS*" : " *APP*"); 11022 pw.print(" UID "); pw.print(procs.keyAt(ia)); 11023 pw.print(" "); pw.println(r); 11024 r.dump(pw, " "); 11025 if (r.persistent) { 11026 numPers++; 11027 } 11028 } 11029 } 11030 } 11031 11032 if (mIsolatedProcesses.size() > 0) { 11033 boolean printed = false; 11034 for (int i=0; i<mIsolatedProcesses.size(); i++) { 11035 ProcessRecord r = mIsolatedProcesses.valueAt(i); 11036 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11037 continue; 11038 } 11039 if (!printed) { 11040 if (needSep) { 11041 pw.println(); 11042 } 11043 pw.println(" Isolated process list (sorted by uid):"); 11044 printedAnything = true; 11045 printed = true; 11046 needSep = true; 11047 } 11048 pw.println(String.format("%sIsolated #%2d: %s", 11049 " ", i, r.toString())); 11050 } 11051 } 11052 11053 if (mLruProcesses.size() > 0) { 11054 if (needSep) { 11055 pw.println(); 11056 } 11057 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 11058 pw.print(" total, non-act at "); 11059 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11060 pw.print(", non-svc at "); 11061 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11062 pw.println("):"); 11063 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 11064 needSep = true; 11065 printedAnything = true; 11066 } 11067 11068 if (dumpAll || dumpPackage != null) { 11069 synchronized (mPidsSelfLocked) { 11070 boolean printed = false; 11071 for (int i=0; i<mPidsSelfLocked.size(); i++) { 11072 ProcessRecord r = mPidsSelfLocked.valueAt(i); 11073 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11074 continue; 11075 } 11076 if (!printed) { 11077 if (needSep) pw.println(); 11078 needSep = true; 11079 pw.println(" PID mappings:"); 11080 printed = true; 11081 printedAnything = true; 11082 } 11083 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 11084 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 11085 } 11086 } 11087 } 11088 11089 if (mForegroundProcesses.size() > 0) { 11090 synchronized (mPidsSelfLocked) { 11091 boolean printed = false; 11092 for (int i=0; i<mForegroundProcesses.size(); i++) { 11093 ProcessRecord r = mPidsSelfLocked.get( 11094 mForegroundProcesses.valueAt(i).pid); 11095 if (dumpPackage != null && (r == null 11096 || !r.pkgList.containsKey(dumpPackage))) { 11097 continue; 11098 } 11099 if (!printed) { 11100 if (needSep) pw.println(); 11101 needSep = true; 11102 pw.println(" Foreground Processes:"); 11103 printed = true; 11104 printedAnything = true; 11105 } 11106 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11107 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11108 } 11109 } 11110 } 11111 11112 if (mPersistentStartingProcesses.size() > 0) { 11113 if (needSep) pw.println(); 11114 needSep = true; 11115 printedAnything = true; 11116 pw.println(" Persisent processes that are starting:"); 11117 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11118 "Starting Norm", "Restarting PERS", dumpPackage); 11119 } 11120 11121 if (mRemovedProcesses.size() > 0) { 11122 if (needSep) pw.println(); 11123 needSep = true; 11124 printedAnything = true; 11125 pw.println(" Processes that are being removed:"); 11126 dumpProcessList(pw, this, mRemovedProcesses, " ", 11127 "Removed Norm", "Removed PERS", dumpPackage); 11128 } 11129 11130 if (mProcessesOnHold.size() > 0) { 11131 if (needSep) pw.println(); 11132 needSep = true; 11133 printedAnything = true; 11134 pw.println(" Processes that are on old until the system is ready:"); 11135 dumpProcessList(pw, this, mProcessesOnHold, " ", 11136 "OnHold Norm", "OnHold PERS", dumpPackage); 11137 } 11138 11139 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11140 11141 if (mProcessCrashTimes.getMap().size() > 0) { 11142 boolean printed = false; 11143 long now = SystemClock.uptimeMillis(); 11144 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11145 final int NP = pmap.size(); 11146 for (int ip=0; ip<NP; ip++) { 11147 String pname = pmap.keyAt(ip); 11148 SparseArray<Long> uids = pmap.valueAt(ip); 11149 final int N = uids.size(); 11150 for (int i=0; i<N; i++) { 11151 int puid = uids.keyAt(i); 11152 ProcessRecord r = mProcessNames.get(pname, puid); 11153 if (dumpPackage != null && (r == null 11154 || !r.pkgList.containsKey(dumpPackage))) { 11155 continue; 11156 } 11157 if (!printed) { 11158 if (needSep) pw.println(); 11159 needSep = true; 11160 pw.println(" Time since processes crashed:"); 11161 printed = true; 11162 printedAnything = true; 11163 } 11164 pw.print(" Process "); pw.print(pname); 11165 pw.print(" uid "); pw.print(puid); 11166 pw.print(": last crashed "); 11167 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11168 pw.println(" ago"); 11169 } 11170 } 11171 } 11172 11173 if (mBadProcesses.getMap().size() > 0) { 11174 boolean printed = false; 11175 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11176 final int NP = pmap.size(); 11177 for (int ip=0; ip<NP; ip++) { 11178 String pname = pmap.keyAt(ip); 11179 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11180 final int N = uids.size(); 11181 for (int i=0; i<N; i++) { 11182 int puid = uids.keyAt(i); 11183 ProcessRecord r = mProcessNames.get(pname, puid); 11184 if (dumpPackage != null && (r == null 11185 || !r.pkgList.containsKey(dumpPackage))) { 11186 continue; 11187 } 11188 if (!printed) { 11189 if (needSep) pw.println(); 11190 needSep = true; 11191 pw.println(" Bad processes:"); 11192 printedAnything = true; 11193 } 11194 BadProcessInfo info = uids.valueAt(i); 11195 pw.print(" Bad process "); pw.print(pname); 11196 pw.print(" uid "); pw.print(puid); 11197 pw.print(": crashed at time "); pw.println(info.time); 11198 if (info.shortMsg != null) { 11199 pw.print(" Short msg: "); pw.println(info.shortMsg); 11200 } 11201 if (info.longMsg != null) { 11202 pw.print(" Long msg: "); pw.println(info.longMsg); 11203 } 11204 if (info.stack != null) { 11205 pw.println(" Stack:"); 11206 int lastPos = 0; 11207 for (int pos=0; pos<info.stack.length(); pos++) { 11208 if (info.stack.charAt(pos) == '\n') { 11209 pw.print(" "); 11210 pw.write(info.stack, lastPos, pos-lastPos); 11211 pw.println(); 11212 lastPos = pos+1; 11213 } 11214 } 11215 if (lastPos < info.stack.length()) { 11216 pw.print(" "); 11217 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11218 pw.println(); 11219 } 11220 } 11221 } 11222 } 11223 } 11224 11225 if (dumpPackage == null) { 11226 pw.println(); 11227 needSep = false; 11228 pw.println(" mStartedUsers:"); 11229 for (int i=0; i<mStartedUsers.size(); i++) { 11230 UserStartedState uss = mStartedUsers.valueAt(i); 11231 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11232 pw.print(": "); uss.dump("", pw); 11233 } 11234 pw.print(" mStartedUserArray: ["); 11235 for (int i=0; i<mStartedUserArray.length; i++) { 11236 if (i > 0) pw.print(", "); 11237 pw.print(mStartedUserArray[i]); 11238 } 11239 pw.println("]"); 11240 pw.print(" mUserLru: ["); 11241 for (int i=0; i<mUserLru.size(); i++) { 11242 if (i > 0) pw.print(", "); 11243 pw.print(mUserLru.get(i)); 11244 } 11245 pw.println("]"); 11246 if (dumpAll) { 11247 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11248 } 11249 } 11250 if (mHomeProcess != null && (dumpPackage == null 11251 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11252 if (needSep) { 11253 pw.println(); 11254 needSep = false; 11255 } 11256 pw.println(" mHomeProcess: " + mHomeProcess); 11257 } 11258 if (mPreviousProcess != null && (dumpPackage == null 11259 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11260 if (needSep) { 11261 pw.println(); 11262 needSep = false; 11263 } 11264 pw.println(" mPreviousProcess: " + mPreviousProcess); 11265 } 11266 if (dumpAll) { 11267 StringBuilder sb = new StringBuilder(128); 11268 sb.append(" mPreviousProcessVisibleTime: "); 11269 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11270 pw.println(sb); 11271 } 11272 if (mHeavyWeightProcess != null && (dumpPackage == null 11273 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11274 if (needSep) { 11275 pw.println(); 11276 needSep = false; 11277 } 11278 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11279 } 11280 if (dumpPackage == null) { 11281 pw.println(" mConfiguration: " + mConfiguration); 11282 } 11283 if (dumpAll) { 11284 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11285 if (mCompatModePackages.getPackages().size() > 0) { 11286 boolean printed = false; 11287 for (Map.Entry<String, Integer> entry 11288 : mCompatModePackages.getPackages().entrySet()) { 11289 String pkg = entry.getKey(); 11290 int mode = entry.getValue(); 11291 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11292 continue; 11293 } 11294 if (!printed) { 11295 pw.println(" mScreenCompatPackages:"); 11296 printed = true; 11297 } 11298 pw.print(" "); pw.print(pkg); pw.print(": "); 11299 pw.print(mode); pw.println(); 11300 } 11301 } 11302 } 11303 if (dumpPackage == null) { 11304 if (mSleeping || mWentToSleep || mLockScreenShown) { 11305 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11306 + " mLockScreenShown " + mLockScreenShown); 11307 } 11308 if (mShuttingDown || mRunningVoice) { 11309 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11310 } 11311 } 11312 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11313 || mOrigWaitForDebugger) { 11314 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11315 || dumpPackage.equals(mOrigDebugApp)) { 11316 if (needSep) { 11317 pw.println(); 11318 needSep = false; 11319 } 11320 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11321 + " mDebugTransient=" + mDebugTransient 11322 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11323 } 11324 } 11325 if (mOpenGlTraceApp != null) { 11326 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11327 if (needSep) { 11328 pw.println(); 11329 needSep = false; 11330 } 11331 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11332 } 11333 } 11334 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11335 || mProfileFd != null) { 11336 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11337 if (needSep) { 11338 pw.println(); 11339 needSep = false; 11340 } 11341 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11342 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11343 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11344 + mAutoStopProfiler); 11345 } 11346 } 11347 if (dumpPackage == null) { 11348 if (mAlwaysFinishActivities || mController != null) { 11349 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11350 + " mController=" + mController); 11351 } 11352 if (dumpAll) { 11353 pw.println(" Total persistent processes: " + numPers); 11354 pw.println(" mProcessesReady=" + mProcessesReady 11355 + " mSystemReady=" + mSystemReady); 11356 pw.println(" mBooting=" + mBooting 11357 + " mBooted=" + mBooted 11358 + " mFactoryTest=" + mFactoryTest); 11359 pw.print(" mLastPowerCheckRealtime="); 11360 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11361 pw.println(""); 11362 pw.print(" mLastPowerCheckUptime="); 11363 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11364 pw.println(""); 11365 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11366 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11367 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11368 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11369 + " (" + mLruProcesses.size() + " total)" 11370 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11371 + " mNumServiceProcs=" + mNumServiceProcs 11372 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11373 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11374 + " mLastMemoryLevel" + mLastMemoryLevel 11375 + " mLastNumProcesses" + mLastNumProcesses); 11376 long now = SystemClock.uptimeMillis(); 11377 pw.print(" mLastIdleTime="); 11378 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11379 pw.print(" mLowRamSinceLastIdle="); 11380 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11381 pw.println(); 11382 } 11383 } 11384 11385 if (!printedAnything) { 11386 pw.println(" (nothing)"); 11387 } 11388 } 11389 11390 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11391 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11392 if (mProcessesToGc.size() > 0) { 11393 boolean printed = false; 11394 long now = SystemClock.uptimeMillis(); 11395 for (int i=0; i<mProcessesToGc.size(); i++) { 11396 ProcessRecord proc = mProcessesToGc.get(i); 11397 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11398 continue; 11399 } 11400 if (!printed) { 11401 if (needSep) pw.println(); 11402 needSep = true; 11403 pw.println(" Processes that are waiting to GC:"); 11404 printed = true; 11405 } 11406 pw.print(" Process "); pw.println(proc); 11407 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11408 pw.print(", last gced="); 11409 pw.print(now-proc.lastRequestedGc); 11410 pw.print(" ms ago, last lowMem="); 11411 pw.print(now-proc.lastLowMemory); 11412 pw.println(" ms ago"); 11413 11414 } 11415 } 11416 return needSep; 11417 } 11418 11419 void printOomLevel(PrintWriter pw, String name, int adj) { 11420 pw.print(" "); 11421 if (adj >= 0) { 11422 pw.print(' '); 11423 if (adj < 10) pw.print(' '); 11424 } else { 11425 if (adj > -10) pw.print(' '); 11426 } 11427 pw.print(adj); 11428 pw.print(": "); 11429 pw.print(name); 11430 pw.print(" ("); 11431 pw.print(mProcessList.getMemLevel(adj)/1024); 11432 pw.println(" kB)"); 11433 } 11434 11435 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11436 int opti, boolean dumpAll) { 11437 boolean needSep = false; 11438 11439 if (mLruProcesses.size() > 0) { 11440 if (needSep) pw.println(); 11441 needSep = true; 11442 pw.println(" OOM levels:"); 11443 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11444 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11445 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11446 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11447 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11448 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11449 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11450 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11451 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11452 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11453 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11454 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11455 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11456 11457 if (needSep) pw.println(); 11458 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11459 pw.print(" total, non-act at "); 11460 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11461 pw.print(", non-svc at "); 11462 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11463 pw.println("):"); 11464 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11465 needSep = true; 11466 } 11467 11468 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11469 11470 pw.println(); 11471 pw.println(" mHomeProcess: " + mHomeProcess); 11472 pw.println(" mPreviousProcess: " + mPreviousProcess); 11473 if (mHeavyWeightProcess != null) { 11474 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11475 } 11476 11477 return true; 11478 } 11479 11480 /** 11481 * There are three ways to call this: 11482 * - no provider specified: dump all the providers 11483 * - a flattened component name that matched an existing provider was specified as the 11484 * first arg: dump that one provider 11485 * - the first arg isn't the flattened component name of an existing provider: 11486 * dump all providers whose component contains the first arg as a substring 11487 */ 11488 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11489 int opti, boolean dumpAll) { 11490 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11491 } 11492 11493 static class ItemMatcher { 11494 ArrayList<ComponentName> components; 11495 ArrayList<String> strings; 11496 ArrayList<Integer> objects; 11497 boolean all; 11498 11499 ItemMatcher() { 11500 all = true; 11501 } 11502 11503 void build(String name) { 11504 ComponentName componentName = ComponentName.unflattenFromString(name); 11505 if (componentName != null) { 11506 if (components == null) { 11507 components = new ArrayList<ComponentName>(); 11508 } 11509 components.add(componentName); 11510 all = false; 11511 } else { 11512 int objectId = 0; 11513 // Not a '/' separated full component name; maybe an object ID? 11514 try { 11515 objectId = Integer.parseInt(name, 16); 11516 if (objects == null) { 11517 objects = new ArrayList<Integer>(); 11518 } 11519 objects.add(objectId); 11520 all = false; 11521 } catch (RuntimeException e) { 11522 // Not an integer; just do string match. 11523 if (strings == null) { 11524 strings = new ArrayList<String>(); 11525 } 11526 strings.add(name); 11527 all = false; 11528 } 11529 } 11530 } 11531 11532 int build(String[] args, int opti) { 11533 for (; opti<args.length; opti++) { 11534 String name = args[opti]; 11535 if ("--".equals(name)) { 11536 return opti+1; 11537 } 11538 build(name); 11539 } 11540 return opti; 11541 } 11542 11543 boolean match(Object object, ComponentName comp) { 11544 if (all) { 11545 return true; 11546 } 11547 if (components != null) { 11548 for (int i=0; i<components.size(); i++) { 11549 if (components.get(i).equals(comp)) { 11550 return true; 11551 } 11552 } 11553 } 11554 if (objects != null) { 11555 for (int i=0; i<objects.size(); i++) { 11556 if (System.identityHashCode(object) == objects.get(i)) { 11557 return true; 11558 } 11559 } 11560 } 11561 if (strings != null) { 11562 String flat = comp.flattenToString(); 11563 for (int i=0; i<strings.size(); i++) { 11564 if (flat.contains(strings.get(i))) { 11565 return true; 11566 } 11567 } 11568 } 11569 return false; 11570 } 11571 } 11572 11573 /** 11574 * There are three things that cmd can be: 11575 * - a flattened component name that matches an existing activity 11576 * - the cmd arg isn't the flattened component name of an existing activity: 11577 * dump all activity whose component contains the cmd as a substring 11578 * - A hex number of the ActivityRecord object instance. 11579 */ 11580 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11581 int opti, boolean dumpAll) { 11582 ArrayList<ActivityRecord> activities; 11583 11584 synchronized (this) { 11585 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11586 } 11587 11588 if (activities.size() <= 0) { 11589 return false; 11590 } 11591 11592 String[] newArgs = new String[args.length - opti]; 11593 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11594 11595 TaskRecord lastTask = null; 11596 boolean needSep = false; 11597 for (int i=activities.size()-1; i>=0; i--) { 11598 ActivityRecord r = activities.get(i); 11599 if (needSep) { 11600 pw.println(); 11601 } 11602 needSep = true; 11603 synchronized (this) { 11604 if (lastTask != r.task) { 11605 lastTask = r.task; 11606 pw.print("TASK "); pw.print(lastTask.affinity); 11607 pw.print(" id="); pw.println(lastTask.taskId); 11608 if (dumpAll) { 11609 lastTask.dump(pw, " "); 11610 } 11611 } 11612 } 11613 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11614 } 11615 return true; 11616 } 11617 11618 /** 11619 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11620 * there is a thread associated with the activity. 11621 */ 11622 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11623 final ActivityRecord r, String[] args, boolean dumpAll) { 11624 String innerPrefix = prefix + " "; 11625 synchronized (this) { 11626 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11627 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11628 pw.print(" pid="); 11629 if (r.app != null) pw.println(r.app.pid); 11630 else pw.println("(not running)"); 11631 if (dumpAll) { 11632 r.dump(pw, innerPrefix); 11633 } 11634 } 11635 if (r.app != null && r.app.thread != null) { 11636 // flush anything that is already in the PrintWriter since the thread is going 11637 // to write to the file descriptor directly 11638 pw.flush(); 11639 try { 11640 TransferPipe tp = new TransferPipe(); 11641 try { 11642 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11643 r.appToken, innerPrefix, args); 11644 tp.go(fd); 11645 } finally { 11646 tp.kill(); 11647 } 11648 } catch (IOException e) { 11649 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11650 } catch (RemoteException e) { 11651 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11652 } 11653 } 11654 } 11655 11656 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11657 int opti, boolean dumpAll, String dumpPackage) { 11658 boolean needSep = false; 11659 boolean onlyHistory = false; 11660 boolean printedAnything = false; 11661 11662 if ("history".equals(dumpPackage)) { 11663 if (opti < args.length && "-s".equals(args[opti])) { 11664 dumpAll = false; 11665 } 11666 onlyHistory = true; 11667 dumpPackage = null; 11668 } 11669 11670 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11671 if (!onlyHistory && dumpAll) { 11672 if (mRegisteredReceivers.size() > 0) { 11673 boolean printed = false; 11674 Iterator it = mRegisteredReceivers.values().iterator(); 11675 while (it.hasNext()) { 11676 ReceiverList r = (ReceiverList)it.next(); 11677 if (dumpPackage != null && (r.app == null || 11678 !dumpPackage.equals(r.app.info.packageName))) { 11679 continue; 11680 } 11681 if (!printed) { 11682 pw.println(" Registered Receivers:"); 11683 needSep = true; 11684 printed = true; 11685 printedAnything = true; 11686 } 11687 pw.print(" * "); pw.println(r); 11688 r.dump(pw, " "); 11689 } 11690 } 11691 11692 if (mReceiverResolver.dump(pw, needSep ? 11693 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11694 " ", dumpPackage, false)) { 11695 needSep = true; 11696 printedAnything = true; 11697 } 11698 } 11699 11700 for (BroadcastQueue q : mBroadcastQueues) { 11701 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11702 printedAnything |= needSep; 11703 } 11704 11705 needSep = true; 11706 11707 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11708 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11709 if (needSep) { 11710 pw.println(); 11711 } 11712 needSep = true; 11713 printedAnything = true; 11714 pw.print(" Sticky broadcasts for user "); 11715 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11716 StringBuilder sb = new StringBuilder(128); 11717 for (Map.Entry<String, ArrayList<Intent>> ent 11718 : mStickyBroadcasts.valueAt(user).entrySet()) { 11719 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11720 if (dumpAll) { 11721 pw.println(":"); 11722 ArrayList<Intent> intents = ent.getValue(); 11723 final int N = intents.size(); 11724 for (int i=0; i<N; i++) { 11725 sb.setLength(0); 11726 sb.append(" Intent: "); 11727 intents.get(i).toShortString(sb, false, true, false, false); 11728 pw.println(sb.toString()); 11729 Bundle bundle = intents.get(i).getExtras(); 11730 if (bundle != null) { 11731 pw.print(" "); 11732 pw.println(bundle.toString()); 11733 } 11734 } 11735 } else { 11736 pw.println(""); 11737 } 11738 } 11739 } 11740 } 11741 11742 if (!onlyHistory && dumpAll) { 11743 pw.println(); 11744 for (BroadcastQueue queue : mBroadcastQueues) { 11745 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11746 + queue.mBroadcastsScheduled); 11747 } 11748 pw.println(" mHandler:"); 11749 mHandler.dump(new PrintWriterPrinter(pw), " "); 11750 needSep = true; 11751 printedAnything = true; 11752 } 11753 11754 if (!printedAnything) { 11755 pw.println(" (nothing)"); 11756 } 11757 } 11758 11759 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11760 int opti, boolean dumpAll, String dumpPackage) { 11761 boolean needSep; 11762 boolean printedAnything = false; 11763 11764 ItemMatcher matcher = new ItemMatcher(); 11765 matcher.build(args, opti); 11766 11767 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11768 11769 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11770 printedAnything |= needSep; 11771 11772 if (mLaunchingProviders.size() > 0) { 11773 boolean printed = false; 11774 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11775 ContentProviderRecord r = mLaunchingProviders.get(i); 11776 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11777 continue; 11778 } 11779 if (!printed) { 11780 if (needSep) pw.println(); 11781 needSep = true; 11782 pw.println(" Launching content providers:"); 11783 printed = true; 11784 printedAnything = true; 11785 } 11786 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11787 pw.println(r); 11788 } 11789 } 11790 11791 if (mGrantedUriPermissions.size() > 0) { 11792 boolean printed = false; 11793 int dumpUid = -2; 11794 if (dumpPackage != null) { 11795 try { 11796 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11797 } catch (NameNotFoundException e) { 11798 dumpUid = -1; 11799 } 11800 } 11801 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11802 int uid = mGrantedUriPermissions.keyAt(i); 11803 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11804 continue; 11805 } 11806 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11807 if (!printed) { 11808 if (needSep) pw.println(); 11809 needSep = true; 11810 pw.println(" Granted Uri Permissions:"); 11811 printed = true; 11812 printedAnything = true; 11813 } 11814 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11815 for (UriPermission perm : perms.values()) { 11816 pw.print(" "); pw.println(perm); 11817 if (dumpAll) { 11818 perm.dump(pw, " "); 11819 } 11820 } 11821 } 11822 } 11823 11824 if (!printedAnything) { 11825 pw.println(" (nothing)"); 11826 } 11827 } 11828 11829 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11830 int opti, boolean dumpAll, String dumpPackage) { 11831 boolean printed = false; 11832 11833 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11834 11835 if (mIntentSenderRecords.size() > 0) { 11836 Iterator<WeakReference<PendingIntentRecord>> it 11837 = mIntentSenderRecords.values().iterator(); 11838 while (it.hasNext()) { 11839 WeakReference<PendingIntentRecord> ref = it.next(); 11840 PendingIntentRecord rec = ref != null ? ref.get(): null; 11841 if (dumpPackage != null && (rec == null 11842 || !dumpPackage.equals(rec.key.packageName))) { 11843 continue; 11844 } 11845 printed = true; 11846 if (rec != null) { 11847 pw.print(" * "); pw.println(rec); 11848 if (dumpAll) { 11849 rec.dump(pw, " "); 11850 } 11851 } else { 11852 pw.print(" * "); pw.println(ref); 11853 } 11854 } 11855 } 11856 11857 if (!printed) { 11858 pw.println(" (nothing)"); 11859 } 11860 } 11861 11862 private static final int dumpProcessList(PrintWriter pw, 11863 ActivityManagerService service, List list, 11864 String prefix, String normalLabel, String persistentLabel, 11865 String dumpPackage) { 11866 int numPers = 0; 11867 final int N = list.size()-1; 11868 for (int i=N; i>=0; i--) { 11869 ProcessRecord r = (ProcessRecord)list.get(i); 11870 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11871 continue; 11872 } 11873 pw.println(String.format("%s%s #%2d: %s", 11874 prefix, (r.persistent ? persistentLabel : normalLabel), 11875 i, r.toString())); 11876 if (r.persistent) { 11877 numPers++; 11878 } 11879 } 11880 return numPers; 11881 } 11882 11883 private static final boolean dumpProcessOomList(PrintWriter pw, 11884 ActivityManagerService service, List<ProcessRecord> origList, 11885 String prefix, String normalLabel, String persistentLabel, 11886 boolean inclDetails, String dumpPackage) { 11887 11888 ArrayList<Pair<ProcessRecord, Integer>> list 11889 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11890 for (int i=0; i<origList.size(); i++) { 11891 ProcessRecord r = origList.get(i); 11892 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11893 continue; 11894 } 11895 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11896 } 11897 11898 if (list.size() <= 0) { 11899 return false; 11900 } 11901 11902 Comparator<Pair<ProcessRecord, Integer>> comparator 11903 = new Comparator<Pair<ProcessRecord, Integer>>() { 11904 @Override 11905 public int compare(Pair<ProcessRecord, Integer> object1, 11906 Pair<ProcessRecord, Integer> object2) { 11907 if (object1.first.setAdj != object2.first.setAdj) { 11908 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11909 } 11910 if (object1.second.intValue() != object2.second.intValue()) { 11911 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11912 } 11913 return 0; 11914 } 11915 }; 11916 11917 Collections.sort(list, comparator); 11918 11919 final long curRealtime = SystemClock.elapsedRealtime(); 11920 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11921 final long curUptime = SystemClock.uptimeMillis(); 11922 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11923 11924 for (int i=list.size()-1; i>=0; i--) { 11925 ProcessRecord r = list.get(i).first; 11926 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11927 char schedGroup; 11928 switch (r.setSchedGroup) { 11929 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11930 schedGroup = 'B'; 11931 break; 11932 case Process.THREAD_GROUP_DEFAULT: 11933 schedGroup = 'F'; 11934 break; 11935 default: 11936 schedGroup = '?'; 11937 break; 11938 } 11939 char foreground; 11940 if (r.foregroundActivities) { 11941 foreground = 'A'; 11942 } else if (r.foregroundServices) { 11943 foreground = 'S'; 11944 } else { 11945 foreground = ' '; 11946 } 11947 String procState = ProcessList.makeProcStateString(r.curProcState); 11948 pw.print(prefix); 11949 pw.print(r.persistent ? persistentLabel : normalLabel); 11950 pw.print(" #"); 11951 int num = (origList.size()-1)-list.get(i).second; 11952 if (num < 10) pw.print(' '); 11953 pw.print(num); 11954 pw.print(": "); 11955 pw.print(oomAdj); 11956 pw.print(' '); 11957 pw.print(schedGroup); 11958 pw.print('/'); 11959 pw.print(foreground); 11960 pw.print('/'); 11961 pw.print(procState); 11962 pw.print(" trm:"); 11963 if (r.trimMemoryLevel < 10) pw.print(' '); 11964 pw.print(r.trimMemoryLevel); 11965 pw.print(' '); 11966 pw.print(r.toShortString()); 11967 pw.print(" ("); 11968 pw.print(r.adjType); 11969 pw.println(')'); 11970 if (r.adjSource != null || r.adjTarget != null) { 11971 pw.print(prefix); 11972 pw.print(" "); 11973 if (r.adjTarget instanceof ComponentName) { 11974 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11975 } else if (r.adjTarget != null) { 11976 pw.print(r.adjTarget.toString()); 11977 } else { 11978 pw.print("{null}"); 11979 } 11980 pw.print("<="); 11981 if (r.adjSource instanceof ProcessRecord) { 11982 pw.print("Proc{"); 11983 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11984 pw.println("}"); 11985 } else if (r.adjSource != null) { 11986 pw.println(r.adjSource.toString()); 11987 } else { 11988 pw.println("{null}"); 11989 } 11990 } 11991 if (inclDetails) { 11992 pw.print(prefix); 11993 pw.print(" "); 11994 pw.print("oom: max="); pw.print(r.maxAdj); 11995 pw.print(" curRaw="); pw.print(r.curRawAdj); 11996 pw.print(" setRaw="); pw.print(r.setRawAdj); 11997 pw.print(" cur="); pw.print(r.curAdj); 11998 pw.print(" set="); pw.println(r.setAdj); 11999 pw.print(prefix); 12000 pw.print(" "); 12001 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 12002 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 12003 pw.print(" lastPss="); pw.print(r.lastPss); 12004 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 12005 pw.print(prefix); 12006 pw.print(" "); 12007 pw.print("keeping="); pw.print(r.keeping); 12008 pw.print(" cached="); pw.print(r.cached); 12009 pw.print(" empty="); pw.print(r.empty); 12010 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 12011 12012 if (!r.keeping) { 12013 if (r.lastWakeTime != 0) { 12014 long wtime; 12015 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 12016 synchronized (stats) { 12017 wtime = stats.getProcessWakeTime(r.info.uid, 12018 r.pid, curRealtime); 12019 } 12020 long timeUsed = wtime - r.lastWakeTime; 12021 pw.print(prefix); 12022 pw.print(" "); 12023 pw.print("keep awake over "); 12024 TimeUtils.formatDuration(realtimeSince, pw); 12025 pw.print(" used "); 12026 TimeUtils.formatDuration(timeUsed, pw); 12027 pw.print(" ("); 12028 pw.print((timeUsed*100)/realtimeSince); 12029 pw.println("%)"); 12030 } 12031 if (r.lastCpuTime != 0) { 12032 long timeUsed = r.curCpuTime - r.lastCpuTime; 12033 pw.print(prefix); 12034 pw.print(" "); 12035 pw.print("run cpu over "); 12036 TimeUtils.formatDuration(uptimeSince, pw); 12037 pw.print(" used "); 12038 TimeUtils.formatDuration(timeUsed, pw); 12039 pw.print(" ("); 12040 pw.print((timeUsed*100)/uptimeSince); 12041 pw.println("%)"); 12042 } 12043 } 12044 } 12045 } 12046 return true; 12047 } 12048 12049 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 12050 ArrayList<ProcessRecord> procs; 12051 synchronized (this) { 12052 if (args != null && args.length > start 12053 && args[start].charAt(0) != '-') { 12054 procs = new ArrayList<ProcessRecord>(); 12055 int pid = -1; 12056 try { 12057 pid = Integer.parseInt(args[start]); 12058 } catch (NumberFormatException e) { 12059 } 12060 for (int i=mLruProcesses.size()-1; i>=0; i--) { 12061 ProcessRecord proc = mLruProcesses.get(i); 12062 if (proc.pid == pid) { 12063 procs.add(proc); 12064 } else if (proc.processName.equals(args[start])) { 12065 procs.add(proc); 12066 } 12067 } 12068 if (procs.size() <= 0) { 12069 return null; 12070 } 12071 } else { 12072 procs = new ArrayList<ProcessRecord>(mLruProcesses); 12073 } 12074 } 12075 return procs; 12076 } 12077 12078 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 12079 PrintWriter pw, String[] args) { 12080 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12081 if (procs == null) { 12082 pw.println("No process found for: " + args[0]); 12083 return; 12084 } 12085 12086 long uptime = SystemClock.uptimeMillis(); 12087 long realtime = SystemClock.elapsedRealtime(); 12088 pw.println("Applications Graphics Acceleration Info:"); 12089 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12090 12091 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12092 ProcessRecord r = procs.get(i); 12093 if (r.thread != null) { 12094 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 12095 pw.flush(); 12096 try { 12097 TransferPipe tp = new TransferPipe(); 12098 try { 12099 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12100 tp.go(fd); 12101 } finally { 12102 tp.kill(); 12103 } 12104 } catch (IOException e) { 12105 pw.println("Failure while dumping the app: " + r); 12106 pw.flush(); 12107 } catch (RemoteException e) { 12108 pw.println("Got a RemoteException while dumping the app " + r); 12109 pw.flush(); 12110 } 12111 } 12112 } 12113 } 12114 12115 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12116 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12117 if (procs == null) { 12118 pw.println("No process found for: " + args[0]); 12119 return; 12120 } 12121 12122 pw.println("Applications Database Info:"); 12123 12124 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12125 ProcessRecord r = procs.get(i); 12126 if (r.thread != null) { 12127 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12128 pw.flush(); 12129 try { 12130 TransferPipe tp = new TransferPipe(); 12131 try { 12132 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12133 tp.go(fd); 12134 } finally { 12135 tp.kill(); 12136 } 12137 } catch (IOException e) { 12138 pw.println("Failure while dumping the app: " + r); 12139 pw.flush(); 12140 } catch (RemoteException e) { 12141 pw.println("Got a RemoteException while dumping the app " + r); 12142 pw.flush(); 12143 } 12144 } 12145 } 12146 } 12147 12148 final static class MemItem { 12149 final boolean isProc; 12150 final String label; 12151 final String shortLabel; 12152 final long pss; 12153 final int id; 12154 final boolean hasActivities; 12155 ArrayList<MemItem> subitems; 12156 12157 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12158 boolean _hasActivities) { 12159 isProc = true; 12160 label = _label; 12161 shortLabel = _shortLabel; 12162 pss = _pss; 12163 id = _id; 12164 hasActivities = _hasActivities; 12165 } 12166 12167 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12168 isProc = false; 12169 label = _label; 12170 shortLabel = _shortLabel; 12171 pss = _pss; 12172 id = _id; 12173 hasActivities = false; 12174 } 12175 } 12176 12177 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12178 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12179 if (sort && !isCompact) { 12180 Collections.sort(items, new Comparator<MemItem>() { 12181 @Override 12182 public int compare(MemItem lhs, MemItem rhs) { 12183 if (lhs.pss < rhs.pss) { 12184 return 1; 12185 } else if (lhs.pss > rhs.pss) { 12186 return -1; 12187 } 12188 return 0; 12189 } 12190 }); 12191 } 12192 12193 for (int i=0; i<items.size(); i++) { 12194 MemItem mi = items.get(i); 12195 if (!isCompact) { 12196 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12197 } else if (mi.isProc) { 12198 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12199 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12200 pw.println(mi.hasActivities ? ",a" : ",e"); 12201 } else { 12202 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12203 pw.println(mi.pss); 12204 } 12205 if (mi.subitems != null) { 12206 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12207 true, isCompact); 12208 } 12209 } 12210 } 12211 12212 // These are in KB. 12213 static final long[] DUMP_MEM_BUCKETS = new long[] { 12214 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12215 120*1024, 160*1024, 200*1024, 12216 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12217 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12218 }; 12219 12220 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12221 boolean stackLike) { 12222 int start = label.lastIndexOf('.'); 12223 if (start >= 0) start++; 12224 else start = 0; 12225 int end = label.length(); 12226 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12227 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12228 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12229 out.append(bucket); 12230 out.append(stackLike ? "MB." : "MB "); 12231 out.append(label, start, end); 12232 return; 12233 } 12234 } 12235 out.append(memKB/1024); 12236 out.append(stackLike ? "MB." : "MB "); 12237 out.append(label, start, end); 12238 } 12239 12240 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12241 ProcessList.NATIVE_ADJ, 12242 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12243 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12244 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12245 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12246 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12247 }; 12248 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12249 "Native", 12250 "System", "Persistent", "Foreground", 12251 "Visible", "Perceptible", 12252 "Heavy Weight", "Backup", 12253 "A Services", "Home", 12254 "Previous", "B Services", "Cached" 12255 }; 12256 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12257 "native", 12258 "sys", "pers", "fore", 12259 "vis", "percept", 12260 "heavy", "backup", 12261 "servicea", "home", 12262 "prev", "serviceb", "cached" 12263 }; 12264 12265 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12266 long realtime, boolean isCheckinRequest, boolean isCompact) { 12267 if (isCheckinRequest || isCompact) { 12268 // short checkin version 12269 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12270 } else { 12271 pw.println("Applications Memory Usage (kB):"); 12272 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12273 } 12274 } 12275 12276 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12277 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12278 boolean dumpDetails = false; 12279 boolean dumpFullDetails = false; 12280 boolean dumpDalvik = false; 12281 boolean oomOnly = false; 12282 boolean isCompact = false; 12283 boolean localOnly = false; 12284 12285 int opti = 0; 12286 while (opti < args.length) { 12287 String opt = args[opti]; 12288 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12289 break; 12290 } 12291 opti++; 12292 if ("-a".equals(opt)) { 12293 dumpDetails = true; 12294 dumpFullDetails = true; 12295 dumpDalvik = true; 12296 } else if ("-d".equals(opt)) { 12297 dumpDalvik = true; 12298 } else if ("-c".equals(opt)) { 12299 isCompact = true; 12300 } else if ("--oom".equals(opt)) { 12301 oomOnly = true; 12302 } else if ("--local".equals(opt)) { 12303 localOnly = true; 12304 } else if ("-h".equals(opt)) { 12305 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12306 pw.println(" -a: include all available information for each process."); 12307 pw.println(" -d: include dalvik details when dumping process details."); 12308 pw.println(" -c: dump in a compact machine-parseable representation."); 12309 pw.println(" --oom: only show processes organized by oom adj."); 12310 pw.println(" --local: only collect details locally, don't call process."); 12311 pw.println("If [process] is specified it can be the name or "); 12312 pw.println("pid of a specific process to dump."); 12313 return; 12314 } else { 12315 pw.println("Unknown argument: " + opt + "; use -h for help"); 12316 } 12317 } 12318 12319 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12320 long uptime = SystemClock.uptimeMillis(); 12321 long realtime = SystemClock.elapsedRealtime(); 12322 final long[] tmpLong = new long[1]; 12323 12324 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12325 if (procs == null) { 12326 // No Java processes. Maybe they want to print a native process. 12327 if (args != null && args.length > opti 12328 && args[opti].charAt(0) != '-') { 12329 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12330 = new ArrayList<ProcessCpuTracker.Stats>(); 12331 updateCpuStatsNow(); 12332 int findPid = -1; 12333 try { 12334 findPid = Integer.parseInt(args[opti]); 12335 } catch (NumberFormatException e) { 12336 } 12337 synchronized (mProcessCpuThread) { 12338 final int N = mProcessCpuTracker.countStats(); 12339 for (int i=0; i<N; i++) { 12340 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12341 if (st.pid == findPid || (st.baseName != null 12342 && st.baseName.equals(args[opti]))) { 12343 nativeProcs.add(st); 12344 } 12345 } 12346 } 12347 if (nativeProcs.size() > 0) { 12348 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12349 isCompact); 12350 Debug.MemoryInfo mi = null; 12351 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12352 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12353 final int pid = r.pid; 12354 if (!isCheckinRequest && dumpDetails) { 12355 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12356 } 12357 if (mi == null) { 12358 mi = new Debug.MemoryInfo(); 12359 } 12360 if (dumpDetails || (!brief && !oomOnly)) { 12361 Debug.getMemoryInfo(pid, mi); 12362 } else { 12363 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12364 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12365 } 12366 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12367 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12368 if (isCheckinRequest) { 12369 pw.println(); 12370 } 12371 } 12372 return; 12373 } 12374 } 12375 pw.println("No process found for: " + args[opti]); 12376 return; 12377 } 12378 12379 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12380 dumpDetails = true; 12381 } 12382 12383 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12384 12385 String[] innerArgs = new String[args.length-opti]; 12386 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12387 12388 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12389 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12390 long nativePss=0, dalvikPss=0, otherPss=0; 12391 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12392 12393 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12394 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12395 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12396 12397 long totalPss = 0; 12398 long cachedPss = 0; 12399 12400 Debug.MemoryInfo mi = null; 12401 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12402 final ProcessRecord r = procs.get(i); 12403 final IApplicationThread thread; 12404 final int pid; 12405 final int oomAdj; 12406 final boolean hasActivities; 12407 synchronized (this) { 12408 thread = r.thread; 12409 pid = r.pid; 12410 oomAdj = r.getSetAdjWithServices(); 12411 hasActivities = r.activities.size() > 0; 12412 } 12413 if (thread != null) { 12414 if (!isCheckinRequest && dumpDetails) { 12415 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12416 } 12417 if (mi == null) { 12418 mi = new Debug.MemoryInfo(); 12419 } 12420 if (dumpDetails || (!brief && !oomOnly)) { 12421 Debug.getMemoryInfo(pid, mi); 12422 } else { 12423 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12424 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12425 } 12426 if (dumpDetails) { 12427 if (localOnly) { 12428 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12429 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12430 if (isCheckinRequest) { 12431 pw.println(); 12432 } 12433 } else { 12434 try { 12435 pw.flush(); 12436 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12437 dumpDalvik, innerArgs); 12438 } catch (RemoteException e) { 12439 if (!isCheckinRequest) { 12440 pw.println("Got RemoteException!"); 12441 pw.flush(); 12442 } 12443 } 12444 } 12445 } 12446 12447 final long myTotalPss = mi.getTotalPss(); 12448 final long myTotalUss = mi.getTotalUss(); 12449 12450 synchronized (this) { 12451 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12452 // Record this for posterity if the process has been stable. 12453 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12454 } 12455 } 12456 12457 if (!isCheckinRequest && mi != null) { 12458 totalPss += myTotalPss; 12459 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12460 (hasActivities ? " / activities)" : ")"), 12461 r.processName, myTotalPss, pid, hasActivities); 12462 procMems.add(pssItem); 12463 procMemsMap.put(pid, pssItem); 12464 12465 nativePss += mi.nativePss; 12466 dalvikPss += mi.dalvikPss; 12467 otherPss += mi.otherPss; 12468 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12469 long mem = mi.getOtherPss(j); 12470 miscPss[j] += mem; 12471 otherPss -= mem; 12472 } 12473 12474 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12475 cachedPss += myTotalPss; 12476 } 12477 12478 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12479 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12480 || oomIndex == (oomPss.length-1)) { 12481 oomPss[oomIndex] += myTotalPss; 12482 if (oomProcs[oomIndex] == null) { 12483 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12484 } 12485 oomProcs[oomIndex].add(pssItem); 12486 break; 12487 } 12488 } 12489 } 12490 } 12491 } 12492 12493 if (!isCheckinRequest && procs.size() > 1) { 12494 // If we are showing aggregations, also look for native processes to 12495 // include so that our aggregations are more accurate. 12496 updateCpuStatsNow(); 12497 synchronized (mProcessCpuThread) { 12498 final int N = mProcessCpuTracker.countStats(); 12499 for (int i=0; i<N; i++) { 12500 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12501 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12502 if (mi == null) { 12503 mi = new Debug.MemoryInfo(); 12504 } 12505 if (!brief && !oomOnly) { 12506 Debug.getMemoryInfo(st.pid, mi); 12507 } else { 12508 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12509 mi.nativePrivateDirty = (int)tmpLong[0]; 12510 } 12511 12512 final long myTotalPss = mi.getTotalPss(); 12513 totalPss += myTotalPss; 12514 12515 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12516 st.name, myTotalPss, st.pid, false); 12517 procMems.add(pssItem); 12518 12519 nativePss += mi.nativePss; 12520 dalvikPss += mi.dalvikPss; 12521 otherPss += mi.otherPss; 12522 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12523 long mem = mi.getOtherPss(j); 12524 miscPss[j] += mem; 12525 otherPss -= mem; 12526 } 12527 oomPss[0] += myTotalPss; 12528 if (oomProcs[0] == null) { 12529 oomProcs[0] = new ArrayList<MemItem>(); 12530 } 12531 oomProcs[0].add(pssItem); 12532 } 12533 } 12534 } 12535 12536 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12537 12538 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12539 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12540 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12541 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12542 String label = Debug.MemoryInfo.getOtherLabel(j); 12543 catMems.add(new MemItem(label, label, miscPss[j], j)); 12544 } 12545 12546 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12547 for (int j=0; j<oomPss.length; j++) { 12548 if (oomPss[j] != 0) { 12549 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12550 : DUMP_MEM_OOM_LABEL[j]; 12551 MemItem item = new MemItem(label, label, oomPss[j], 12552 DUMP_MEM_OOM_ADJ[j]); 12553 item.subitems = oomProcs[j]; 12554 oomMems.add(item); 12555 } 12556 } 12557 12558 if (!brief && !oomOnly && !isCompact) { 12559 pw.println(); 12560 pw.println("Total PSS by process:"); 12561 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12562 pw.println(); 12563 } 12564 if (!isCompact) { 12565 pw.println("Total PSS by OOM adjustment:"); 12566 } 12567 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12568 if (!brief && !oomOnly) { 12569 PrintWriter out = categoryPw != null ? categoryPw : pw; 12570 if (!isCompact) { 12571 out.println(); 12572 out.println("Total PSS by category:"); 12573 } 12574 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12575 } 12576 if (!isCompact) { 12577 pw.println(); 12578 } 12579 MemInfoReader memInfo = new MemInfoReader(); 12580 memInfo.readMemInfo(); 12581 if (!brief) { 12582 if (!isCompact) { 12583 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12584 pw.print(" kB (status "); 12585 switch (mLastMemoryLevel) { 12586 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12587 pw.println("normal)"); 12588 break; 12589 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12590 pw.println("moderate)"); 12591 break; 12592 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12593 pw.println("low)"); 12594 break; 12595 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12596 pw.println("critical)"); 12597 break; 12598 default: 12599 pw.print(mLastMemoryLevel); 12600 pw.println(")"); 12601 break; 12602 } 12603 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12604 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12605 pw.print(cachedPss); pw.print(" cached pss + "); 12606 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12607 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12608 } else { 12609 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12610 pw.print(cachedPss + memInfo.getCachedSizeKb() 12611 + memInfo.getFreeSizeKb()); pw.print(","); 12612 pw.println(totalPss - cachedPss); 12613 } 12614 } 12615 if (!isCompact) { 12616 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12617 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12618 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12619 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12620 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12621 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12622 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12623 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12624 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12625 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12626 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12627 } 12628 if (!brief) { 12629 if (memInfo.getZramTotalSizeKb() != 0) { 12630 if (!isCompact) { 12631 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12632 pw.print(" kB physical used for "); 12633 pw.print(memInfo.getSwapTotalSizeKb() 12634 - memInfo.getSwapFreeSizeKb()); 12635 pw.print(" kB in swap ("); 12636 pw.print(memInfo.getSwapTotalSizeKb()); 12637 pw.println(" kB total swap)"); 12638 } else { 12639 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12640 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12641 pw.println(memInfo.getSwapFreeSizeKb()); 12642 } 12643 } 12644 final int[] SINGLE_LONG_FORMAT = new int[] { 12645 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12646 }; 12647 long[] longOut = new long[1]; 12648 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12649 SINGLE_LONG_FORMAT, null, longOut, null); 12650 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12651 longOut[0] = 0; 12652 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12653 SINGLE_LONG_FORMAT, null, longOut, null); 12654 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12655 longOut[0] = 0; 12656 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12657 SINGLE_LONG_FORMAT, null, longOut, null); 12658 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12659 longOut[0] = 0; 12660 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12661 SINGLE_LONG_FORMAT, null, longOut, null); 12662 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12663 if (!isCompact) { 12664 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12665 pw.print(" KSM: "); pw.print(sharing); 12666 pw.print(" kB saved from shared "); 12667 pw.print(shared); pw.println(" kB"); 12668 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12669 pw.print(voltile); pw.println(" kB volatile"); 12670 } 12671 pw.print(" Tuning: "); 12672 pw.print(ActivityManager.staticGetMemoryClass()); 12673 pw.print(" (large "); 12674 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12675 pw.print("), oom "); 12676 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12677 pw.print(" kB"); 12678 pw.print(", restore limit "); 12679 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12680 pw.print(" kB"); 12681 if (ActivityManager.isLowRamDeviceStatic()) { 12682 pw.print(" (low-ram)"); 12683 } 12684 if (ActivityManager.isHighEndGfx()) { 12685 pw.print(" (high-end-gfx)"); 12686 } 12687 pw.println(); 12688 } else { 12689 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12690 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12691 pw.println(voltile); 12692 pw.print("tuning,"); 12693 pw.print(ActivityManager.staticGetMemoryClass()); 12694 pw.print(','); 12695 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12696 pw.print(','); 12697 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12698 if (ActivityManager.isLowRamDeviceStatic()) { 12699 pw.print(",low-ram"); 12700 } 12701 if (ActivityManager.isHighEndGfx()) { 12702 pw.print(",high-end-gfx"); 12703 } 12704 pw.println(); 12705 } 12706 } 12707 } 12708 } 12709 12710 /** 12711 * Searches array of arguments for the specified string 12712 * @param args array of argument strings 12713 * @param value value to search for 12714 * @return true if the value is contained in the array 12715 */ 12716 private static boolean scanArgs(String[] args, String value) { 12717 if (args != null) { 12718 for (String arg : args) { 12719 if (value.equals(arg)) { 12720 return true; 12721 } 12722 } 12723 } 12724 return false; 12725 } 12726 12727 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12728 ContentProviderRecord cpr, boolean always) { 12729 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12730 12731 if (!inLaunching || always) { 12732 synchronized (cpr) { 12733 cpr.launchingApp = null; 12734 cpr.notifyAll(); 12735 } 12736 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12737 String names[] = cpr.info.authority.split(";"); 12738 for (int j = 0; j < names.length; j++) { 12739 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12740 } 12741 } 12742 12743 for (int i=0; i<cpr.connections.size(); i++) { 12744 ContentProviderConnection conn = cpr.connections.get(i); 12745 if (conn.waiting) { 12746 // If this connection is waiting for the provider, then we don't 12747 // need to mess with its process unless we are always removing 12748 // or for some reason the provider is not currently launching. 12749 if (inLaunching && !always) { 12750 continue; 12751 } 12752 } 12753 ProcessRecord capp = conn.client; 12754 conn.dead = true; 12755 if (conn.stableCount > 0) { 12756 if (!capp.persistent && capp.thread != null 12757 && capp.pid != 0 12758 && capp.pid != MY_PID) { 12759 killUnneededProcessLocked(capp, "depends on provider " 12760 + cpr.name.flattenToShortString() 12761 + " in dying proc " + (proc != null ? proc.processName : "??")); 12762 } 12763 } else if (capp.thread != null && conn.provider.provider != null) { 12764 try { 12765 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12766 } catch (RemoteException e) { 12767 } 12768 // In the protocol here, we don't expect the client to correctly 12769 // clean up this connection, we'll just remove it. 12770 cpr.connections.remove(i); 12771 conn.client.conProviders.remove(conn); 12772 } 12773 } 12774 12775 if (inLaunching && always) { 12776 mLaunchingProviders.remove(cpr); 12777 } 12778 return inLaunching; 12779 } 12780 12781 /** 12782 * Main code for cleaning up a process when it has gone away. This is 12783 * called both as a result of the process dying, or directly when stopping 12784 * a process when running in single process mode. 12785 */ 12786 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12787 boolean restarting, boolean allowRestart, int index) { 12788 if (index >= 0) { 12789 removeLruProcessLocked(app); 12790 ProcessList.remove(app.pid); 12791 } 12792 12793 mProcessesToGc.remove(app); 12794 mPendingPssProcesses.remove(app); 12795 12796 // Dismiss any open dialogs. 12797 if (app.crashDialog != null && !app.forceCrashReport) { 12798 app.crashDialog.dismiss(); 12799 app.crashDialog = null; 12800 } 12801 if (app.anrDialog != null) { 12802 app.anrDialog.dismiss(); 12803 app.anrDialog = null; 12804 } 12805 if (app.waitDialog != null) { 12806 app.waitDialog.dismiss(); 12807 app.waitDialog = null; 12808 } 12809 12810 app.crashing = false; 12811 app.notResponding = false; 12812 12813 app.resetPackageList(mProcessStats); 12814 app.unlinkDeathRecipient(); 12815 app.makeInactive(mProcessStats); 12816 app.forcingToForeground = null; 12817 updateProcessForegroundLocked(app, false, false); 12818 app.foregroundActivities = false; 12819 app.hasShownUi = false; 12820 app.treatLikeActivity = false; 12821 app.hasAboveClient = false; 12822 app.hasClientActivities = false; 12823 12824 mServices.killServicesLocked(app, allowRestart); 12825 12826 boolean restart = false; 12827 12828 // Remove published content providers. 12829 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12830 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12831 final boolean always = app.bad || !allowRestart; 12832 if (removeDyingProviderLocked(app, cpr, always) || always) { 12833 // We left the provider in the launching list, need to 12834 // restart it. 12835 restart = true; 12836 } 12837 12838 cpr.provider = null; 12839 cpr.proc = null; 12840 } 12841 app.pubProviders.clear(); 12842 12843 // Take care of any launching providers waiting for this process. 12844 if (checkAppInLaunchingProvidersLocked(app, false)) { 12845 restart = true; 12846 } 12847 12848 // Unregister from connected content providers. 12849 if (!app.conProviders.isEmpty()) { 12850 for (int i=0; i<app.conProviders.size(); i++) { 12851 ContentProviderConnection conn = app.conProviders.get(i); 12852 conn.provider.connections.remove(conn); 12853 } 12854 app.conProviders.clear(); 12855 } 12856 12857 // At this point there may be remaining entries in mLaunchingProviders 12858 // where we were the only one waiting, so they are no longer of use. 12859 // Look for these and clean up if found. 12860 // XXX Commented out for now. Trying to figure out a way to reproduce 12861 // the actual situation to identify what is actually going on. 12862 if (false) { 12863 for (int i=0; i<mLaunchingProviders.size(); i++) { 12864 ContentProviderRecord cpr = (ContentProviderRecord) 12865 mLaunchingProviders.get(i); 12866 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12867 synchronized (cpr) { 12868 cpr.launchingApp = null; 12869 cpr.notifyAll(); 12870 } 12871 } 12872 } 12873 } 12874 12875 skipCurrentReceiverLocked(app); 12876 12877 // Unregister any receivers. 12878 for (int i=app.receivers.size()-1; i>=0; i--) { 12879 removeReceiverLocked(app.receivers.valueAt(i)); 12880 } 12881 app.receivers.clear(); 12882 12883 // If the app is undergoing backup, tell the backup manager about it 12884 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12885 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12886 + mBackupTarget.appInfo + " died during backup"); 12887 try { 12888 IBackupManager bm = IBackupManager.Stub.asInterface( 12889 ServiceManager.getService(Context.BACKUP_SERVICE)); 12890 bm.agentDisconnected(app.info.packageName); 12891 } catch (RemoteException e) { 12892 // can't happen; backup manager is local 12893 } 12894 } 12895 12896 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12897 ProcessChangeItem item = mPendingProcessChanges.get(i); 12898 if (item.pid == app.pid) { 12899 mPendingProcessChanges.remove(i); 12900 mAvailProcessChanges.add(item); 12901 } 12902 } 12903 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12904 12905 // If the caller is restarting this app, then leave it in its 12906 // current lists and let the caller take care of it. 12907 if (restarting) { 12908 return; 12909 } 12910 12911 if (!app.persistent || app.isolated) { 12912 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12913 "Removing non-persistent process during cleanup: " + app); 12914 mProcessNames.remove(app.processName, app.uid); 12915 mIsolatedProcesses.remove(app.uid); 12916 if (mHeavyWeightProcess == app) { 12917 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12918 mHeavyWeightProcess.userId, 0)); 12919 mHeavyWeightProcess = null; 12920 } 12921 } else if (!app.removed) { 12922 // This app is persistent, so we need to keep its record around. 12923 // If it is not already on the pending app list, add it there 12924 // and start a new process for it. 12925 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12926 mPersistentStartingProcesses.add(app); 12927 restart = true; 12928 } 12929 } 12930 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12931 "Clean-up removing on hold: " + app); 12932 mProcessesOnHold.remove(app); 12933 12934 if (app == mHomeProcess) { 12935 mHomeProcess = null; 12936 } 12937 if (app == mPreviousProcess) { 12938 mPreviousProcess = null; 12939 } 12940 12941 if (restart && !app.isolated) { 12942 // We have components that still need to be running in the 12943 // process, so re-launch it. 12944 mProcessNames.put(app.processName, app.uid, app); 12945 startProcessLocked(app, "restart", app.processName); 12946 } else if (app.pid > 0 && app.pid != MY_PID) { 12947 // Goodbye! 12948 boolean removed; 12949 synchronized (mPidsSelfLocked) { 12950 mPidsSelfLocked.remove(app.pid); 12951 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12952 } 12953 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12954 app.processName, app.info.uid); 12955 if (app.isolated) { 12956 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12957 } 12958 app.setPid(0); 12959 } 12960 } 12961 12962 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12963 // Look through the content providers we are waiting to have launched, 12964 // and if any run in this process then either schedule a restart of 12965 // the process or kill the client waiting for it if this process has 12966 // gone bad. 12967 int NL = mLaunchingProviders.size(); 12968 boolean restart = false; 12969 for (int i=0; i<NL; i++) { 12970 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12971 if (cpr.launchingApp == app) { 12972 if (!alwaysBad && !app.bad) { 12973 restart = true; 12974 } else { 12975 removeDyingProviderLocked(app, cpr, true); 12976 // cpr should have been removed from mLaunchingProviders 12977 NL = mLaunchingProviders.size(); 12978 i--; 12979 } 12980 } 12981 } 12982 return restart; 12983 } 12984 12985 // ========================================================= 12986 // SERVICES 12987 // ========================================================= 12988 12989 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12990 int flags) { 12991 enforceNotIsolatedCaller("getServices"); 12992 synchronized (this) { 12993 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12994 } 12995 } 12996 12997 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12998 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12999 synchronized (this) { 13000 return mServices.getRunningServiceControlPanelLocked(name); 13001 } 13002 } 13003 13004 public ComponentName startService(IApplicationThread caller, Intent service, 13005 String resolvedType, int userId) { 13006 enforceNotIsolatedCaller("startService"); 13007 // Refuse possible leaked file descriptors 13008 if (service != null && service.hasFileDescriptors() == true) { 13009 throw new IllegalArgumentException("File descriptors passed in Intent"); 13010 } 13011 13012 if (DEBUG_SERVICE) 13013 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 13014 synchronized(this) { 13015 final int callingPid = Binder.getCallingPid(); 13016 final int callingUid = Binder.getCallingUid(); 13017 final long origId = Binder.clearCallingIdentity(); 13018 ComponentName res = mServices.startServiceLocked(caller, service, 13019 resolvedType, callingPid, callingUid, userId); 13020 Binder.restoreCallingIdentity(origId); 13021 return res; 13022 } 13023 } 13024 13025 ComponentName startServiceInPackage(int uid, 13026 Intent service, String resolvedType, int userId) { 13027 synchronized(this) { 13028 if (DEBUG_SERVICE) 13029 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 13030 final long origId = Binder.clearCallingIdentity(); 13031 ComponentName res = mServices.startServiceLocked(null, service, 13032 resolvedType, -1, uid, userId); 13033 Binder.restoreCallingIdentity(origId); 13034 return res; 13035 } 13036 } 13037 13038 public int stopService(IApplicationThread caller, Intent service, 13039 String resolvedType, int userId) { 13040 enforceNotIsolatedCaller("stopService"); 13041 // Refuse possible leaked file descriptors 13042 if (service != null && service.hasFileDescriptors() == true) { 13043 throw new IllegalArgumentException("File descriptors passed in Intent"); 13044 } 13045 13046 synchronized(this) { 13047 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 13048 } 13049 } 13050 13051 public IBinder peekService(Intent service, String resolvedType) { 13052 enforceNotIsolatedCaller("peekService"); 13053 // Refuse possible leaked file descriptors 13054 if (service != null && service.hasFileDescriptors() == true) { 13055 throw new IllegalArgumentException("File descriptors passed in Intent"); 13056 } 13057 synchronized(this) { 13058 return mServices.peekServiceLocked(service, resolvedType); 13059 } 13060 } 13061 13062 public boolean stopServiceToken(ComponentName className, IBinder token, 13063 int startId) { 13064 synchronized(this) { 13065 return mServices.stopServiceTokenLocked(className, token, startId); 13066 } 13067 } 13068 13069 public void setServiceForeground(ComponentName className, IBinder token, 13070 int id, Notification notification, boolean removeNotification) { 13071 synchronized(this) { 13072 mServices.setServiceForegroundLocked(className, token, id, notification, 13073 removeNotification); 13074 } 13075 } 13076 13077 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 13078 boolean requireFull, String name, String callerPackage) { 13079 final int callingUserId = UserHandle.getUserId(callingUid); 13080 if (callingUserId != userId) { 13081 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 13082 if ((requireFull || checkComponentPermission( 13083 android.Manifest.permission.INTERACT_ACROSS_USERS, 13084 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 13085 && checkComponentPermission( 13086 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 13087 callingPid, callingUid, -1, true) 13088 != PackageManager.PERMISSION_GRANTED) { 13089 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 13090 // In this case, they would like to just execute as their 13091 // owner user instead of failing. 13092 userId = callingUserId; 13093 } else { 13094 StringBuilder builder = new StringBuilder(128); 13095 builder.append("Permission Denial: "); 13096 builder.append(name); 13097 if (callerPackage != null) { 13098 builder.append(" from "); 13099 builder.append(callerPackage); 13100 } 13101 builder.append(" asks to run as user "); 13102 builder.append(userId); 13103 builder.append(" but is calling from user "); 13104 builder.append(UserHandle.getUserId(callingUid)); 13105 builder.append("; this requires "); 13106 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13107 if (!requireFull) { 13108 builder.append(" or "); 13109 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13110 } 13111 String msg = builder.toString(); 13112 Slog.w(TAG, msg); 13113 throw new SecurityException(msg); 13114 } 13115 } 13116 } 13117 if (userId == UserHandle.USER_CURRENT 13118 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13119 // Note that we may be accessing this outside of a lock... 13120 // shouldn't be a big deal, if this is being called outside 13121 // of a locked context there is intrinsically a race with 13122 // the value the caller will receive and someone else changing it. 13123 userId = mCurrentUserId; 13124 } 13125 if (!allowAll && userId < 0) { 13126 throw new IllegalArgumentException( 13127 "Call does not support special user #" + userId); 13128 } 13129 } 13130 return userId; 13131 } 13132 13133 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13134 String className, int flags) { 13135 boolean result = false; 13136 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13137 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13138 if (ActivityManager.checkUidPermission( 13139 android.Manifest.permission.INTERACT_ACROSS_USERS, 13140 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13141 ComponentName comp = new ComponentName(aInfo.packageName, className); 13142 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13143 + " requests FLAG_SINGLE_USER, but app does not hold " 13144 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13145 Slog.w(TAG, msg); 13146 throw new SecurityException(msg); 13147 } 13148 result = true; 13149 } 13150 } else if (componentProcessName == aInfo.packageName) { 13151 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13152 } else if ("system".equals(componentProcessName)) { 13153 result = true; 13154 } 13155 if (DEBUG_MU) { 13156 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13157 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13158 } 13159 return result; 13160 } 13161 13162 public int bindService(IApplicationThread caller, IBinder token, 13163 Intent service, String resolvedType, 13164 IServiceConnection connection, int flags, int userId) { 13165 enforceNotIsolatedCaller("bindService"); 13166 // Refuse possible leaked file descriptors 13167 if (service != null && service.hasFileDescriptors() == true) { 13168 throw new IllegalArgumentException("File descriptors passed in Intent"); 13169 } 13170 13171 synchronized(this) { 13172 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13173 connection, flags, userId); 13174 } 13175 } 13176 13177 public boolean unbindService(IServiceConnection connection) { 13178 synchronized (this) { 13179 return mServices.unbindServiceLocked(connection); 13180 } 13181 } 13182 13183 public void publishService(IBinder token, Intent intent, IBinder service) { 13184 // Refuse possible leaked file descriptors 13185 if (intent != null && intent.hasFileDescriptors() == true) { 13186 throw new IllegalArgumentException("File descriptors passed in Intent"); 13187 } 13188 13189 synchronized(this) { 13190 if (!(token instanceof ServiceRecord)) { 13191 throw new IllegalArgumentException("Invalid service token"); 13192 } 13193 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13194 } 13195 } 13196 13197 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13198 // Refuse possible leaked file descriptors 13199 if (intent != null && intent.hasFileDescriptors() == true) { 13200 throw new IllegalArgumentException("File descriptors passed in Intent"); 13201 } 13202 13203 synchronized(this) { 13204 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13205 } 13206 } 13207 13208 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13209 synchronized(this) { 13210 if (!(token instanceof ServiceRecord)) { 13211 throw new IllegalArgumentException("Invalid service token"); 13212 } 13213 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13214 } 13215 } 13216 13217 // ========================================================= 13218 // BACKUP AND RESTORE 13219 // ========================================================= 13220 13221 // Cause the target app to be launched if necessary and its backup agent 13222 // instantiated. The backup agent will invoke backupAgentCreated() on the 13223 // activity manager to announce its creation. 13224 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13225 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13226 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13227 13228 synchronized(this) { 13229 // !!! TODO: currently no check here that we're already bound 13230 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13231 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13232 synchronized (stats) { 13233 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13234 } 13235 13236 // Backup agent is now in use, its package can't be stopped. 13237 try { 13238 AppGlobals.getPackageManager().setPackageStoppedState( 13239 app.packageName, false, UserHandle.getUserId(app.uid)); 13240 } catch (RemoteException e) { 13241 } catch (IllegalArgumentException e) { 13242 Slog.w(TAG, "Failed trying to unstop package " 13243 + app.packageName + ": " + e); 13244 } 13245 13246 BackupRecord r = new BackupRecord(ss, app, backupMode); 13247 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13248 ? new ComponentName(app.packageName, app.backupAgentName) 13249 : new ComponentName("android", "FullBackupAgent"); 13250 // startProcessLocked() returns existing proc's record if it's already running 13251 ProcessRecord proc = startProcessLocked(app.processName, app, 13252 false, 0, "backup", hostingName, false, false, false); 13253 if (proc == null) { 13254 Slog.e(TAG, "Unable to start backup agent process " + r); 13255 return false; 13256 } 13257 13258 r.app = proc; 13259 mBackupTarget = r; 13260 mBackupAppName = app.packageName; 13261 13262 // Try not to kill the process during backup 13263 updateOomAdjLocked(proc); 13264 13265 // If the process is already attached, schedule the creation of the backup agent now. 13266 // If it is not yet live, this will be done when it attaches to the framework. 13267 if (proc.thread != null) { 13268 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13269 try { 13270 proc.thread.scheduleCreateBackupAgent(app, 13271 compatibilityInfoForPackageLocked(app), backupMode); 13272 } catch (RemoteException e) { 13273 // Will time out on the backup manager side 13274 } 13275 } else { 13276 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13277 } 13278 // Invariants: at this point, the target app process exists and the application 13279 // is either already running or in the process of coming up. mBackupTarget and 13280 // mBackupAppName describe the app, so that when it binds back to the AM we 13281 // know that it's scheduled for a backup-agent operation. 13282 } 13283 13284 return true; 13285 } 13286 13287 @Override 13288 public void clearPendingBackup() { 13289 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13290 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13291 13292 synchronized (this) { 13293 mBackupTarget = null; 13294 mBackupAppName = null; 13295 } 13296 } 13297 13298 // A backup agent has just come up 13299 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13300 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13301 + " = " + agent); 13302 13303 synchronized(this) { 13304 if (!agentPackageName.equals(mBackupAppName)) { 13305 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13306 return; 13307 } 13308 } 13309 13310 long oldIdent = Binder.clearCallingIdentity(); 13311 try { 13312 IBackupManager bm = IBackupManager.Stub.asInterface( 13313 ServiceManager.getService(Context.BACKUP_SERVICE)); 13314 bm.agentConnected(agentPackageName, agent); 13315 } catch (RemoteException e) { 13316 // can't happen; the backup manager service is local 13317 } catch (Exception e) { 13318 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13319 e.printStackTrace(); 13320 } finally { 13321 Binder.restoreCallingIdentity(oldIdent); 13322 } 13323 } 13324 13325 // done with this agent 13326 public void unbindBackupAgent(ApplicationInfo appInfo) { 13327 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13328 if (appInfo == null) { 13329 Slog.w(TAG, "unbind backup agent for null app"); 13330 return; 13331 } 13332 13333 synchronized(this) { 13334 try { 13335 if (mBackupAppName == null) { 13336 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13337 return; 13338 } 13339 13340 if (!mBackupAppName.equals(appInfo.packageName)) { 13341 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13342 return; 13343 } 13344 13345 // Not backing this app up any more; reset its OOM adjustment 13346 final ProcessRecord proc = mBackupTarget.app; 13347 updateOomAdjLocked(proc); 13348 13349 // If the app crashed during backup, 'thread' will be null here 13350 if (proc.thread != null) { 13351 try { 13352 proc.thread.scheduleDestroyBackupAgent(appInfo, 13353 compatibilityInfoForPackageLocked(appInfo)); 13354 } catch (Exception e) { 13355 Slog.e(TAG, "Exception when unbinding backup agent:"); 13356 e.printStackTrace(); 13357 } 13358 } 13359 } finally { 13360 mBackupTarget = null; 13361 mBackupAppName = null; 13362 } 13363 } 13364 } 13365 // ========================================================= 13366 // BROADCASTS 13367 // ========================================================= 13368 13369 private final List getStickiesLocked(String action, IntentFilter filter, 13370 List cur, int userId) { 13371 final ContentResolver resolver = mContext.getContentResolver(); 13372 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13373 if (stickies == null) { 13374 return cur; 13375 } 13376 final ArrayList<Intent> list = stickies.get(action); 13377 if (list == null) { 13378 return cur; 13379 } 13380 int N = list.size(); 13381 for (int i=0; i<N; i++) { 13382 Intent intent = list.get(i); 13383 if (filter.match(resolver, intent, true, TAG) >= 0) { 13384 if (cur == null) { 13385 cur = new ArrayList<Intent>(); 13386 } 13387 cur.add(intent); 13388 } 13389 } 13390 return cur; 13391 } 13392 13393 boolean isPendingBroadcastProcessLocked(int pid) { 13394 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13395 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13396 } 13397 13398 void skipPendingBroadcastLocked(int pid) { 13399 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13400 for (BroadcastQueue queue : mBroadcastQueues) { 13401 queue.skipPendingBroadcastLocked(pid); 13402 } 13403 } 13404 13405 // The app just attached; send any pending broadcasts that it should receive 13406 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13407 boolean didSomething = false; 13408 for (BroadcastQueue queue : mBroadcastQueues) { 13409 didSomething |= queue.sendPendingBroadcastsLocked(app); 13410 } 13411 return didSomething; 13412 } 13413 13414 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13415 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13416 enforceNotIsolatedCaller("registerReceiver"); 13417 int callingUid; 13418 int callingPid; 13419 synchronized(this) { 13420 ProcessRecord callerApp = null; 13421 if (caller != null) { 13422 callerApp = getRecordForAppLocked(caller); 13423 if (callerApp == null) { 13424 throw new SecurityException( 13425 "Unable to find app for caller " + caller 13426 + " (pid=" + Binder.getCallingPid() 13427 + ") when registering receiver " + receiver); 13428 } 13429 if (callerApp.info.uid != Process.SYSTEM_UID && 13430 !callerApp.pkgList.containsKey(callerPackage) && 13431 !"android".equals(callerPackage)) { 13432 throw new SecurityException("Given caller package " + callerPackage 13433 + " is not running in process " + callerApp); 13434 } 13435 callingUid = callerApp.info.uid; 13436 callingPid = callerApp.pid; 13437 } else { 13438 callerPackage = null; 13439 callingUid = Binder.getCallingUid(); 13440 callingPid = Binder.getCallingPid(); 13441 } 13442 13443 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13444 true, true, "registerReceiver", callerPackage); 13445 13446 List allSticky = null; 13447 13448 // Look for any matching sticky broadcasts... 13449 Iterator actions = filter.actionsIterator(); 13450 if (actions != null) { 13451 while (actions.hasNext()) { 13452 String action = (String)actions.next(); 13453 allSticky = getStickiesLocked(action, filter, allSticky, 13454 UserHandle.USER_ALL); 13455 allSticky = getStickiesLocked(action, filter, allSticky, 13456 UserHandle.getUserId(callingUid)); 13457 } 13458 } else { 13459 allSticky = getStickiesLocked(null, filter, allSticky, 13460 UserHandle.USER_ALL); 13461 allSticky = getStickiesLocked(null, filter, allSticky, 13462 UserHandle.getUserId(callingUid)); 13463 } 13464 13465 // The first sticky in the list is returned directly back to 13466 // the client. 13467 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13468 13469 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13470 + ": " + sticky); 13471 13472 if (receiver == null) { 13473 return sticky; 13474 } 13475 13476 ReceiverList rl 13477 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13478 if (rl == null) { 13479 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13480 userId, receiver); 13481 if (rl.app != null) { 13482 rl.app.receivers.add(rl); 13483 } else { 13484 try { 13485 receiver.asBinder().linkToDeath(rl, 0); 13486 } catch (RemoteException e) { 13487 return sticky; 13488 } 13489 rl.linkedToDeath = true; 13490 } 13491 mRegisteredReceivers.put(receiver.asBinder(), rl); 13492 } else if (rl.uid != callingUid) { 13493 throw new IllegalArgumentException( 13494 "Receiver requested to register for uid " + callingUid 13495 + " was previously registered for uid " + rl.uid); 13496 } else if (rl.pid != callingPid) { 13497 throw new IllegalArgumentException( 13498 "Receiver requested to register for pid " + callingPid 13499 + " was previously registered for pid " + rl.pid); 13500 } else if (rl.userId != userId) { 13501 throw new IllegalArgumentException( 13502 "Receiver requested to register for user " + userId 13503 + " was previously registered for user " + rl.userId); 13504 } 13505 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13506 permission, callingUid, userId); 13507 rl.add(bf); 13508 if (!bf.debugCheck()) { 13509 Slog.w(TAG, "==> For Dynamic broadast"); 13510 } 13511 mReceiverResolver.addFilter(bf); 13512 13513 // Enqueue broadcasts for all existing stickies that match 13514 // this filter. 13515 if (allSticky != null) { 13516 ArrayList receivers = new ArrayList(); 13517 receivers.add(bf); 13518 13519 int N = allSticky.size(); 13520 for (int i=0; i<N; i++) { 13521 Intent intent = (Intent)allSticky.get(i); 13522 BroadcastQueue queue = broadcastQueueForIntent(intent); 13523 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13524 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13525 null, null, false, true, true, -1); 13526 queue.enqueueParallelBroadcastLocked(r); 13527 queue.scheduleBroadcastsLocked(); 13528 } 13529 } 13530 13531 return sticky; 13532 } 13533 } 13534 13535 public void unregisterReceiver(IIntentReceiver receiver) { 13536 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13537 13538 final long origId = Binder.clearCallingIdentity(); 13539 try { 13540 boolean doTrim = false; 13541 13542 synchronized(this) { 13543 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13544 if (rl != null) { 13545 if (rl.curBroadcast != null) { 13546 BroadcastRecord r = rl.curBroadcast; 13547 final boolean doNext = finishReceiverLocked( 13548 receiver.asBinder(), r.resultCode, r.resultData, 13549 r.resultExtras, r.resultAbort); 13550 if (doNext) { 13551 doTrim = true; 13552 r.queue.processNextBroadcast(false); 13553 } 13554 } 13555 13556 if (rl.app != null) { 13557 rl.app.receivers.remove(rl); 13558 } 13559 removeReceiverLocked(rl); 13560 if (rl.linkedToDeath) { 13561 rl.linkedToDeath = false; 13562 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13563 } 13564 } 13565 } 13566 13567 // If we actually concluded any broadcasts, we might now be able 13568 // to trim the recipients' apps from our working set 13569 if (doTrim) { 13570 trimApplications(); 13571 return; 13572 } 13573 13574 } finally { 13575 Binder.restoreCallingIdentity(origId); 13576 } 13577 } 13578 13579 void removeReceiverLocked(ReceiverList rl) { 13580 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13581 int N = rl.size(); 13582 for (int i=0; i<N; i++) { 13583 mReceiverResolver.removeFilter(rl.get(i)); 13584 } 13585 } 13586 13587 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13588 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13589 ProcessRecord r = mLruProcesses.get(i); 13590 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13591 try { 13592 r.thread.dispatchPackageBroadcast(cmd, packages); 13593 } catch (RemoteException ex) { 13594 } 13595 } 13596 } 13597 } 13598 13599 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13600 int[] users) { 13601 List<ResolveInfo> receivers = null; 13602 try { 13603 HashSet<ComponentName> singleUserReceivers = null; 13604 boolean scannedFirstReceivers = false; 13605 for (int user : users) { 13606 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13607 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13608 if (user != 0 && newReceivers != null) { 13609 // If this is not the primary user, we need to check for 13610 // any receivers that should be filtered out. 13611 for (int i=0; i<newReceivers.size(); i++) { 13612 ResolveInfo ri = newReceivers.get(i); 13613 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13614 newReceivers.remove(i); 13615 i--; 13616 } 13617 } 13618 } 13619 if (newReceivers != null && newReceivers.size() == 0) { 13620 newReceivers = null; 13621 } 13622 if (receivers == null) { 13623 receivers = newReceivers; 13624 } else if (newReceivers != null) { 13625 // We need to concatenate the additional receivers 13626 // found with what we have do far. This would be easy, 13627 // but we also need to de-dup any receivers that are 13628 // singleUser. 13629 if (!scannedFirstReceivers) { 13630 // Collect any single user receivers we had already retrieved. 13631 scannedFirstReceivers = true; 13632 for (int i=0; i<receivers.size(); i++) { 13633 ResolveInfo ri = receivers.get(i); 13634 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13635 ComponentName cn = new ComponentName( 13636 ri.activityInfo.packageName, ri.activityInfo.name); 13637 if (singleUserReceivers == null) { 13638 singleUserReceivers = new HashSet<ComponentName>(); 13639 } 13640 singleUserReceivers.add(cn); 13641 } 13642 } 13643 } 13644 // Add the new results to the existing results, tracking 13645 // and de-dupping single user receivers. 13646 for (int i=0; i<newReceivers.size(); i++) { 13647 ResolveInfo ri = newReceivers.get(i); 13648 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13649 ComponentName cn = new ComponentName( 13650 ri.activityInfo.packageName, ri.activityInfo.name); 13651 if (singleUserReceivers == null) { 13652 singleUserReceivers = new HashSet<ComponentName>(); 13653 } 13654 if (!singleUserReceivers.contains(cn)) { 13655 singleUserReceivers.add(cn); 13656 receivers.add(ri); 13657 } 13658 } else { 13659 receivers.add(ri); 13660 } 13661 } 13662 } 13663 } 13664 } catch (RemoteException ex) { 13665 // pm is in same process, this will never happen. 13666 } 13667 return receivers; 13668 } 13669 13670 private final int broadcastIntentLocked(ProcessRecord callerApp, 13671 String callerPackage, Intent intent, String resolvedType, 13672 IIntentReceiver resultTo, int resultCode, String resultData, 13673 Bundle map, String requiredPermission, int appOp, 13674 boolean ordered, boolean sticky, int callingPid, int callingUid, 13675 int userId) { 13676 intent = new Intent(intent); 13677 13678 // By default broadcasts do not go to stopped apps. 13679 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13680 13681 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13682 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13683 + " ordered=" + ordered + " userid=" + userId); 13684 if ((resultTo != null) && !ordered) { 13685 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13686 } 13687 13688 userId = handleIncomingUser(callingPid, callingUid, userId, 13689 true, false, "broadcast", callerPackage); 13690 13691 // Make sure that the user who is receiving this broadcast is started. 13692 // If not, we will just skip it. 13693 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13694 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13695 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13696 Slog.w(TAG, "Skipping broadcast of " + intent 13697 + ": user " + userId + " is stopped"); 13698 return ActivityManager.BROADCAST_SUCCESS; 13699 } 13700 } 13701 13702 /* 13703 * Prevent non-system code (defined here to be non-persistent 13704 * processes) from sending protected broadcasts. 13705 */ 13706 int callingAppId = UserHandle.getAppId(callingUid); 13707 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13708 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13709 callingUid == 0) { 13710 // Always okay. 13711 } else if (callerApp == null || !callerApp.persistent) { 13712 try { 13713 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13714 intent.getAction())) { 13715 String msg = "Permission Denial: not allowed to send broadcast " 13716 + intent.getAction() + " from pid=" 13717 + callingPid + ", uid=" + callingUid; 13718 Slog.w(TAG, msg); 13719 throw new SecurityException(msg); 13720 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13721 // Special case for compatibility: we don't want apps to send this, 13722 // but historically it has not been protected and apps may be using it 13723 // to poke their own app widget. So, instead of making it protected, 13724 // just limit it to the caller. 13725 if (callerApp == null) { 13726 String msg = "Permission Denial: not allowed to send broadcast " 13727 + intent.getAction() + " from unknown caller."; 13728 Slog.w(TAG, msg); 13729 throw new SecurityException(msg); 13730 } else if (intent.getComponent() != null) { 13731 // They are good enough to send to an explicit component... verify 13732 // it is being sent to the calling app. 13733 if (!intent.getComponent().getPackageName().equals( 13734 callerApp.info.packageName)) { 13735 String msg = "Permission Denial: not allowed to send broadcast " 13736 + intent.getAction() + " to " 13737 + intent.getComponent().getPackageName() + " from " 13738 + callerApp.info.packageName; 13739 Slog.w(TAG, msg); 13740 throw new SecurityException(msg); 13741 } 13742 } else { 13743 // Limit broadcast to their own package. 13744 intent.setPackage(callerApp.info.packageName); 13745 } 13746 } 13747 } catch (RemoteException e) { 13748 Slog.w(TAG, "Remote exception", e); 13749 return ActivityManager.BROADCAST_SUCCESS; 13750 } 13751 } 13752 13753 // Handle special intents: if this broadcast is from the package 13754 // manager about a package being removed, we need to remove all of 13755 // its activities from the history stack. 13756 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13757 intent.getAction()); 13758 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13759 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13760 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13761 || uidRemoved) { 13762 if (checkComponentPermission( 13763 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13764 callingPid, callingUid, -1, true) 13765 == PackageManager.PERMISSION_GRANTED) { 13766 if (uidRemoved) { 13767 final Bundle intentExtras = intent.getExtras(); 13768 final int uid = intentExtras != null 13769 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13770 if (uid >= 0) { 13771 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13772 synchronized (bs) { 13773 bs.removeUidStatsLocked(uid); 13774 } 13775 mAppOpsService.uidRemoved(uid); 13776 } 13777 } else { 13778 // If resources are unavailable just force stop all 13779 // those packages and flush the attribute cache as well. 13780 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13781 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13782 if (list != null && (list.length > 0)) { 13783 for (String pkg : list) { 13784 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13785 "storage unmount"); 13786 } 13787 sendPackageBroadcastLocked( 13788 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13789 } 13790 } else { 13791 Uri data = intent.getData(); 13792 String ssp; 13793 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13794 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13795 intent.getAction()); 13796 boolean fullUninstall = removed && 13797 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13798 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13799 forceStopPackageLocked(ssp, UserHandle.getAppId( 13800 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13801 false, fullUninstall, userId, 13802 removed ? "pkg removed" : "pkg changed"); 13803 } 13804 if (removed) { 13805 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13806 new String[] {ssp}, userId); 13807 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13808 mAppOpsService.packageRemoved( 13809 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13810 13811 // Remove all permissions granted from/to this package 13812 removeUriPermissionsForPackageLocked(ssp, userId, true); 13813 } 13814 } 13815 } 13816 } 13817 } 13818 } else { 13819 String msg = "Permission Denial: " + intent.getAction() 13820 + " broadcast from " + callerPackage + " (pid=" + callingPid 13821 + ", uid=" + callingUid + ")" 13822 + " requires " 13823 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13824 Slog.w(TAG, msg); 13825 throw new SecurityException(msg); 13826 } 13827 13828 // Special case for adding a package: by default turn on compatibility 13829 // mode. 13830 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13831 Uri data = intent.getData(); 13832 String ssp; 13833 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13834 mCompatModePackages.handlePackageAddedLocked(ssp, 13835 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13836 } 13837 } 13838 13839 /* 13840 * If this is the time zone changed action, queue up a message that will reset the timezone 13841 * of all currently running processes. This message will get queued up before the broadcast 13842 * happens. 13843 */ 13844 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13845 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13846 } 13847 13848 /* 13849 * If the user set the time, let all running processes know. 13850 */ 13851 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13852 final int is24Hour = intent.getBooleanExtra( 13853 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13854 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13855 } 13856 13857 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13858 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13859 } 13860 13861 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13862 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13863 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13864 } 13865 13866 // Add to the sticky list if requested. 13867 if (sticky) { 13868 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13869 callingPid, callingUid) 13870 != PackageManager.PERMISSION_GRANTED) { 13871 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13872 + callingPid + ", uid=" + callingUid 13873 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13874 Slog.w(TAG, msg); 13875 throw new SecurityException(msg); 13876 } 13877 if (requiredPermission != null) { 13878 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13879 + " and enforce permission " + requiredPermission); 13880 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13881 } 13882 if (intent.getComponent() != null) { 13883 throw new SecurityException( 13884 "Sticky broadcasts can't target a specific component"); 13885 } 13886 // We use userId directly here, since the "all" target is maintained 13887 // as a separate set of sticky broadcasts. 13888 if (userId != UserHandle.USER_ALL) { 13889 // But first, if this is not a broadcast to all users, then 13890 // make sure it doesn't conflict with an existing broadcast to 13891 // all users. 13892 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13893 UserHandle.USER_ALL); 13894 if (stickies != null) { 13895 ArrayList<Intent> list = stickies.get(intent.getAction()); 13896 if (list != null) { 13897 int N = list.size(); 13898 int i; 13899 for (i=0; i<N; i++) { 13900 if (intent.filterEquals(list.get(i))) { 13901 throw new IllegalArgumentException( 13902 "Sticky broadcast " + intent + " for user " 13903 + userId + " conflicts with existing global broadcast"); 13904 } 13905 } 13906 } 13907 } 13908 } 13909 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13910 if (stickies == null) { 13911 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13912 mStickyBroadcasts.put(userId, stickies); 13913 } 13914 ArrayList<Intent> list = stickies.get(intent.getAction()); 13915 if (list == null) { 13916 list = new ArrayList<Intent>(); 13917 stickies.put(intent.getAction(), list); 13918 } 13919 int N = list.size(); 13920 int i; 13921 for (i=0; i<N; i++) { 13922 if (intent.filterEquals(list.get(i))) { 13923 // This sticky already exists, replace it. 13924 list.set(i, new Intent(intent)); 13925 break; 13926 } 13927 } 13928 if (i >= N) { 13929 list.add(new Intent(intent)); 13930 } 13931 } 13932 13933 int[] users; 13934 if (userId == UserHandle.USER_ALL) { 13935 // Caller wants broadcast to go to all started users. 13936 users = mStartedUserArray; 13937 } else { 13938 // Caller wants broadcast to go to one specific user. 13939 users = new int[] {userId}; 13940 } 13941 13942 // Figure out who all will receive this broadcast. 13943 List receivers = null; 13944 List<BroadcastFilter> registeredReceivers = null; 13945 // Need to resolve the intent to interested receivers... 13946 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13947 == 0) { 13948 receivers = collectReceiverComponents(intent, resolvedType, users); 13949 } 13950 if (intent.getComponent() == null) { 13951 registeredReceivers = mReceiverResolver.queryIntent(intent, 13952 resolvedType, false, userId); 13953 } 13954 13955 final boolean replacePending = 13956 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13957 13958 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13959 + " replacePending=" + replacePending); 13960 13961 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13962 if (!ordered && NR > 0) { 13963 // If we are not serializing this broadcast, then send the 13964 // registered receivers separately so they don't wait for the 13965 // components to be launched. 13966 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13967 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13968 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13969 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13970 ordered, sticky, false, userId); 13971 if (DEBUG_BROADCAST) Slog.v( 13972 TAG, "Enqueueing parallel broadcast " + r); 13973 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13974 if (!replaced) { 13975 queue.enqueueParallelBroadcastLocked(r); 13976 queue.scheduleBroadcastsLocked(); 13977 } 13978 registeredReceivers = null; 13979 NR = 0; 13980 } 13981 13982 // Merge into one list. 13983 int ir = 0; 13984 if (receivers != null) { 13985 // A special case for PACKAGE_ADDED: do not allow the package 13986 // being added to see this broadcast. This prevents them from 13987 // using this as a back door to get run as soon as they are 13988 // installed. Maybe in the future we want to have a special install 13989 // broadcast or such for apps, but we'd like to deliberately make 13990 // this decision. 13991 String skipPackages[] = null; 13992 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13993 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13994 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13995 Uri data = intent.getData(); 13996 if (data != null) { 13997 String pkgName = data.getSchemeSpecificPart(); 13998 if (pkgName != null) { 13999 skipPackages = new String[] { pkgName }; 14000 } 14001 } 14002 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 14003 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 14004 } 14005 if (skipPackages != null && (skipPackages.length > 0)) { 14006 for (String skipPackage : skipPackages) { 14007 if (skipPackage != null) { 14008 int NT = receivers.size(); 14009 for (int it=0; it<NT; it++) { 14010 ResolveInfo curt = (ResolveInfo)receivers.get(it); 14011 if (curt.activityInfo.packageName.equals(skipPackage)) { 14012 receivers.remove(it); 14013 it--; 14014 NT--; 14015 } 14016 } 14017 } 14018 } 14019 } 14020 14021 int NT = receivers != null ? receivers.size() : 0; 14022 int it = 0; 14023 ResolveInfo curt = null; 14024 BroadcastFilter curr = null; 14025 while (it < NT && ir < NR) { 14026 if (curt == null) { 14027 curt = (ResolveInfo)receivers.get(it); 14028 } 14029 if (curr == null) { 14030 curr = registeredReceivers.get(ir); 14031 } 14032 if (curr.getPriority() >= curt.priority) { 14033 // Insert this broadcast record into the final list. 14034 receivers.add(it, curr); 14035 ir++; 14036 curr = null; 14037 it++; 14038 NT++; 14039 } else { 14040 // Skip to the next ResolveInfo in the final list. 14041 it++; 14042 curt = null; 14043 } 14044 } 14045 } 14046 while (ir < NR) { 14047 if (receivers == null) { 14048 receivers = new ArrayList(); 14049 } 14050 receivers.add(registeredReceivers.get(ir)); 14051 ir++; 14052 } 14053 14054 if ((receivers != null && receivers.size() > 0) 14055 || resultTo != null) { 14056 BroadcastQueue queue = broadcastQueueForIntent(intent); 14057 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 14058 callerPackage, callingPid, callingUid, resolvedType, 14059 requiredPermission, appOp, receivers, resultTo, resultCode, 14060 resultData, map, ordered, sticky, false, userId); 14061 if (DEBUG_BROADCAST) Slog.v( 14062 TAG, "Enqueueing ordered broadcast " + r 14063 + ": prev had " + queue.mOrderedBroadcasts.size()); 14064 if (DEBUG_BROADCAST) { 14065 int seq = r.intent.getIntExtra("seq", -1); 14066 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 14067 } 14068 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 14069 if (!replaced) { 14070 queue.enqueueOrderedBroadcastLocked(r); 14071 queue.scheduleBroadcastsLocked(); 14072 } 14073 } 14074 14075 return ActivityManager.BROADCAST_SUCCESS; 14076 } 14077 14078 final Intent verifyBroadcastLocked(Intent intent) { 14079 // Refuse possible leaked file descriptors 14080 if (intent != null && intent.hasFileDescriptors() == true) { 14081 throw new IllegalArgumentException("File descriptors passed in Intent"); 14082 } 14083 14084 int flags = intent.getFlags(); 14085 14086 if (!mProcessesReady) { 14087 // if the caller really truly claims to know what they're doing, go 14088 // ahead and allow the broadcast without launching any receivers 14089 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 14090 intent = new Intent(intent); 14091 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 14092 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 14093 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 14094 + " before boot completion"); 14095 throw new IllegalStateException("Cannot broadcast before boot completed"); 14096 } 14097 } 14098 14099 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14100 throw new IllegalArgumentException( 14101 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14102 } 14103 14104 return intent; 14105 } 14106 14107 public final int broadcastIntent(IApplicationThread caller, 14108 Intent intent, String resolvedType, IIntentReceiver resultTo, 14109 int resultCode, String resultData, Bundle map, 14110 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14111 enforceNotIsolatedCaller("broadcastIntent"); 14112 synchronized(this) { 14113 intent = verifyBroadcastLocked(intent); 14114 14115 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14116 final int callingPid = Binder.getCallingPid(); 14117 final int callingUid = Binder.getCallingUid(); 14118 final long origId = Binder.clearCallingIdentity(); 14119 int res = broadcastIntentLocked(callerApp, 14120 callerApp != null ? callerApp.info.packageName : null, 14121 intent, resolvedType, resultTo, 14122 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14123 callingPid, callingUid, userId); 14124 Binder.restoreCallingIdentity(origId); 14125 return res; 14126 } 14127 } 14128 14129 int broadcastIntentInPackage(String packageName, int uid, 14130 Intent intent, String resolvedType, IIntentReceiver resultTo, 14131 int resultCode, String resultData, Bundle map, 14132 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14133 synchronized(this) { 14134 intent = verifyBroadcastLocked(intent); 14135 14136 final long origId = Binder.clearCallingIdentity(); 14137 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14138 resultTo, resultCode, resultData, map, requiredPermission, 14139 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14140 Binder.restoreCallingIdentity(origId); 14141 return res; 14142 } 14143 } 14144 14145 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14146 // Refuse possible leaked file descriptors 14147 if (intent != null && intent.hasFileDescriptors() == true) { 14148 throw new IllegalArgumentException("File descriptors passed in Intent"); 14149 } 14150 14151 userId = handleIncomingUser(Binder.getCallingPid(), 14152 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14153 14154 synchronized(this) { 14155 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14156 != PackageManager.PERMISSION_GRANTED) { 14157 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14158 + Binder.getCallingPid() 14159 + ", uid=" + Binder.getCallingUid() 14160 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14161 Slog.w(TAG, msg); 14162 throw new SecurityException(msg); 14163 } 14164 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14165 if (stickies != null) { 14166 ArrayList<Intent> list = stickies.get(intent.getAction()); 14167 if (list != null) { 14168 int N = list.size(); 14169 int i; 14170 for (i=0; i<N; i++) { 14171 if (intent.filterEquals(list.get(i))) { 14172 list.remove(i); 14173 break; 14174 } 14175 } 14176 if (list.size() <= 0) { 14177 stickies.remove(intent.getAction()); 14178 } 14179 } 14180 if (stickies.size() <= 0) { 14181 mStickyBroadcasts.remove(userId); 14182 } 14183 } 14184 } 14185 } 14186 14187 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14188 String resultData, Bundle resultExtras, boolean resultAbort) { 14189 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14190 if (r == null) { 14191 Slog.w(TAG, "finishReceiver called but not found on queue"); 14192 return false; 14193 } 14194 14195 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14196 } 14197 14198 void backgroundServicesFinishedLocked(int userId) { 14199 for (BroadcastQueue queue : mBroadcastQueues) { 14200 queue.backgroundServicesFinishedLocked(userId); 14201 } 14202 } 14203 14204 public void finishReceiver(IBinder who, int resultCode, String resultData, 14205 Bundle resultExtras, boolean resultAbort) { 14206 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14207 14208 // Refuse possible leaked file descriptors 14209 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14210 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14211 } 14212 14213 final long origId = Binder.clearCallingIdentity(); 14214 try { 14215 boolean doNext = false; 14216 BroadcastRecord r; 14217 14218 synchronized(this) { 14219 r = broadcastRecordForReceiverLocked(who); 14220 if (r != null) { 14221 doNext = r.queue.finishReceiverLocked(r, resultCode, 14222 resultData, resultExtras, resultAbort, true); 14223 } 14224 } 14225 14226 if (doNext) { 14227 r.queue.processNextBroadcast(false); 14228 } 14229 trimApplications(); 14230 } finally { 14231 Binder.restoreCallingIdentity(origId); 14232 } 14233 } 14234 14235 // ========================================================= 14236 // INSTRUMENTATION 14237 // ========================================================= 14238 14239 public boolean startInstrumentation(ComponentName className, 14240 String profileFile, int flags, Bundle arguments, 14241 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14242 int userId) { 14243 enforceNotIsolatedCaller("startInstrumentation"); 14244 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14245 userId, false, true, "startInstrumentation", null); 14246 // Refuse possible leaked file descriptors 14247 if (arguments != null && arguments.hasFileDescriptors()) { 14248 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14249 } 14250 14251 synchronized(this) { 14252 InstrumentationInfo ii = null; 14253 ApplicationInfo ai = null; 14254 try { 14255 ii = mContext.getPackageManager().getInstrumentationInfo( 14256 className, STOCK_PM_FLAGS); 14257 ai = AppGlobals.getPackageManager().getApplicationInfo( 14258 ii.targetPackage, STOCK_PM_FLAGS, userId); 14259 } catch (PackageManager.NameNotFoundException e) { 14260 } catch (RemoteException e) { 14261 } 14262 if (ii == null) { 14263 reportStartInstrumentationFailure(watcher, className, 14264 "Unable to find instrumentation info for: " + className); 14265 return false; 14266 } 14267 if (ai == null) { 14268 reportStartInstrumentationFailure(watcher, className, 14269 "Unable to find instrumentation target package: " + ii.targetPackage); 14270 return false; 14271 } 14272 14273 int match = mContext.getPackageManager().checkSignatures( 14274 ii.targetPackage, ii.packageName); 14275 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14276 String msg = "Permission Denial: starting instrumentation " 14277 + className + " from pid=" 14278 + Binder.getCallingPid() 14279 + ", uid=" + Binder.getCallingPid() 14280 + " not allowed because package " + ii.packageName 14281 + " does not have a signature matching the target " 14282 + ii.targetPackage; 14283 reportStartInstrumentationFailure(watcher, className, msg); 14284 throw new SecurityException(msg); 14285 } 14286 14287 final long origId = Binder.clearCallingIdentity(); 14288 // Instrumentation can kill and relaunch even persistent processes 14289 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14290 "start instr"); 14291 ProcessRecord app = addAppLocked(ai, false); 14292 app.instrumentationClass = className; 14293 app.instrumentationInfo = ai; 14294 app.instrumentationProfileFile = profileFile; 14295 app.instrumentationArguments = arguments; 14296 app.instrumentationWatcher = watcher; 14297 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14298 app.instrumentationResultClass = className; 14299 Binder.restoreCallingIdentity(origId); 14300 } 14301 14302 return true; 14303 } 14304 14305 /** 14306 * Report errors that occur while attempting to start Instrumentation. Always writes the 14307 * error to the logs, but if somebody is watching, send the report there too. This enables 14308 * the "am" command to report errors with more information. 14309 * 14310 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14311 * @param cn The component name of the instrumentation. 14312 * @param report The error report. 14313 */ 14314 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14315 ComponentName cn, String report) { 14316 Slog.w(TAG, report); 14317 try { 14318 if (watcher != null) { 14319 Bundle results = new Bundle(); 14320 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14321 results.putString("Error", report); 14322 watcher.instrumentationStatus(cn, -1, results); 14323 } 14324 } catch (RemoteException e) { 14325 Slog.w(TAG, e); 14326 } 14327 } 14328 14329 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14330 if (app.instrumentationWatcher != null) { 14331 try { 14332 // NOTE: IInstrumentationWatcher *must* be oneway here 14333 app.instrumentationWatcher.instrumentationFinished( 14334 app.instrumentationClass, 14335 resultCode, 14336 results); 14337 } catch (RemoteException e) { 14338 } 14339 } 14340 if (app.instrumentationUiAutomationConnection != null) { 14341 try { 14342 app.instrumentationUiAutomationConnection.shutdown(); 14343 } catch (RemoteException re) { 14344 /* ignore */ 14345 } 14346 // Only a UiAutomation can set this flag and now that 14347 // it is finished we make sure it is reset to its default. 14348 mUserIsMonkey = false; 14349 } 14350 app.instrumentationWatcher = null; 14351 app.instrumentationUiAutomationConnection = null; 14352 app.instrumentationClass = null; 14353 app.instrumentationInfo = null; 14354 app.instrumentationProfileFile = null; 14355 app.instrumentationArguments = null; 14356 14357 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14358 "finished inst"); 14359 } 14360 14361 public void finishInstrumentation(IApplicationThread target, 14362 int resultCode, Bundle results) { 14363 int userId = UserHandle.getCallingUserId(); 14364 // Refuse possible leaked file descriptors 14365 if (results != null && results.hasFileDescriptors()) { 14366 throw new IllegalArgumentException("File descriptors passed in Intent"); 14367 } 14368 14369 synchronized(this) { 14370 ProcessRecord app = getRecordForAppLocked(target); 14371 if (app == null) { 14372 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14373 return; 14374 } 14375 final long origId = Binder.clearCallingIdentity(); 14376 finishInstrumentationLocked(app, resultCode, results); 14377 Binder.restoreCallingIdentity(origId); 14378 } 14379 } 14380 14381 // ========================================================= 14382 // CONFIGURATION 14383 // ========================================================= 14384 14385 public ConfigurationInfo getDeviceConfigurationInfo() { 14386 ConfigurationInfo config = new ConfigurationInfo(); 14387 synchronized (this) { 14388 config.reqTouchScreen = mConfiguration.touchscreen; 14389 config.reqKeyboardType = mConfiguration.keyboard; 14390 config.reqNavigation = mConfiguration.navigation; 14391 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14392 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14393 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14394 } 14395 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14396 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14397 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14398 } 14399 config.reqGlEsVersion = GL_ES_VERSION; 14400 } 14401 return config; 14402 } 14403 14404 ActivityStack getFocusedStack() { 14405 return mStackSupervisor.getFocusedStack(); 14406 } 14407 14408 public Configuration getConfiguration() { 14409 Configuration ci; 14410 synchronized(this) { 14411 ci = new Configuration(mConfiguration); 14412 } 14413 return ci; 14414 } 14415 14416 public void updatePersistentConfiguration(Configuration values) { 14417 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14418 "updateConfiguration()"); 14419 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14420 "updateConfiguration()"); 14421 if (values == null) { 14422 throw new NullPointerException("Configuration must not be null"); 14423 } 14424 14425 synchronized(this) { 14426 final long origId = Binder.clearCallingIdentity(); 14427 updateConfigurationLocked(values, null, true, false); 14428 Binder.restoreCallingIdentity(origId); 14429 } 14430 } 14431 14432 public void updateConfiguration(Configuration values) { 14433 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14434 "updateConfiguration()"); 14435 14436 synchronized(this) { 14437 if (values == null && mWindowManager != null) { 14438 // sentinel: fetch the current configuration from the window manager 14439 values = mWindowManager.computeNewConfiguration(); 14440 } 14441 14442 if (mWindowManager != null) { 14443 mProcessList.applyDisplaySize(mWindowManager); 14444 } 14445 14446 final long origId = Binder.clearCallingIdentity(); 14447 if (values != null) { 14448 Settings.System.clearConfiguration(values); 14449 } 14450 updateConfigurationLocked(values, null, false, false); 14451 Binder.restoreCallingIdentity(origId); 14452 } 14453 } 14454 14455 /** 14456 * Do either or both things: (1) change the current configuration, and (2) 14457 * make sure the given activity is running with the (now) current 14458 * configuration. Returns true if the activity has been left running, or 14459 * false if <var>starting</var> is being destroyed to match the new 14460 * configuration. 14461 * @param persistent TODO 14462 */ 14463 boolean updateConfigurationLocked(Configuration values, 14464 ActivityRecord starting, boolean persistent, boolean initLocale) { 14465 int changes = 0; 14466 14467 if (values != null) { 14468 Configuration newConfig = new Configuration(mConfiguration); 14469 changes = newConfig.updateFrom(values); 14470 if (changes != 0) { 14471 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14472 Slog.i(TAG, "Updating configuration to: " + values); 14473 } 14474 14475 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14476 14477 if (values.locale != null && !initLocale) { 14478 saveLocaleLocked(values.locale, 14479 !values.locale.equals(mConfiguration.locale), 14480 values.userSetLocale); 14481 } 14482 14483 mConfigurationSeq++; 14484 if (mConfigurationSeq <= 0) { 14485 mConfigurationSeq = 1; 14486 } 14487 newConfig.seq = mConfigurationSeq; 14488 mConfiguration = newConfig; 14489 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14490 14491 final Configuration configCopy = new Configuration(mConfiguration); 14492 14493 // TODO: If our config changes, should we auto dismiss any currently 14494 // showing dialogs? 14495 mShowDialogs = shouldShowDialogs(newConfig); 14496 14497 AttributeCache ac = AttributeCache.instance(); 14498 if (ac != null) { 14499 ac.updateConfiguration(configCopy); 14500 } 14501 14502 // Make sure all resources in our process are updated 14503 // right now, so that anyone who is going to retrieve 14504 // resource values after we return will be sure to get 14505 // the new ones. This is especially important during 14506 // boot, where the first config change needs to guarantee 14507 // all resources have that config before following boot 14508 // code is executed. 14509 mSystemThread.applyConfigurationToResources(configCopy); 14510 14511 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14512 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14513 msg.obj = new Configuration(configCopy); 14514 mHandler.sendMessage(msg); 14515 } 14516 14517 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14518 ProcessRecord app = mLruProcesses.get(i); 14519 try { 14520 if (app.thread != null) { 14521 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14522 + app.processName + " new config " + mConfiguration); 14523 app.thread.scheduleConfigurationChanged(configCopy); 14524 } 14525 } catch (Exception e) { 14526 } 14527 } 14528 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14529 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14530 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14531 | Intent.FLAG_RECEIVER_FOREGROUND); 14532 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14533 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14534 Process.SYSTEM_UID, UserHandle.USER_ALL); 14535 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14536 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14537 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14538 broadcastIntentLocked(null, null, intent, 14539 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14540 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14541 } 14542 } 14543 } 14544 14545 boolean kept = true; 14546 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14547 // mainStack is null during startup. 14548 if (mainStack != null) { 14549 if (changes != 0 && starting == null) { 14550 // If the configuration changed, and the caller is not already 14551 // in the process of starting an activity, then find the top 14552 // activity to check if its configuration needs to change. 14553 starting = mainStack.topRunningActivityLocked(null); 14554 } 14555 14556 if (starting != null) { 14557 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14558 // And we need to make sure at this point that all other activities 14559 // are made visible with the correct configuration. 14560 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14561 } 14562 } 14563 14564 if (values != null && mWindowManager != null) { 14565 mWindowManager.setNewConfiguration(mConfiguration); 14566 } 14567 14568 return kept; 14569 } 14570 14571 /** 14572 * Decide based on the configuration whether we should shouw the ANR, 14573 * crash, etc dialogs. The idea is that if there is no affordnace to 14574 * press the on-screen buttons, we shouldn't show the dialog. 14575 * 14576 * A thought: SystemUI might also want to get told about this, the Power 14577 * dialog / global actions also might want different behaviors. 14578 */ 14579 private static final boolean shouldShowDialogs(Configuration config) { 14580 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14581 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14582 } 14583 14584 /** 14585 * Save the locale. You must be inside a synchronized (this) block. 14586 */ 14587 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14588 if(isDiff) { 14589 SystemProperties.set("user.language", l.getLanguage()); 14590 SystemProperties.set("user.region", l.getCountry()); 14591 } 14592 14593 if(isPersist) { 14594 SystemProperties.set("persist.sys.language", l.getLanguage()); 14595 SystemProperties.set("persist.sys.country", l.getCountry()); 14596 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14597 } 14598 } 14599 14600 @Override 14601 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14602 ActivityRecord srec = ActivityRecord.forToken(token); 14603 return srec != null && srec.task.affinity != null && 14604 srec.task.affinity.equals(destAffinity); 14605 } 14606 14607 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14608 Intent resultData) { 14609 14610 synchronized (this) { 14611 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14612 if (stack != null) { 14613 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14614 } 14615 return false; 14616 } 14617 } 14618 14619 public int getLaunchedFromUid(IBinder activityToken) { 14620 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14621 if (srec == null) { 14622 return -1; 14623 } 14624 return srec.launchedFromUid; 14625 } 14626 14627 public String getLaunchedFromPackage(IBinder activityToken) { 14628 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14629 if (srec == null) { 14630 return null; 14631 } 14632 return srec.launchedFromPackage; 14633 } 14634 14635 // ========================================================= 14636 // LIFETIME MANAGEMENT 14637 // ========================================================= 14638 14639 // Returns which broadcast queue the app is the current [or imminent] receiver 14640 // on, or 'null' if the app is not an active broadcast recipient. 14641 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14642 BroadcastRecord r = app.curReceiver; 14643 if (r != null) { 14644 return r.queue; 14645 } 14646 14647 // It's not the current receiver, but it might be starting up to become one 14648 synchronized (this) { 14649 for (BroadcastQueue queue : mBroadcastQueues) { 14650 r = queue.mPendingBroadcast; 14651 if (r != null && r.curApp == app) { 14652 // found it; report which queue it's in 14653 return queue; 14654 } 14655 } 14656 } 14657 14658 return null; 14659 } 14660 14661 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14662 boolean doingAll, long now) { 14663 if (mAdjSeq == app.adjSeq) { 14664 // This adjustment has already been computed. 14665 return app.curRawAdj; 14666 } 14667 14668 if (app.thread == null) { 14669 app.adjSeq = mAdjSeq; 14670 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14671 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14672 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14673 } 14674 14675 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14676 app.adjSource = null; 14677 app.adjTarget = null; 14678 app.empty = false; 14679 app.cached = false; 14680 14681 final int activitiesSize = app.activities.size(); 14682 14683 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14684 // The max adjustment doesn't allow this app to be anything 14685 // below foreground, so it is not worth doing work for it. 14686 app.adjType = "fixed"; 14687 app.adjSeq = mAdjSeq; 14688 app.curRawAdj = app.maxAdj; 14689 app.foregroundActivities = false; 14690 app.keeping = true; 14691 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14692 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14693 // System processes can do UI, and when they do we want to have 14694 // them trim their memory after the user leaves the UI. To 14695 // facilitate this, here we need to determine whether or not it 14696 // is currently showing UI. 14697 app.systemNoUi = true; 14698 if (app == TOP_APP) { 14699 app.systemNoUi = false; 14700 } else if (activitiesSize > 0) { 14701 for (int j = 0; j < activitiesSize; j++) { 14702 final ActivityRecord r = app.activities.get(j); 14703 if (r.visible) { 14704 app.systemNoUi = false; 14705 } 14706 } 14707 } 14708 if (!app.systemNoUi) { 14709 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14710 } 14711 return (app.curAdj=app.maxAdj); 14712 } 14713 14714 app.keeping = false; 14715 app.systemNoUi = false; 14716 14717 // Determine the importance of the process, starting with most 14718 // important to least, and assign an appropriate OOM adjustment. 14719 int adj; 14720 int schedGroup; 14721 int procState; 14722 boolean foregroundActivities = false; 14723 boolean interesting = false; 14724 BroadcastQueue queue; 14725 if (app == TOP_APP) { 14726 // The last app on the list is the foreground app. 14727 adj = ProcessList.FOREGROUND_APP_ADJ; 14728 schedGroup = Process.THREAD_GROUP_DEFAULT; 14729 app.adjType = "top-activity"; 14730 foregroundActivities = true; 14731 interesting = true; 14732 procState = ActivityManager.PROCESS_STATE_TOP; 14733 } else if (app.instrumentationClass != null) { 14734 // Don't want to kill running instrumentation. 14735 adj = ProcessList.FOREGROUND_APP_ADJ; 14736 schedGroup = Process.THREAD_GROUP_DEFAULT; 14737 app.adjType = "instrumentation"; 14738 interesting = true; 14739 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14740 } else if ((queue = isReceivingBroadcast(app)) != null) { 14741 // An app that is currently receiving a broadcast also 14742 // counts as being in the foreground for OOM killer purposes. 14743 // It's placed in a sched group based on the nature of the 14744 // broadcast as reflected by which queue it's active in. 14745 adj = ProcessList.FOREGROUND_APP_ADJ; 14746 schedGroup = (queue == mFgBroadcastQueue) 14747 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14748 app.adjType = "broadcast"; 14749 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14750 } else if (app.executingServices.size() > 0) { 14751 // An app that is currently executing a service callback also 14752 // counts as being in the foreground. 14753 adj = ProcessList.FOREGROUND_APP_ADJ; 14754 schedGroup = app.execServicesFg ? 14755 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14756 app.adjType = "exec-service"; 14757 procState = ActivityManager.PROCESS_STATE_SERVICE; 14758 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14759 } else { 14760 // As far as we know the process is empty. We may change our mind later. 14761 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14762 // At this point we don't actually know the adjustment. Use the cached adj 14763 // value that the caller wants us to. 14764 adj = cachedAdj; 14765 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14766 app.cached = true; 14767 app.empty = true; 14768 app.adjType = "cch-empty"; 14769 } 14770 14771 // Examine all activities if not already foreground. 14772 if (!foregroundActivities && activitiesSize > 0) { 14773 for (int j = 0; j < activitiesSize; j++) { 14774 final ActivityRecord r = app.activities.get(j); 14775 if (r.app != app) { 14776 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14777 + app + "?!?"); 14778 continue; 14779 } 14780 if (r.visible) { 14781 // App has a visible activity; only upgrade adjustment. 14782 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14783 adj = ProcessList.VISIBLE_APP_ADJ; 14784 app.adjType = "visible"; 14785 } 14786 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14787 procState = ActivityManager.PROCESS_STATE_TOP; 14788 } 14789 schedGroup = Process.THREAD_GROUP_DEFAULT; 14790 app.cached = false; 14791 app.empty = false; 14792 foregroundActivities = true; 14793 break; 14794 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14795 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14796 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14797 app.adjType = "pausing"; 14798 } 14799 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14800 procState = ActivityManager.PROCESS_STATE_TOP; 14801 } 14802 schedGroup = Process.THREAD_GROUP_DEFAULT; 14803 app.cached = false; 14804 app.empty = false; 14805 foregroundActivities = true; 14806 } else if (r.state == ActivityState.STOPPING) { 14807 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14808 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14809 app.adjType = "stopping"; 14810 } 14811 // For the process state, we will at this point consider the 14812 // process to be cached. It will be cached either as an activity 14813 // or empty depending on whether the activity is finishing. We do 14814 // this so that we can treat the process as cached for purposes of 14815 // memory trimming (determing current memory level, trim command to 14816 // send to process) since there can be an arbitrary number of stopping 14817 // processes and they should soon all go into the cached state. 14818 if (!r.finishing) { 14819 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14820 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14821 } 14822 } 14823 app.cached = false; 14824 app.empty = false; 14825 foregroundActivities = true; 14826 } else { 14827 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14828 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14829 app.adjType = "cch-act"; 14830 } 14831 } 14832 } 14833 } 14834 14835 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14836 if (app.foregroundServices) { 14837 // The user is aware of this app, so make it visible. 14838 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14839 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14840 app.cached = false; 14841 app.adjType = "fg-service"; 14842 schedGroup = Process.THREAD_GROUP_DEFAULT; 14843 } else if (app.forcingToForeground != null) { 14844 // The user is aware of this app, so make it visible. 14845 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14846 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14847 app.cached = false; 14848 app.adjType = "force-fg"; 14849 app.adjSource = app.forcingToForeground; 14850 schedGroup = Process.THREAD_GROUP_DEFAULT; 14851 } 14852 } 14853 14854 if (app.foregroundServices) { 14855 interesting = true; 14856 } 14857 14858 if (app == mHeavyWeightProcess) { 14859 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14860 // We don't want to kill the current heavy-weight process. 14861 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14862 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14863 app.cached = false; 14864 app.adjType = "heavy"; 14865 } 14866 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14867 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14868 } 14869 } 14870 14871 if (app == mHomeProcess) { 14872 if (adj > ProcessList.HOME_APP_ADJ) { 14873 // This process is hosting what we currently consider to be the 14874 // home app, so we don't want to let it go into the background. 14875 adj = ProcessList.HOME_APP_ADJ; 14876 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14877 app.cached = false; 14878 app.adjType = "home"; 14879 } 14880 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14881 procState = ActivityManager.PROCESS_STATE_HOME; 14882 } 14883 } 14884 14885 if (app == mPreviousProcess && app.activities.size() > 0) { 14886 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14887 // This was the previous process that showed UI to the user. 14888 // We want to try to keep it around more aggressively, to give 14889 // a good experience around switching between two apps. 14890 adj = ProcessList.PREVIOUS_APP_ADJ; 14891 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14892 app.cached = false; 14893 app.adjType = "previous"; 14894 } 14895 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14896 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14897 } 14898 } 14899 14900 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14901 + " reason=" + app.adjType); 14902 14903 // By default, we use the computed adjustment. It may be changed if 14904 // there are applications dependent on our services or providers, but 14905 // this gives us a baseline and makes sure we don't get into an 14906 // infinite recursion. 14907 app.adjSeq = mAdjSeq; 14908 app.curRawAdj = adj; 14909 app.hasStartedServices = false; 14910 14911 if (mBackupTarget != null && app == mBackupTarget.app) { 14912 // If possible we want to avoid killing apps while they're being backed up 14913 if (adj > ProcessList.BACKUP_APP_ADJ) { 14914 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14915 adj = ProcessList.BACKUP_APP_ADJ; 14916 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14917 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14918 } 14919 app.adjType = "backup"; 14920 app.cached = false; 14921 } 14922 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14923 procState = ActivityManager.PROCESS_STATE_BACKUP; 14924 } 14925 } 14926 14927 boolean mayBeTop = false; 14928 14929 for (int is = app.services.size()-1; 14930 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14931 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14932 || procState > ActivityManager.PROCESS_STATE_TOP); 14933 is--) { 14934 ServiceRecord s = app.services.valueAt(is); 14935 if (s.startRequested) { 14936 app.hasStartedServices = true; 14937 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14938 procState = ActivityManager.PROCESS_STATE_SERVICE; 14939 } 14940 if (app.hasShownUi && app != mHomeProcess) { 14941 // If this process has shown some UI, let it immediately 14942 // go to the LRU list because it may be pretty heavy with 14943 // UI stuff. We'll tag it with a label just to help 14944 // debug and understand what is going on. 14945 if (adj > ProcessList.SERVICE_ADJ) { 14946 app.adjType = "cch-started-ui-services"; 14947 } 14948 } else { 14949 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14950 // This service has seen some activity within 14951 // recent memory, so we will keep its process ahead 14952 // of the background processes. 14953 if (adj > ProcessList.SERVICE_ADJ) { 14954 adj = ProcessList.SERVICE_ADJ; 14955 app.adjType = "started-services"; 14956 app.cached = false; 14957 } 14958 } 14959 // If we have let the service slide into the background 14960 // state, still have some text describing what it is doing 14961 // even though the service no longer has an impact. 14962 if (adj > ProcessList.SERVICE_ADJ) { 14963 app.adjType = "cch-started-services"; 14964 } 14965 } 14966 // Don't kill this process because it is doing work; it 14967 // has said it is doing work. 14968 app.keeping = true; 14969 } 14970 for (int conni = s.connections.size()-1; 14971 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14972 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14973 || procState > ActivityManager.PROCESS_STATE_TOP); 14974 conni--) { 14975 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14976 for (int i = 0; 14977 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14978 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14979 || procState > ActivityManager.PROCESS_STATE_TOP); 14980 i++) { 14981 // XXX should compute this based on the max of 14982 // all connected clients. 14983 ConnectionRecord cr = clist.get(i); 14984 if (cr.binding.client == app) { 14985 // Binding to ourself is not interesting. 14986 continue; 14987 } 14988 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14989 ProcessRecord client = cr.binding.client; 14990 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14991 TOP_APP, doingAll, now); 14992 int clientProcState = client.curProcState; 14993 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14994 // If the other app is cached for any reason, for purposes here 14995 // we are going to consider it empty. The specific cached state 14996 // doesn't propagate except under certain conditions. 14997 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14998 } 14999 String adjType = null; 15000 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 15001 // Not doing bind OOM management, so treat 15002 // this guy more like a started service. 15003 if (app.hasShownUi && app != mHomeProcess) { 15004 // If this process has shown some UI, let it immediately 15005 // go to the LRU list because it may be pretty heavy with 15006 // UI stuff. We'll tag it with a label just to help 15007 // debug and understand what is going on. 15008 if (adj > clientAdj) { 15009 adjType = "cch-bound-ui-services"; 15010 } 15011 app.cached = false; 15012 clientAdj = adj; 15013 clientProcState = procState; 15014 } else { 15015 if (now >= (s.lastActivity 15016 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 15017 // This service has not seen activity within 15018 // recent memory, so allow it to drop to the 15019 // LRU list if there is no other reason to keep 15020 // it around. We'll also tag it with a label just 15021 // to help debug and undertand what is going on. 15022 if (adj > clientAdj) { 15023 adjType = "cch-bound-services"; 15024 } 15025 clientAdj = adj; 15026 } 15027 } 15028 } 15029 if (adj > clientAdj) { 15030 // If this process has recently shown UI, and 15031 // the process that is binding to it is less 15032 // important than being visible, then we don't 15033 // care about the binding as much as we care 15034 // about letting this process get into the LRU 15035 // list to be killed and restarted if needed for 15036 // memory. 15037 if (app.hasShownUi && app != mHomeProcess 15038 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15039 adjType = "cch-bound-ui-services"; 15040 } else { 15041 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 15042 |Context.BIND_IMPORTANT)) != 0) { 15043 adj = clientAdj; 15044 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 15045 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 15046 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15047 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 15048 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 15049 adj = clientAdj; 15050 } else { 15051 if (adj > ProcessList.VISIBLE_APP_ADJ) { 15052 adj = ProcessList.VISIBLE_APP_ADJ; 15053 } 15054 } 15055 if (!client.cached) { 15056 app.cached = false; 15057 } 15058 if (client.keeping) { 15059 app.keeping = true; 15060 } 15061 adjType = "service"; 15062 } 15063 } 15064 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15065 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15066 schedGroup = Process.THREAD_GROUP_DEFAULT; 15067 } 15068 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15069 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15070 // Special handling of clients who are in the top state. 15071 // We *may* want to consider this process to be in the 15072 // top state as well, but only if there is not another 15073 // reason for it to be running. Being on the top is a 15074 // special state, meaning you are specifically running 15075 // for the current top app. If the process is already 15076 // running in the background for some other reason, it 15077 // is more important to continue considering it to be 15078 // in the background state. 15079 mayBeTop = true; 15080 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15081 } else { 15082 // Special handling for above-top states (persistent 15083 // processes). These should not bring the current process 15084 // into the top state, since they are not on top. Instead 15085 // give them the best state after that. 15086 clientProcState = 15087 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15088 } 15089 } 15090 } else { 15091 if (clientProcState < 15092 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 15093 clientProcState = 15094 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 15095 } 15096 } 15097 if (procState > clientProcState) { 15098 procState = clientProcState; 15099 } 15100 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15101 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15102 app.pendingUiClean = true; 15103 } 15104 if (adjType != null) { 15105 app.adjType = adjType; 15106 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15107 .REASON_SERVICE_IN_USE; 15108 app.adjSource = cr.binding.client; 15109 app.adjSourceOom = clientAdj; 15110 app.adjTarget = s.name; 15111 } 15112 } 15113 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15114 app.treatLikeActivity = true; 15115 } 15116 final ActivityRecord a = cr.activity; 15117 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15118 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15119 (a.visible || a.state == ActivityState.RESUMED 15120 || a.state == ActivityState.PAUSING)) { 15121 adj = ProcessList.FOREGROUND_APP_ADJ; 15122 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15123 schedGroup = Process.THREAD_GROUP_DEFAULT; 15124 } 15125 app.cached = false; 15126 app.adjType = "service"; 15127 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15128 .REASON_SERVICE_IN_USE; 15129 app.adjSource = a; 15130 app.adjSourceOom = adj; 15131 app.adjTarget = s.name; 15132 } 15133 } 15134 } 15135 } 15136 } 15137 15138 for (int provi = app.pubProviders.size()-1; 15139 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15140 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15141 || procState > ActivityManager.PROCESS_STATE_TOP); 15142 provi--) { 15143 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15144 for (int i = cpr.connections.size()-1; 15145 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15146 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15147 || procState > ActivityManager.PROCESS_STATE_TOP); 15148 i--) { 15149 ContentProviderConnection conn = cpr.connections.get(i); 15150 ProcessRecord client = conn.client; 15151 if (client == app) { 15152 // Being our own client is not interesting. 15153 continue; 15154 } 15155 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15156 int clientProcState = client.curProcState; 15157 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15158 // If the other app is cached for any reason, for purposes here 15159 // we are going to consider it empty. 15160 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15161 } 15162 if (adj > clientAdj) { 15163 if (app.hasShownUi && app != mHomeProcess 15164 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15165 app.adjType = "cch-ui-provider"; 15166 } else { 15167 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15168 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15169 app.adjType = "provider"; 15170 } 15171 app.cached &= client.cached; 15172 app.keeping |= client.keeping; 15173 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15174 .REASON_PROVIDER_IN_USE; 15175 app.adjSource = client; 15176 app.adjSourceOom = clientAdj; 15177 app.adjTarget = cpr.name; 15178 } 15179 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15180 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15181 // Special handling of clients who are in the top state. 15182 // We *may* want to consider this process to be in the 15183 // top state as well, but only if there is not another 15184 // reason for it to be running. Being on the top is a 15185 // special state, meaning you are specifically running 15186 // for the current top app. If the process is already 15187 // running in the background for some other reason, it 15188 // is more important to continue considering it to be 15189 // in the background state. 15190 mayBeTop = true; 15191 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15192 } else { 15193 // Special handling for above-top states (persistent 15194 // processes). These should not bring the current process 15195 // into the top state, since they are not on top. Instead 15196 // give them the best state after that. 15197 clientProcState = 15198 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15199 } 15200 } 15201 if (procState > clientProcState) { 15202 procState = clientProcState; 15203 } 15204 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15205 schedGroup = Process.THREAD_GROUP_DEFAULT; 15206 } 15207 } 15208 // If the provider has external (non-framework) process 15209 // dependencies, ensure that its adjustment is at least 15210 // FOREGROUND_APP_ADJ. 15211 if (cpr.hasExternalProcessHandles()) { 15212 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15213 adj = ProcessList.FOREGROUND_APP_ADJ; 15214 schedGroup = Process.THREAD_GROUP_DEFAULT; 15215 app.cached = false; 15216 app.keeping = true; 15217 app.adjType = "provider"; 15218 app.adjTarget = cpr.name; 15219 } 15220 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15221 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15222 } 15223 } 15224 } 15225 15226 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15227 // A client of one of our services or providers is in the top state. We 15228 // *may* want to be in the top state, but not if we are already running in 15229 // the background for some other reason. For the decision here, we are going 15230 // to pick out a few specific states that we want to remain in when a client 15231 // is top (states that tend to be longer-term) and otherwise allow it to go 15232 // to the top state. 15233 switch (procState) { 15234 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15235 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15236 case ActivityManager.PROCESS_STATE_SERVICE: 15237 // These all are longer-term states, so pull them up to the top 15238 // of the background states, but not all the way to the top state. 15239 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15240 break; 15241 default: 15242 // Otherwise, top is a better choice, so take it. 15243 procState = ActivityManager.PROCESS_STATE_TOP; 15244 break; 15245 } 15246 } 15247 15248 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15249 if (app.hasClientActivities) { 15250 // This is a cached process, but with client activities. Mark it so. 15251 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15252 app.adjType = "cch-client-act"; 15253 } else if (app.treatLikeActivity) { 15254 // This is a cached process, but somebody wants us to treat it like it has 15255 // an activity, okay! 15256 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15257 app.adjType = "cch-as-act"; 15258 } 15259 } 15260 15261 if (adj == ProcessList.SERVICE_ADJ) { 15262 if (doingAll) { 15263 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15264 mNewNumServiceProcs++; 15265 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15266 if (!app.serviceb) { 15267 // This service isn't far enough down on the LRU list to 15268 // normally be a B service, but if we are low on RAM and it 15269 // is large we want to force it down since we would prefer to 15270 // keep launcher over it. 15271 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15272 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15273 app.serviceHighRam = true; 15274 app.serviceb = true; 15275 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15276 } else { 15277 mNewNumAServiceProcs++; 15278 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15279 } 15280 } else { 15281 app.serviceHighRam = false; 15282 } 15283 } 15284 if (app.serviceb) { 15285 adj = ProcessList.SERVICE_B_ADJ; 15286 } 15287 } 15288 15289 app.curRawAdj = adj; 15290 15291 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15292 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15293 if (adj > app.maxAdj) { 15294 adj = app.maxAdj; 15295 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15296 schedGroup = Process.THREAD_GROUP_DEFAULT; 15297 } 15298 } 15299 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15300 app.keeping = true; 15301 } 15302 15303 // Do final modification to adj. Everything we do between here and applying 15304 // the final setAdj must be done in this function, because we will also use 15305 // it when computing the final cached adj later. Note that we don't need to 15306 // worry about this for max adj above, since max adj will always be used to 15307 // keep it out of the cached vaues. 15308 adj = app.modifyRawOomAdj(adj); 15309 15310 app.curProcState = procState; 15311 app.foregroundActivities = foregroundActivities; 15312 15313 return app.curRawAdj; 15314 } 15315 15316 /** 15317 * Schedule PSS collection of a process. 15318 */ 15319 void requestPssLocked(ProcessRecord proc, int procState) { 15320 if (mPendingPssProcesses.contains(proc)) { 15321 return; 15322 } 15323 if (mPendingPssProcesses.size() == 0) { 15324 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15325 } 15326 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15327 proc.pssProcState = procState; 15328 mPendingPssProcesses.add(proc); 15329 } 15330 15331 /** 15332 * Schedule PSS collection of all processes. 15333 */ 15334 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15335 if (!always) { 15336 if (now < (mLastFullPssTime + 15337 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15338 return; 15339 } 15340 } 15341 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15342 mLastFullPssTime = now; 15343 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15344 mPendingPssProcesses.clear(); 15345 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15346 ProcessRecord app = mLruProcesses.get(i); 15347 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15348 app.pssProcState = app.setProcState; 15349 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15350 isSleeping(), now); 15351 mPendingPssProcesses.add(app); 15352 } 15353 } 15354 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15355 } 15356 15357 /** 15358 * Ask a given process to GC right now. 15359 */ 15360 final void performAppGcLocked(ProcessRecord app) { 15361 try { 15362 app.lastRequestedGc = SystemClock.uptimeMillis(); 15363 if (app.thread != null) { 15364 if (app.reportLowMemory) { 15365 app.reportLowMemory = false; 15366 app.thread.scheduleLowMemory(); 15367 } else { 15368 app.thread.processInBackground(); 15369 } 15370 } 15371 } catch (Exception e) { 15372 // whatever. 15373 } 15374 } 15375 15376 /** 15377 * Returns true if things are idle enough to perform GCs. 15378 */ 15379 private final boolean canGcNowLocked() { 15380 boolean processingBroadcasts = false; 15381 for (BroadcastQueue q : mBroadcastQueues) { 15382 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15383 processingBroadcasts = true; 15384 } 15385 } 15386 return !processingBroadcasts 15387 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15388 } 15389 15390 /** 15391 * Perform GCs on all processes that are waiting for it, but only 15392 * if things are idle. 15393 */ 15394 final void performAppGcsLocked() { 15395 final int N = mProcessesToGc.size(); 15396 if (N <= 0) { 15397 return; 15398 } 15399 if (canGcNowLocked()) { 15400 while (mProcessesToGc.size() > 0) { 15401 ProcessRecord proc = mProcessesToGc.remove(0); 15402 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15403 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15404 <= SystemClock.uptimeMillis()) { 15405 // To avoid spamming the system, we will GC processes one 15406 // at a time, waiting a few seconds between each. 15407 performAppGcLocked(proc); 15408 scheduleAppGcsLocked(); 15409 return; 15410 } else { 15411 // It hasn't been long enough since we last GCed this 15412 // process... put it in the list to wait for its time. 15413 addProcessToGcListLocked(proc); 15414 break; 15415 } 15416 } 15417 } 15418 15419 scheduleAppGcsLocked(); 15420 } 15421 } 15422 15423 /** 15424 * If all looks good, perform GCs on all processes waiting for them. 15425 */ 15426 final void performAppGcsIfAppropriateLocked() { 15427 if (canGcNowLocked()) { 15428 performAppGcsLocked(); 15429 return; 15430 } 15431 // Still not idle, wait some more. 15432 scheduleAppGcsLocked(); 15433 } 15434 15435 /** 15436 * Schedule the execution of all pending app GCs. 15437 */ 15438 final void scheduleAppGcsLocked() { 15439 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15440 15441 if (mProcessesToGc.size() > 0) { 15442 // Schedule a GC for the time to the next process. 15443 ProcessRecord proc = mProcessesToGc.get(0); 15444 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15445 15446 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15447 long now = SystemClock.uptimeMillis(); 15448 if (when < (now+GC_TIMEOUT)) { 15449 when = now + GC_TIMEOUT; 15450 } 15451 mHandler.sendMessageAtTime(msg, when); 15452 } 15453 } 15454 15455 /** 15456 * Add a process to the array of processes waiting to be GCed. Keeps the 15457 * list in sorted order by the last GC time. The process can't already be 15458 * on the list. 15459 */ 15460 final void addProcessToGcListLocked(ProcessRecord proc) { 15461 boolean added = false; 15462 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15463 if (mProcessesToGc.get(i).lastRequestedGc < 15464 proc.lastRequestedGc) { 15465 added = true; 15466 mProcessesToGc.add(i+1, proc); 15467 break; 15468 } 15469 } 15470 if (!added) { 15471 mProcessesToGc.add(0, proc); 15472 } 15473 } 15474 15475 /** 15476 * Set up to ask a process to GC itself. This will either do it 15477 * immediately, or put it on the list of processes to gc the next 15478 * time things are idle. 15479 */ 15480 final void scheduleAppGcLocked(ProcessRecord app) { 15481 long now = SystemClock.uptimeMillis(); 15482 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15483 return; 15484 } 15485 if (!mProcessesToGc.contains(app)) { 15486 addProcessToGcListLocked(app); 15487 scheduleAppGcsLocked(); 15488 } 15489 } 15490 15491 final void checkExcessivePowerUsageLocked(boolean doKills) { 15492 updateCpuStatsNow(); 15493 15494 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15495 boolean doWakeKills = doKills; 15496 boolean doCpuKills = doKills; 15497 if (mLastPowerCheckRealtime == 0) { 15498 doWakeKills = false; 15499 } 15500 if (mLastPowerCheckUptime == 0) { 15501 doCpuKills = false; 15502 } 15503 if (stats.isScreenOn()) { 15504 doWakeKills = false; 15505 } 15506 final long curRealtime = SystemClock.elapsedRealtime(); 15507 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15508 final long curUptime = SystemClock.uptimeMillis(); 15509 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15510 mLastPowerCheckRealtime = curRealtime; 15511 mLastPowerCheckUptime = curUptime; 15512 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15513 doWakeKills = false; 15514 } 15515 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15516 doCpuKills = false; 15517 } 15518 int i = mLruProcesses.size(); 15519 while (i > 0) { 15520 i--; 15521 ProcessRecord app = mLruProcesses.get(i); 15522 if (!app.keeping) { 15523 long wtime; 15524 synchronized (stats) { 15525 wtime = stats.getProcessWakeTime(app.info.uid, 15526 app.pid, curRealtime); 15527 } 15528 long wtimeUsed = wtime - app.lastWakeTime; 15529 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15530 if (DEBUG_POWER) { 15531 StringBuilder sb = new StringBuilder(128); 15532 sb.append("Wake for "); 15533 app.toShortString(sb); 15534 sb.append(": over "); 15535 TimeUtils.formatDuration(realtimeSince, sb); 15536 sb.append(" used "); 15537 TimeUtils.formatDuration(wtimeUsed, sb); 15538 sb.append(" ("); 15539 sb.append((wtimeUsed*100)/realtimeSince); 15540 sb.append("%)"); 15541 Slog.i(TAG, sb.toString()); 15542 sb.setLength(0); 15543 sb.append("CPU for "); 15544 app.toShortString(sb); 15545 sb.append(": over "); 15546 TimeUtils.formatDuration(uptimeSince, sb); 15547 sb.append(" used "); 15548 TimeUtils.formatDuration(cputimeUsed, sb); 15549 sb.append(" ("); 15550 sb.append((cputimeUsed*100)/uptimeSince); 15551 sb.append("%)"); 15552 Slog.i(TAG, sb.toString()); 15553 } 15554 // If a process has held a wake lock for more 15555 // than 50% of the time during this period, 15556 // that sounds bad. Kill! 15557 if (doWakeKills && realtimeSince > 0 15558 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15559 synchronized (stats) { 15560 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15561 realtimeSince, wtimeUsed); 15562 } 15563 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15564 + " during " + realtimeSince); 15565 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15566 } else if (doCpuKills && uptimeSince > 0 15567 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15568 synchronized (stats) { 15569 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15570 uptimeSince, cputimeUsed); 15571 } 15572 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15573 + " during " + uptimeSince); 15574 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15575 } else { 15576 app.lastWakeTime = wtime; 15577 app.lastCpuTime = app.curCpuTime; 15578 } 15579 } 15580 } 15581 } 15582 15583 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15584 ProcessRecord TOP_APP, boolean doingAll, long now) { 15585 boolean success = true; 15586 15587 if (app.curRawAdj != app.setRawAdj) { 15588 if (wasKeeping && !app.keeping) { 15589 // This app is no longer something we want to keep. Note 15590 // its current wake lock time to later know to kill it if 15591 // it is not behaving well. 15592 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15593 synchronized (stats) { 15594 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15595 app.pid, SystemClock.elapsedRealtime()); 15596 } 15597 app.lastCpuTime = app.curCpuTime; 15598 } 15599 15600 app.setRawAdj = app.curRawAdj; 15601 } 15602 15603 int changes = 0; 15604 15605 if (app.curAdj != app.setAdj) { 15606 ProcessList.setOomAdj(app.pid, app.curAdj); 15607 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15608 TAG, "Set " + app.pid + " " + app.processName + 15609 " adj " + app.curAdj + ": " + app.adjType); 15610 app.setAdj = app.curAdj; 15611 } 15612 15613 if (app.setSchedGroup != app.curSchedGroup) { 15614 app.setSchedGroup = app.curSchedGroup; 15615 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15616 "Setting process group of " + app.processName 15617 + " to " + app.curSchedGroup); 15618 if (app.waitingToKill != null && 15619 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15620 killUnneededProcessLocked(app, app.waitingToKill); 15621 success = false; 15622 } else { 15623 if (true) { 15624 long oldId = Binder.clearCallingIdentity(); 15625 try { 15626 Process.setProcessGroup(app.pid, app.curSchedGroup); 15627 } catch (Exception e) { 15628 Slog.w(TAG, "Failed setting process group of " + app.pid 15629 + " to " + app.curSchedGroup); 15630 e.printStackTrace(); 15631 } finally { 15632 Binder.restoreCallingIdentity(oldId); 15633 } 15634 } else { 15635 if (app.thread != null) { 15636 try { 15637 app.thread.setSchedulingGroup(app.curSchedGroup); 15638 } catch (RemoteException e) { 15639 } 15640 } 15641 } 15642 Process.setSwappiness(app.pid, 15643 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15644 } 15645 } 15646 if (app.repForegroundActivities != app.foregroundActivities) { 15647 app.repForegroundActivities = app.foregroundActivities; 15648 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15649 } 15650 if (app.repProcState != app.curProcState) { 15651 app.repProcState = app.curProcState; 15652 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15653 if (app.thread != null) { 15654 try { 15655 if (false) { 15656 //RuntimeException h = new RuntimeException("here"); 15657 Slog.i(TAG, "Sending new process state " + app.repProcState 15658 + " to " + app /*, h*/); 15659 } 15660 app.thread.setProcessState(app.repProcState); 15661 } catch (RemoteException e) { 15662 } 15663 } 15664 } 15665 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15666 app.setProcState)) { 15667 app.lastStateTime = now; 15668 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15669 isSleeping(), now); 15670 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15671 + ProcessList.makeProcStateString(app.setProcState) + " to " 15672 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15673 + (app.nextPssTime-now) + ": " + app); 15674 } else { 15675 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15676 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15677 requestPssLocked(app, app.setProcState); 15678 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15679 isSleeping(), now); 15680 } else if (false && DEBUG_PSS) { 15681 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15682 } 15683 } 15684 if (app.setProcState != app.curProcState) { 15685 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15686 "Proc state change of " + app.processName 15687 + " to " + app.curProcState); 15688 app.setProcState = app.curProcState; 15689 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15690 app.notCachedSinceIdle = false; 15691 } 15692 if (!doingAll) { 15693 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15694 } else { 15695 app.procStateChanged = true; 15696 } 15697 } 15698 15699 if (changes != 0) { 15700 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15701 int i = mPendingProcessChanges.size()-1; 15702 ProcessChangeItem item = null; 15703 while (i >= 0) { 15704 item = mPendingProcessChanges.get(i); 15705 if (item.pid == app.pid) { 15706 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15707 break; 15708 } 15709 i--; 15710 } 15711 if (i < 0) { 15712 // No existing item in pending changes; need a new one. 15713 final int NA = mAvailProcessChanges.size(); 15714 if (NA > 0) { 15715 item = mAvailProcessChanges.remove(NA-1); 15716 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15717 } else { 15718 item = new ProcessChangeItem(); 15719 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15720 } 15721 item.changes = 0; 15722 item.pid = app.pid; 15723 item.uid = app.info.uid; 15724 if (mPendingProcessChanges.size() == 0) { 15725 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15726 "*** Enqueueing dispatch processes changed!"); 15727 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15728 } 15729 mPendingProcessChanges.add(item); 15730 } 15731 item.changes |= changes; 15732 item.processState = app.repProcState; 15733 item.foregroundActivities = app.repForegroundActivities; 15734 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15735 + Integer.toHexString(System.identityHashCode(item)) 15736 + " " + app.toShortString() + ": changes=" + item.changes 15737 + " procState=" + item.processState 15738 + " foreground=" + item.foregroundActivities 15739 + " type=" + app.adjType + " source=" + app.adjSource 15740 + " target=" + app.adjTarget); 15741 } 15742 15743 return success; 15744 } 15745 15746 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15747 if (proc.thread != null && proc.baseProcessTracker != null) { 15748 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15749 } 15750 } 15751 15752 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15753 ProcessRecord TOP_APP, boolean doingAll, long now) { 15754 if (app.thread == null) { 15755 return false; 15756 } 15757 15758 final boolean wasKeeping = app.keeping; 15759 15760 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15761 15762 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15763 } 15764 15765 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15766 boolean oomAdj) { 15767 if (isForeground != proc.foregroundServices) { 15768 proc.foregroundServices = isForeground; 15769 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15770 proc.info.uid); 15771 if (isForeground) { 15772 if (curProcs == null) { 15773 curProcs = new ArrayList<ProcessRecord>(); 15774 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15775 } 15776 if (!curProcs.contains(proc)) { 15777 curProcs.add(proc); 15778 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15779 proc.info.packageName, proc.info.uid); 15780 } 15781 } else { 15782 if (curProcs != null) { 15783 if (curProcs.remove(proc)) { 15784 mBatteryStatsService.noteEvent( 15785 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15786 proc.info.packageName, proc.info.uid); 15787 if (curProcs.size() <= 0) { 15788 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15789 } 15790 } 15791 } 15792 } 15793 if (oomAdj) { 15794 updateOomAdjLocked(); 15795 } 15796 } 15797 } 15798 15799 private final ActivityRecord resumedAppLocked() { 15800 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15801 String pkg; 15802 int uid; 15803 if (act != null && !act.sleeping) { 15804 pkg = act.packageName; 15805 uid = act.info.applicationInfo.uid; 15806 } else { 15807 pkg = null; 15808 uid = -1; 15809 } 15810 // Has the UID or resumed package name changed? 15811 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15812 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15813 if (mCurResumedPackage != null) { 15814 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15815 mCurResumedPackage, mCurResumedUid); 15816 } 15817 mCurResumedPackage = pkg; 15818 mCurResumedUid = uid; 15819 if (mCurResumedPackage != null) { 15820 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15821 mCurResumedPackage, mCurResumedUid); 15822 } 15823 } 15824 return act; 15825 } 15826 15827 final boolean updateOomAdjLocked(ProcessRecord app) { 15828 final ActivityRecord TOP_ACT = resumedAppLocked(); 15829 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15830 final boolean wasCached = app.cached; 15831 15832 mAdjSeq++; 15833 15834 // This is the desired cached adjusment we want to tell it to use. 15835 // If our app is currently cached, we know it, and that is it. Otherwise, 15836 // we don't know it yet, and it needs to now be cached we will then 15837 // need to do a complete oom adj. 15838 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15839 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15840 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15841 SystemClock.uptimeMillis()); 15842 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15843 // Changed to/from cached state, so apps after it in the LRU 15844 // list may also be changed. 15845 updateOomAdjLocked(); 15846 } 15847 return success; 15848 } 15849 15850 final void updateOomAdjLocked() { 15851 final ActivityRecord TOP_ACT = resumedAppLocked(); 15852 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15853 final long now = SystemClock.uptimeMillis(); 15854 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15855 final int N = mLruProcesses.size(); 15856 15857 if (false) { 15858 RuntimeException e = new RuntimeException(); 15859 e.fillInStackTrace(); 15860 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15861 } 15862 15863 mAdjSeq++; 15864 mNewNumServiceProcs = 0; 15865 mNewNumAServiceProcs = 0; 15866 15867 final int emptyProcessLimit; 15868 final int cachedProcessLimit; 15869 if (mProcessLimit <= 0) { 15870 emptyProcessLimit = cachedProcessLimit = 0; 15871 } else if (mProcessLimit == 1) { 15872 emptyProcessLimit = 1; 15873 cachedProcessLimit = 0; 15874 } else { 15875 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15876 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15877 } 15878 15879 // Let's determine how many processes we have running vs. 15880 // how many slots we have for background processes; we may want 15881 // to put multiple processes in a slot of there are enough of 15882 // them. 15883 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15884 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15885 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15886 if (numEmptyProcs > cachedProcessLimit) { 15887 // If there are more empty processes than our limit on cached 15888 // processes, then use the cached process limit for the factor. 15889 // This ensures that the really old empty processes get pushed 15890 // down to the bottom, so if we are running low on memory we will 15891 // have a better chance at keeping around more cached processes 15892 // instead of a gazillion empty processes. 15893 numEmptyProcs = cachedProcessLimit; 15894 } 15895 int emptyFactor = numEmptyProcs/numSlots; 15896 if (emptyFactor < 1) emptyFactor = 1; 15897 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15898 if (cachedFactor < 1) cachedFactor = 1; 15899 int stepCached = 0; 15900 int stepEmpty = 0; 15901 int numCached = 0; 15902 int numEmpty = 0; 15903 int numTrimming = 0; 15904 15905 mNumNonCachedProcs = 0; 15906 mNumCachedHiddenProcs = 0; 15907 15908 // First update the OOM adjustment for each of the 15909 // application processes based on their current state. 15910 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15911 int nextCachedAdj = curCachedAdj+1; 15912 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15913 int nextEmptyAdj = curEmptyAdj+2; 15914 for (int i=N-1; i>=0; i--) { 15915 ProcessRecord app = mLruProcesses.get(i); 15916 if (!app.killedByAm && app.thread != null) { 15917 app.procStateChanged = false; 15918 final boolean wasKeeping = app.keeping; 15919 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15920 15921 // If we haven't yet assigned the final cached adj 15922 // to the process, do that now. 15923 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15924 switch (app.curProcState) { 15925 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15926 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15927 // This process is a cached process holding activities... 15928 // assign it the next cached value for that type, and then 15929 // step that cached level. 15930 app.curRawAdj = curCachedAdj; 15931 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15932 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15933 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15934 + ")"); 15935 if (curCachedAdj != nextCachedAdj) { 15936 stepCached++; 15937 if (stepCached >= cachedFactor) { 15938 stepCached = 0; 15939 curCachedAdj = nextCachedAdj; 15940 nextCachedAdj += 2; 15941 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15942 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15943 } 15944 } 15945 } 15946 break; 15947 default: 15948 // For everything else, assign next empty cached process 15949 // level and bump that up. Note that this means that 15950 // long-running services that have dropped down to the 15951 // cached level will be treated as empty (since their process 15952 // state is still as a service), which is what we want. 15953 app.curRawAdj = curEmptyAdj; 15954 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15955 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15956 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15957 + ")"); 15958 if (curEmptyAdj != nextEmptyAdj) { 15959 stepEmpty++; 15960 if (stepEmpty >= emptyFactor) { 15961 stepEmpty = 0; 15962 curEmptyAdj = nextEmptyAdj; 15963 nextEmptyAdj += 2; 15964 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15965 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15966 } 15967 } 15968 } 15969 break; 15970 } 15971 } 15972 15973 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15974 15975 // Count the number of process types. 15976 switch (app.curProcState) { 15977 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15978 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15979 mNumCachedHiddenProcs++; 15980 numCached++; 15981 if (numCached > cachedProcessLimit) { 15982 killUnneededProcessLocked(app, "cached #" + numCached); 15983 } 15984 break; 15985 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15986 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15987 && app.lastActivityTime < oldTime) { 15988 killUnneededProcessLocked(app, "empty for " 15989 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15990 / 1000) + "s"); 15991 } else { 15992 numEmpty++; 15993 if (numEmpty > emptyProcessLimit) { 15994 killUnneededProcessLocked(app, "empty #" + numEmpty); 15995 } 15996 } 15997 break; 15998 default: 15999 mNumNonCachedProcs++; 16000 break; 16001 } 16002 16003 if (app.isolated && app.services.size() <= 0) { 16004 // If this is an isolated process, and there are no 16005 // services running in it, then the process is no longer 16006 // needed. We agressively kill these because we can by 16007 // definition not re-use the same process again, and it is 16008 // good to avoid having whatever code was running in them 16009 // left sitting around after no longer needed. 16010 killUnneededProcessLocked(app, "isolated not needed"); 16011 } 16012 16013 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16014 && !app.killedByAm) { 16015 numTrimming++; 16016 } 16017 } 16018 } 16019 16020 mNumServiceProcs = mNewNumServiceProcs; 16021 16022 // Now determine the memory trimming level of background processes. 16023 // Unfortunately we need to start at the back of the list to do this 16024 // properly. We only do this if the number of background apps we 16025 // are managing to keep around is less than half the maximum we desire; 16026 // if we are keeping a good number around, we'll let them use whatever 16027 // memory they want. 16028 final int numCachedAndEmpty = numCached + numEmpty; 16029 int memFactor; 16030 if (numCached <= ProcessList.TRIM_CACHED_APPS 16031 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 16032 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 16033 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 16034 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 16035 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 16036 } else { 16037 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 16038 } 16039 } else { 16040 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 16041 } 16042 // We always allow the memory level to go up (better). We only allow it to go 16043 // down if we are in a state where that is allowed, *and* the total number of processes 16044 // has gone down since last time. 16045 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 16046 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 16047 + " last=" + mLastNumProcesses); 16048 if (memFactor > mLastMemoryLevel) { 16049 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 16050 memFactor = mLastMemoryLevel; 16051 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 16052 } 16053 } 16054 mLastMemoryLevel = memFactor; 16055 mLastNumProcesses = mLruProcesses.size(); 16056 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 16057 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 16058 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 16059 if (mLowRamStartTime == 0) { 16060 mLowRamStartTime = now; 16061 } 16062 int step = 0; 16063 int fgTrimLevel; 16064 switch (memFactor) { 16065 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 16066 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 16067 break; 16068 case ProcessStats.ADJ_MEM_FACTOR_LOW: 16069 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 16070 break; 16071 default: 16072 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 16073 break; 16074 } 16075 int factor = numTrimming/3; 16076 int minFactor = 2; 16077 if (mHomeProcess != null) minFactor++; 16078 if (mPreviousProcess != null) minFactor++; 16079 if (factor < minFactor) factor = minFactor; 16080 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 16081 for (int i=N-1; i>=0; i--) { 16082 ProcessRecord app = mLruProcesses.get(i); 16083 if (allChanged || app.procStateChanged) { 16084 setProcessTrackerState(app, trackerMemFactor, now); 16085 app.procStateChanged = false; 16086 } 16087 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 16088 && !app.killedByAm) { 16089 if (app.trimMemoryLevel < curLevel && app.thread != null) { 16090 try { 16091 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16092 "Trimming memory of " + app.processName 16093 + " to " + curLevel); 16094 app.thread.scheduleTrimMemory(curLevel); 16095 } catch (RemoteException e) { 16096 } 16097 if (false) { 16098 // For now we won't do this; our memory trimming seems 16099 // to be good enough at this point that destroying 16100 // activities causes more harm than good. 16101 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16102 && app != mHomeProcess && app != mPreviousProcess) { 16103 // Need to do this on its own message because the stack may not 16104 // be in a consistent state at this point. 16105 // For these apps we will also finish their activities 16106 // to help them free memory. 16107 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16108 } 16109 } 16110 } 16111 app.trimMemoryLevel = curLevel; 16112 step++; 16113 if (step >= factor) { 16114 step = 0; 16115 switch (curLevel) { 16116 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16117 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16118 break; 16119 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16120 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16121 break; 16122 } 16123 } 16124 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16125 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16126 && app.thread != null) { 16127 try { 16128 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16129 "Trimming memory of heavy-weight " + app.processName 16130 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16131 app.thread.scheduleTrimMemory( 16132 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16133 } catch (RemoteException e) { 16134 } 16135 } 16136 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16137 } else { 16138 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16139 || app.systemNoUi) && app.pendingUiClean) { 16140 // If this application is now in the background and it 16141 // had done UI, then give it the special trim level to 16142 // have it free UI resources. 16143 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16144 if (app.trimMemoryLevel < level && app.thread != null) { 16145 try { 16146 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16147 "Trimming memory of bg-ui " + app.processName 16148 + " to " + level); 16149 app.thread.scheduleTrimMemory(level); 16150 } catch (RemoteException e) { 16151 } 16152 } 16153 app.pendingUiClean = false; 16154 } 16155 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16156 try { 16157 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16158 "Trimming memory of fg " + app.processName 16159 + " to " + fgTrimLevel); 16160 app.thread.scheduleTrimMemory(fgTrimLevel); 16161 } catch (RemoteException e) { 16162 } 16163 } 16164 app.trimMemoryLevel = fgTrimLevel; 16165 } 16166 } 16167 } else { 16168 if (mLowRamStartTime != 0) { 16169 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16170 mLowRamStartTime = 0; 16171 } 16172 for (int i=N-1; i>=0; i--) { 16173 ProcessRecord app = mLruProcesses.get(i); 16174 if (allChanged || app.procStateChanged) { 16175 setProcessTrackerState(app, trackerMemFactor, now); 16176 app.procStateChanged = false; 16177 } 16178 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16179 || app.systemNoUi) && app.pendingUiClean) { 16180 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16181 && app.thread != null) { 16182 try { 16183 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16184 "Trimming memory of ui hidden " + app.processName 16185 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16186 app.thread.scheduleTrimMemory( 16187 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16188 } catch (RemoteException e) { 16189 } 16190 } 16191 app.pendingUiClean = false; 16192 } 16193 app.trimMemoryLevel = 0; 16194 } 16195 } 16196 16197 if (mAlwaysFinishActivities) { 16198 // Need to do this on its own message because the stack may not 16199 // be in a consistent state at this point. 16200 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16201 } 16202 16203 if (allChanged) { 16204 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16205 } 16206 16207 if (mProcessStats.shouldWriteNowLocked(now)) { 16208 mHandler.post(new Runnable() { 16209 @Override public void run() { 16210 synchronized (ActivityManagerService.this) { 16211 mProcessStats.writeStateAsyncLocked(); 16212 } 16213 } 16214 }); 16215 } 16216 16217 if (DEBUG_OOM_ADJ) { 16218 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16219 } 16220 } 16221 16222 final void trimApplications() { 16223 synchronized (this) { 16224 int i; 16225 16226 // First remove any unused application processes whose package 16227 // has been removed. 16228 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16229 final ProcessRecord app = mRemovedProcesses.get(i); 16230 if (app.activities.size() == 0 16231 && app.curReceiver == null && app.services.size() == 0) { 16232 Slog.i( 16233 TAG, "Exiting empty application process " 16234 + app.processName + " (" 16235 + (app.thread != null ? app.thread.asBinder() : null) 16236 + ")\n"); 16237 if (app.pid > 0 && app.pid != MY_PID) { 16238 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16239 app.processName, app.setAdj, "empty"); 16240 app.killedByAm = true; 16241 Process.killProcessQuiet(app.pid); 16242 } else { 16243 try { 16244 app.thread.scheduleExit(); 16245 } catch (Exception e) { 16246 // Ignore exceptions. 16247 } 16248 } 16249 cleanUpApplicationRecordLocked(app, false, true, -1); 16250 mRemovedProcesses.remove(i); 16251 16252 if (app.persistent) { 16253 if (app.persistent) { 16254 addAppLocked(app.info, false); 16255 } 16256 } 16257 } 16258 } 16259 16260 // Now update the oom adj for all processes. 16261 updateOomAdjLocked(); 16262 } 16263 } 16264 16265 /** This method sends the specified signal to each of the persistent apps */ 16266 public void signalPersistentProcesses(int sig) throws RemoteException { 16267 if (sig != Process.SIGNAL_USR1) { 16268 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16269 } 16270 16271 synchronized (this) { 16272 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16273 != PackageManager.PERMISSION_GRANTED) { 16274 throw new SecurityException("Requires permission " 16275 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16276 } 16277 16278 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16279 ProcessRecord r = mLruProcesses.get(i); 16280 if (r.thread != null && r.persistent) { 16281 Process.sendSignal(r.pid, sig); 16282 } 16283 } 16284 } 16285 } 16286 16287 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16288 if (proc == null || proc == mProfileProc) { 16289 proc = mProfileProc; 16290 path = mProfileFile; 16291 profileType = mProfileType; 16292 clearProfilerLocked(); 16293 } 16294 if (proc == null) { 16295 return; 16296 } 16297 try { 16298 proc.thread.profilerControl(false, path, null, profileType); 16299 } catch (RemoteException e) { 16300 throw new IllegalStateException("Process disappeared"); 16301 } 16302 } 16303 16304 private void clearProfilerLocked() { 16305 if (mProfileFd != null) { 16306 try { 16307 mProfileFd.close(); 16308 } catch (IOException e) { 16309 } 16310 } 16311 mProfileApp = null; 16312 mProfileProc = null; 16313 mProfileFile = null; 16314 mProfileType = 0; 16315 mAutoStopProfiler = false; 16316 } 16317 16318 public boolean profileControl(String process, int userId, boolean start, 16319 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16320 16321 try { 16322 synchronized (this) { 16323 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16324 // its own permission. 16325 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16326 != PackageManager.PERMISSION_GRANTED) { 16327 throw new SecurityException("Requires permission " 16328 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16329 } 16330 16331 if (start && fd == null) { 16332 throw new IllegalArgumentException("null fd"); 16333 } 16334 16335 ProcessRecord proc = null; 16336 if (process != null) { 16337 proc = findProcessLocked(process, userId, "profileControl"); 16338 } 16339 16340 if (start && (proc == null || proc.thread == null)) { 16341 throw new IllegalArgumentException("Unknown process: " + process); 16342 } 16343 16344 if (start) { 16345 stopProfilerLocked(null, null, 0); 16346 setProfileApp(proc.info, proc.processName, path, fd, false); 16347 mProfileProc = proc; 16348 mProfileType = profileType; 16349 try { 16350 fd = fd.dup(); 16351 } catch (IOException e) { 16352 fd = null; 16353 } 16354 proc.thread.profilerControl(start, path, fd, profileType); 16355 fd = null; 16356 mProfileFd = null; 16357 } else { 16358 stopProfilerLocked(proc, path, profileType); 16359 if (fd != null) { 16360 try { 16361 fd.close(); 16362 } catch (IOException e) { 16363 } 16364 } 16365 } 16366 16367 return true; 16368 } 16369 } catch (RemoteException e) { 16370 throw new IllegalStateException("Process disappeared"); 16371 } finally { 16372 if (fd != null) { 16373 try { 16374 fd.close(); 16375 } catch (IOException e) { 16376 } 16377 } 16378 } 16379 } 16380 16381 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16382 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16383 userId, true, true, callName, null); 16384 ProcessRecord proc = null; 16385 try { 16386 int pid = Integer.parseInt(process); 16387 synchronized (mPidsSelfLocked) { 16388 proc = mPidsSelfLocked.get(pid); 16389 } 16390 } catch (NumberFormatException e) { 16391 } 16392 16393 if (proc == null) { 16394 ArrayMap<String, SparseArray<ProcessRecord>> all 16395 = mProcessNames.getMap(); 16396 SparseArray<ProcessRecord> procs = all.get(process); 16397 if (procs != null && procs.size() > 0) { 16398 proc = procs.valueAt(0); 16399 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16400 for (int i=1; i<procs.size(); i++) { 16401 ProcessRecord thisProc = procs.valueAt(i); 16402 if (thisProc.userId == userId) { 16403 proc = thisProc; 16404 break; 16405 } 16406 } 16407 } 16408 } 16409 } 16410 16411 return proc; 16412 } 16413 16414 public boolean dumpHeap(String process, int userId, boolean managed, 16415 String path, ParcelFileDescriptor fd) throws RemoteException { 16416 16417 try { 16418 synchronized (this) { 16419 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16420 // its own permission (same as profileControl). 16421 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16422 != PackageManager.PERMISSION_GRANTED) { 16423 throw new SecurityException("Requires permission " 16424 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16425 } 16426 16427 if (fd == null) { 16428 throw new IllegalArgumentException("null fd"); 16429 } 16430 16431 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16432 if (proc == null || proc.thread == null) { 16433 throw new IllegalArgumentException("Unknown process: " + process); 16434 } 16435 16436 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16437 if (!isDebuggable) { 16438 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16439 throw new SecurityException("Process not debuggable: " + proc); 16440 } 16441 } 16442 16443 proc.thread.dumpHeap(managed, path, fd); 16444 fd = null; 16445 return true; 16446 } 16447 } catch (RemoteException e) { 16448 throw new IllegalStateException("Process disappeared"); 16449 } finally { 16450 if (fd != null) { 16451 try { 16452 fd.close(); 16453 } catch (IOException e) { 16454 } 16455 } 16456 } 16457 } 16458 16459 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16460 public void monitor() { 16461 synchronized (this) { } 16462 } 16463 16464 void onCoreSettingsChange(Bundle settings) { 16465 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16466 ProcessRecord processRecord = mLruProcesses.get(i); 16467 try { 16468 if (processRecord.thread != null) { 16469 processRecord.thread.setCoreSettings(settings); 16470 } 16471 } catch (RemoteException re) { 16472 /* ignore */ 16473 } 16474 } 16475 } 16476 16477 // Multi-user methods 16478 16479 /** 16480 * Start user, if its not already running, but don't bring it to foreground. 16481 */ 16482 @Override 16483 public boolean startUserInBackground(final int userId) { 16484 return startUser(userId, /* foreground */ false); 16485 } 16486 16487 /** 16488 * Refreshes the list of users related to the current user when either a 16489 * user switch happens or when a new related user is started in the 16490 * background. 16491 */ 16492 private void updateCurrentProfileIdsLocked() { 16493 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16494 mCurrentUserId, false /* enabledOnly */); 16495 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16496 for (int i = 0; i < currentProfileIds.length; i++) { 16497 currentProfileIds[i] = profiles.get(i).id; 16498 } 16499 mCurrentProfileIds = currentProfileIds; 16500 } 16501 16502 private Set getProfileIdsLocked(int userId) { 16503 Set userIds = new HashSet<Integer>(); 16504 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16505 userId, false /* enabledOnly */); 16506 for (UserInfo user : profiles) { 16507 userIds.add(Integer.valueOf(user.id)); 16508 } 16509 return userIds; 16510 } 16511 16512 @Override 16513 public boolean switchUser(final int userId) { 16514 return startUser(userId, /* foregound */ true); 16515 } 16516 16517 private boolean startUser(final int userId, boolean foreground) { 16518 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16519 != PackageManager.PERMISSION_GRANTED) { 16520 String msg = "Permission Denial: switchUser() from pid=" 16521 + Binder.getCallingPid() 16522 + ", uid=" + Binder.getCallingUid() 16523 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16524 Slog.w(TAG, msg); 16525 throw new SecurityException(msg); 16526 } 16527 16528 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16529 16530 final long ident = Binder.clearCallingIdentity(); 16531 try { 16532 synchronized (this) { 16533 final int oldUserId = mCurrentUserId; 16534 if (oldUserId == userId) { 16535 return true; 16536 } 16537 16538 mStackSupervisor.setLockTaskModeLocked(null); 16539 16540 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16541 if (userInfo == null) { 16542 Slog.w(TAG, "No user info for user #" + userId); 16543 return false; 16544 } 16545 16546 if (foreground) { 16547 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16548 R.anim.screen_user_enter); 16549 } 16550 16551 boolean needStart = false; 16552 16553 // If the user we are switching to is not currently started, then 16554 // we need to start it now. 16555 if (mStartedUsers.get(userId) == null) { 16556 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16557 updateStartedUserArrayLocked(); 16558 needStart = true; 16559 } 16560 16561 final Integer userIdInt = Integer.valueOf(userId); 16562 mUserLru.remove(userIdInt); 16563 mUserLru.add(userIdInt); 16564 16565 if (foreground) { 16566 mCurrentUserId = userId; 16567 updateCurrentProfileIdsLocked(); 16568 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16569 // Once the internal notion of the active user has switched, we lock the device 16570 // with the option to show the user switcher on the keyguard. 16571 mWindowManager.lockNow(null); 16572 } else { 16573 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16574 updateCurrentProfileIdsLocked(); 16575 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16576 mUserLru.remove(currentUserIdInt); 16577 mUserLru.add(currentUserIdInt); 16578 } 16579 16580 final UserStartedState uss = mStartedUsers.get(userId); 16581 16582 // Make sure user is in the started state. If it is currently 16583 // stopping, we need to knock that off. 16584 if (uss.mState == UserStartedState.STATE_STOPPING) { 16585 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16586 // so we can just fairly silently bring the user back from 16587 // the almost-dead. 16588 uss.mState = UserStartedState.STATE_RUNNING; 16589 updateStartedUserArrayLocked(); 16590 needStart = true; 16591 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16592 // This means ACTION_SHUTDOWN has been sent, so we will 16593 // need to treat this as a new boot of the user. 16594 uss.mState = UserStartedState.STATE_BOOTING; 16595 updateStartedUserArrayLocked(); 16596 needStart = true; 16597 } 16598 16599 if (uss.mState == UserStartedState.STATE_BOOTING) { 16600 // Booting up a new user, need to tell system services about it. 16601 // Note that this is on the same handler as scheduling of broadcasts, 16602 // which is important because it needs to go first. 16603 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16604 } 16605 16606 if (foreground) { 16607 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16608 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16609 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16610 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16611 oldUserId, userId, uss)); 16612 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16613 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16614 } 16615 16616 if (needStart) { 16617 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16618 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16619 | Intent.FLAG_RECEIVER_FOREGROUND); 16620 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16621 broadcastIntentLocked(null, null, intent, 16622 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16623 false, false, MY_PID, Process.SYSTEM_UID, userId); 16624 } 16625 16626 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16627 if (userId != 0) { 16628 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16629 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16630 broadcastIntentLocked(null, null, intent, null, 16631 new IIntentReceiver.Stub() { 16632 public void performReceive(Intent intent, int resultCode, 16633 String data, Bundle extras, boolean ordered, 16634 boolean sticky, int sendingUser) { 16635 userInitialized(uss, userId); 16636 } 16637 }, 0, null, null, null, AppOpsManager.OP_NONE, 16638 true, false, MY_PID, Process.SYSTEM_UID, 16639 userId); 16640 uss.initializing = true; 16641 } else { 16642 getUserManagerLocked().makeInitialized(userInfo.id); 16643 } 16644 } 16645 16646 if (foreground) { 16647 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16648 if (homeInFront) { 16649 startHomeActivityLocked(userId); 16650 } else { 16651 mStackSupervisor.resumeTopActivitiesLocked(); 16652 } 16653 EventLogTags.writeAmSwitchUser(userId); 16654 getUserManagerLocked().userForeground(userId); 16655 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16656 } 16657 16658 if (needStart) { 16659 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16660 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16661 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16662 broadcastIntentLocked(null, null, intent, 16663 null, new IIntentReceiver.Stub() { 16664 @Override 16665 public void performReceive(Intent intent, int resultCode, String data, 16666 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16667 throws RemoteException { 16668 } 16669 }, 0, null, null, 16670 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16671 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16672 } 16673 } 16674 } finally { 16675 Binder.restoreCallingIdentity(ident); 16676 } 16677 16678 return true; 16679 } 16680 16681 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16682 long ident = Binder.clearCallingIdentity(); 16683 try { 16684 Intent intent; 16685 if (oldUserId >= 0) { 16686 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16687 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16688 | Intent.FLAG_RECEIVER_FOREGROUND); 16689 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16690 broadcastIntentLocked(null, null, intent, 16691 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16692 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16693 } 16694 if (newUserId >= 0) { 16695 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16696 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16697 | Intent.FLAG_RECEIVER_FOREGROUND); 16698 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16699 broadcastIntentLocked(null, null, intent, 16700 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16701 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16702 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16703 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16704 | Intent.FLAG_RECEIVER_FOREGROUND); 16705 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16706 broadcastIntentLocked(null, null, intent, 16707 null, null, 0, null, null, 16708 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16709 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16710 } 16711 } finally { 16712 Binder.restoreCallingIdentity(ident); 16713 } 16714 } 16715 16716 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16717 final int newUserId) { 16718 final int N = mUserSwitchObservers.beginBroadcast(); 16719 if (N > 0) { 16720 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16721 int mCount = 0; 16722 @Override 16723 public void sendResult(Bundle data) throws RemoteException { 16724 synchronized (ActivityManagerService.this) { 16725 if (mCurUserSwitchCallback == this) { 16726 mCount++; 16727 if (mCount == N) { 16728 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16729 } 16730 } 16731 } 16732 } 16733 }; 16734 synchronized (this) { 16735 uss.switching = true; 16736 mCurUserSwitchCallback = callback; 16737 } 16738 for (int i=0; i<N; i++) { 16739 try { 16740 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16741 newUserId, callback); 16742 } catch (RemoteException e) { 16743 } 16744 } 16745 } else { 16746 synchronized (this) { 16747 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16748 } 16749 } 16750 mUserSwitchObservers.finishBroadcast(); 16751 } 16752 16753 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16754 synchronized (this) { 16755 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16756 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16757 } 16758 } 16759 16760 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16761 mCurUserSwitchCallback = null; 16762 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16763 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16764 oldUserId, newUserId, uss)); 16765 } 16766 16767 void userInitialized(UserStartedState uss, int newUserId) { 16768 completeSwitchAndInitalize(uss, newUserId, true, false); 16769 } 16770 16771 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16772 completeSwitchAndInitalize(uss, newUserId, false, true); 16773 } 16774 16775 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16776 boolean clearInitializing, boolean clearSwitching) { 16777 boolean unfrozen = false; 16778 synchronized (this) { 16779 if (clearInitializing) { 16780 uss.initializing = false; 16781 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16782 } 16783 if (clearSwitching) { 16784 uss.switching = false; 16785 } 16786 if (!uss.switching && !uss.initializing) { 16787 mWindowManager.stopFreezingScreen(); 16788 unfrozen = true; 16789 } 16790 } 16791 if (unfrozen) { 16792 final int N = mUserSwitchObservers.beginBroadcast(); 16793 for (int i=0; i<N; i++) { 16794 try { 16795 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16796 } catch (RemoteException e) { 16797 } 16798 } 16799 mUserSwitchObservers.finishBroadcast(); 16800 } 16801 } 16802 16803 void scheduleStartProfilesLocked() { 16804 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16805 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16806 DateUtils.SECOND_IN_MILLIS); 16807 } 16808 } 16809 16810 void startProfilesLocked() { 16811 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16812 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16813 mCurrentUserId, false /* enabledOnly */); 16814 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16815 for (UserInfo user : profiles) { 16816 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16817 && user.id != mCurrentUserId) { 16818 toStart.add(user); 16819 } 16820 } 16821 final int n = toStart.size(); 16822 int i = 0; 16823 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16824 startUserInBackground(toStart.get(i).id); 16825 } 16826 if (i < n) { 16827 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16828 } 16829 } 16830 16831 void finishUserSwitch(UserStartedState uss) { 16832 synchronized (this) { 16833 if (uss.mState == UserStartedState.STATE_BOOTING 16834 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16835 uss.mState = UserStartedState.STATE_RUNNING; 16836 final int userId = uss.mHandle.getIdentifier(); 16837 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16838 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16839 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16840 broadcastIntentLocked(null, null, intent, 16841 null, null, 0, null, null, 16842 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16843 true, false, MY_PID, Process.SYSTEM_UID, userId); 16844 } 16845 16846 startProfilesLocked(); 16847 16848 int num = mUserLru.size(); 16849 int i = 0; 16850 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16851 Integer oldUserId = mUserLru.get(i); 16852 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16853 if (oldUss == null) { 16854 // Shouldn't happen, but be sane if it does. 16855 mUserLru.remove(i); 16856 num--; 16857 continue; 16858 } 16859 if (oldUss.mState == UserStartedState.STATE_STOPPING 16860 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16861 // This user is already stopping, doesn't count. 16862 num--; 16863 i++; 16864 continue; 16865 } 16866 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16867 // Owner and current can't be stopped, but count as running. 16868 i++; 16869 continue; 16870 } 16871 // This is a user to be stopped. 16872 stopUserLocked(oldUserId, null); 16873 num--; 16874 i++; 16875 } 16876 } 16877 } 16878 16879 @Override 16880 public int stopUser(final int userId, final IStopUserCallback callback) { 16881 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16882 != PackageManager.PERMISSION_GRANTED) { 16883 String msg = "Permission Denial: switchUser() from pid=" 16884 + Binder.getCallingPid() 16885 + ", uid=" + Binder.getCallingUid() 16886 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16887 Slog.w(TAG, msg); 16888 throw new SecurityException(msg); 16889 } 16890 if (userId <= 0) { 16891 throw new IllegalArgumentException("Can't stop primary user " + userId); 16892 } 16893 synchronized (this) { 16894 return stopUserLocked(userId, callback); 16895 } 16896 } 16897 16898 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16899 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16900 if (mCurrentUserId == userId) { 16901 return ActivityManager.USER_OP_IS_CURRENT; 16902 } 16903 16904 final UserStartedState uss = mStartedUsers.get(userId); 16905 if (uss == null) { 16906 // User is not started, nothing to do... but we do need to 16907 // callback if requested. 16908 if (callback != null) { 16909 mHandler.post(new Runnable() { 16910 @Override 16911 public void run() { 16912 try { 16913 callback.userStopped(userId); 16914 } catch (RemoteException e) { 16915 } 16916 } 16917 }); 16918 } 16919 return ActivityManager.USER_OP_SUCCESS; 16920 } 16921 16922 if (callback != null) { 16923 uss.mStopCallbacks.add(callback); 16924 } 16925 16926 if (uss.mState != UserStartedState.STATE_STOPPING 16927 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16928 uss.mState = UserStartedState.STATE_STOPPING; 16929 updateStartedUserArrayLocked(); 16930 16931 long ident = Binder.clearCallingIdentity(); 16932 try { 16933 // We are going to broadcast ACTION_USER_STOPPING and then 16934 // once that is done send a final ACTION_SHUTDOWN and then 16935 // stop the user. 16936 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16937 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16938 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16939 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16940 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16941 // This is the result receiver for the final shutdown broadcast. 16942 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16943 @Override 16944 public void performReceive(Intent intent, int resultCode, String data, 16945 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16946 finishUserStop(uss); 16947 } 16948 }; 16949 // This is the result receiver for the initial stopping broadcast. 16950 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16951 @Override 16952 public void performReceive(Intent intent, int resultCode, String data, 16953 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16954 // On to the next. 16955 synchronized (ActivityManagerService.this) { 16956 if (uss.mState != UserStartedState.STATE_STOPPING) { 16957 // Whoops, we are being started back up. Abort, abort! 16958 return; 16959 } 16960 uss.mState = UserStartedState.STATE_SHUTDOWN; 16961 } 16962 mSystemServiceManager.stopUser(userId); 16963 broadcastIntentLocked(null, null, shutdownIntent, 16964 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16965 true, false, MY_PID, Process.SYSTEM_UID, userId); 16966 } 16967 }; 16968 // Kick things off. 16969 broadcastIntentLocked(null, null, stoppingIntent, 16970 null, stoppingReceiver, 0, null, null, 16971 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16972 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16973 } finally { 16974 Binder.restoreCallingIdentity(ident); 16975 } 16976 } 16977 16978 return ActivityManager.USER_OP_SUCCESS; 16979 } 16980 16981 void finishUserStop(UserStartedState uss) { 16982 final int userId = uss.mHandle.getIdentifier(); 16983 boolean stopped; 16984 ArrayList<IStopUserCallback> callbacks; 16985 synchronized (this) { 16986 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16987 if (mStartedUsers.get(userId) != uss) { 16988 stopped = false; 16989 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16990 stopped = false; 16991 } else { 16992 stopped = true; 16993 // User can no longer run. 16994 mStartedUsers.remove(userId); 16995 mUserLru.remove(Integer.valueOf(userId)); 16996 updateStartedUserArrayLocked(); 16997 16998 // Clean up all state and processes associated with the user. 16999 // Kill all the processes for the user. 17000 forceStopUserLocked(userId, "finish user"); 17001 } 17002 } 17003 17004 for (int i=0; i<callbacks.size(); i++) { 17005 try { 17006 if (stopped) callbacks.get(i).userStopped(userId); 17007 else callbacks.get(i).userStopAborted(userId); 17008 } catch (RemoteException e) { 17009 } 17010 } 17011 17012 if (stopped) { 17013 mSystemServiceManager.cleanupUser(userId); 17014 synchronized (this) { 17015 mStackSupervisor.removeUserLocked(userId); 17016 } 17017 } 17018 } 17019 17020 @Override 17021 public UserInfo getCurrentUser() { 17022 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17023 != PackageManager.PERMISSION_GRANTED) && ( 17024 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17025 != PackageManager.PERMISSION_GRANTED)) { 17026 String msg = "Permission Denial: getCurrentUser() from pid=" 17027 + Binder.getCallingPid() 17028 + ", uid=" + Binder.getCallingUid() 17029 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17030 Slog.w(TAG, msg); 17031 throw new SecurityException(msg); 17032 } 17033 synchronized (this) { 17034 return getUserManagerLocked().getUserInfo(mCurrentUserId); 17035 } 17036 } 17037 17038 int getCurrentUserIdLocked() { 17039 return mCurrentUserId; 17040 } 17041 17042 @Override 17043 public boolean isUserRunning(int userId, boolean orStopped) { 17044 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17045 != PackageManager.PERMISSION_GRANTED) { 17046 String msg = "Permission Denial: isUserRunning() from pid=" 17047 + Binder.getCallingPid() 17048 + ", uid=" + Binder.getCallingUid() 17049 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17050 Slog.w(TAG, msg); 17051 throw new SecurityException(msg); 17052 } 17053 synchronized (this) { 17054 return isUserRunningLocked(userId, orStopped); 17055 } 17056 } 17057 17058 boolean isUserRunningLocked(int userId, boolean orStopped) { 17059 UserStartedState state = mStartedUsers.get(userId); 17060 if (state == null) { 17061 return false; 17062 } 17063 if (orStopped) { 17064 return true; 17065 } 17066 return state.mState != UserStartedState.STATE_STOPPING 17067 && state.mState != UserStartedState.STATE_SHUTDOWN; 17068 } 17069 17070 @Override 17071 public int[] getRunningUserIds() { 17072 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 17073 != PackageManager.PERMISSION_GRANTED) { 17074 String msg = "Permission Denial: isUserRunning() from pid=" 17075 + Binder.getCallingPid() 17076 + ", uid=" + Binder.getCallingUid() 17077 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 17078 Slog.w(TAG, msg); 17079 throw new SecurityException(msg); 17080 } 17081 synchronized (this) { 17082 return mStartedUserArray; 17083 } 17084 } 17085 17086 private void updateStartedUserArrayLocked() { 17087 int num = 0; 17088 for (int i=0; i<mStartedUsers.size(); i++) { 17089 UserStartedState uss = mStartedUsers.valueAt(i); 17090 // This list does not include stopping users. 17091 if (uss.mState != UserStartedState.STATE_STOPPING 17092 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17093 num++; 17094 } 17095 } 17096 mStartedUserArray = new int[num]; 17097 num = 0; 17098 for (int i=0; i<mStartedUsers.size(); i++) { 17099 UserStartedState uss = mStartedUsers.valueAt(i); 17100 if (uss.mState != UserStartedState.STATE_STOPPING 17101 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17102 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17103 num++; 17104 } 17105 } 17106 } 17107 17108 @Override 17109 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17110 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17111 != PackageManager.PERMISSION_GRANTED) { 17112 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17113 + Binder.getCallingPid() 17114 + ", uid=" + Binder.getCallingUid() 17115 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17116 Slog.w(TAG, msg); 17117 throw new SecurityException(msg); 17118 } 17119 17120 mUserSwitchObservers.register(observer); 17121 } 17122 17123 @Override 17124 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17125 mUserSwitchObservers.unregister(observer); 17126 } 17127 17128 private boolean userExists(int userId) { 17129 if (userId == 0) { 17130 return true; 17131 } 17132 UserManagerService ums = getUserManagerLocked(); 17133 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17134 } 17135 17136 int[] getUsersLocked() { 17137 UserManagerService ums = getUserManagerLocked(); 17138 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17139 } 17140 17141 UserManagerService getUserManagerLocked() { 17142 if (mUserManager == null) { 17143 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17144 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17145 } 17146 return mUserManager; 17147 } 17148 17149 private int applyUserId(int uid, int userId) { 17150 return UserHandle.getUid(userId, uid); 17151 } 17152 17153 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17154 if (info == null) return null; 17155 ApplicationInfo newInfo = new ApplicationInfo(info); 17156 newInfo.uid = applyUserId(info.uid, userId); 17157 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17158 + info.packageName; 17159 return newInfo; 17160 } 17161 17162 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17163 if (aInfo == null 17164 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17165 return aInfo; 17166 } 17167 17168 ActivityInfo info = new ActivityInfo(aInfo); 17169 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17170 return info; 17171 } 17172 17173 private final class LocalService extends ActivityManagerInternal { 17174 @Override 17175 public void goingToSleep() { 17176 ActivityManagerService.this.goingToSleep(); 17177 } 17178 17179 @Override 17180 public void wakingUp() { 17181 ActivityManagerService.this.wakingUp(); 17182 } 17183 } 17184} 17185