ActivityManagerService.java revision 5df281a570555ee132a12a4aac9aec96e8618270
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.IUiAutomationConnection; 99import android.app.IUserSwitchObserver; 100import android.app.Instrumentation; 101import android.app.Notification; 102import android.app.NotificationManager; 103import android.app.PendingIntent; 104import android.app.backup.IBackupManager; 105import android.content.ActivityNotFoundException; 106import android.content.BroadcastReceiver; 107import android.content.ClipData; 108import android.content.ComponentCallbacks2; 109import android.content.ComponentName; 110import android.content.ContentProvider; 111import android.content.ContentResolver; 112import android.content.Context; 113import android.content.DialogInterface; 114import android.content.IContentProvider; 115import android.content.IIntentReceiver; 116import android.content.IIntentSender; 117import android.content.Intent; 118import android.content.IntentFilter; 119import android.content.IntentSender; 120import android.content.pm.ActivityInfo; 121import android.content.pm.ApplicationInfo; 122import android.content.pm.ConfigurationInfo; 123import android.content.pm.IPackageDataObserver; 124import android.content.pm.IPackageManager; 125import android.content.pm.InstrumentationInfo; 126import android.content.pm.PackageInfo; 127import android.content.pm.PackageManager; 128import android.content.pm.ParceledListSlice; 129import android.content.pm.UserInfo; 130import android.content.pm.PackageManager.NameNotFoundException; 131import android.content.pm.PathPermission; 132import android.content.pm.ProviderInfo; 133import android.content.pm.ResolveInfo; 134import android.content.pm.ServiceInfo; 135import android.content.res.CompatibilityInfo; 136import android.content.res.Configuration; 137import android.graphics.Bitmap; 138import android.net.Proxy; 139import android.net.ProxyInfo; 140import android.net.Uri; 141import android.os.Binder; 142import android.os.Build; 143import android.os.Bundle; 144import android.os.Debug; 145import android.os.DropBoxManager; 146import android.os.Environment; 147import android.os.FactoryTest; 148import android.os.FileObserver; 149import android.os.FileUtils; 150import android.os.Handler; 151import android.os.IBinder; 152import android.os.IPermissionController; 153import android.os.IRemoteCallback; 154import android.os.IUserManager; 155import android.os.Looper; 156import android.os.Message; 157import android.os.Parcel; 158import android.os.ParcelFileDescriptor; 159import android.os.Process; 160import android.os.RemoteCallbackList; 161import android.os.RemoteException; 162import android.os.SELinux; 163import android.os.ServiceManager; 164import android.os.StrictMode; 165import android.os.SystemClock; 166import android.os.SystemProperties; 167import android.os.UpdateLock; 168import android.os.UserHandle; 169import android.provider.Settings; 170import android.text.format.DateUtils; 171import android.text.format.Time; 172import android.util.AtomicFile; 173import android.util.EventLog; 174import android.util.Log; 175import android.util.Pair; 176import android.util.PrintWriterPrinter; 177import android.util.Slog; 178import android.util.SparseArray; 179import android.util.TimeUtils; 180import android.util.Xml; 181import android.view.Gravity; 182import android.view.LayoutInflater; 183import android.view.View; 184import android.view.WindowManager; 185 186import java.io.BufferedInputStream; 187import java.io.BufferedOutputStream; 188import java.io.DataInputStream; 189import java.io.DataOutputStream; 190import java.io.File; 191import java.io.FileDescriptor; 192import java.io.FileInputStream; 193import java.io.FileNotFoundException; 194import java.io.FileOutputStream; 195import java.io.IOException; 196import java.io.InputStreamReader; 197import java.io.PrintWriter; 198import java.io.StringWriter; 199import java.lang.ref.WeakReference; 200import java.util.ArrayList; 201import java.util.Arrays; 202import java.util.Collections; 203import java.util.Comparator; 204import java.util.HashMap; 205import java.util.HashSet; 206import java.util.Iterator; 207import java.util.List; 208import java.util.Locale; 209import java.util.Map; 210import java.util.Set; 211import java.util.concurrent.atomic.AtomicBoolean; 212import java.util.concurrent.atomic.AtomicLong; 213 214public final class ActivityManagerService extends ActivityManagerNative 215 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 216 private static final String USER_DATA_DIR = "/data/user/"; 217 static final String TAG = "ActivityManager"; 218 static final String TAG_MU = "ActivityManagerServiceMU"; 219 static final boolean DEBUG = false; 220 static final boolean localLOGV = DEBUG; 221 static final boolean DEBUG_BACKUP = localLOGV || false; 222 static final boolean DEBUG_BROADCAST = localLOGV || false; 223 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 224 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 225 static final boolean DEBUG_CLEANUP = localLOGV || false; 226 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 227 static final boolean DEBUG_FOCUS = false; 228 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 229 static final boolean DEBUG_MU = localLOGV || false; 230 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 231 static final boolean DEBUG_LRU = localLOGV || false; 232 static final boolean DEBUG_PAUSE = localLOGV || false; 233 static final boolean DEBUG_POWER = localLOGV || false; 234 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 235 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 236 static final boolean DEBUG_PROCESSES = localLOGV || false; 237 static final boolean DEBUG_PROVIDER = localLOGV || false; 238 static final boolean DEBUG_RESULTS = localLOGV || false; 239 static final boolean DEBUG_SERVICE = localLOGV || false; 240 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 241 static final boolean DEBUG_STACK = localLOGV || false; 242 static final boolean DEBUG_SWITCH = localLOGV || false; 243 static final boolean DEBUG_TASKS = localLOGV || false; 244 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 245 static final boolean DEBUG_TRANSITION = localLOGV || false; 246 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 247 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 248 static final boolean DEBUG_VISBILITY = localLOGV || false; 249 static final boolean DEBUG_PSS = localLOGV || false; 250 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 251 static final boolean VALIDATE_TOKENS = false; 252 static final boolean SHOW_ACTIVITY_START_TIME = true; 253 254 // Control over CPU and battery monitoring. 255 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 256 static final boolean MONITOR_CPU_USAGE = true; 257 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 258 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 259 static final boolean MONITOR_THREAD_CPU_USAGE = false; 260 261 // The flags that are set for all calls we make to the package manager. 262 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 263 264 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 265 266 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 267 268 // Maximum number of recent tasks that we can remember. 269 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 270 271 // Amount of time after a call to stopAppSwitches() during which we will 272 // prevent further untrusted switches from happening. 273 static final long APP_SWITCH_DELAY_TIME = 5*1000; 274 275 // How long we wait for a launched process to attach to the activity manager 276 // before we decide it's never going to come up for real. 277 static final int PROC_START_TIMEOUT = 10*1000; 278 279 // How long we wait for a launched process to attach to the activity manager 280 // before we decide it's never going to come up for real, when the process was 281 // started with a wrapper for instrumentation (such as Valgrind) because it 282 // could take much longer than usual. 283 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 284 285 // How long to wait after going idle before forcing apps to GC. 286 static final int GC_TIMEOUT = 5*1000; 287 288 // The minimum amount of time between successive GC requests for a process. 289 static final int GC_MIN_INTERVAL = 60*1000; 290 291 // The minimum amount of time between successive PSS requests for a process. 292 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 293 294 // The minimum amount of time between successive PSS requests for a process 295 // when the request is due to the memory state being lowered. 296 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 297 298 // The rate at which we check for apps using excessive power -- 15 mins. 299 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 300 301 // The minimum sample duration we will allow before deciding we have 302 // enough data on wake locks to start killing things. 303 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 304 305 // The minimum sample duration we will allow before deciding we have 306 // enough data on CPU usage to start killing things. 307 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 308 309 // How long we allow a receiver to run before giving up on it. 310 static final int BROADCAST_FG_TIMEOUT = 10*1000; 311 static final int BROADCAST_BG_TIMEOUT = 60*1000; 312 313 // How long we wait until we timeout on key dispatching. 314 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 315 316 // How long we wait until we timeout on key dispatching during instrumentation. 317 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 318 319 // Amount of time we wait for observers to handle a user switch before 320 // giving up on them and unfreezing the screen. 321 static final int USER_SWITCH_TIMEOUT = 2*1000; 322 323 // Maximum number of users we allow to be running at a time. 324 static final int MAX_RUNNING_USERS = 3; 325 326 // How long to wait in getAssistContextExtras for the activity and foreground services 327 // to respond with the result. 328 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 329 330 // Maximum number of persisted Uri grants a package is allowed 331 static final int MAX_PERSISTED_URI_GRANTS = 128; 332 333 static final int MY_PID = Process.myPid(); 334 335 static final String[] EMPTY_STRING_ARRAY = new String[0]; 336 337 // How many bytes to write into the dropbox log before truncating 338 static final int DROPBOX_MAX_SIZE = 256 * 1024; 339 340 /** All system services */ 341 SystemServiceManager mSystemServiceManager; 342 343 /** Run all ActivityStacks through this */ 344 ActivityStackSupervisor mStackSupervisor; 345 346 public IntentFirewall mIntentFirewall; 347 348 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 349 // default actuion automatically. Important for devices without direct input 350 // devices. 351 private boolean mShowDialogs = true; 352 353 /** 354 * Description of a request to start a new activity, which has been held 355 * due to app switches being disabled. 356 */ 357 static class PendingActivityLaunch { 358 final ActivityRecord r; 359 final ActivityRecord sourceRecord; 360 final int startFlags; 361 final ActivityStack stack; 362 363 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 364 int _startFlags, ActivityStack _stack) { 365 r = _r; 366 sourceRecord = _sourceRecord; 367 startFlags = _startFlags; 368 stack = _stack; 369 } 370 } 371 372 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 373 = new ArrayList<PendingActivityLaunch>(); 374 375 BroadcastQueue mFgBroadcastQueue; 376 BroadcastQueue mBgBroadcastQueue; 377 // Convenient for easy iteration over the queues. Foreground is first 378 // so that dispatch of foreground broadcasts gets precedence. 379 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 380 381 BroadcastQueue broadcastQueueForIntent(Intent intent) { 382 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 383 if (DEBUG_BACKGROUND_BROADCAST) { 384 Slog.i(TAG, "Broadcast intent " + intent + " on " 385 + (isFg ? "foreground" : "background") 386 + " queue"); 387 } 388 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 389 } 390 391 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 392 for (BroadcastQueue queue : mBroadcastQueues) { 393 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 394 if (r != null) { 395 return r; 396 } 397 } 398 return null; 399 } 400 401 /** 402 * Activity we have told the window manager to have key focus. 403 */ 404 ActivityRecord mFocusedActivity = null; 405 406 /** 407 * List of intents that were used to start the most recent tasks. 408 */ 409 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 410 411 public class PendingAssistExtras extends Binder implements Runnable { 412 public final ActivityRecord activity; 413 public boolean haveResult = false; 414 public Bundle result = null; 415 public PendingAssistExtras(ActivityRecord _activity) { 416 activity = _activity; 417 } 418 @Override 419 public void run() { 420 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 421 synchronized (this) { 422 haveResult = true; 423 notifyAll(); 424 } 425 } 426 } 427 428 final ArrayList<PendingAssistExtras> mPendingAssistExtras 429 = new ArrayList<PendingAssistExtras>(); 430 431 /** 432 * Process management. 433 */ 434 final ProcessList mProcessList = new ProcessList(); 435 436 /** 437 * All of the applications we currently have running organized by name. 438 * The keys are strings of the application package name (as 439 * returned by the package manager), and the keys are ApplicationRecord 440 * objects. 441 */ 442 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 443 444 /** 445 * Tracking long-term execution of processes to look for abuse and other 446 * bad app behavior. 447 */ 448 final ProcessStatsService mProcessStats; 449 450 /** 451 * The currently running isolated processes. 452 */ 453 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 454 455 /** 456 * Counter for assigning isolated process uids, to avoid frequently reusing the 457 * same ones. 458 */ 459 int mNextIsolatedProcessUid = 0; 460 461 /** 462 * The currently running heavy-weight process, if any. 463 */ 464 ProcessRecord mHeavyWeightProcess = null; 465 466 /** 467 * The last time that various processes have crashed. 468 */ 469 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 470 471 /** 472 * Information about a process that is currently marked as bad. 473 */ 474 static final class BadProcessInfo { 475 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 476 this.time = time; 477 this.shortMsg = shortMsg; 478 this.longMsg = longMsg; 479 this.stack = stack; 480 } 481 482 final long time; 483 final String shortMsg; 484 final String longMsg; 485 final String stack; 486 } 487 488 /** 489 * Set of applications that we consider to be bad, and will reject 490 * incoming broadcasts from (which the user has no control over). 491 * Processes are added to this set when they have crashed twice within 492 * a minimum amount of time; they are removed from it when they are 493 * later restarted (hopefully due to some user action). The value is the 494 * time it was added to the list. 495 */ 496 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 497 498 /** 499 * All of the processes we currently have running organized by pid. 500 * The keys are the pid running the application. 501 * 502 * <p>NOTE: This object is protected by its own lock, NOT the global 503 * activity manager lock! 504 */ 505 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 506 507 /** 508 * All of the processes that have been forced to be foreground. The key 509 * is the pid of the caller who requested it (we hold a death 510 * link on it). 511 */ 512 abstract class ForegroundToken implements IBinder.DeathRecipient { 513 int pid; 514 IBinder token; 515 } 516 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 517 518 /** 519 * List of records for processes that someone had tried to start before the 520 * system was ready. We don't start them at that point, but ensure they 521 * are started by the time booting is complete. 522 */ 523 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 524 525 /** 526 * List of persistent applications that are in the process 527 * of being started. 528 */ 529 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 530 531 /** 532 * Processes that are being forcibly torn down. 533 */ 534 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 535 536 /** 537 * List of running applications, sorted by recent usage. 538 * The first entry in the list is the least recently used. 539 */ 540 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 541 542 /** 543 * Where in mLruProcesses that the processes hosting activities start. 544 */ 545 int mLruProcessActivityStart = 0; 546 547 /** 548 * Where in mLruProcesses that the processes hosting services start. 549 * This is after (lower index) than mLruProcessesActivityStart. 550 */ 551 int mLruProcessServiceStart = 0; 552 553 /** 554 * List of processes that should gc as soon as things are idle. 555 */ 556 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 557 558 /** 559 * Processes we want to collect PSS data from. 560 */ 561 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 562 563 /** 564 * Last time we requested PSS data of all processes. 565 */ 566 long mLastFullPssTime = SystemClock.uptimeMillis(); 567 568 /** 569 * This is the process holding what we currently consider to be 570 * the "home" activity. 571 */ 572 ProcessRecord mHomeProcess; 573 574 /** 575 * This is the process holding the activity the user last visited that 576 * is in a different process from the one they are currently in. 577 */ 578 ProcessRecord mPreviousProcess; 579 580 /** 581 * The time at which the previous process was last visible. 582 */ 583 long mPreviousProcessVisibleTime; 584 585 /** 586 * Which uses have been started, so are allowed to run code. 587 */ 588 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 589 590 /** 591 * LRU list of history of current users. Most recently current is at the end. 592 */ 593 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 594 595 /** 596 * Constant array of the users that are currently started. 597 */ 598 int[] mStartedUserArray = new int[] { 0 }; 599 600 /** 601 * Registered observers of the user switching mechanics. 602 */ 603 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 604 = new RemoteCallbackList<IUserSwitchObserver>(); 605 606 /** 607 * Currently active user switch. 608 */ 609 Object mCurUserSwitchCallback; 610 611 /** 612 * Packages that the user has asked to have run in screen size 613 * compatibility mode instead of filling the screen. 614 */ 615 final CompatModePackages mCompatModePackages; 616 617 /** 618 * Set of IntentSenderRecord objects that are currently active. 619 */ 620 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 621 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 622 623 /** 624 * Fingerprints (hashCode()) of stack traces that we've 625 * already logged DropBox entries for. Guarded by itself. If 626 * something (rogue user app) forces this over 627 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 628 */ 629 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 630 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 631 632 /** 633 * Strict Mode background batched logging state. 634 * 635 * The string buffer is guarded by itself, and its lock is also 636 * used to determine if another batched write is already 637 * in-flight. 638 */ 639 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 640 641 /** 642 * Keeps track of all IIntentReceivers that have been registered for 643 * broadcasts. Hash keys are the receiver IBinder, hash value is 644 * a ReceiverList. 645 */ 646 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 647 new HashMap<IBinder, ReceiverList>(); 648 649 /** 650 * Resolver for broadcast intents to registered receivers. 651 * Holds BroadcastFilter (subclass of IntentFilter). 652 */ 653 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 654 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 655 @Override 656 protected boolean allowFilterResult( 657 BroadcastFilter filter, List<BroadcastFilter> dest) { 658 IBinder target = filter.receiverList.receiver.asBinder(); 659 for (int i=dest.size()-1; i>=0; i--) { 660 if (dest.get(i).receiverList.receiver.asBinder() == target) { 661 return false; 662 } 663 } 664 return true; 665 } 666 667 @Override 668 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 669 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 670 || userId == filter.owningUserId) { 671 return super.newResult(filter, match, userId); 672 } 673 return null; 674 } 675 676 @Override 677 protected BroadcastFilter[] newArray(int size) { 678 return new BroadcastFilter[size]; 679 } 680 681 @Override 682 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 683 return packageName.equals(filter.packageName); 684 } 685 }; 686 687 /** 688 * State of all active sticky broadcasts per user. Keys are the action of the 689 * sticky Intent, values are an ArrayList of all broadcasted intents with 690 * that action (which should usually be one). The SparseArray is keyed 691 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 692 * for stickies that are sent to all users. 693 */ 694 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 695 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 696 697 final ActiveServices mServices; 698 699 /** 700 * Backup/restore process management 701 */ 702 String mBackupAppName = null; 703 BackupRecord mBackupTarget = null; 704 705 final ProviderMap mProviderMap; 706 707 /** 708 * List of content providers who have clients waiting for them. The 709 * application is currently being launched and the provider will be 710 * removed from this list once it is published. 711 */ 712 final ArrayList<ContentProviderRecord> mLaunchingProviders 713 = new ArrayList<ContentProviderRecord>(); 714 715 /** 716 * File storing persisted {@link #mGrantedUriPermissions}. 717 */ 718 private final AtomicFile mGrantFile; 719 720 /** XML constants used in {@link #mGrantFile} */ 721 private static final String TAG_URI_GRANTS = "uri-grants"; 722 private static final String TAG_URI_GRANT = "uri-grant"; 723 private static final String ATTR_USER_HANDLE = "userHandle"; 724 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 725 private static final String ATTR_TARGET_PKG = "targetPkg"; 726 private static final String ATTR_URI = "uri"; 727 private static final String ATTR_MODE_FLAGS = "modeFlags"; 728 private static final String ATTR_CREATED_TIME = "createdTime"; 729 private static final String ATTR_PREFIX = "prefix"; 730 731 /** 732 * Global set of specific {@link Uri} permissions that have been granted. 733 * This optimized lookup structure maps from {@link UriPermission#targetUid} 734 * to {@link UriPermission#uri} to {@link UriPermission}. 735 */ 736 @GuardedBy("this") 737 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 738 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 739 740 public static class GrantUri { 741 public final Uri uri; 742 public final boolean prefix; 743 744 public GrantUri(Uri uri, boolean prefix) { 745 this.uri = uri; 746 this.prefix = prefix; 747 } 748 749 @Override 750 public int hashCode() { 751 return toString().hashCode(); 752 } 753 754 @Override 755 public boolean equals(Object o) { 756 if (o instanceof GrantUri) { 757 GrantUri other = (GrantUri) o; 758 return uri.equals(other.uri) && prefix == other.prefix; 759 } 760 return false; 761 } 762 763 @Override 764 public String toString() { 765 if (prefix) { 766 return uri.toString() + " [prefix]"; 767 } else { 768 return uri.toString(); 769 } 770 } 771 } 772 773 CoreSettingsObserver mCoreSettingsObserver; 774 775 /** 776 * Thread-local storage used to carry caller permissions over through 777 * indirect content-provider access. 778 */ 779 private class Identity { 780 public int pid; 781 public int uid; 782 783 Identity(int _pid, int _uid) { 784 pid = _pid; 785 uid = _uid; 786 } 787 } 788 789 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 790 791 /** 792 * All information we have collected about the runtime performance of 793 * any user id that can impact battery performance. 794 */ 795 final BatteryStatsService mBatteryStatsService; 796 797 /** 798 * Information about component usage 799 */ 800 final UsageStatsService mUsageStatsService; 801 802 /** 803 * Information about and control over application operations 804 */ 805 final AppOpsService mAppOpsService; 806 807 /** 808 * Current configuration information. HistoryRecord objects are given 809 * a reference to this object to indicate which configuration they are 810 * currently running in, so this object must be kept immutable. 811 */ 812 Configuration mConfiguration = new Configuration(); 813 814 /** 815 * Current sequencing integer of the configuration, for skipping old 816 * configurations. 817 */ 818 int mConfigurationSeq = 0; 819 820 /** 821 * Hardware-reported OpenGLES version. 822 */ 823 final int GL_ES_VERSION; 824 825 /** 826 * List of initialization arguments to pass to all processes when binding applications to them. 827 * For example, references to the commonly used services. 828 */ 829 HashMap<String, IBinder> mAppBindArgs; 830 831 /** 832 * Temporary to avoid allocations. Protected by main lock. 833 */ 834 final StringBuilder mStringBuilder = new StringBuilder(256); 835 836 /** 837 * Used to control how we initialize the service. 838 */ 839 ComponentName mTopComponent; 840 String mTopAction = Intent.ACTION_MAIN; 841 String mTopData; 842 boolean mProcessesReady = false; 843 boolean mSystemReady = false; 844 boolean mBooting = false; 845 boolean mWaitingUpdate = false; 846 boolean mDidUpdate = false; 847 boolean mOnBattery = false; 848 boolean mLaunchWarningShown = false; 849 850 Context mContext; 851 852 int mFactoryTest; 853 854 boolean mCheckedForSetup; 855 856 /** 857 * The time at which we will allow normal application switches again, 858 * after a call to {@link #stopAppSwitches()}. 859 */ 860 long mAppSwitchesAllowedTime; 861 862 /** 863 * This is set to true after the first switch after mAppSwitchesAllowedTime 864 * is set; any switches after that will clear the time. 865 */ 866 boolean mDidAppSwitch; 867 868 /** 869 * Last time (in realtime) at which we checked for power usage. 870 */ 871 long mLastPowerCheckRealtime; 872 873 /** 874 * Last time (in uptime) at which we checked for power usage. 875 */ 876 long mLastPowerCheckUptime; 877 878 /** 879 * Set while we are wanting to sleep, to prevent any 880 * activities from being started/resumed. 881 */ 882 private boolean mSleeping = false; 883 884 /** 885 * Set while we are running a voice interaction. This overrides 886 * sleeping while it is active. 887 */ 888 private boolean mRunningVoice = false; 889 890 /** 891 * State of external calls telling us if the device is asleep. 892 */ 893 private boolean mWentToSleep = false; 894 895 /** 896 * State of external call telling us if the lock screen is shown. 897 */ 898 private boolean mLockScreenShown = false; 899 900 /** 901 * Set if we are shutting down the system, similar to sleeping. 902 */ 903 boolean mShuttingDown = false; 904 905 /** 906 * Current sequence id for oom_adj computation traversal. 907 */ 908 int mAdjSeq = 0; 909 910 /** 911 * Current sequence id for process LRU updating. 912 */ 913 int mLruSeq = 0; 914 915 /** 916 * Keep track of the non-cached/empty process we last found, to help 917 * determine how to distribute cached/empty processes next time. 918 */ 919 int mNumNonCachedProcs = 0; 920 921 /** 922 * Keep track of the number of cached hidden procs, to balance oom adj 923 * distribution between those and empty procs. 924 */ 925 int mNumCachedHiddenProcs = 0; 926 927 /** 928 * Keep track of the number of service processes we last found, to 929 * determine on the next iteration which should be B services. 930 */ 931 int mNumServiceProcs = 0; 932 int mNewNumAServiceProcs = 0; 933 int mNewNumServiceProcs = 0; 934 935 /** 936 * Allow the current computed overall memory level of the system to go down? 937 * This is set to false when we are killing processes for reasons other than 938 * memory management, so that the now smaller process list will not be taken as 939 * an indication that memory is tighter. 940 */ 941 boolean mAllowLowerMemLevel = false; 942 943 /** 944 * The last computed memory level, for holding when we are in a state that 945 * processes are going away for other reasons. 946 */ 947 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 948 949 /** 950 * The last total number of process we have, to determine if changes actually look 951 * like a shrinking number of process due to lower RAM. 952 */ 953 int mLastNumProcesses; 954 955 /** 956 * The uptime of the last time we performed idle maintenance. 957 */ 958 long mLastIdleTime = SystemClock.uptimeMillis(); 959 960 /** 961 * Total time spent with RAM that has been added in the past since the last idle time. 962 */ 963 long mLowRamTimeSinceLastIdle = 0; 964 965 /** 966 * If RAM is currently low, when that horrible situation started. 967 */ 968 long mLowRamStartTime = 0; 969 970 /** 971 * For reporting to battery stats the current top application. 972 */ 973 private String mCurResumedPackage = null; 974 private int mCurResumedUid = -1; 975 976 /** 977 * For reporting to battery stats the apps currently running foreground 978 * service. The ProcessMap is package/uid tuples; each of these contain 979 * an array of the currently foreground processes. 980 */ 981 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 982 = new ProcessMap<ArrayList<ProcessRecord>>(); 983 984 /** 985 * This is set if we had to do a delayed dexopt of an app before launching 986 * it, to increase the ANR timeouts in that case. 987 */ 988 boolean mDidDexOpt; 989 990 /** 991 * Set if the systemServer made a call to enterSafeMode. 992 */ 993 boolean mSafeMode; 994 995 String mDebugApp = null; 996 boolean mWaitForDebugger = false; 997 boolean mDebugTransient = false; 998 String mOrigDebugApp = null; 999 boolean mOrigWaitForDebugger = false; 1000 boolean mAlwaysFinishActivities = false; 1001 IActivityController mController = null; 1002 String mProfileApp = null; 1003 ProcessRecord mProfileProc = null; 1004 String mProfileFile; 1005 ParcelFileDescriptor mProfileFd; 1006 int mProfileType = 0; 1007 boolean mAutoStopProfiler = false; 1008 String mOpenGlTraceApp = null; 1009 1010 static class ProcessChangeItem { 1011 static final int CHANGE_ACTIVITIES = 1<<0; 1012 static final int CHANGE_PROCESS_STATE = 1<<1; 1013 int changes; 1014 int uid; 1015 int pid; 1016 int processState; 1017 boolean foregroundActivities; 1018 } 1019 1020 final RemoteCallbackList<IProcessObserver> mProcessObservers 1021 = new RemoteCallbackList<IProcessObserver>(); 1022 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1023 1024 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1025 = new ArrayList<ProcessChangeItem>(); 1026 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1027 = new ArrayList<ProcessChangeItem>(); 1028 1029 /** 1030 * Runtime CPU use collection thread. This object's lock is used to 1031 * protect all related state. 1032 */ 1033 final Thread mProcessCpuThread; 1034 1035 /** 1036 * Used to collect process stats when showing not responding dialog. 1037 * Protected by mProcessCpuThread. 1038 */ 1039 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1040 MONITOR_THREAD_CPU_USAGE); 1041 final AtomicLong mLastCpuTime = new AtomicLong(0); 1042 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1043 1044 long mLastWriteTime = 0; 1045 1046 /** 1047 * Used to retain an update lock when the foreground activity is in 1048 * immersive mode. 1049 */ 1050 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1051 1052 /** 1053 * Set to true after the system has finished booting. 1054 */ 1055 boolean mBooted = false; 1056 1057 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1058 int mProcessLimitOverride = -1; 1059 1060 WindowManagerService mWindowManager; 1061 1062 final ActivityThread mSystemThread; 1063 1064 int mCurrentUserId = 0; 1065 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1066 private UserManagerService mUserManager; 1067 1068 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1069 final ProcessRecord mApp; 1070 final int mPid; 1071 final IApplicationThread mAppThread; 1072 1073 AppDeathRecipient(ProcessRecord app, int pid, 1074 IApplicationThread thread) { 1075 if (localLOGV) Slog.v( 1076 TAG, "New death recipient " + this 1077 + " for thread " + thread.asBinder()); 1078 mApp = app; 1079 mPid = pid; 1080 mAppThread = thread; 1081 } 1082 1083 @Override 1084 public void binderDied() { 1085 if (localLOGV) Slog.v( 1086 TAG, "Death received in " + this 1087 + " for thread " + mAppThread.asBinder()); 1088 synchronized(ActivityManagerService.this) { 1089 appDiedLocked(mApp, mPid, mAppThread); 1090 } 1091 } 1092 } 1093 1094 static final int SHOW_ERROR_MSG = 1; 1095 static final int SHOW_NOT_RESPONDING_MSG = 2; 1096 static final int SHOW_FACTORY_ERROR_MSG = 3; 1097 static final int UPDATE_CONFIGURATION_MSG = 4; 1098 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1099 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1100 static final int SERVICE_TIMEOUT_MSG = 12; 1101 static final int UPDATE_TIME_ZONE = 13; 1102 static final int SHOW_UID_ERROR_MSG = 14; 1103 static final int IM_FEELING_LUCKY_MSG = 15; 1104 static final int PROC_START_TIMEOUT_MSG = 20; 1105 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1106 static final int KILL_APPLICATION_MSG = 22; 1107 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1108 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1109 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1110 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1111 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1112 static final int CLEAR_DNS_CACHE_MSG = 28; 1113 static final int UPDATE_HTTP_PROXY_MSG = 29; 1114 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1115 static final int DISPATCH_PROCESSES_CHANGED = 31; 1116 static final int DISPATCH_PROCESS_DIED = 32; 1117 static final int REPORT_MEM_USAGE_MSG = 33; 1118 static final int REPORT_USER_SWITCH_MSG = 34; 1119 static final int CONTINUE_USER_SWITCH_MSG = 35; 1120 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1121 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1122 static final int PERSIST_URI_GRANTS_MSG = 38; 1123 static final int REQUEST_ALL_PSS_MSG = 39; 1124 static final int START_PROFILES_MSG = 40; 1125 static final int UPDATE_TIME = 41; 1126 static final int SYSTEM_USER_START_MSG = 42; 1127 static final int SYSTEM_USER_CURRENT_MSG = 43; 1128 1129 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1130 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1131 static final int FIRST_COMPAT_MODE_MSG = 300; 1132 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1133 1134 AlertDialog mUidAlert; 1135 CompatModeDialog mCompatModeDialog; 1136 long mLastMemUsageReportTime = 0; 1137 1138 /** 1139 * Flag whether the current user is a "monkey", i.e. whether 1140 * the UI is driven by a UI automation tool. 1141 */ 1142 private boolean mUserIsMonkey; 1143 1144 final ServiceThread mHandlerThread; 1145 final MainHandler mHandler; 1146 1147 final class MainHandler extends Handler { 1148 public MainHandler(Looper looper) { 1149 super(looper, null, true); 1150 } 1151 1152 @Override 1153 public void handleMessage(Message msg) { 1154 switch (msg.what) { 1155 case SHOW_ERROR_MSG: { 1156 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1157 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1158 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1159 synchronized (ActivityManagerService.this) { 1160 ProcessRecord proc = (ProcessRecord)data.get("app"); 1161 AppErrorResult res = (AppErrorResult) data.get("result"); 1162 if (proc != null && proc.crashDialog != null) { 1163 Slog.e(TAG, "App already has crash dialog: " + proc); 1164 if (res != null) { 1165 res.set(0); 1166 } 1167 return; 1168 } 1169 if (!showBackground && UserHandle.getAppId(proc.uid) 1170 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1171 && proc.pid != MY_PID) { 1172 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1173 if (res != null) { 1174 res.set(0); 1175 } 1176 return; 1177 } 1178 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1179 Dialog d = new AppErrorDialog(mContext, 1180 ActivityManagerService.this, res, proc); 1181 d.show(); 1182 proc.crashDialog = d; 1183 } else { 1184 // The device is asleep, so just pretend that the user 1185 // saw a crash dialog and hit "force quit". 1186 if (res != null) { 1187 res.set(0); 1188 } 1189 } 1190 } 1191 1192 ensureBootCompleted(); 1193 } break; 1194 case SHOW_NOT_RESPONDING_MSG: { 1195 synchronized (ActivityManagerService.this) { 1196 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1197 ProcessRecord proc = (ProcessRecord)data.get("app"); 1198 if (proc != null && proc.anrDialog != null) { 1199 Slog.e(TAG, "App already has anr dialog: " + proc); 1200 return; 1201 } 1202 1203 Intent intent = new Intent("android.intent.action.ANR"); 1204 if (!mProcessesReady) { 1205 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1206 | Intent.FLAG_RECEIVER_FOREGROUND); 1207 } 1208 broadcastIntentLocked(null, null, intent, 1209 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1210 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1211 1212 if (mShowDialogs) { 1213 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1214 mContext, proc, (ActivityRecord)data.get("activity"), 1215 msg.arg1 != 0); 1216 d.show(); 1217 proc.anrDialog = d; 1218 } else { 1219 // Just kill the app if there is no dialog to be shown. 1220 killAppAtUsersRequest(proc, null); 1221 } 1222 } 1223 1224 ensureBootCompleted(); 1225 } break; 1226 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1227 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1228 synchronized (ActivityManagerService.this) { 1229 ProcessRecord proc = (ProcessRecord) data.get("app"); 1230 if (proc == null) { 1231 Slog.e(TAG, "App not found when showing strict mode dialog."); 1232 break; 1233 } 1234 if (proc.crashDialog != null) { 1235 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1236 return; 1237 } 1238 AppErrorResult res = (AppErrorResult) data.get("result"); 1239 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1240 Dialog d = new StrictModeViolationDialog(mContext, 1241 ActivityManagerService.this, res, proc); 1242 d.show(); 1243 proc.crashDialog = d; 1244 } else { 1245 // The device is asleep, so just pretend that the user 1246 // saw a crash dialog and hit "force quit". 1247 res.set(0); 1248 } 1249 } 1250 ensureBootCompleted(); 1251 } break; 1252 case SHOW_FACTORY_ERROR_MSG: { 1253 Dialog d = new FactoryErrorDialog( 1254 mContext, msg.getData().getCharSequence("msg")); 1255 d.show(); 1256 ensureBootCompleted(); 1257 } break; 1258 case UPDATE_CONFIGURATION_MSG: { 1259 final ContentResolver resolver = mContext.getContentResolver(); 1260 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1261 } break; 1262 case GC_BACKGROUND_PROCESSES_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 performAppGcsIfAppropriateLocked(); 1265 } 1266 } break; 1267 case WAIT_FOR_DEBUGGER_MSG: { 1268 synchronized (ActivityManagerService.this) { 1269 ProcessRecord app = (ProcessRecord)msg.obj; 1270 if (msg.arg1 != 0) { 1271 if (!app.waitedForDebugger) { 1272 Dialog d = new AppWaitingForDebuggerDialog( 1273 ActivityManagerService.this, 1274 mContext, app); 1275 app.waitDialog = d; 1276 app.waitedForDebugger = true; 1277 d.show(); 1278 } 1279 } else { 1280 if (app.waitDialog != null) { 1281 app.waitDialog.dismiss(); 1282 app.waitDialog = null; 1283 } 1284 } 1285 } 1286 } break; 1287 case SERVICE_TIMEOUT_MSG: { 1288 if (mDidDexOpt) { 1289 mDidDexOpt = false; 1290 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1291 nmsg.obj = msg.obj; 1292 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1293 return; 1294 } 1295 mServices.serviceTimeout((ProcessRecord)msg.obj); 1296 } break; 1297 case UPDATE_TIME_ZONE: { 1298 synchronized (ActivityManagerService.this) { 1299 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1300 ProcessRecord r = mLruProcesses.get(i); 1301 if (r.thread != null) { 1302 try { 1303 r.thread.updateTimeZone(); 1304 } catch (RemoteException ex) { 1305 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1306 } 1307 } 1308 } 1309 } 1310 } break; 1311 case CLEAR_DNS_CACHE_MSG: { 1312 synchronized (ActivityManagerService.this) { 1313 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1314 ProcessRecord r = mLruProcesses.get(i); 1315 if (r.thread != null) { 1316 try { 1317 r.thread.clearDnsCache(); 1318 } catch (RemoteException ex) { 1319 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1320 } 1321 } 1322 } 1323 } 1324 } break; 1325 case UPDATE_HTTP_PROXY_MSG: { 1326 ProxyInfo proxy = (ProxyInfo)msg.obj; 1327 String host = ""; 1328 String port = ""; 1329 String exclList = ""; 1330 String pacFileUrl = ""; 1331 if (proxy != null) { 1332 host = proxy.getHost(); 1333 port = Integer.toString(proxy.getPort()); 1334 exclList = proxy.getExclusionListAsString(); 1335 if (proxy.getPacFileUrl() != null) { 1336 pacFileUrl = proxy.getPacFileUrl().toString(); 1337 } 1338 } 1339 synchronized (ActivityManagerService.this) { 1340 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1341 ProcessRecord r = mLruProcesses.get(i); 1342 if (r.thread != null) { 1343 try { 1344 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1345 } catch (RemoteException ex) { 1346 Slog.w(TAG, "Failed to update http proxy for: " + 1347 r.info.processName); 1348 } 1349 } 1350 } 1351 } 1352 } break; 1353 case SHOW_UID_ERROR_MSG: { 1354 String title = "System UIDs Inconsistent"; 1355 String text = "UIDs on the system are inconsistent, you need to wipe your" 1356 + " data partition or your device will be unstable."; 1357 Log.e(TAG, title + ": " + text); 1358 if (mShowDialogs) { 1359 // XXX This is a temporary dialog, no need to localize. 1360 AlertDialog d = new BaseErrorDialog(mContext); 1361 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1362 d.setCancelable(false); 1363 d.setTitle(title); 1364 d.setMessage(text); 1365 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1366 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1367 mUidAlert = d; 1368 d.show(); 1369 } 1370 } break; 1371 case IM_FEELING_LUCKY_MSG: { 1372 if (mUidAlert != null) { 1373 mUidAlert.dismiss(); 1374 mUidAlert = null; 1375 } 1376 } break; 1377 case PROC_START_TIMEOUT_MSG: { 1378 if (mDidDexOpt) { 1379 mDidDexOpt = false; 1380 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1381 nmsg.obj = msg.obj; 1382 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1383 return; 1384 } 1385 ProcessRecord app = (ProcessRecord)msg.obj; 1386 synchronized (ActivityManagerService.this) { 1387 processStartTimedOutLocked(app); 1388 } 1389 } break; 1390 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1391 synchronized (ActivityManagerService.this) { 1392 doPendingActivityLaunchesLocked(true); 1393 } 1394 } break; 1395 case KILL_APPLICATION_MSG: { 1396 synchronized (ActivityManagerService.this) { 1397 int appid = msg.arg1; 1398 boolean restart = (msg.arg2 == 1); 1399 Bundle bundle = (Bundle)msg.obj; 1400 String pkg = bundle.getString("pkg"); 1401 String reason = bundle.getString("reason"); 1402 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1403 false, UserHandle.USER_ALL, reason); 1404 } 1405 } break; 1406 case FINALIZE_PENDING_INTENT_MSG: { 1407 ((PendingIntentRecord)msg.obj).completeFinalize(); 1408 } break; 1409 case POST_HEAVY_NOTIFICATION_MSG: { 1410 INotificationManager inm = NotificationManager.getService(); 1411 if (inm == null) { 1412 return; 1413 } 1414 1415 ActivityRecord root = (ActivityRecord)msg.obj; 1416 ProcessRecord process = root.app; 1417 if (process == null) { 1418 return; 1419 } 1420 1421 try { 1422 Context context = mContext.createPackageContext(process.info.packageName, 0); 1423 String text = mContext.getString(R.string.heavy_weight_notification, 1424 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1425 Notification notification = new Notification(); 1426 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1427 notification.when = 0; 1428 notification.flags = Notification.FLAG_ONGOING_EVENT; 1429 notification.tickerText = text; 1430 notification.defaults = 0; // please be quiet 1431 notification.sound = null; 1432 notification.vibrate = null; 1433 notification.setLatestEventInfo(context, text, 1434 mContext.getText(R.string.heavy_weight_notification_detail), 1435 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1436 PendingIntent.FLAG_CANCEL_CURRENT, null, 1437 new UserHandle(root.userId))); 1438 1439 try { 1440 int[] outId = new int[1]; 1441 inm.enqueueNotificationWithTag("android", "android", null, 1442 R.string.heavy_weight_notification, 1443 notification, outId, root.userId); 1444 } catch (RuntimeException e) { 1445 Slog.w(ActivityManagerService.TAG, 1446 "Error showing notification for heavy-weight app", e); 1447 } catch (RemoteException e) { 1448 } 1449 } catch (NameNotFoundException e) { 1450 Slog.w(TAG, "Unable to create context for heavy notification", e); 1451 } 1452 } break; 1453 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1454 INotificationManager inm = NotificationManager.getService(); 1455 if (inm == null) { 1456 return; 1457 } 1458 try { 1459 inm.cancelNotificationWithTag("android", null, 1460 R.string.heavy_weight_notification, msg.arg1); 1461 } catch (RuntimeException e) { 1462 Slog.w(ActivityManagerService.TAG, 1463 "Error canceling notification for service", e); 1464 } catch (RemoteException e) { 1465 } 1466 } break; 1467 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1468 synchronized (ActivityManagerService.this) { 1469 checkExcessivePowerUsageLocked(true); 1470 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1471 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1472 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1473 } 1474 } break; 1475 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1476 synchronized (ActivityManagerService.this) { 1477 ActivityRecord ar = (ActivityRecord)msg.obj; 1478 if (mCompatModeDialog != null) { 1479 if (mCompatModeDialog.mAppInfo.packageName.equals( 1480 ar.info.applicationInfo.packageName)) { 1481 return; 1482 } 1483 mCompatModeDialog.dismiss(); 1484 mCompatModeDialog = null; 1485 } 1486 if (ar != null && false) { 1487 if (mCompatModePackages.getPackageAskCompatModeLocked( 1488 ar.packageName)) { 1489 int mode = mCompatModePackages.computeCompatModeLocked( 1490 ar.info.applicationInfo); 1491 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1492 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1493 mCompatModeDialog = new CompatModeDialog( 1494 ActivityManagerService.this, mContext, 1495 ar.info.applicationInfo); 1496 mCompatModeDialog.show(); 1497 } 1498 } 1499 } 1500 } 1501 break; 1502 } 1503 case DISPATCH_PROCESSES_CHANGED: { 1504 dispatchProcessesChanged(); 1505 break; 1506 } 1507 case DISPATCH_PROCESS_DIED: { 1508 final int pid = msg.arg1; 1509 final int uid = msg.arg2; 1510 dispatchProcessDied(pid, uid); 1511 break; 1512 } 1513 case REPORT_MEM_USAGE_MSG: { 1514 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1515 Thread thread = new Thread() { 1516 @Override public void run() { 1517 final SparseArray<ProcessMemInfo> infoMap 1518 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1519 for (int i=0, N=memInfos.size(); i<N; i++) { 1520 ProcessMemInfo mi = memInfos.get(i); 1521 infoMap.put(mi.pid, mi); 1522 } 1523 updateCpuStatsNow(); 1524 synchronized (mProcessCpuThread) { 1525 final int N = mProcessCpuTracker.countStats(); 1526 for (int i=0; i<N; i++) { 1527 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1528 if (st.vsize > 0) { 1529 long pss = Debug.getPss(st.pid, null); 1530 if (pss > 0) { 1531 if (infoMap.indexOfKey(st.pid) < 0) { 1532 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1533 ProcessList.NATIVE_ADJ, -1, "native", null); 1534 mi.pss = pss; 1535 memInfos.add(mi); 1536 } 1537 } 1538 } 1539 } 1540 } 1541 1542 long totalPss = 0; 1543 for (int i=0, N=memInfos.size(); i<N; i++) { 1544 ProcessMemInfo mi = memInfos.get(i); 1545 if (mi.pss == 0) { 1546 mi.pss = Debug.getPss(mi.pid, null); 1547 } 1548 totalPss += mi.pss; 1549 } 1550 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1551 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1552 if (lhs.oomAdj != rhs.oomAdj) { 1553 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1554 } 1555 if (lhs.pss != rhs.pss) { 1556 return lhs.pss < rhs.pss ? 1 : -1; 1557 } 1558 return 0; 1559 } 1560 }); 1561 1562 StringBuilder tag = new StringBuilder(128); 1563 StringBuilder stack = new StringBuilder(128); 1564 tag.append("Low on memory -- "); 1565 appendMemBucket(tag, totalPss, "total", false); 1566 appendMemBucket(stack, totalPss, "total", true); 1567 1568 StringBuilder logBuilder = new StringBuilder(1024); 1569 logBuilder.append("Low on memory:\n"); 1570 1571 boolean firstLine = true; 1572 int lastOomAdj = Integer.MIN_VALUE; 1573 for (int i=0, N=memInfos.size(); i<N; i++) { 1574 ProcessMemInfo mi = memInfos.get(i); 1575 1576 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1577 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1578 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1579 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1580 if (lastOomAdj != mi.oomAdj) { 1581 lastOomAdj = mi.oomAdj; 1582 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1583 tag.append(" / "); 1584 } 1585 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1586 if (firstLine) { 1587 stack.append(":"); 1588 firstLine = false; 1589 } 1590 stack.append("\n\t at "); 1591 } else { 1592 stack.append("$"); 1593 } 1594 } else { 1595 tag.append(" "); 1596 stack.append("$"); 1597 } 1598 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1599 appendMemBucket(tag, mi.pss, mi.name, false); 1600 } 1601 appendMemBucket(stack, mi.pss, mi.name, true); 1602 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1603 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1604 stack.append("("); 1605 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1606 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1607 stack.append(DUMP_MEM_OOM_LABEL[k]); 1608 stack.append(":"); 1609 stack.append(DUMP_MEM_OOM_ADJ[k]); 1610 } 1611 } 1612 stack.append(")"); 1613 } 1614 } 1615 1616 logBuilder.append(" "); 1617 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1618 logBuilder.append(' '); 1619 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1620 logBuilder.append(' '); 1621 ProcessList.appendRamKb(logBuilder, mi.pss); 1622 logBuilder.append(" kB: "); 1623 logBuilder.append(mi.name); 1624 logBuilder.append(" ("); 1625 logBuilder.append(mi.pid); 1626 logBuilder.append(") "); 1627 logBuilder.append(mi.adjType); 1628 logBuilder.append('\n'); 1629 if (mi.adjReason != null) { 1630 logBuilder.append(" "); 1631 logBuilder.append(mi.adjReason); 1632 logBuilder.append('\n'); 1633 } 1634 } 1635 1636 logBuilder.append(" "); 1637 ProcessList.appendRamKb(logBuilder, totalPss); 1638 logBuilder.append(" kB: TOTAL\n"); 1639 1640 long[] infos = new long[Debug.MEMINFO_COUNT]; 1641 Debug.getMemInfo(infos); 1642 logBuilder.append(" MemInfo: "); 1643 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1644 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1645 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1646 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1647 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1648 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1649 logBuilder.append(" ZRAM: "); 1650 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1651 logBuilder.append(" kB RAM, "); 1652 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1653 logBuilder.append(" kB swap total, "); 1654 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1655 logBuilder.append(" kB swap free\n"); 1656 } 1657 Slog.i(TAG, logBuilder.toString()); 1658 1659 StringBuilder dropBuilder = new StringBuilder(1024); 1660 /* 1661 StringWriter oomSw = new StringWriter(); 1662 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1663 StringWriter catSw = new StringWriter(); 1664 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1665 String[] emptyArgs = new String[] { }; 1666 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1667 oomPw.flush(); 1668 String oomString = oomSw.toString(); 1669 */ 1670 dropBuilder.append(stack); 1671 dropBuilder.append('\n'); 1672 dropBuilder.append('\n'); 1673 dropBuilder.append(logBuilder); 1674 dropBuilder.append('\n'); 1675 /* 1676 dropBuilder.append(oomString); 1677 dropBuilder.append('\n'); 1678 */ 1679 StringWriter catSw = new StringWriter(); 1680 synchronized (ActivityManagerService.this) { 1681 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1682 String[] emptyArgs = new String[] { }; 1683 catPw.println(); 1684 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1685 catPw.println(); 1686 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1687 false, false, null); 1688 catPw.println(); 1689 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1690 catPw.flush(); 1691 } 1692 dropBuilder.append(catSw.toString()); 1693 addErrorToDropBox("lowmem", null, "system_server", null, 1694 null, tag.toString(), dropBuilder.toString(), null, null); 1695 //Slog.i(TAG, "Sent to dropbox:"); 1696 //Slog.i(TAG, dropBuilder.toString()); 1697 synchronized (ActivityManagerService.this) { 1698 long now = SystemClock.uptimeMillis(); 1699 if (mLastMemUsageReportTime < now) { 1700 mLastMemUsageReportTime = now; 1701 } 1702 } 1703 } 1704 }; 1705 thread.start(); 1706 break; 1707 } 1708 case REPORT_USER_SWITCH_MSG: { 1709 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1710 break; 1711 } 1712 case CONTINUE_USER_SWITCH_MSG: { 1713 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1714 break; 1715 } 1716 case USER_SWITCH_TIMEOUT_MSG: { 1717 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2); 1718 break; 1719 } 1720 case IMMERSIVE_MODE_LOCK_MSG: { 1721 final boolean nextState = (msg.arg1 != 0); 1722 if (mUpdateLock.isHeld() != nextState) { 1723 if (DEBUG_IMMERSIVE) { 1724 final ActivityRecord r = (ActivityRecord) msg.obj; 1725 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1726 } 1727 if (nextState) { 1728 mUpdateLock.acquire(); 1729 } else { 1730 mUpdateLock.release(); 1731 } 1732 } 1733 break; 1734 } 1735 case PERSIST_URI_GRANTS_MSG: { 1736 writeGrantedUriPermissions(); 1737 break; 1738 } 1739 case REQUEST_ALL_PSS_MSG: { 1740 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1741 break; 1742 } 1743 case START_PROFILES_MSG: { 1744 synchronized (ActivityManagerService.this) { 1745 startProfilesLocked(); 1746 } 1747 break; 1748 } 1749 case UPDATE_TIME: { 1750 synchronized (ActivityManagerService.this) { 1751 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1752 ProcessRecord r = mLruProcesses.get(i); 1753 if (r.thread != null) { 1754 try { 1755 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1756 } catch (RemoteException ex) { 1757 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1758 } 1759 } 1760 } 1761 } 1762 break; 1763 } 1764 case SYSTEM_USER_START_MSG: { 1765 mSystemServiceManager.startUser(msg.arg1); 1766 break; 1767 } 1768 case SYSTEM_USER_CURRENT_MSG: { 1769 mSystemServiceManager.switchUser(msg.arg1); 1770 break; 1771 } 1772 } 1773 } 1774 }; 1775 1776 static final int COLLECT_PSS_BG_MSG = 1; 1777 1778 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1779 @Override 1780 public void handleMessage(Message msg) { 1781 switch (msg.what) { 1782 case COLLECT_PSS_BG_MSG: { 1783 int i=0, num=0; 1784 long start = SystemClock.uptimeMillis(); 1785 long[] tmp = new long[1]; 1786 do { 1787 ProcessRecord proc; 1788 int procState; 1789 int pid; 1790 synchronized (ActivityManagerService.this) { 1791 if (i >= mPendingPssProcesses.size()) { 1792 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1793 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1794 mPendingPssProcesses.clear(); 1795 return; 1796 } 1797 proc = mPendingPssProcesses.get(i); 1798 procState = proc.pssProcState; 1799 if (proc.thread != null && procState == proc.setProcState) { 1800 pid = proc.pid; 1801 } else { 1802 proc = null; 1803 pid = 0; 1804 } 1805 i++; 1806 } 1807 if (proc != null) { 1808 long pss = Debug.getPss(pid, tmp); 1809 synchronized (ActivityManagerService.this) { 1810 if (proc.thread != null && proc.setProcState == procState 1811 && proc.pid == pid) { 1812 num++; 1813 proc.lastPssTime = SystemClock.uptimeMillis(); 1814 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1815 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1816 + ": " + pss + " lastPss=" + proc.lastPss 1817 + " state=" + ProcessList.makeProcStateString(procState)); 1818 if (proc.initialIdlePss == 0) { 1819 proc.initialIdlePss = pss; 1820 } 1821 proc.lastPss = pss; 1822 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1823 proc.lastCachedPss = pss; 1824 } 1825 } 1826 } 1827 } 1828 } while (true); 1829 } 1830 } 1831 } 1832 }; 1833 1834 /** 1835 * Monitor for package changes and update our internal state. 1836 */ 1837 private final PackageMonitor mPackageMonitor = new PackageMonitor() { 1838 @Override 1839 public void onPackageRemoved(String packageName, int uid) { 1840 // Remove all tasks with activities in the specified package from the list of recent tasks 1841 synchronized (ActivityManagerService.this) { 1842 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1843 TaskRecord tr = mRecentTasks.get(i); 1844 ComponentName cn = tr.intent.getComponent(); 1845 if (cn != null && cn.getPackageName().equals(packageName)) { 1846 // If the package name matches, remove the task and kill the process 1847 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS); 1848 } 1849 } 1850 } 1851 } 1852 1853 @Override 1854 public boolean onPackageChanged(String packageName, int uid, String[] components) { 1855 final PackageManager pm = mContext.getPackageManager(); 1856 final ArrayList<Pair<Intent, Integer>> recentTaskIntents = 1857 new ArrayList<Pair<Intent, Integer>>(); 1858 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>(); 1859 // Copy the list of recent tasks so that we don't hold onto the lock on 1860 // ActivityManagerService for long periods while checking if components exist. 1861 synchronized (ActivityManagerService.this) { 1862 for (int i = mRecentTasks.size() - 1; i >= 0; i--) { 1863 TaskRecord tr = mRecentTasks.get(i); 1864 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId)); 1865 } 1866 } 1867 // Check the recent tasks and filter out all tasks with components that no longer exist. 1868 Intent tmpI = new Intent(); 1869 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) { 1870 Pair<Intent, Integer> p = recentTaskIntents.get(i); 1871 ComponentName cn = p.first.getComponent(); 1872 if (cn != null && cn.getPackageName().equals(packageName)) { 1873 try { 1874 // Add the task to the list to remove if the component no longer exists 1875 tmpI.setComponent(cn); 1876 if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) { 1877 tasksToRemove.add(p.second); 1878 } 1879 } catch (Exception e) {} 1880 } 1881 } 1882 // Prune all the tasks with removed components from the list of recent tasks 1883 synchronized (ActivityManagerService.this) { 1884 for (int i = tasksToRemove.size() - 1; i >= 0; i--) { 1885 // Remove the task but don't kill the process (since other components in that 1886 // package may still be running and in the background) 1887 removeTaskByIdLocked(tasksToRemove.get(i), 0); 1888 } 1889 } 1890 return true; 1891 } 1892 1893 @Override 1894 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) { 1895 // Force stop the specified packages 1896 if (packages != null) { 1897 for (String pkg : packages) { 1898 synchronized (ActivityManagerService.this) { 1899 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 1900 "finished booting")) { 1901 return true; 1902 } 1903 } 1904 } 1905 } 1906 return false; 1907 } 1908 }; 1909 1910 public void setSystemProcess() { 1911 try { 1912 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1913 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1914 ServiceManager.addService("meminfo", new MemBinder(this)); 1915 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1916 ServiceManager.addService("dbinfo", new DbBinder(this)); 1917 if (MONITOR_CPU_USAGE) { 1918 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1919 } 1920 ServiceManager.addService("permission", new PermissionController(this)); 1921 1922 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1923 "android", STOCK_PM_FLAGS); 1924 mSystemThread.installSystemApplicationInfo(info); 1925 1926 synchronized (this) { 1927 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1928 app.persistent = true; 1929 app.pid = MY_PID; 1930 app.maxAdj = ProcessList.SYSTEM_ADJ; 1931 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1932 mProcessNames.put(app.processName, app.uid, app); 1933 synchronized (mPidsSelfLocked) { 1934 mPidsSelfLocked.put(app.pid, app); 1935 } 1936 updateLruProcessLocked(app, false, null); 1937 updateOomAdjLocked(); 1938 } 1939 } catch (PackageManager.NameNotFoundException e) { 1940 throw new RuntimeException( 1941 "Unable to find android system package", e); 1942 } 1943 } 1944 1945 public void setWindowManager(WindowManagerService wm) { 1946 mWindowManager = wm; 1947 mStackSupervisor.setWindowManager(wm); 1948 } 1949 1950 public void startObservingNativeCrashes() { 1951 final NativeCrashListener ncl = new NativeCrashListener(this); 1952 ncl.start(); 1953 } 1954 1955 public IAppOpsService getAppOpsService() { 1956 return mAppOpsService; 1957 } 1958 1959 static class MemBinder extends Binder { 1960 ActivityManagerService mActivityManagerService; 1961 MemBinder(ActivityManagerService activityManagerService) { 1962 mActivityManagerService = activityManagerService; 1963 } 1964 1965 @Override 1966 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1967 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1968 != PackageManager.PERMISSION_GRANTED) { 1969 pw.println("Permission Denial: can't dump meminfo from from pid=" 1970 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1971 + " without permission " + android.Manifest.permission.DUMP); 1972 return; 1973 } 1974 1975 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1976 } 1977 } 1978 1979 static class GraphicsBinder extends Binder { 1980 ActivityManagerService mActivityManagerService; 1981 GraphicsBinder(ActivityManagerService activityManagerService) { 1982 mActivityManagerService = activityManagerService; 1983 } 1984 1985 @Override 1986 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1987 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1988 != PackageManager.PERMISSION_GRANTED) { 1989 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1990 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1991 + " without permission " + android.Manifest.permission.DUMP); 1992 return; 1993 } 1994 1995 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1996 } 1997 } 1998 1999 static class DbBinder extends Binder { 2000 ActivityManagerService mActivityManagerService; 2001 DbBinder(ActivityManagerService activityManagerService) { 2002 mActivityManagerService = activityManagerService; 2003 } 2004 2005 @Override 2006 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2007 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2008 != PackageManager.PERMISSION_GRANTED) { 2009 pw.println("Permission Denial: can't dump dbinfo from from pid=" 2010 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2011 + " without permission " + android.Manifest.permission.DUMP); 2012 return; 2013 } 2014 2015 mActivityManagerService.dumpDbInfo(fd, pw, args); 2016 } 2017 } 2018 2019 static class CpuBinder extends Binder { 2020 ActivityManagerService mActivityManagerService; 2021 CpuBinder(ActivityManagerService activityManagerService) { 2022 mActivityManagerService = activityManagerService; 2023 } 2024 2025 @Override 2026 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 2027 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 2028 != PackageManager.PERMISSION_GRANTED) { 2029 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 2030 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 2031 + " without permission " + android.Manifest.permission.DUMP); 2032 return; 2033 } 2034 2035 synchronized (mActivityManagerService.mProcessCpuThread) { 2036 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 2037 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 2038 SystemClock.uptimeMillis())); 2039 } 2040 } 2041 } 2042 2043 public static final class Lifecycle extends SystemService { 2044 private final ActivityManagerService mService; 2045 2046 public Lifecycle(Context context) { 2047 super(context); 2048 mService = new ActivityManagerService(context); 2049 } 2050 2051 @Override 2052 public void onStart() { 2053 mService.start(); 2054 } 2055 2056 public ActivityManagerService getService() { 2057 return mService; 2058 } 2059 } 2060 2061 // Note: This method is invoked on the main thread but may need to attach various 2062 // handlers to other threads. So take care to be explicit about the looper. 2063 public ActivityManagerService(Context systemContext) { 2064 mContext = systemContext; 2065 mFactoryTest = FactoryTest.getMode(); 2066 mSystemThread = ActivityThread.currentActivityThread(); 2067 2068 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 2069 2070 mHandlerThread = new ServiceThread(TAG, 2071 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 2072 mHandlerThread.start(); 2073 mHandler = new MainHandler(mHandlerThread.getLooper()); 2074 2075 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 2076 "foreground", BROADCAST_FG_TIMEOUT, false); 2077 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 2078 "background", BROADCAST_BG_TIMEOUT, true); 2079 mBroadcastQueues[0] = mFgBroadcastQueue; 2080 mBroadcastQueues[1] = mBgBroadcastQueue; 2081 2082 mServices = new ActiveServices(this); 2083 mProviderMap = new ProviderMap(this); 2084 2085 // TODO: Move creation of battery stats service outside of activity manager service. 2086 File dataDir = Environment.getDataDirectory(); 2087 File systemDir = new File(dataDir, "system"); 2088 systemDir.mkdirs(); 2089 mBatteryStatsService = new BatteryStatsService(new File( 2090 systemDir, "batterystats.bin").toString(), mHandler); 2091 mBatteryStatsService.getActiveStatistics().readLocked(); 2092 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2093 mOnBattery = DEBUG_POWER ? true 2094 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2095 mBatteryStatsService.getActiveStatistics().setCallback(this); 2096 2097 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2098 2099 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2100 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2101 2102 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2103 2104 // User 0 is the first and only user that runs at boot. 2105 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2106 mUserLru.add(Integer.valueOf(0)); 2107 updateStartedUserArrayLocked(); 2108 2109 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2110 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2111 2112 mConfiguration.setToDefaults(); 2113 mConfiguration.setLocale(Locale.getDefault()); 2114 2115 mConfigurationSeq = mConfiguration.seq = 1; 2116 mProcessCpuTracker.init(); 2117 2118 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2119 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2120 mStackSupervisor = new ActivityStackSupervisor(this); 2121 2122 mProcessCpuThread = new Thread("CpuTracker") { 2123 @Override 2124 public void run() { 2125 while (true) { 2126 try { 2127 try { 2128 synchronized(this) { 2129 final long now = SystemClock.uptimeMillis(); 2130 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2131 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2132 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2133 // + ", write delay=" + nextWriteDelay); 2134 if (nextWriteDelay < nextCpuDelay) { 2135 nextCpuDelay = nextWriteDelay; 2136 } 2137 if (nextCpuDelay > 0) { 2138 mProcessCpuMutexFree.set(true); 2139 this.wait(nextCpuDelay); 2140 } 2141 } 2142 } catch (InterruptedException e) { 2143 } 2144 updateCpuStatsNow(); 2145 } catch (Exception e) { 2146 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2147 } 2148 } 2149 } 2150 }; 2151 2152 Watchdog.getInstance().addMonitor(this); 2153 Watchdog.getInstance().addThread(mHandler); 2154 } 2155 2156 public void setSystemServiceManager(SystemServiceManager mgr) { 2157 mSystemServiceManager = mgr; 2158 } 2159 2160 private void start() { 2161 mProcessCpuThread.start(); 2162 2163 mBatteryStatsService.publish(mContext); 2164 mUsageStatsService.publish(mContext); 2165 mAppOpsService.publish(mContext); 2166 2167 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2168 } 2169 2170 @Override 2171 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2172 throws RemoteException { 2173 if (code == SYSPROPS_TRANSACTION) { 2174 // We need to tell all apps about the system property change. 2175 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2176 synchronized(this) { 2177 final int NP = mProcessNames.getMap().size(); 2178 for (int ip=0; ip<NP; ip++) { 2179 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2180 final int NA = apps.size(); 2181 for (int ia=0; ia<NA; ia++) { 2182 ProcessRecord app = apps.valueAt(ia); 2183 if (app.thread != null) { 2184 procs.add(app.thread.asBinder()); 2185 } 2186 } 2187 } 2188 } 2189 2190 int N = procs.size(); 2191 for (int i=0; i<N; i++) { 2192 Parcel data2 = Parcel.obtain(); 2193 try { 2194 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2195 } catch (RemoteException e) { 2196 } 2197 data2.recycle(); 2198 } 2199 } 2200 try { 2201 return super.onTransact(code, data, reply, flags); 2202 } catch (RuntimeException e) { 2203 // The activity manager only throws security exceptions, so let's 2204 // log all others. 2205 if (!(e instanceof SecurityException)) { 2206 Slog.wtf(TAG, "Activity Manager Crash", e); 2207 } 2208 throw e; 2209 } 2210 } 2211 2212 void updateCpuStats() { 2213 final long now = SystemClock.uptimeMillis(); 2214 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2215 return; 2216 } 2217 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2218 synchronized (mProcessCpuThread) { 2219 mProcessCpuThread.notify(); 2220 } 2221 } 2222 } 2223 2224 void updateCpuStatsNow() { 2225 synchronized (mProcessCpuThread) { 2226 mProcessCpuMutexFree.set(false); 2227 final long now = SystemClock.uptimeMillis(); 2228 boolean haveNewCpuStats = false; 2229 2230 if (MONITOR_CPU_USAGE && 2231 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2232 mLastCpuTime.set(now); 2233 haveNewCpuStats = true; 2234 mProcessCpuTracker.update(); 2235 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2236 //Slog.i(TAG, "Total CPU usage: " 2237 // + mProcessCpu.getTotalCpuPercent() + "%"); 2238 2239 // Slog the cpu usage if the property is set. 2240 if ("true".equals(SystemProperties.get("events.cpu"))) { 2241 int user = mProcessCpuTracker.getLastUserTime(); 2242 int system = mProcessCpuTracker.getLastSystemTime(); 2243 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2244 int irq = mProcessCpuTracker.getLastIrqTime(); 2245 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2246 int idle = mProcessCpuTracker.getLastIdleTime(); 2247 2248 int total = user + system + iowait + irq + softIrq + idle; 2249 if (total == 0) total = 1; 2250 2251 EventLog.writeEvent(EventLogTags.CPU, 2252 ((user+system+iowait+irq+softIrq) * 100) / total, 2253 (user * 100) / total, 2254 (system * 100) / total, 2255 (iowait * 100) / total, 2256 (irq * 100) / total, 2257 (softIrq * 100) / total); 2258 } 2259 } 2260 2261 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2262 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2263 synchronized(bstats) { 2264 synchronized(mPidsSelfLocked) { 2265 if (haveNewCpuStats) { 2266 if (mOnBattery) { 2267 int perc = bstats.startAddingCpuLocked(); 2268 int totalUTime = 0; 2269 int totalSTime = 0; 2270 final int N = mProcessCpuTracker.countStats(); 2271 for (int i=0; i<N; i++) { 2272 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2273 if (!st.working) { 2274 continue; 2275 } 2276 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2277 int otherUTime = (st.rel_utime*perc)/100; 2278 int otherSTime = (st.rel_stime*perc)/100; 2279 totalUTime += otherUTime; 2280 totalSTime += otherSTime; 2281 if (pr != null) { 2282 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2283 if (ps == null || !ps.isActive()) { 2284 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2285 pr.info.uid, pr.processName); 2286 } 2287 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2288 st.rel_stime-otherSTime); 2289 ps.addSpeedStepTimes(cpuSpeedTimes); 2290 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2291 } else { 2292 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2293 if (ps == null || !ps.isActive()) { 2294 st.batteryStats = ps = bstats.getProcessStatsLocked( 2295 bstats.mapUid(st.uid), st.name); 2296 } 2297 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2298 st.rel_stime-otherSTime); 2299 ps.addSpeedStepTimes(cpuSpeedTimes); 2300 } 2301 } 2302 bstats.finishAddingCpuLocked(perc, totalUTime, 2303 totalSTime, cpuSpeedTimes); 2304 } 2305 } 2306 } 2307 2308 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2309 mLastWriteTime = now; 2310 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2311 } 2312 } 2313 } 2314 } 2315 2316 @Override 2317 public void batteryNeedsCpuUpdate() { 2318 updateCpuStatsNow(); 2319 } 2320 2321 @Override 2322 public void batteryPowerChanged(boolean onBattery) { 2323 // When plugging in, update the CPU stats first before changing 2324 // the plug state. 2325 updateCpuStatsNow(); 2326 synchronized (this) { 2327 synchronized(mPidsSelfLocked) { 2328 mOnBattery = DEBUG_POWER ? true : onBattery; 2329 } 2330 } 2331 } 2332 2333 /** 2334 * Initialize the application bind args. These are passed to each 2335 * process when the bindApplication() IPC is sent to the process. They're 2336 * lazily setup to make sure the services are running when they're asked for. 2337 */ 2338 private HashMap<String, IBinder> getCommonServicesLocked() { 2339 if (mAppBindArgs == null) { 2340 mAppBindArgs = new HashMap<String, IBinder>(); 2341 2342 // Setup the application init args 2343 mAppBindArgs.put("package", ServiceManager.getService("package")); 2344 mAppBindArgs.put("window", ServiceManager.getService("window")); 2345 mAppBindArgs.put(Context.ALARM_SERVICE, 2346 ServiceManager.getService(Context.ALARM_SERVICE)); 2347 } 2348 return mAppBindArgs; 2349 } 2350 2351 final void setFocusedActivityLocked(ActivityRecord r) { 2352 if (mFocusedActivity != r) { 2353 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2354 mFocusedActivity = r; 2355 if (r.task != null && r.task.voiceInteractor != null) { 2356 startRunningVoiceLocked(); 2357 } else { 2358 finishRunningVoiceLocked(); 2359 } 2360 mStackSupervisor.setFocusedStack(r); 2361 if (r != null) { 2362 mWindowManager.setFocusedApp(r.appToken, true); 2363 } 2364 applyUpdateLockStateLocked(r); 2365 } 2366 } 2367 2368 final void clearFocusedActivity(ActivityRecord r) { 2369 if (mFocusedActivity == r) { 2370 mFocusedActivity = null; 2371 } 2372 } 2373 2374 @Override 2375 public void setFocusedStack(int stackId) { 2376 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2377 synchronized (ActivityManagerService.this) { 2378 ActivityStack stack = mStackSupervisor.getStack(stackId); 2379 if (stack != null) { 2380 ActivityRecord r = stack.topRunningActivityLocked(null); 2381 if (r != null) { 2382 setFocusedActivityLocked(r); 2383 } 2384 } 2385 } 2386 } 2387 2388 @Override 2389 public void notifyActivityDrawn(IBinder token) { 2390 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2391 synchronized (this) { 2392 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2393 if (r != null) { 2394 r.task.stack.notifyActivityDrawnLocked(r); 2395 } 2396 } 2397 } 2398 2399 final void applyUpdateLockStateLocked(ActivityRecord r) { 2400 // Modifications to the UpdateLock state are done on our handler, outside 2401 // the activity manager's locks. The new state is determined based on the 2402 // state *now* of the relevant activity record. The object is passed to 2403 // the handler solely for logging detail, not to be consulted/modified. 2404 final boolean nextState = r != null && r.immersive; 2405 mHandler.sendMessage( 2406 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2407 } 2408 2409 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2410 Message msg = Message.obtain(); 2411 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2412 msg.obj = r.task.askedCompatMode ? null : r; 2413 mHandler.sendMessage(msg); 2414 } 2415 2416 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2417 String what, Object obj, ProcessRecord srcApp) { 2418 app.lastActivityTime = now; 2419 2420 if (app.activities.size() > 0) { 2421 // Don't want to touch dependent processes that are hosting activities. 2422 return index; 2423 } 2424 2425 int lrui = mLruProcesses.lastIndexOf(app); 2426 if (lrui < 0) { 2427 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2428 + what + " " + obj + " from " + srcApp); 2429 return index; 2430 } 2431 2432 if (lrui >= index) { 2433 // Don't want to cause this to move dependent processes *back* in the 2434 // list as if they were less frequently used. 2435 return index; 2436 } 2437 2438 if (lrui >= mLruProcessActivityStart) { 2439 // Don't want to touch dependent processes that are hosting activities. 2440 return index; 2441 } 2442 2443 mLruProcesses.remove(lrui); 2444 if (index > 0) { 2445 index--; 2446 } 2447 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2448 + " in LRU list: " + app); 2449 mLruProcesses.add(index, app); 2450 return index; 2451 } 2452 2453 final void removeLruProcessLocked(ProcessRecord app) { 2454 int lrui = mLruProcesses.lastIndexOf(app); 2455 if (lrui >= 0) { 2456 if (lrui <= mLruProcessActivityStart) { 2457 mLruProcessActivityStart--; 2458 } 2459 if (lrui <= mLruProcessServiceStart) { 2460 mLruProcessServiceStart--; 2461 } 2462 mLruProcesses.remove(lrui); 2463 } 2464 } 2465 2466 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2467 ProcessRecord client) { 2468 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2469 || app.treatLikeActivity; 2470 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2471 if (!activityChange && hasActivity) { 2472 // The process has activities, so we are only allowing activity-based adjustments 2473 // to move it. It should be kept in the front of the list with other 2474 // processes that have activities, and we don't want those to change their 2475 // order except due to activity operations. 2476 return; 2477 } 2478 2479 mLruSeq++; 2480 final long now = SystemClock.uptimeMillis(); 2481 app.lastActivityTime = now; 2482 2483 // First a quick reject: if the app is already at the position we will 2484 // put it, then there is nothing to do. 2485 if (hasActivity) { 2486 final int N = mLruProcesses.size(); 2487 if (N > 0 && mLruProcesses.get(N-1) == app) { 2488 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2489 return; 2490 } 2491 } else { 2492 if (mLruProcessServiceStart > 0 2493 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2494 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2495 return; 2496 } 2497 } 2498 2499 int lrui = mLruProcesses.lastIndexOf(app); 2500 2501 if (app.persistent && lrui >= 0) { 2502 // We don't care about the position of persistent processes, as long as 2503 // they are in the list. 2504 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2505 return; 2506 } 2507 2508 /* In progress: compute new position first, so we can avoid doing work 2509 if the process is not actually going to move. Not yet working. 2510 int addIndex; 2511 int nextIndex; 2512 boolean inActivity = false, inService = false; 2513 if (hasActivity) { 2514 // Process has activities, put it at the very tipsy-top. 2515 addIndex = mLruProcesses.size(); 2516 nextIndex = mLruProcessServiceStart; 2517 inActivity = true; 2518 } else if (hasService) { 2519 // Process has services, put it at the top of the service list. 2520 addIndex = mLruProcessActivityStart; 2521 nextIndex = mLruProcessServiceStart; 2522 inActivity = true; 2523 inService = true; 2524 } else { 2525 // Process not otherwise of interest, it goes to the top of the non-service area. 2526 addIndex = mLruProcessServiceStart; 2527 if (client != null) { 2528 int clientIndex = mLruProcesses.lastIndexOf(client); 2529 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2530 + app); 2531 if (clientIndex >= 0 && addIndex > clientIndex) { 2532 addIndex = clientIndex; 2533 } 2534 } 2535 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2536 } 2537 2538 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2539 + mLruProcessActivityStart + "): " + app); 2540 */ 2541 2542 if (lrui >= 0) { 2543 if (lrui < mLruProcessActivityStart) { 2544 mLruProcessActivityStart--; 2545 } 2546 if (lrui < mLruProcessServiceStart) { 2547 mLruProcessServiceStart--; 2548 } 2549 /* 2550 if (addIndex > lrui) { 2551 addIndex--; 2552 } 2553 if (nextIndex > lrui) { 2554 nextIndex--; 2555 } 2556 */ 2557 mLruProcesses.remove(lrui); 2558 } 2559 2560 /* 2561 mLruProcesses.add(addIndex, app); 2562 if (inActivity) { 2563 mLruProcessActivityStart++; 2564 } 2565 if (inService) { 2566 mLruProcessActivityStart++; 2567 } 2568 */ 2569 2570 int nextIndex; 2571 if (hasActivity) { 2572 final int N = mLruProcesses.size(); 2573 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2574 // Process doesn't have activities, but has clients with 2575 // activities... move it up, but one below the top (the top 2576 // should always have a real activity). 2577 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2578 mLruProcesses.add(N-1, app); 2579 // To keep it from spamming the LRU list (by making a bunch of clients), 2580 // we will push down any other entries owned by the app. 2581 final int uid = app.info.uid; 2582 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2583 ProcessRecord subProc = mLruProcesses.get(i); 2584 if (subProc.info.uid == uid) { 2585 // We want to push this one down the list. If the process after 2586 // it is for the same uid, however, don't do so, because we don't 2587 // want them internally to be re-ordered. 2588 if (mLruProcesses.get(i-1).info.uid != uid) { 2589 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2590 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2591 ProcessRecord tmp = mLruProcesses.get(i); 2592 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2593 mLruProcesses.set(i-1, tmp); 2594 i--; 2595 } 2596 } else { 2597 // A gap, we can stop here. 2598 break; 2599 } 2600 } 2601 } else { 2602 // Process has activities, put it at the very tipsy-top. 2603 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2604 mLruProcesses.add(app); 2605 } 2606 nextIndex = mLruProcessServiceStart; 2607 } else if (hasService) { 2608 // Process has services, put it at the top of the service list. 2609 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2610 mLruProcesses.add(mLruProcessActivityStart, app); 2611 nextIndex = mLruProcessServiceStart; 2612 mLruProcessActivityStart++; 2613 } else { 2614 // Process not otherwise of interest, it goes to the top of the non-service area. 2615 int index = mLruProcessServiceStart; 2616 if (client != null) { 2617 // If there is a client, don't allow the process to be moved up higher 2618 // in the list than that client. 2619 int clientIndex = mLruProcesses.lastIndexOf(client); 2620 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2621 + " when updating " + app); 2622 if (clientIndex <= lrui) { 2623 // Don't allow the client index restriction to push it down farther in the 2624 // list than it already is. 2625 clientIndex = lrui; 2626 } 2627 if (clientIndex >= 0 && index > clientIndex) { 2628 index = clientIndex; 2629 } 2630 } 2631 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2632 mLruProcesses.add(index, app); 2633 nextIndex = index-1; 2634 mLruProcessActivityStart++; 2635 mLruProcessServiceStart++; 2636 } 2637 2638 // If the app is currently using a content provider or service, 2639 // bump those processes as well. 2640 for (int j=app.connections.size()-1; j>=0; j--) { 2641 ConnectionRecord cr = app.connections.valueAt(j); 2642 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2643 && cr.binding.service.app != null 2644 && cr.binding.service.app.lruSeq != mLruSeq 2645 && !cr.binding.service.app.persistent) { 2646 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2647 "service connection", cr, app); 2648 } 2649 } 2650 for (int j=app.conProviders.size()-1; j>=0; j--) { 2651 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2652 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2653 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2654 "provider reference", cpr, app); 2655 } 2656 } 2657 } 2658 2659 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2660 if (uid == Process.SYSTEM_UID) { 2661 // The system gets to run in any process. If there are multiple 2662 // processes with the same uid, just pick the first (this 2663 // should never happen). 2664 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2665 if (procs == null) return null; 2666 final int N = procs.size(); 2667 for (int i = 0; i < N; i++) { 2668 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2669 } 2670 } 2671 ProcessRecord proc = mProcessNames.get(processName, uid); 2672 if (false && proc != null && !keepIfLarge 2673 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2674 && proc.lastCachedPss >= 4000) { 2675 // Turn this condition on to cause killing to happen regularly, for testing. 2676 if (proc.baseProcessTracker != null) { 2677 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2678 } 2679 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2680 + "k from cached"); 2681 } else if (proc != null && !keepIfLarge 2682 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2683 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2684 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2685 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2686 if (proc.baseProcessTracker != null) { 2687 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2688 } 2689 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2690 + "k from cached"); 2691 } 2692 } 2693 return proc; 2694 } 2695 2696 void ensurePackageDexOpt(String packageName) { 2697 IPackageManager pm = AppGlobals.getPackageManager(); 2698 try { 2699 if (pm.performDexOpt(packageName)) { 2700 mDidDexOpt = true; 2701 } 2702 } catch (RemoteException e) { 2703 } 2704 } 2705 2706 boolean isNextTransitionForward() { 2707 int transit = mWindowManager.getPendingAppTransition(); 2708 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2709 || transit == AppTransition.TRANSIT_TASK_OPEN 2710 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2711 } 2712 2713 final ProcessRecord startProcessLocked(String processName, 2714 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2715 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2716 boolean isolated, boolean keepIfLarge) { 2717 ProcessRecord app; 2718 if (!isolated) { 2719 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2720 } else { 2721 // If this is an isolated process, it can't re-use an existing process. 2722 app = null; 2723 } 2724 // We don't have to do anything more if: 2725 // (1) There is an existing application record; and 2726 // (2) The caller doesn't think it is dead, OR there is no thread 2727 // object attached to it so we know it couldn't have crashed; and 2728 // (3) There is a pid assigned to it, so it is either starting or 2729 // already running. 2730 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2731 + " app=" + app + " knownToBeDead=" + knownToBeDead 2732 + " thread=" + (app != null ? app.thread : null) 2733 + " pid=" + (app != null ? app.pid : -1)); 2734 if (app != null && app.pid > 0) { 2735 if (!knownToBeDead || app.thread == null) { 2736 // We already have the app running, or are waiting for it to 2737 // come up (we have a pid but not yet its thread), so keep it. 2738 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2739 // If this is a new package in the process, add the package to the list 2740 app.addPackage(info.packageName, mProcessStats); 2741 return app; 2742 } 2743 2744 // An application record is attached to a previous process, 2745 // clean it up now. 2746 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2747 handleAppDiedLocked(app, true, true); 2748 } 2749 2750 String hostingNameStr = hostingName != null 2751 ? hostingName.flattenToShortString() : null; 2752 2753 if (!isolated) { 2754 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2755 // If we are in the background, then check to see if this process 2756 // is bad. If so, we will just silently fail. 2757 if (mBadProcesses.get(info.processName, info.uid) != null) { 2758 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2759 + "/" + info.processName); 2760 return null; 2761 } 2762 } else { 2763 // When the user is explicitly starting a process, then clear its 2764 // crash count so that we won't make it bad until they see at 2765 // least one crash dialog again, and make the process good again 2766 // if it had been bad. 2767 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2768 + "/" + info.processName); 2769 mProcessCrashTimes.remove(info.processName, info.uid); 2770 if (mBadProcesses.get(info.processName, info.uid) != null) { 2771 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2772 UserHandle.getUserId(info.uid), info.uid, 2773 info.processName); 2774 mBadProcesses.remove(info.processName, info.uid); 2775 if (app != null) { 2776 app.bad = false; 2777 } 2778 } 2779 } 2780 } 2781 2782 if (app == null) { 2783 app = newProcessRecordLocked(info, processName, isolated); 2784 if (app == null) { 2785 Slog.w(TAG, "Failed making new process record for " 2786 + processName + "/" + info.uid + " isolated=" + isolated); 2787 return null; 2788 } 2789 mProcessNames.put(processName, app.uid, app); 2790 if (isolated) { 2791 mIsolatedProcesses.put(app.uid, app); 2792 } 2793 } else { 2794 // If this is a new package in the process, add the package to the list 2795 app.addPackage(info.packageName, mProcessStats); 2796 } 2797 2798 // If the system is not ready yet, then hold off on starting this 2799 // process until it is. 2800 if (!mProcessesReady 2801 && !isAllowedWhileBooting(info) 2802 && !allowWhileBooting) { 2803 if (!mProcessesOnHold.contains(app)) { 2804 mProcessesOnHold.add(app); 2805 } 2806 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2807 return app; 2808 } 2809 2810 startProcessLocked(app, hostingType, hostingNameStr); 2811 return (app.pid != 0) ? app : null; 2812 } 2813 2814 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2815 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2816 } 2817 2818 private final void startProcessLocked(ProcessRecord app, 2819 String hostingType, String hostingNameStr) { 2820 if (app.pid > 0 && app.pid != MY_PID) { 2821 synchronized (mPidsSelfLocked) { 2822 mPidsSelfLocked.remove(app.pid); 2823 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2824 } 2825 app.setPid(0); 2826 } 2827 2828 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2829 "startProcessLocked removing on hold: " + app); 2830 mProcessesOnHold.remove(app); 2831 2832 updateCpuStats(); 2833 2834 try { 2835 int uid = app.uid; 2836 2837 int[] gids = null; 2838 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2839 if (!app.isolated) { 2840 int[] permGids = null; 2841 try { 2842 final PackageManager pm = mContext.getPackageManager(); 2843 permGids = pm.getPackageGids(app.info.packageName); 2844 2845 if (Environment.isExternalStorageEmulated()) { 2846 if (pm.checkPermission( 2847 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2848 app.info.packageName) == PERMISSION_GRANTED) { 2849 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2850 } else { 2851 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2852 } 2853 } 2854 } catch (PackageManager.NameNotFoundException e) { 2855 Slog.w(TAG, "Unable to retrieve gids", e); 2856 } 2857 2858 /* 2859 * Add shared application GID so applications can share some 2860 * resources like shared libraries 2861 */ 2862 if (permGids == null) { 2863 gids = new int[1]; 2864 } else { 2865 gids = new int[permGids.length + 1]; 2866 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2867 } 2868 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2869 } 2870 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2871 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2872 && mTopComponent != null 2873 && app.processName.equals(mTopComponent.getPackageName())) { 2874 uid = 0; 2875 } 2876 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2877 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2878 uid = 0; 2879 } 2880 } 2881 int debugFlags = 0; 2882 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2883 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2884 // Also turn on CheckJNI for debuggable apps. It's quite 2885 // awkward to turn on otherwise. 2886 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2887 } 2888 // Run the app in safe mode if its manifest requests so or the 2889 // system is booted in safe mode. 2890 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2891 mSafeMode == true) { 2892 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2893 } 2894 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2895 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2896 } 2897 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2898 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2899 } 2900 if ("1".equals(SystemProperties.get("debug.assert"))) { 2901 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2902 } 2903 2904 String requiredAbi = app.info.requiredCpuAbi; 2905 if (requiredAbi == null) { 2906 requiredAbi = Build.SUPPORTED_ABIS[0]; 2907 } 2908 2909 // Start the process. It will either succeed and return a result containing 2910 // the PID of the new process, or else throw a RuntimeException. 2911 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2912 app.processName, uid, uid, gids, debugFlags, mountExternal, 2913 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2914 2915 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2916 synchronized (bs) { 2917 if (bs.isOnBattery()) { 2918 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2919 } 2920 } 2921 2922 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2923 UserHandle.getUserId(uid), startResult.pid, uid, 2924 app.processName, hostingType, 2925 hostingNameStr != null ? hostingNameStr : ""); 2926 2927 if (app.persistent) { 2928 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2929 } 2930 2931 StringBuilder buf = mStringBuilder; 2932 buf.setLength(0); 2933 buf.append("Start proc "); 2934 buf.append(app.processName); 2935 buf.append(" for "); 2936 buf.append(hostingType); 2937 if (hostingNameStr != null) { 2938 buf.append(" "); 2939 buf.append(hostingNameStr); 2940 } 2941 buf.append(": pid="); 2942 buf.append(startResult.pid); 2943 buf.append(" uid="); 2944 buf.append(uid); 2945 buf.append(" gids={"); 2946 if (gids != null) { 2947 for (int gi=0; gi<gids.length; gi++) { 2948 if (gi != 0) buf.append(", "); 2949 buf.append(gids[gi]); 2950 2951 } 2952 } 2953 buf.append("}"); 2954 Slog.i(TAG, buf.toString()); 2955 app.setPid(startResult.pid); 2956 app.usingWrapper = startResult.usingWrapper; 2957 app.removed = false; 2958 synchronized (mPidsSelfLocked) { 2959 this.mPidsSelfLocked.put(startResult.pid, app); 2960 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2961 msg.obj = app; 2962 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2963 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2964 } 2965 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2966 app.processName, app.info.uid); 2967 if (app.isolated) { 2968 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2969 } 2970 } catch (RuntimeException e) { 2971 // XXX do better error recovery. 2972 app.setPid(0); 2973 Slog.e(TAG, "Failure starting process " + app.processName, e); 2974 } 2975 } 2976 2977 void updateUsageStats(ActivityRecord component, boolean resumed) { 2978 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2979 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2980 if (resumed) { 2981 mUsageStatsService.noteResumeComponent(component.realActivity); 2982 synchronized (stats) { 2983 stats.noteActivityResumedLocked(component.app.uid); 2984 } 2985 } else { 2986 mUsageStatsService.notePauseComponent(component.realActivity); 2987 synchronized (stats) { 2988 stats.noteActivityPausedLocked(component.app.uid); 2989 } 2990 } 2991 } 2992 2993 Intent getHomeIntent() { 2994 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2995 intent.setComponent(mTopComponent); 2996 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2997 intent.addCategory(Intent.CATEGORY_HOME); 2998 } 2999 return intent; 3000 } 3001 3002 boolean startHomeActivityLocked(int userId) { 3003 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 3004 && mTopAction == null) { 3005 // We are running in factory test mode, but unable to find 3006 // the factory test app, so just sit around displaying the 3007 // error message and don't try to start anything. 3008 return false; 3009 } 3010 Intent intent = getHomeIntent(); 3011 ActivityInfo aInfo = 3012 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 3013 if (aInfo != null) { 3014 intent.setComponent(new ComponentName( 3015 aInfo.applicationInfo.packageName, aInfo.name)); 3016 // Don't do this if the home app is currently being 3017 // instrumented. 3018 aInfo = new ActivityInfo(aInfo); 3019 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 3020 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 3021 aInfo.applicationInfo.uid, true); 3022 if (app == null || app.instrumentationClass == null) { 3023 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 3024 mStackSupervisor.startHomeActivity(intent, aInfo); 3025 } 3026 } 3027 3028 return true; 3029 } 3030 3031 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 3032 ActivityInfo ai = null; 3033 ComponentName comp = intent.getComponent(); 3034 try { 3035 if (comp != null) { 3036 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 3037 } else { 3038 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 3039 intent, 3040 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 3041 flags, userId); 3042 3043 if (info != null) { 3044 ai = info.activityInfo; 3045 } 3046 } 3047 } catch (RemoteException e) { 3048 // ignore 3049 } 3050 3051 return ai; 3052 } 3053 3054 /** 3055 * Starts the "new version setup screen" if appropriate. 3056 */ 3057 void startSetupActivityLocked() { 3058 // Only do this once per boot. 3059 if (mCheckedForSetup) { 3060 return; 3061 } 3062 3063 // We will show this screen if the current one is a different 3064 // version than the last one shown, and we are not running in 3065 // low-level factory test mode. 3066 final ContentResolver resolver = mContext.getContentResolver(); 3067 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 3068 Settings.Global.getInt(resolver, 3069 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 3070 mCheckedForSetup = true; 3071 3072 // See if we should be showing the platform update setup UI. 3073 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 3074 List<ResolveInfo> ris = mContext.getPackageManager() 3075 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 3076 3077 // We don't allow third party apps to replace this. 3078 ResolveInfo ri = null; 3079 for (int i=0; ris != null && i<ris.size(); i++) { 3080 if ((ris.get(i).activityInfo.applicationInfo.flags 3081 & ApplicationInfo.FLAG_SYSTEM) != 0) { 3082 ri = ris.get(i); 3083 break; 3084 } 3085 } 3086 3087 if (ri != null) { 3088 String vers = ri.activityInfo.metaData != null 3089 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 3090 : null; 3091 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 3092 vers = ri.activityInfo.applicationInfo.metaData.getString( 3093 Intent.METADATA_SETUP_VERSION); 3094 } 3095 String lastVers = Settings.Secure.getString( 3096 resolver, Settings.Secure.LAST_SETUP_SHOWN); 3097 if (vers != null && !vers.equals(lastVers)) { 3098 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 3099 intent.setComponent(new ComponentName( 3100 ri.activityInfo.packageName, ri.activityInfo.name)); 3101 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 3102 null, null, null, null, 0, 0, 0, null, 0, null, false, null, null); 3103 } 3104 } 3105 } 3106 } 3107 3108 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3109 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3110 } 3111 3112 void enforceNotIsolatedCaller(String caller) { 3113 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3114 throw new SecurityException("Isolated process not allowed to call " + caller); 3115 } 3116 } 3117 3118 @Override 3119 public int getFrontActivityScreenCompatMode() { 3120 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3121 synchronized (this) { 3122 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3123 } 3124 } 3125 3126 @Override 3127 public void setFrontActivityScreenCompatMode(int mode) { 3128 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3129 "setFrontActivityScreenCompatMode"); 3130 synchronized (this) { 3131 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3132 } 3133 } 3134 3135 @Override 3136 public int getPackageScreenCompatMode(String packageName) { 3137 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3138 synchronized (this) { 3139 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3140 } 3141 } 3142 3143 @Override 3144 public void setPackageScreenCompatMode(String packageName, int mode) { 3145 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3146 "setPackageScreenCompatMode"); 3147 synchronized (this) { 3148 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3149 } 3150 } 3151 3152 @Override 3153 public boolean getPackageAskScreenCompat(String packageName) { 3154 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3155 synchronized (this) { 3156 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3157 } 3158 } 3159 3160 @Override 3161 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3162 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3163 "setPackageAskScreenCompat"); 3164 synchronized (this) { 3165 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3166 } 3167 } 3168 3169 private void dispatchProcessesChanged() { 3170 int N; 3171 synchronized (this) { 3172 N = mPendingProcessChanges.size(); 3173 if (mActiveProcessChanges.length < N) { 3174 mActiveProcessChanges = new ProcessChangeItem[N]; 3175 } 3176 mPendingProcessChanges.toArray(mActiveProcessChanges); 3177 mAvailProcessChanges.addAll(mPendingProcessChanges); 3178 mPendingProcessChanges.clear(); 3179 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3180 } 3181 3182 int i = mProcessObservers.beginBroadcast(); 3183 while (i > 0) { 3184 i--; 3185 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3186 if (observer != null) { 3187 try { 3188 for (int j=0; j<N; j++) { 3189 ProcessChangeItem item = mActiveProcessChanges[j]; 3190 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3191 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3192 + item.pid + " uid=" + item.uid + ": " 3193 + item.foregroundActivities); 3194 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3195 item.foregroundActivities); 3196 } 3197 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) { 3198 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid=" 3199 + item.pid + " uid=" + item.uid + ": " + item.processState); 3200 observer.onProcessStateChanged(item.pid, item.uid, item.processState); 3201 } 3202 } 3203 } catch (RemoteException e) { 3204 } 3205 } 3206 } 3207 mProcessObservers.finishBroadcast(); 3208 } 3209 3210 private void dispatchProcessDied(int pid, int uid) { 3211 int i = mProcessObservers.beginBroadcast(); 3212 while (i > 0) { 3213 i--; 3214 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3215 if (observer != null) { 3216 try { 3217 observer.onProcessDied(pid, uid); 3218 } catch (RemoteException e) { 3219 } 3220 } 3221 } 3222 mProcessObservers.finishBroadcast(); 3223 } 3224 3225 final void doPendingActivityLaunchesLocked(boolean doResume) { 3226 final int N = mPendingActivityLaunches.size(); 3227 if (N <= 0) { 3228 return; 3229 } 3230 for (int i=0; i<N; i++) { 3231 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3232 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags, 3233 doResume && i == (N-1), null); 3234 } 3235 mPendingActivityLaunches.clear(); 3236 } 3237 3238 @Override 3239 public final int startActivity(IApplicationThread caller, String callingPackage, 3240 Intent intent, String resolvedType, IBinder resultTo, 3241 String resultWho, int requestCode, int startFlags, 3242 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3243 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3244 resultWho, requestCode, 3245 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3246 } 3247 3248 @Override 3249 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3250 Intent intent, String resolvedType, IBinder resultTo, 3251 String resultWho, int requestCode, int startFlags, 3252 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3253 enforceNotIsolatedCaller("startActivity"); 3254 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3255 false, true, "startActivity", null); 3256 // TODO: Switch to user app stacks here. 3257 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3258 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3259 null, null, options, userId, null); 3260 } 3261 3262 @Override 3263 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3264 Intent intent, String resolvedType, IBinder resultTo, 3265 String resultWho, int requestCode, int startFlags, String profileFile, 3266 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3267 enforceNotIsolatedCaller("startActivityAndWait"); 3268 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3269 false, true, "startActivityAndWait", null); 3270 WaitResult res = new WaitResult(); 3271 // TODO: Switch to user app stacks here. 3272 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3273 null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3274 res, null, options, UserHandle.getCallingUserId(), null); 3275 return res; 3276 } 3277 3278 @Override 3279 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3280 Intent intent, String resolvedType, IBinder resultTo, 3281 String resultWho, int requestCode, int startFlags, Configuration config, 3282 Bundle options, int userId) { 3283 enforceNotIsolatedCaller("startActivityWithConfig"); 3284 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3285 false, true, "startActivityWithConfig", null); 3286 // TODO: Switch to user app stacks here. 3287 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3288 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, 3289 null, null, null, config, options, userId, null); 3290 return ret; 3291 } 3292 3293 @Override 3294 public int startActivityIntentSender(IApplicationThread caller, 3295 IntentSender intent, Intent fillInIntent, String resolvedType, 3296 IBinder resultTo, String resultWho, int requestCode, 3297 int flagsMask, int flagsValues, Bundle options) { 3298 enforceNotIsolatedCaller("startActivityIntentSender"); 3299 // Refuse possible leaked file descriptors 3300 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3301 throw new IllegalArgumentException("File descriptors passed in Intent"); 3302 } 3303 3304 IIntentSender sender = intent.getTarget(); 3305 if (!(sender instanceof PendingIntentRecord)) { 3306 throw new IllegalArgumentException("Bad PendingIntent object"); 3307 } 3308 3309 PendingIntentRecord pir = (PendingIntentRecord)sender; 3310 3311 synchronized (this) { 3312 // If this is coming from the currently resumed activity, it is 3313 // effectively saying that app switches are allowed at this point. 3314 final ActivityStack stack = getFocusedStack(); 3315 if (stack.mResumedActivity != null && 3316 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3317 mAppSwitchesAllowedTime = 0; 3318 } 3319 } 3320 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3321 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3322 return ret; 3323 } 3324 3325 @Override 3326 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid, 3327 Intent intent, String resolvedType, IVoiceInteractionSession session, 3328 IVoiceInteractor interactor, int startFlags, String profileFile, 3329 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3330 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION) 3331 != PackageManager.PERMISSION_GRANTED) { 3332 String msg = "Permission Denial: startVoiceActivity() from pid=" 3333 + Binder.getCallingPid() 3334 + ", uid=" + Binder.getCallingUid() 3335 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION; 3336 Slog.w(TAG, msg); 3337 throw new SecurityException(msg); 3338 } 3339 if (session == null || interactor == null) { 3340 throw new NullPointerException("null session or interactor"); 3341 } 3342 userId = handleIncomingUser(callingPid, callingUid, userId, 3343 false, true, "startVoiceActivity", null); 3344 // TODO: Switch to user app stacks here. 3345 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent, 3346 resolvedType, session, interactor, null, null, 0, startFlags, 3347 profileFile, profileFd, null, null, options, userId, null); 3348 } 3349 3350 @Override 3351 public boolean startNextMatchingActivity(IBinder callingActivity, 3352 Intent intent, Bundle options) { 3353 // Refuse possible leaked file descriptors 3354 if (intent != null && intent.hasFileDescriptors() == true) { 3355 throw new IllegalArgumentException("File descriptors passed in Intent"); 3356 } 3357 3358 synchronized (this) { 3359 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3360 if (r == null) { 3361 ActivityOptions.abort(options); 3362 return false; 3363 } 3364 if (r.app == null || r.app.thread == null) { 3365 // The caller is not running... d'oh! 3366 ActivityOptions.abort(options); 3367 return false; 3368 } 3369 intent = new Intent(intent); 3370 // The caller is not allowed to change the data. 3371 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3372 // And we are resetting to find the next component... 3373 intent.setComponent(null); 3374 3375 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3376 3377 ActivityInfo aInfo = null; 3378 try { 3379 List<ResolveInfo> resolves = 3380 AppGlobals.getPackageManager().queryIntentActivities( 3381 intent, r.resolvedType, 3382 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3383 UserHandle.getCallingUserId()); 3384 3385 // Look for the original activity in the list... 3386 final int N = resolves != null ? resolves.size() : 0; 3387 for (int i=0; i<N; i++) { 3388 ResolveInfo rInfo = resolves.get(i); 3389 if (rInfo.activityInfo.packageName.equals(r.packageName) 3390 && rInfo.activityInfo.name.equals(r.info.name)) { 3391 // We found the current one... the next matching is 3392 // after it. 3393 i++; 3394 if (i<N) { 3395 aInfo = resolves.get(i).activityInfo; 3396 } 3397 if (debug) { 3398 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3399 + "/" + r.info.name); 3400 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3401 + "/" + aInfo.name); 3402 } 3403 break; 3404 } 3405 } 3406 } catch (RemoteException e) { 3407 } 3408 3409 if (aInfo == null) { 3410 // Nobody who is next! 3411 ActivityOptions.abort(options); 3412 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3413 return false; 3414 } 3415 3416 intent.setComponent(new ComponentName( 3417 aInfo.applicationInfo.packageName, aInfo.name)); 3418 intent.setFlags(intent.getFlags()&~( 3419 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3420 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3421 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3422 Intent.FLAG_ACTIVITY_NEW_TASK)); 3423 3424 // Okay now we need to start the new activity, replacing the 3425 // currently running activity. This is a little tricky because 3426 // we want to start the new one as if the current one is finished, 3427 // but not finish the current one first so that there is no flicker. 3428 // And thus... 3429 final boolean wasFinishing = r.finishing; 3430 r.finishing = true; 3431 3432 // Propagate reply information over to the new activity. 3433 final ActivityRecord resultTo = r.resultTo; 3434 final String resultWho = r.resultWho; 3435 final int requestCode = r.requestCode; 3436 r.resultTo = null; 3437 if (resultTo != null) { 3438 resultTo.removeResultsLocked(r, resultWho, requestCode); 3439 } 3440 3441 final long origId = Binder.clearCallingIdentity(); 3442 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3443 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null, 3444 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3445 options, false, null, null); 3446 Binder.restoreCallingIdentity(origId); 3447 3448 r.finishing = wasFinishing; 3449 if (res != ActivityManager.START_SUCCESS) { 3450 return false; 3451 } 3452 return true; 3453 } 3454 } 3455 3456 final int startActivityInPackage(int uid, String callingPackage, 3457 Intent intent, String resolvedType, IBinder resultTo, 3458 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3459 IActivityContainer container) { 3460 3461 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3462 false, true, "startActivityInPackage", null); 3463 3464 // TODO: Switch to user app stacks here. 3465 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3466 null, null, resultTo, resultWho, requestCode, startFlags, 3467 null, null, null, null, options, userId, container); 3468 return ret; 3469 } 3470 3471 @Override 3472 public final int startActivities(IApplicationThread caller, String callingPackage, 3473 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3474 int userId) { 3475 enforceNotIsolatedCaller("startActivities"); 3476 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3477 false, true, "startActivity", null); 3478 // TODO: Switch to user app stacks here. 3479 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3480 resolvedTypes, resultTo, options, userId); 3481 return ret; 3482 } 3483 3484 final int startActivitiesInPackage(int uid, String callingPackage, 3485 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3486 Bundle options, int userId) { 3487 3488 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3489 false, true, "startActivityInPackage", null); 3490 // TODO: Switch to user app stacks here. 3491 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3492 resultTo, options, userId); 3493 return ret; 3494 } 3495 3496 final void addRecentTaskLocked(TaskRecord task) { 3497 int N = mRecentTasks.size(); 3498 // Quick case: check if the top-most recent task is the same. 3499 if (N > 0 && mRecentTasks.get(0) == task) { 3500 return; 3501 } 3502 // Another quick case: never add voice sessions. 3503 if (task.voiceSession != null) { 3504 return; 3505 } 3506 // Remove any existing entries that are the same kind of task. 3507 final Intent intent = task.intent; 3508 final boolean document = intent != null && intent.isDocument(); 3509 for (int i=0; i<N; i++) { 3510 TaskRecord tr = mRecentTasks.get(i); 3511 if (task != tr) { 3512 if (task.userId != tr.userId) { 3513 continue; 3514 } 3515 final Intent trIntent = tr.intent; 3516 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3517 (intent == null || !intent.filterEquals(trIntent))) { 3518 continue; 3519 } 3520 if (document || trIntent != null && trIntent.isDocument()) { 3521 // Document tasks do not match other tasks. 3522 continue; 3523 } 3524 } 3525 3526 // Either task and tr are the same or, their affinities match or their intents match 3527 // and neither of them is a document. 3528 tr.disposeThumbnail(); 3529 mRecentTasks.remove(i); 3530 i--; 3531 N--; 3532 if (task.intent == null) { 3533 // If the new recent task we are adding is not fully 3534 // specified, then replace it with the existing recent task. 3535 task = tr; 3536 } 3537 } 3538 if (N >= MAX_RECENT_TASKS) { 3539 mRecentTasks.remove(N-1).disposeThumbnail(); 3540 } 3541 mRecentTasks.add(0, task); 3542 } 3543 3544 @Override 3545 public void reportActivityFullyDrawn(IBinder token) { 3546 synchronized (this) { 3547 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3548 if (r == null) { 3549 return; 3550 } 3551 r.reportFullyDrawnLocked(); 3552 } 3553 } 3554 3555 @Override 3556 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3557 synchronized (this) { 3558 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3559 if (r == null) { 3560 return; 3561 } 3562 final long origId = Binder.clearCallingIdentity(); 3563 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3564 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3565 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3566 if (config != null) { 3567 r.frozenBeforeDestroy = true; 3568 if (!updateConfigurationLocked(config, r, false, false)) { 3569 mStackSupervisor.resumeTopActivitiesLocked(); 3570 } 3571 } 3572 Binder.restoreCallingIdentity(origId); 3573 } 3574 } 3575 3576 @Override 3577 public int getRequestedOrientation(IBinder token) { 3578 synchronized (this) { 3579 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3580 if (r == null) { 3581 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3582 } 3583 return mWindowManager.getAppOrientation(r.appToken); 3584 } 3585 } 3586 3587 /** 3588 * This is the internal entry point for handling Activity.finish(). 3589 * 3590 * @param token The Binder token referencing the Activity we want to finish. 3591 * @param resultCode Result code, if any, from this Activity. 3592 * @param resultData Result data (Intent), if any, from this Activity. 3593 * @param finishTask Whether to finish the task associated with this Activity. Only applies to 3594 * the root Activity in the task. 3595 * 3596 * @return Returns true if the activity successfully finished, or false if it is still running. 3597 */ 3598 @Override 3599 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData, 3600 boolean finishTask) { 3601 // Refuse possible leaked file descriptors 3602 if (resultData != null && resultData.hasFileDescriptors() == true) { 3603 throw new IllegalArgumentException("File descriptors passed in Intent"); 3604 } 3605 3606 synchronized(this) { 3607 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3608 if (r == null) { 3609 return true; 3610 } 3611 // Keep track of the root activity of the task before we finish it 3612 TaskRecord tr = r.task; 3613 ActivityRecord rootR = tr.getRootActivity(); 3614 if (mController != null) { 3615 // Find the first activity that is not finishing. 3616 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3617 if (next != null) { 3618 // ask watcher if this is allowed 3619 boolean resumeOK = true; 3620 try { 3621 resumeOK = mController.activityResuming(next.packageName); 3622 } catch (RemoteException e) { 3623 mController = null; 3624 Watchdog.getInstance().setActivityController(null); 3625 } 3626 3627 if (!resumeOK) { 3628 return false; 3629 } 3630 } 3631 } 3632 final long origId = Binder.clearCallingIdentity(); 3633 try { 3634 boolean res; 3635 if (finishTask && r == rootR) { 3636 // If requested, remove the task that is associated to this activity only if it 3637 // was the root activity in the task. The result code and data is ignored because 3638 // we don't support returning them across task boundaries. 3639 res = removeTaskByIdLocked(tr.taskId, 0); 3640 } else { 3641 res = tr.stack.requestFinishActivityLocked(token, resultCode, 3642 resultData, "app-request", true); 3643 } 3644 return res; 3645 } finally { 3646 Binder.restoreCallingIdentity(origId); 3647 } 3648 } 3649 } 3650 3651 @Override 3652 public final void finishHeavyWeightApp() { 3653 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3654 != PackageManager.PERMISSION_GRANTED) { 3655 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3656 + Binder.getCallingPid() 3657 + ", uid=" + Binder.getCallingUid() 3658 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3659 Slog.w(TAG, msg); 3660 throw new SecurityException(msg); 3661 } 3662 3663 synchronized(this) { 3664 if (mHeavyWeightProcess == null) { 3665 return; 3666 } 3667 3668 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3669 mHeavyWeightProcess.activities); 3670 for (int i=0; i<activities.size(); i++) { 3671 ActivityRecord r = activities.get(i); 3672 if (!r.finishing) { 3673 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3674 null, "finish-heavy", true); 3675 } 3676 } 3677 3678 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3679 mHeavyWeightProcess.userId, 0)); 3680 mHeavyWeightProcess = null; 3681 } 3682 } 3683 3684 @Override 3685 public void crashApplication(int uid, int initialPid, String packageName, 3686 String message) { 3687 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3688 != PackageManager.PERMISSION_GRANTED) { 3689 String msg = "Permission Denial: crashApplication() from pid=" 3690 + Binder.getCallingPid() 3691 + ", uid=" + Binder.getCallingUid() 3692 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3693 Slog.w(TAG, msg); 3694 throw new SecurityException(msg); 3695 } 3696 3697 synchronized(this) { 3698 ProcessRecord proc = null; 3699 3700 // Figure out which process to kill. We don't trust that initialPid 3701 // still has any relation to current pids, so must scan through the 3702 // list. 3703 synchronized (mPidsSelfLocked) { 3704 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3705 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3706 if (p.uid != uid) { 3707 continue; 3708 } 3709 if (p.pid == initialPid) { 3710 proc = p; 3711 break; 3712 } 3713 if (p.pkgList.containsKey(packageName)) { 3714 proc = p; 3715 } 3716 } 3717 } 3718 3719 if (proc == null) { 3720 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3721 + " initialPid=" + initialPid 3722 + " packageName=" + packageName); 3723 return; 3724 } 3725 3726 if (proc.thread != null) { 3727 if (proc.pid == Process.myPid()) { 3728 Log.w(TAG, "crashApplication: trying to crash self!"); 3729 return; 3730 } 3731 long ident = Binder.clearCallingIdentity(); 3732 try { 3733 proc.thread.scheduleCrash(message); 3734 } catch (RemoteException e) { 3735 } 3736 Binder.restoreCallingIdentity(ident); 3737 } 3738 } 3739 } 3740 3741 @Override 3742 public final void finishSubActivity(IBinder token, String resultWho, 3743 int requestCode) { 3744 synchronized(this) { 3745 final long origId = Binder.clearCallingIdentity(); 3746 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3747 if (r != null) { 3748 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3749 } 3750 Binder.restoreCallingIdentity(origId); 3751 } 3752 } 3753 3754 @Override 3755 public boolean finishActivityAffinity(IBinder token) { 3756 synchronized(this) { 3757 final long origId = Binder.clearCallingIdentity(); 3758 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3759 boolean res = false; 3760 if (r != null) { 3761 res = r.task.stack.finishActivityAffinityLocked(r); 3762 } 3763 Binder.restoreCallingIdentity(origId); 3764 return res; 3765 } 3766 } 3767 3768 @Override 3769 public boolean willActivityBeVisible(IBinder token) { 3770 synchronized(this) { 3771 ActivityStack stack = ActivityRecord.getStackLocked(token); 3772 if (stack != null) { 3773 return stack.willActivityBeVisibleLocked(token); 3774 } 3775 return false; 3776 } 3777 } 3778 3779 @Override 3780 public void overridePendingTransition(IBinder token, String packageName, 3781 int enterAnim, int exitAnim) { 3782 synchronized(this) { 3783 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3784 if (self == null) { 3785 return; 3786 } 3787 3788 final long origId = Binder.clearCallingIdentity(); 3789 3790 if (self.state == ActivityState.RESUMED 3791 || self.state == ActivityState.PAUSING) { 3792 mWindowManager.overridePendingAppTransition(packageName, 3793 enterAnim, exitAnim, null); 3794 } 3795 3796 Binder.restoreCallingIdentity(origId); 3797 } 3798 } 3799 3800 /** 3801 * Main function for removing an existing process from the activity manager 3802 * as a result of that process going away. Clears out all connections 3803 * to the process. 3804 */ 3805 private final void handleAppDiedLocked(ProcessRecord app, 3806 boolean restarting, boolean allowRestart) { 3807 int pid = app.pid; 3808 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3809 if (!restarting) { 3810 removeLruProcessLocked(app); 3811 if (pid > 0) { 3812 ProcessList.remove(pid); 3813 } 3814 } 3815 3816 if (mProfileProc == app) { 3817 clearProfilerLocked(); 3818 } 3819 3820 // Remove this application's activities from active lists. 3821 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3822 3823 app.activities.clear(); 3824 3825 if (app.instrumentationClass != null) { 3826 Slog.w(TAG, "Crash of app " + app.processName 3827 + " running instrumentation " + app.instrumentationClass); 3828 Bundle info = new Bundle(); 3829 info.putString("shortMsg", "Process crashed."); 3830 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3831 } 3832 3833 if (!restarting) { 3834 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3835 // If there was nothing to resume, and we are not already 3836 // restarting this process, but there is a visible activity that 3837 // is hosted by the process... then make sure all visible 3838 // activities are running, taking care of restarting this 3839 // process. 3840 if (hasVisibleActivities) { 3841 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3842 } 3843 } 3844 } 3845 } 3846 3847 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3848 IBinder threadBinder = thread.asBinder(); 3849 // Find the application record. 3850 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3851 ProcessRecord rec = mLruProcesses.get(i); 3852 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3853 return i; 3854 } 3855 } 3856 return -1; 3857 } 3858 3859 final ProcessRecord getRecordForAppLocked( 3860 IApplicationThread thread) { 3861 if (thread == null) { 3862 return null; 3863 } 3864 3865 int appIndex = getLRURecordIndexForAppLocked(thread); 3866 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3867 } 3868 3869 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3870 // If there are no longer any background processes running, 3871 // and the app that died was not running instrumentation, 3872 // then tell everyone we are now low on memory. 3873 boolean haveBg = false; 3874 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3875 ProcessRecord rec = mLruProcesses.get(i); 3876 if (rec.thread != null 3877 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3878 haveBg = true; 3879 break; 3880 } 3881 } 3882 3883 if (!haveBg) { 3884 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3885 if (doReport) { 3886 long now = SystemClock.uptimeMillis(); 3887 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3888 doReport = false; 3889 } else { 3890 mLastMemUsageReportTime = now; 3891 } 3892 } 3893 final ArrayList<ProcessMemInfo> memInfos 3894 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3895 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3896 long now = SystemClock.uptimeMillis(); 3897 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3898 ProcessRecord rec = mLruProcesses.get(i); 3899 if (rec == dyingProc || rec.thread == null) { 3900 continue; 3901 } 3902 if (doReport) { 3903 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3904 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3905 } 3906 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3907 // The low memory report is overriding any current 3908 // state for a GC request. Make sure to do 3909 // heavy/important/visible/foreground processes first. 3910 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3911 rec.lastRequestedGc = 0; 3912 } else { 3913 rec.lastRequestedGc = rec.lastLowMemory; 3914 } 3915 rec.reportLowMemory = true; 3916 rec.lastLowMemory = now; 3917 mProcessesToGc.remove(rec); 3918 addProcessToGcListLocked(rec); 3919 } 3920 } 3921 if (doReport) { 3922 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3923 mHandler.sendMessage(msg); 3924 } 3925 scheduleAppGcsLocked(); 3926 } 3927 } 3928 3929 final void appDiedLocked(ProcessRecord app, int pid, 3930 IApplicationThread thread) { 3931 3932 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3933 synchronized (stats) { 3934 stats.noteProcessDiedLocked(app.info.uid, pid); 3935 } 3936 3937 // Clean up already done if the process has been re-started. 3938 if (app.pid == pid && app.thread != null && 3939 app.thread.asBinder() == thread.asBinder()) { 3940 boolean doLowMem = app.instrumentationClass == null; 3941 boolean doOomAdj = doLowMem; 3942 if (!app.killedByAm) { 3943 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3944 + ") has died."); 3945 mAllowLowerMemLevel = true; 3946 } else { 3947 // Note that we always want to do oom adj to update our state with the 3948 // new number of procs. 3949 mAllowLowerMemLevel = false; 3950 doLowMem = false; 3951 } 3952 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3953 if (DEBUG_CLEANUP) Slog.v( 3954 TAG, "Dying app: " + app + ", pid: " + pid 3955 + ", thread: " + thread.asBinder()); 3956 handleAppDiedLocked(app, false, true); 3957 3958 if (doOomAdj) { 3959 updateOomAdjLocked(); 3960 } 3961 if (doLowMem) { 3962 doLowMemReportIfNeededLocked(app); 3963 } 3964 } else if (app.pid != pid) { 3965 // A new process has already been started. 3966 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3967 + ") has died and restarted (pid " + app.pid + ")."); 3968 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3969 } else if (DEBUG_PROCESSES) { 3970 Slog.d(TAG, "Received spurious death notification for thread " 3971 + thread.asBinder()); 3972 } 3973 } 3974 3975 /** 3976 * If a stack trace dump file is configured, dump process stack traces. 3977 * @param clearTraces causes the dump file to be erased prior to the new 3978 * traces being written, if true; when false, the new traces will be 3979 * appended to any existing file content. 3980 * @param firstPids of dalvik VM processes to dump stack traces for first 3981 * @param lastPids of dalvik VM processes to dump stack traces for last 3982 * @param nativeProcs optional list of native process names to dump stack crawls 3983 * @return file containing stack traces, or null if no dump file is configured 3984 */ 3985 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3986 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3987 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3988 if (tracesPath == null || tracesPath.length() == 0) { 3989 return null; 3990 } 3991 3992 File tracesFile = new File(tracesPath); 3993 try { 3994 File tracesDir = tracesFile.getParentFile(); 3995 if (!tracesDir.exists()) { 3996 tracesFile.mkdirs(); 3997 if (!SELinux.restorecon(tracesDir)) { 3998 return null; 3999 } 4000 } 4001 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4002 4003 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 4004 tracesFile.createNewFile(); 4005 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4006 } catch (IOException e) { 4007 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 4008 return null; 4009 } 4010 4011 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 4012 return tracesFile; 4013 } 4014 4015 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 4016 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 4017 // Use a FileObserver to detect when traces finish writing. 4018 // The order of traces is considered important to maintain for legibility. 4019 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 4020 @Override 4021 public synchronized void onEvent(int event, String path) { notify(); } 4022 }; 4023 4024 try { 4025 observer.startWatching(); 4026 4027 // First collect all of the stacks of the most important pids. 4028 if (firstPids != null) { 4029 try { 4030 int num = firstPids.size(); 4031 for (int i = 0; i < num; i++) { 4032 synchronized (observer) { 4033 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 4034 observer.wait(200); // Wait for write-close, give up after 200msec 4035 } 4036 } 4037 } catch (InterruptedException e) { 4038 Log.wtf(TAG, e); 4039 } 4040 } 4041 4042 // Next collect the stacks of the native pids 4043 if (nativeProcs != null) { 4044 int[] pids = Process.getPidsForCommands(nativeProcs); 4045 if (pids != null) { 4046 for (int pid : pids) { 4047 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 4048 } 4049 } 4050 } 4051 4052 // Lastly, measure CPU usage. 4053 if (processCpuTracker != null) { 4054 processCpuTracker.init(); 4055 System.gc(); 4056 processCpuTracker.update(); 4057 try { 4058 synchronized (processCpuTracker) { 4059 processCpuTracker.wait(500); // measure over 1/2 second. 4060 } 4061 } catch (InterruptedException e) { 4062 } 4063 processCpuTracker.update(); 4064 4065 // We'll take the stack crawls of just the top apps using CPU. 4066 final int N = processCpuTracker.countWorkingStats(); 4067 int numProcs = 0; 4068 for (int i=0; i<N && numProcs<5; i++) { 4069 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 4070 if (lastPids.indexOfKey(stats.pid) >= 0) { 4071 numProcs++; 4072 try { 4073 synchronized (observer) { 4074 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 4075 observer.wait(200); // Wait for write-close, give up after 200msec 4076 } 4077 } catch (InterruptedException e) { 4078 Log.wtf(TAG, e); 4079 } 4080 4081 } 4082 } 4083 } 4084 } finally { 4085 observer.stopWatching(); 4086 } 4087 } 4088 4089 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 4090 if (true || IS_USER_BUILD) { 4091 return; 4092 } 4093 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 4094 if (tracesPath == null || tracesPath.length() == 0) { 4095 return; 4096 } 4097 4098 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 4099 StrictMode.allowThreadDiskWrites(); 4100 try { 4101 final File tracesFile = new File(tracesPath); 4102 final File tracesDir = tracesFile.getParentFile(); 4103 final File tracesTmp = new File(tracesDir, "__tmp__"); 4104 try { 4105 if (!tracesDir.exists()) { 4106 tracesFile.mkdirs(); 4107 if (!SELinux.restorecon(tracesDir.getPath())) { 4108 return; 4109 } 4110 } 4111 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 4112 4113 if (tracesFile.exists()) { 4114 tracesTmp.delete(); 4115 tracesFile.renameTo(tracesTmp); 4116 } 4117 StringBuilder sb = new StringBuilder(); 4118 Time tobj = new Time(); 4119 tobj.set(System.currentTimeMillis()); 4120 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 4121 sb.append(": "); 4122 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 4123 sb.append(" since "); 4124 sb.append(msg); 4125 FileOutputStream fos = new FileOutputStream(tracesFile); 4126 fos.write(sb.toString().getBytes()); 4127 if (app == null) { 4128 fos.write("\n*** No application process!".getBytes()); 4129 } 4130 fos.close(); 4131 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 4132 } catch (IOException e) { 4133 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 4134 return; 4135 } 4136 4137 if (app != null) { 4138 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 4139 firstPids.add(app.pid); 4140 dumpStackTraces(tracesPath, firstPids, null, null, null); 4141 } 4142 4143 File lastTracesFile = null; 4144 File curTracesFile = null; 4145 for (int i=9; i>=0; i--) { 4146 String name = String.format(Locale.US, "slow%02d.txt", i); 4147 curTracesFile = new File(tracesDir, name); 4148 if (curTracesFile.exists()) { 4149 if (lastTracesFile != null) { 4150 curTracesFile.renameTo(lastTracesFile); 4151 } else { 4152 curTracesFile.delete(); 4153 } 4154 } 4155 lastTracesFile = curTracesFile; 4156 } 4157 tracesFile.renameTo(curTracesFile); 4158 if (tracesTmp.exists()) { 4159 tracesTmp.renameTo(tracesFile); 4160 } 4161 } finally { 4162 StrictMode.setThreadPolicy(oldPolicy); 4163 } 4164 } 4165 4166 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4167 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4168 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4169 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4170 4171 if (mController != null) { 4172 try { 4173 // 0 == continue, -1 = kill process immediately 4174 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4175 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4176 } catch (RemoteException e) { 4177 mController = null; 4178 Watchdog.getInstance().setActivityController(null); 4179 } 4180 } 4181 4182 long anrTime = SystemClock.uptimeMillis(); 4183 if (MONITOR_CPU_USAGE) { 4184 updateCpuStatsNow(); 4185 } 4186 4187 synchronized (this) { 4188 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4189 if (mShuttingDown) { 4190 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4191 return; 4192 } else if (app.notResponding) { 4193 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4194 return; 4195 } else if (app.crashing) { 4196 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4197 return; 4198 } 4199 4200 // In case we come through here for the same app before completing 4201 // this one, mark as anring now so we will bail out. 4202 app.notResponding = true; 4203 4204 // Log the ANR to the event log. 4205 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4206 app.processName, app.info.flags, annotation); 4207 4208 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4209 firstPids.add(app.pid); 4210 4211 int parentPid = app.pid; 4212 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4213 if (parentPid != app.pid) firstPids.add(parentPid); 4214 4215 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4216 4217 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4218 ProcessRecord r = mLruProcesses.get(i); 4219 if (r != null && r.thread != null) { 4220 int pid = r.pid; 4221 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4222 if (r.persistent) { 4223 firstPids.add(pid); 4224 } else { 4225 lastPids.put(pid, Boolean.TRUE); 4226 } 4227 } 4228 } 4229 } 4230 } 4231 4232 // Log the ANR to the main log. 4233 StringBuilder info = new StringBuilder(); 4234 info.setLength(0); 4235 info.append("ANR in ").append(app.processName); 4236 if (activity != null && activity.shortComponentName != null) { 4237 info.append(" (").append(activity.shortComponentName).append(")"); 4238 } 4239 info.append("\n"); 4240 info.append("PID: ").append(app.pid).append("\n"); 4241 if (annotation != null) { 4242 info.append("Reason: ").append(annotation).append("\n"); 4243 } 4244 if (parent != null && parent != activity) { 4245 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4246 } 4247 4248 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4249 4250 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4251 NATIVE_STACKS_OF_INTEREST); 4252 4253 String cpuInfo = null; 4254 if (MONITOR_CPU_USAGE) { 4255 updateCpuStatsNow(); 4256 synchronized (mProcessCpuThread) { 4257 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4258 } 4259 info.append(processCpuTracker.printCurrentLoad()); 4260 info.append(cpuInfo); 4261 } 4262 4263 info.append(processCpuTracker.printCurrentState(anrTime)); 4264 4265 Slog.e(TAG, info.toString()); 4266 if (tracesFile == null) { 4267 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4268 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4269 } 4270 4271 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4272 cpuInfo, tracesFile, null); 4273 4274 if (mController != null) { 4275 try { 4276 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4277 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4278 if (res != 0) { 4279 if (res < 0 && app.pid != MY_PID) { 4280 Process.killProcess(app.pid); 4281 } else { 4282 synchronized (this) { 4283 mServices.scheduleServiceTimeoutLocked(app); 4284 } 4285 } 4286 return; 4287 } 4288 } catch (RemoteException e) { 4289 mController = null; 4290 Watchdog.getInstance().setActivityController(null); 4291 } 4292 } 4293 4294 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4295 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4296 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4297 4298 synchronized (this) { 4299 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4300 killUnneededProcessLocked(app, "background ANR"); 4301 return; 4302 } 4303 4304 // Set the app's notResponding state, and look up the errorReportReceiver 4305 makeAppNotRespondingLocked(app, 4306 activity != null ? activity.shortComponentName : null, 4307 annotation != null ? "ANR " + annotation : "ANR", 4308 info.toString()); 4309 4310 // Bring up the infamous App Not Responding dialog 4311 Message msg = Message.obtain(); 4312 HashMap<String, Object> map = new HashMap<String, Object>(); 4313 msg.what = SHOW_NOT_RESPONDING_MSG; 4314 msg.obj = map; 4315 msg.arg1 = aboveSystem ? 1 : 0; 4316 map.put("app", app); 4317 if (activity != null) { 4318 map.put("activity", activity); 4319 } 4320 4321 mHandler.sendMessage(msg); 4322 } 4323 } 4324 4325 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4326 if (!mLaunchWarningShown) { 4327 mLaunchWarningShown = true; 4328 mHandler.post(new Runnable() { 4329 @Override 4330 public void run() { 4331 synchronized (ActivityManagerService.this) { 4332 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4333 d.show(); 4334 mHandler.postDelayed(new Runnable() { 4335 @Override 4336 public void run() { 4337 synchronized (ActivityManagerService.this) { 4338 d.dismiss(); 4339 mLaunchWarningShown = false; 4340 } 4341 } 4342 }, 4000); 4343 } 4344 } 4345 }); 4346 } 4347 } 4348 4349 @Override 4350 public boolean clearApplicationUserData(final String packageName, 4351 final IPackageDataObserver observer, int userId) { 4352 enforceNotIsolatedCaller("clearApplicationUserData"); 4353 int uid = Binder.getCallingUid(); 4354 int pid = Binder.getCallingPid(); 4355 userId = handleIncomingUser(pid, uid, 4356 userId, false, true, "clearApplicationUserData", null); 4357 long callingId = Binder.clearCallingIdentity(); 4358 try { 4359 IPackageManager pm = AppGlobals.getPackageManager(); 4360 int pkgUid = -1; 4361 synchronized(this) { 4362 try { 4363 pkgUid = pm.getPackageUid(packageName, userId); 4364 } catch (RemoteException e) { 4365 } 4366 if (pkgUid == -1) { 4367 Slog.w(TAG, "Invalid packageName: " + packageName); 4368 if (observer != null) { 4369 try { 4370 observer.onRemoveCompleted(packageName, false); 4371 } catch (RemoteException e) { 4372 Slog.i(TAG, "Observer no longer exists."); 4373 } 4374 } 4375 return false; 4376 } 4377 if (uid == pkgUid || checkComponentPermission( 4378 android.Manifest.permission.CLEAR_APP_USER_DATA, 4379 pid, uid, -1, true) 4380 == PackageManager.PERMISSION_GRANTED) { 4381 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4382 } else { 4383 throw new SecurityException("PID " + pid + " does not have permission " 4384 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4385 + " of package " + packageName); 4386 } 4387 } 4388 4389 try { 4390 // Clear application user data 4391 pm.clearApplicationUserData(packageName, observer, userId); 4392 4393 // Remove all permissions granted from/to this package 4394 removeUriPermissionsForPackageLocked(packageName, userId, true); 4395 4396 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4397 Uri.fromParts("package", packageName, null)); 4398 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4399 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4400 null, null, 0, null, null, null, false, false, userId); 4401 } catch (RemoteException e) { 4402 } 4403 } finally { 4404 Binder.restoreCallingIdentity(callingId); 4405 } 4406 return true; 4407 } 4408 4409 @Override 4410 public void killBackgroundProcesses(final String packageName, int userId) { 4411 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4412 != PackageManager.PERMISSION_GRANTED && 4413 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4414 != PackageManager.PERMISSION_GRANTED) { 4415 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4416 + Binder.getCallingPid() 4417 + ", uid=" + Binder.getCallingUid() 4418 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4419 Slog.w(TAG, msg); 4420 throw new SecurityException(msg); 4421 } 4422 4423 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4424 userId, true, true, "killBackgroundProcesses", null); 4425 long callingId = Binder.clearCallingIdentity(); 4426 try { 4427 IPackageManager pm = AppGlobals.getPackageManager(); 4428 synchronized(this) { 4429 int appId = -1; 4430 try { 4431 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4432 } catch (RemoteException e) { 4433 } 4434 if (appId == -1) { 4435 Slog.w(TAG, "Invalid packageName: " + packageName); 4436 return; 4437 } 4438 killPackageProcessesLocked(packageName, appId, userId, 4439 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4440 } 4441 } finally { 4442 Binder.restoreCallingIdentity(callingId); 4443 } 4444 } 4445 4446 @Override 4447 public void killAllBackgroundProcesses() { 4448 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4449 != PackageManager.PERMISSION_GRANTED) { 4450 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4451 + Binder.getCallingPid() 4452 + ", uid=" + Binder.getCallingUid() 4453 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4454 Slog.w(TAG, msg); 4455 throw new SecurityException(msg); 4456 } 4457 4458 long callingId = Binder.clearCallingIdentity(); 4459 try { 4460 synchronized(this) { 4461 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4462 final int NP = mProcessNames.getMap().size(); 4463 for (int ip=0; ip<NP; ip++) { 4464 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4465 final int NA = apps.size(); 4466 for (int ia=0; ia<NA; ia++) { 4467 ProcessRecord app = apps.valueAt(ia); 4468 if (app.persistent) { 4469 // we don't kill persistent processes 4470 continue; 4471 } 4472 if (app.removed) { 4473 procs.add(app); 4474 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4475 app.removed = true; 4476 procs.add(app); 4477 } 4478 } 4479 } 4480 4481 int N = procs.size(); 4482 for (int i=0; i<N; i++) { 4483 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4484 } 4485 mAllowLowerMemLevel = true; 4486 updateOomAdjLocked(); 4487 doLowMemReportIfNeededLocked(null); 4488 } 4489 } finally { 4490 Binder.restoreCallingIdentity(callingId); 4491 } 4492 } 4493 4494 @Override 4495 public void forceStopPackage(final String packageName, int userId) { 4496 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4497 != PackageManager.PERMISSION_GRANTED) { 4498 String msg = "Permission Denial: forceStopPackage() from pid=" 4499 + Binder.getCallingPid() 4500 + ", uid=" + Binder.getCallingUid() 4501 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4502 Slog.w(TAG, msg); 4503 throw new SecurityException(msg); 4504 } 4505 final int callingPid = Binder.getCallingPid(); 4506 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4507 userId, true, true, "forceStopPackage", null); 4508 long callingId = Binder.clearCallingIdentity(); 4509 try { 4510 IPackageManager pm = AppGlobals.getPackageManager(); 4511 synchronized(this) { 4512 int[] users = userId == UserHandle.USER_ALL 4513 ? getUsersLocked() : new int[] { userId }; 4514 for (int user : users) { 4515 int pkgUid = -1; 4516 try { 4517 pkgUid = pm.getPackageUid(packageName, user); 4518 } catch (RemoteException e) { 4519 } 4520 if (pkgUid == -1) { 4521 Slog.w(TAG, "Invalid packageName: " + packageName); 4522 continue; 4523 } 4524 try { 4525 pm.setPackageStoppedState(packageName, true, user); 4526 } catch (RemoteException e) { 4527 } catch (IllegalArgumentException e) { 4528 Slog.w(TAG, "Failed trying to unstop package " 4529 + packageName + ": " + e); 4530 } 4531 if (isUserRunningLocked(user, false)) { 4532 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4533 } 4534 } 4535 } 4536 } finally { 4537 Binder.restoreCallingIdentity(callingId); 4538 } 4539 } 4540 4541 /* 4542 * The pkg name and app id have to be specified. 4543 */ 4544 @Override 4545 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4546 if (pkg == null) { 4547 return; 4548 } 4549 // Make sure the uid is valid. 4550 if (appid < 0) { 4551 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4552 return; 4553 } 4554 int callerUid = Binder.getCallingUid(); 4555 // Only the system server can kill an application 4556 if (callerUid == Process.SYSTEM_UID) { 4557 // Post an aysnc message to kill the application 4558 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4559 msg.arg1 = appid; 4560 msg.arg2 = 0; 4561 Bundle bundle = new Bundle(); 4562 bundle.putString("pkg", pkg); 4563 bundle.putString("reason", reason); 4564 msg.obj = bundle; 4565 mHandler.sendMessage(msg); 4566 } else { 4567 throw new SecurityException(callerUid + " cannot kill pkg: " + 4568 pkg); 4569 } 4570 } 4571 4572 @Override 4573 public void closeSystemDialogs(String reason) { 4574 enforceNotIsolatedCaller("closeSystemDialogs"); 4575 4576 final int pid = Binder.getCallingPid(); 4577 final int uid = Binder.getCallingUid(); 4578 final long origId = Binder.clearCallingIdentity(); 4579 try { 4580 synchronized (this) { 4581 // Only allow this from foreground processes, so that background 4582 // applications can't abuse it to prevent system UI from being shown. 4583 if (uid >= Process.FIRST_APPLICATION_UID) { 4584 ProcessRecord proc; 4585 synchronized (mPidsSelfLocked) { 4586 proc = mPidsSelfLocked.get(pid); 4587 } 4588 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4589 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4590 + " from background process " + proc); 4591 return; 4592 } 4593 } 4594 closeSystemDialogsLocked(reason); 4595 } 4596 } finally { 4597 Binder.restoreCallingIdentity(origId); 4598 } 4599 } 4600 4601 void closeSystemDialogsLocked(String reason) { 4602 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4603 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4604 | Intent.FLAG_RECEIVER_FOREGROUND); 4605 if (reason != null) { 4606 intent.putExtra("reason", reason); 4607 } 4608 mWindowManager.closeSystemDialogs(reason); 4609 4610 mStackSupervisor.closeSystemDialogsLocked(); 4611 4612 broadcastIntentLocked(null, null, intent, null, 4613 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4614 Process.SYSTEM_UID, UserHandle.USER_ALL); 4615 } 4616 4617 @Override 4618 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4619 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4620 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4621 for (int i=pids.length-1; i>=0; i--) { 4622 ProcessRecord proc; 4623 int oomAdj; 4624 synchronized (this) { 4625 synchronized (mPidsSelfLocked) { 4626 proc = mPidsSelfLocked.get(pids[i]); 4627 oomAdj = proc != null ? proc.setAdj : 0; 4628 } 4629 } 4630 infos[i] = new Debug.MemoryInfo(); 4631 Debug.getMemoryInfo(pids[i], infos[i]); 4632 if (proc != null) { 4633 synchronized (this) { 4634 if (proc.thread != null && proc.setAdj == oomAdj) { 4635 // Record this for posterity if the process has been stable. 4636 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4637 infos[i].getTotalUss(), false, proc.pkgList); 4638 } 4639 } 4640 } 4641 } 4642 return infos; 4643 } 4644 4645 @Override 4646 public long[] getProcessPss(int[] pids) { 4647 enforceNotIsolatedCaller("getProcessPss"); 4648 long[] pss = new long[pids.length]; 4649 for (int i=pids.length-1; i>=0; i--) { 4650 ProcessRecord proc; 4651 int oomAdj; 4652 synchronized (this) { 4653 synchronized (mPidsSelfLocked) { 4654 proc = mPidsSelfLocked.get(pids[i]); 4655 oomAdj = proc != null ? proc.setAdj : 0; 4656 } 4657 } 4658 long[] tmpUss = new long[1]; 4659 pss[i] = Debug.getPss(pids[i], tmpUss); 4660 if (proc != null) { 4661 synchronized (this) { 4662 if (proc.thread != null && proc.setAdj == oomAdj) { 4663 // Record this for posterity if the process has been stable. 4664 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4665 } 4666 } 4667 } 4668 } 4669 return pss; 4670 } 4671 4672 @Override 4673 public void killApplicationProcess(String processName, int uid) { 4674 if (processName == null) { 4675 return; 4676 } 4677 4678 int callerUid = Binder.getCallingUid(); 4679 // Only the system server can kill an application 4680 if (callerUid == Process.SYSTEM_UID) { 4681 synchronized (this) { 4682 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4683 if (app != null && app.thread != null) { 4684 try { 4685 app.thread.scheduleSuicide(); 4686 } catch (RemoteException e) { 4687 // If the other end already died, then our work here is done. 4688 } 4689 } else { 4690 Slog.w(TAG, "Process/uid not found attempting kill of " 4691 + processName + " / " + uid); 4692 } 4693 } 4694 } else { 4695 throw new SecurityException(callerUid + " cannot kill app process: " + 4696 processName); 4697 } 4698 } 4699 4700 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4701 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4702 false, true, false, false, UserHandle.getUserId(uid), reason); 4703 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4704 Uri.fromParts("package", packageName, null)); 4705 if (!mProcessesReady) { 4706 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4707 | Intent.FLAG_RECEIVER_FOREGROUND); 4708 } 4709 intent.putExtra(Intent.EXTRA_UID, uid); 4710 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4711 broadcastIntentLocked(null, null, intent, 4712 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4713 false, false, 4714 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4715 } 4716 4717 private void forceStopUserLocked(int userId, String reason) { 4718 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4719 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4720 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4721 | Intent.FLAG_RECEIVER_FOREGROUND); 4722 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4723 broadcastIntentLocked(null, null, intent, 4724 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4725 false, false, 4726 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4727 } 4728 4729 private final boolean killPackageProcessesLocked(String packageName, int appId, 4730 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4731 boolean doit, boolean evenPersistent, String reason) { 4732 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4733 4734 // Remove all processes this package may have touched: all with the 4735 // same UID (except for the system or root user), and all whose name 4736 // matches the package name. 4737 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4738 final int NP = mProcessNames.getMap().size(); 4739 for (int ip=0; ip<NP; ip++) { 4740 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4741 final int NA = apps.size(); 4742 for (int ia=0; ia<NA; ia++) { 4743 ProcessRecord app = apps.valueAt(ia); 4744 if (app.persistent && !evenPersistent) { 4745 // we don't kill persistent processes 4746 continue; 4747 } 4748 if (app.removed) { 4749 if (doit) { 4750 procs.add(app); 4751 } 4752 continue; 4753 } 4754 4755 // Skip process if it doesn't meet our oom adj requirement. 4756 if (app.setAdj < minOomAdj) { 4757 continue; 4758 } 4759 4760 // If no package is specified, we call all processes under the 4761 // give user id. 4762 if (packageName == null) { 4763 if (app.userId != userId) { 4764 continue; 4765 } 4766 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4767 continue; 4768 } 4769 // Package has been specified, we want to hit all processes 4770 // that match it. We need to qualify this by the processes 4771 // that are running under the specified app and user ID. 4772 } else { 4773 if (UserHandle.getAppId(app.uid) != appId) { 4774 continue; 4775 } 4776 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4777 continue; 4778 } 4779 if (!app.pkgList.containsKey(packageName)) { 4780 continue; 4781 } 4782 } 4783 4784 // Process has passed all conditions, kill it! 4785 if (!doit) { 4786 return true; 4787 } 4788 app.removed = true; 4789 procs.add(app); 4790 } 4791 } 4792 4793 int N = procs.size(); 4794 for (int i=0; i<N; i++) { 4795 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4796 } 4797 updateOomAdjLocked(); 4798 return N > 0; 4799 } 4800 4801 private final boolean forceStopPackageLocked(String name, int appId, 4802 boolean callerWillRestart, boolean purgeCache, boolean doit, 4803 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4804 int i; 4805 int N; 4806 4807 if (userId == UserHandle.USER_ALL && name == null) { 4808 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4809 } 4810 4811 if (appId < 0 && name != null) { 4812 try { 4813 appId = UserHandle.getAppId( 4814 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4815 } catch (RemoteException e) { 4816 } 4817 } 4818 4819 if (doit) { 4820 if (name != null) { 4821 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4822 + " user=" + userId + ": " + reason); 4823 } else { 4824 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4825 } 4826 4827 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4828 for (int ip=pmap.size()-1; ip>=0; ip--) { 4829 SparseArray<Long> ba = pmap.valueAt(ip); 4830 for (i=ba.size()-1; i>=0; i--) { 4831 boolean remove = false; 4832 final int entUid = ba.keyAt(i); 4833 if (name != null) { 4834 if (userId == UserHandle.USER_ALL) { 4835 if (UserHandle.getAppId(entUid) == appId) { 4836 remove = true; 4837 } 4838 } else { 4839 if (entUid == UserHandle.getUid(userId, appId)) { 4840 remove = true; 4841 } 4842 } 4843 } else if (UserHandle.getUserId(entUid) == userId) { 4844 remove = true; 4845 } 4846 if (remove) { 4847 ba.removeAt(i); 4848 } 4849 } 4850 if (ba.size() == 0) { 4851 pmap.removeAt(ip); 4852 } 4853 } 4854 } 4855 4856 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4857 -100, callerWillRestart, true, doit, evenPersistent, 4858 name == null ? ("stop user " + userId) : ("stop " + name)); 4859 4860 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4861 if (!doit) { 4862 return true; 4863 } 4864 didSomething = true; 4865 } 4866 4867 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4868 if (!doit) { 4869 return true; 4870 } 4871 didSomething = true; 4872 } 4873 4874 if (name == null) { 4875 // Remove all sticky broadcasts from this user. 4876 mStickyBroadcasts.remove(userId); 4877 } 4878 4879 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4880 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4881 userId, providers)) { 4882 if (!doit) { 4883 return true; 4884 } 4885 didSomething = true; 4886 } 4887 N = providers.size(); 4888 for (i=0; i<N; i++) { 4889 removeDyingProviderLocked(null, providers.get(i), true); 4890 } 4891 4892 // Remove transient permissions granted from/to this package/user 4893 removeUriPermissionsForPackageLocked(name, userId, false); 4894 4895 if (name == null || uninstalling) { 4896 // Remove pending intents. For now we only do this when force 4897 // stopping users, because we have some problems when doing this 4898 // for packages -- app widgets are not currently cleaned up for 4899 // such packages, so they can be left with bad pending intents. 4900 if (mIntentSenderRecords.size() > 0) { 4901 Iterator<WeakReference<PendingIntentRecord>> it 4902 = mIntentSenderRecords.values().iterator(); 4903 while (it.hasNext()) { 4904 WeakReference<PendingIntentRecord> wpir = it.next(); 4905 if (wpir == null) { 4906 it.remove(); 4907 continue; 4908 } 4909 PendingIntentRecord pir = wpir.get(); 4910 if (pir == null) { 4911 it.remove(); 4912 continue; 4913 } 4914 if (name == null) { 4915 // Stopping user, remove all objects for the user. 4916 if (pir.key.userId != userId) { 4917 // Not the same user, skip it. 4918 continue; 4919 } 4920 } else { 4921 if (UserHandle.getAppId(pir.uid) != appId) { 4922 // Different app id, skip it. 4923 continue; 4924 } 4925 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4926 // Different user, skip it. 4927 continue; 4928 } 4929 if (!pir.key.packageName.equals(name)) { 4930 // Different package, skip it. 4931 continue; 4932 } 4933 } 4934 if (!doit) { 4935 return true; 4936 } 4937 didSomething = true; 4938 it.remove(); 4939 pir.canceled = true; 4940 if (pir.key.activity != null) { 4941 pir.key.activity.pendingResults.remove(pir.ref); 4942 } 4943 } 4944 } 4945 } 4946 4947 if (doit) { 4948 if (purgeCache && name != null) { 4949 AttributeCache ac = AttributeCache.instance(); 4950 if (ac != null) { 4951 ac.removePackage(name); 4952 } 4953 } 4954 if (mBooted) { 4955 mStackSupervisor.resumeTopActivitiesLocked(); 4956 mStackSupervisor.scheduleIdleLocked(); 4957 } 4958 } 4959 4960 return didSomething; 4961 } 4962 4963 private final boolean removeProcessLocked(ProcessRecord app, 4964 boolean callerWillRestart, boolean allowRestart, String reason) { 4965 final String name = app.processName; 4966 final int uid = app.uid; 4967 if (DEBUG_PROCESSES) Slog.d( 4968 TAG, "Force removing proc " + app.toShortString() + " (" + name 4969 + "/" + uid + ")"); 4970 4971 mProcessNames.remove(name, uid); 4972 mIsolatedProcesses.remove(app.uid); 4973 if (mHeavyWeightProcess == app) { 4974 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4975 mHeavyWeightProcess.userId, 0)); 4976 mHeavyWeightProcess = null; 4977 } 4978 boolean needRestart = false; 4979 if (app.pid > 0 && app.pid != MY_PID) { 4980 int pid = app.pid; 4981 synchronized (mPidsSelfLocked) { 4982 mPidsSelfLocked.remove(pid); 4983 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4984 } 4985 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4986 app.processName, app.info.uid); 4987 if (app.isolated) { 4988 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4989 } 4990 killUnneededProcessLocked(app, reason); 4991 handleAppDiedLocked(app, true, allowRestart); 4992 removeLruProcessLocked(app); 4993 4994 if (app.persistent && !app.isolated) { 4995 if (!callerWillRestart) { 4996 addAppLocked(app.info, false); 4997 } else { 4998 needRestart = true; 4999 } 5000 } 5001 } else { 5002 mRemovedProcesses.add(app); 5003 } 5004 5005 return needRestart; 5006 } 5007 5008 private final void processStartTimedOutLocked(ProcessRecord app) { 5009 final int pid = app.pid; 5010 boolean gone = false; 5011 synchronized (mPidsSelfLocked) { 5012 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 5013 if (knownApp != null && knownApp.thread == null) { 5014 mPidsSelfLocked.remove(pid); 5015 gone = true; 5016 } 5017 } 5018 5019 if (gone) { 5020 Slog.w(TAG, "Process " + app + " failed to attach"); 5021 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 5022 pid, app.uid, app.processName); 5023 mProcessNames.remove(app.processName, app.uid); 5024 mIsolatedProcesses.remove(app.uid); 5025 if (mHeavyWeightProcess == app) { 5026 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 5027 mHeavyWeightProcess.userId, 0)); 5028 mHeavyWeightProcess = null; 5029 } 5030 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 5031 app.processName, app.info.uid); 5032 if (app.isolated) { 5033 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 5034 } 5035 // Take care of any launching providers waiting for this process. 5036 checkAppInLaunchingProvidersLocked(app, true); 5037 // Take care of any services that are waiting for the process. 5038 mServices.processStartTimedOutLocked(app); 5039 killUnneededProcessLocked(app, "start timeout"); 5040 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 5041 Slog.w(TAG, "Unattached app died before backup, skipping"); 5042 try { 5043 IBackupManager bm = IBackupManager.Stub.asInterface( 5044 ServiceManager.getService(Context.BACKUP_SERVICE)); 5045 bm.agentDisconnected(app.info.packageName); 5046 } catch (RemoteException e) { 5047 // Can't happen; the backup manager is local 5048 } 5049 } 5050 if (isPendingBroadcastProcessLocked(pid)) { 5051 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 5052 skipPendingBroadcastLocked(pid); 5053 } 5054 } else { 5055 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 5056 } 5057 } 5058 5059 private final boolean attachApplicationLocked(IApplicationThread thread, 5060 int pid) { 5061 5062 // Find the application record that is being attached... either via 5063 // the pid if we are running in multiple processes, or just pull the 5064 // next app record if we are emulating process with anonymous threads. 5065 ProcessRecord app; 5066 if (pid != MY_PID && pid >= 0) { 5067 synchronized (mPidsSelfLocked) { 5068 app = mPidsSelfLocked.get(pid); 5069 } 5070 } else { 5071 app = null; 5072 } 5073 5074 if (app == null) { 5075 Slog.w(TAG, "No pending application record for pid " + pid 5076 + " (IApplicationThread " + thread + "); dropping process"); 5077 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 5078 if (pid > 0 && pid != MY_PID) { 5079 Process.killProcessQuiet(pid); 5080 } else { 5081 try { 5082 thread.scheduleExit(); 5083 } catch (Exception e) { 5084 // Ignore exceptions. 5085 } 5086 } 5087 return false; 5088 } 5089 5090 // If this application record is still attached to a previous 5091 // process, clean it up now. 5092 if (app.thread != null) { 5093 handleAppDiedLocked(app, true, true); 5094 } 5095 5096 // Tell the process all about itself. 5097 5098 if (localLOGV) Slog.v( 5099 TAG, "Binding process pid " + pid + " to record " + app); 5100 5101 final String processName = app.processName; 5102 try { 5103 AppDeathRecipient adr = new AppDeathRecipient( 5104 app, pid, thread); 5105 thread.asBinder().linkToDeath(adr, 0); 5106 app.deathRecipient = adr; 5107 } catch (RemoteException e) { 5108 app.resetPackageList(mProcessStats); 5109 startProcessLocked(app, "link fail", processName); 5110 return false; 5111 } 5112 5113 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 5114 5115 app.makeActive(thread, mProcessStats); 5116 app.curAdj = app.setAdj = -100; 5117 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 5118 app.forcingToForeground = null; 5119 updateProcessForegroundLocked(app, false, false); 5120 app.hasShownUi = false; 5121 app.debugging = false; 5122 app.cached = false; 5123 5124 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 5125 5126 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 5127 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 5128 5129 if (!normalMode) { 5130 Slog.i(TAG, "Launching preboot mode app: " + app); 5131 } 5132 5133 if (localLOGV) Slog.v( 5134 TAG, "New app record " + app 5135 + " thread=" + thread.asBinder() + " pid=" + pid); 5136 try { 5137 int testMode = IApplicationThread.DEBUG_OFF; 5138 if (mDebugApp != null && mDebugApp.equals(processName)) { 5139 testMode = mWaitForDebugger 5140 ? IApplicationThread.DEBUG_WAIT 5141 : IApplicationThread.DEBUG_ON; 5142 app.debugging = true; 5143 if (mDebugTransient) { 5144 mDebugApp = mOrigDebugApp; 5145 mWaitForDebugger = mOrigWaitForDebugger; 5146 } 5147 } 5148 String profileFile = app.instrumentationProfileFile; 5149 ParcelFileDescriptor profileFd = null; 5150 boolean profileAutoStop = false; 5151 if (mProfileApp != null && mProfileApp.equals(processName)) { 5152 mProfileProc = app; 5153 profileFile = mProfileFile; 5154 profileFd = mProfileFd; 5155 profileAutoStop = mAutoStopProfiler; 5156 } 5157 boolean enableOpenGlTrace = false; 5158 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5159 enableOpenGlTrace = true; 5160 mOpenGlTraceApp = null; 5161 } 5162 5163 // If the app is being launched for restore or full backup, set it up specially 5164 boolean isRestrictedBackupMode = false; 5165 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5166 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5167 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5168 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5169 } 5170 5171 ensurePackageDexOpt(app.instrumentationInfo != null 5172 ? app.instrumentationInfo.packageName 5173 : app.info.packageName); 5174 if (app.instrumentationClass != null) { 5175 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5176 } 5177 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5178 + processName + " with config " + mConfiguration); 5179 ApplicationInfo appInfo = app.instrumentationInfo != null 5180 ? app.instrumentationInfo : app.info; 5181 app.compat = compatibilityInfoForPackageLocked(appInfo); 5182 if (profileFd != null) { 5183 profileFd = profileFd.dup(); 5184 } 5185 thread.bindApplication(processName, appInfo, providers, 5186 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5187 app.instrumentationArguments, app.instrumentationWatcher, 5188 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5189 isRestrictedBackupMode || !normalMode, app.persistent, 5190 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5191 mCoreSettingsObserver.getCoreSettingsLocked()); 5192 updateLruProcessLocked(app, false, null); 5193 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5194 } catch (Exception e) { 5195 // todo: Yikes! What should we do? For now we will try to 5196 // start another process, but that could easily get us in 5197 // an infinite loop of restarting processes... 5198 Slog.w(TAG, "Exception thrown during bind!", e); 5199 5200 app.resetPackageList(mProcessStats); 5201 app.unlinkDeathRecipient(); 5202 startProcessLocked(app, "bind fail", processName); 5203 return false; 5204 } 5205 5206 // Remove this record from the list of starting applications. 5207 mPersistentStartingProcesses.remove(app); 5208 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5209 "Attach application locked removing on hold: " + app); 5210 mProcessesOnHold.remove(app); 5211 5212 boolean badApp = false; 5213 boolean didSomething = false; 5214 5215 // See if the top visible activity is waiting to run in this process... 5216 if (normalMode) { 5217 try { 5218 if (mStackSupervisor.attachApplicationLocked(app)) { 5219 didSomething = true; 5220 } 5221 } catch (Exception e) { 5222 badApp = true; 5223 } 5224 } 5225 5226 // Find any services that should be running in this process... 5227 if (!badApp) { 5228 try { 5229 didSomething |= mServices.attachApplicationLocked(app, processName); 5230 } catch (Exception e) { 5231 badApp = true; 5232 } 5233 } 5234 5235 // Check if a next-broadcast receiver is in this process... 5236 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5237 try { 5238 didSomething |= sendPendingBroadcastsLocked(app); 5239 } catch (Exception e) { 5240 // If the app died trying to launch the receiver we declare it 'bad' 5241 badApp = true; 5242 } 5243 } 5244 5245 // Check whether the next backup agent is in this process... 5246 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5247 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5248 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5249 try { 5250 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5251 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5252 mBackupTarget.backupMode); 5253 } catch (Exception e) { 5254 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5255 e.printStackTrace(); 5256 } 5257 } 5258 5259 if (badApp) { 5260 // todo: Also need to kill application to deal with all 5261 // kinds of exceptions. 5262 handleAppDiedLocked(app, false, true); 5263 return false; 5264 } 5265 5266 if (!didSomething) { 5267 updateOomAdjLocked(); 5268 } 5269 5270 return true; 5271 } 5272 5273 @Override 5274 public final void attachApplication(IApplicationThread thread) { 5275 synchronized (this) { 5276 int callingPid = Binder.getCallingPid(); 5277 final long origId = Binder.clearCallingIdentity(); 5278 attachApplicationLocked(thread, callingPid); 5279 Binder.restoreCallingIdentity(origId); 5280 } 5281 } 5282 5283 @Override 5284 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5285 final long origId = Binder.clearCallingIdentity(); 5286 synchronized (this) { 5287 ActivityStack stack = ActivityRecord.getStackLocked(token); 5288 if (stack != null) { 5289 ActivityRecord r = 5290 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5291 if (stopProfiling) { 5292 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5293 try { 5294 mProfileFd.close(); 5295 } catch (IOException e) { 5296 } 5297 clearProfilerLocked(); 5298 } 5299 } 5300 } 5301 } 5302 Binder.restoreCallingIdentity(origId); 5303 } 5304 5305 void enableScreenAfterBoot() { 5306 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5307 SystemClock.uptimeMillis()); 5308 mWindowManager.enableScreenAfterBoot(); 5309 5310 synchronized (this) { 5311 updateEventDispatchingLocked(); 5312 } 5313 } 5314 5315 @Override 5316 public void showBootMessage(final CharSequence msg, final boolean always) { 5317 enforceNotIsolatedCaller("showBootMessage"); 5318 mWindowManager.showBootMessage(msg, always); 5319 } 5320 5321 @Override 5322 public void dismissKeyguardOnNextActivity() { 5323 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5324 final long token = Binder.clearCallingIdentity(); 5325 try { 5326 synchronized (this) { 5327 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5328 if (mLockScreenShown) { 5329 mLockScreenShown = false; 5330 comeOutOfSleepIfNeededLocked(); 5331 } 5332 mStackSupervisor.setDismissKeyguard(true); 5333 } 5334 } finally { 5335 Binder.restoreCallingIdentity(token); 5336 } 5337 } 5338 5339 final void finishBooting() { 5340 // Register receivers to handle package update events 5341 mPackageMonitor.register(mContext, Looper.getMainLooper(), false); 5342 5343 synchronized (this) { 5344 // Ensure that any processes we had put on hold are now started 5345 // up. 5346 final int NP = mProcessesOnHold.size(); 5347 if (NP > 0) { 5348 ArrayList<ProcessRecord> procs = 5349 new ArrayList<ProcessRecord>(mProcessesOnHold); 5350 for (int ip=0; ip<NP; ip++) { 5351 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5352 + procs.get(ip)); 5353 startProcessLocked(procs.get(ip), "on-hold", null); 5354 } 5355 } 5356 5357 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5358 // Start looking for apps that are abusing wake locks. 5359 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5360 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5361 // Tell anyone interested that we are done booting! 5362 SystemProperties.set("sys.boot_completed", "1"); 5363 SystemProperties.set("dev.bootcomplete", "1"); 5364 for (int i=0; i<mStartedUsers.size(); i++) { 5365 UserStartedState uss = mStartedUsers.valueAt(i); 5366 if (uss.mState == UserStartedState.STATE_BOOTING) { 5367 uss.mState = UserStartedState.STATE_RUNNING; 5368 final int userId = mStartedUsers.keyAt(i); 5369 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5370 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5371 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5372 broadcastIntentLocked(null, null, intent, null, 5373 new IIntentReceiver.Stub() { 5374 @Override 5375 public void performReceive(Intent intent, int resultCode, 5376 String data, Bundle extras, boolean ordered, 5377 boolean sticky, int sendingUser) { 5378 synchronized (ActivityManagerService.this) { 5379 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5380 true, false); 5381 } 5382 } 5383 }, 5384 0, null, null, 5385 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5386 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5387 userId); 5388 } 5389 } 5390 scheduleStartProfilesLocked(); 5391 } 5392 } 5393 } 5394 5395 final void ensureBootCompleted() { 5396 boolean booting; 5397 boolean enableScreen; 5398 synchronized (this) { 5399 booting = mBooting; 5400 mBooting = false; 5401 enableScreen = !mBooted; 5402 mBooted = true; 5403 } 5404 5405 if (booting) { 5406 finishBooting(); 5407 } 5408 5409 if (enableScreen) { 5410 enableScreenAfterBoot(); 5411 } 5412 } 5413 5414 @Override 5415 public final void activityResumed(IBinder token) { 5416 final long origId = Binder.clearCallingIdentity(); 5417 synchronized(this) { 5418 ActivityStack stack = ActivityRecord.getStackLocked(token); 5419 if (stack != null) { 5420 ActivityRecord.activityResumedLocked(token); 5421 } 5422 } 5423 Binder.restoreCallingIdentity(origId); 5424 } 5425 5426 @Override 5427 public final void activityPaused(IBinder token) { 5428 final long origId = Binder.clearCallingIdentity(); 5429 synchronized(this) { 5430 ActivityStack stack = ActivityRecord.getStackLocked(token); 5431 if (stack != null) { 5432 stack.activityPausedLocked(token, false); 5433 } 5434 } 5435 Binder.restoreCallingIdentity(origId); 5436 } 5437 5438 @Override 5439 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5440 CharSequence description) { 5441 if (localLOGV) Slog.v( 5442 TAG, "Activity stopped: token=" + token); 5443 5444 // Refuse possible leaked file descriptors 5445 if (icicle != null && icicle.hasFileDescriptors()) { 5446 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5447 } 5448 5449 final long origId = Binder.clearCallingIdentity(); 5450 5451 synchronized (this) { 5452 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5453 if (r != null) { 5454 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5455 } 5456 } 5457 5458 trimApplications(); 5459 5460 Binder.restoreCallingIdentity(origId); 5461 } 5462 5463 @Override 5464 public final void activityDestroyed(IBinder token) { 5465 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5466 synchronized (this) { 5467 ActivityStack stack = ActivityRecord.getStackLocked(token); 5468 if (stack != null) { 5469 stack.activityDestroyedLocked(token); 5470 } 5471 } 5472 } 5473 5474 @Override 5475 public String getCallingPackage(IBinder token) { 5476 synchronized (this) { 5477 ActivityRecord r = getCallingRecordLocked(token); 5478 return r != null ? r.info.packageName : null; 5479 } 5480 } 5481 5482 @Override 5483 public ComponentName getCallingActivity(IBinder token) { 5484 synchronized (this) { 5485 ActivityRecord r = getCallingRecordLocked(token); 5486 return r != null ? r.intent.getComponent() : null; 5487 } 5488 } 5489 5490 private ActivityRecord getCallingRecordLocked(IBinder token) { 5491 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5492 if (r == null) { 5493 return null; 5494 } 5495 return r.resultTo; 5496 } 5497 5498 @Override 5499 public ComponentName getActivityClassForToken(IBinder token) { 5500 synchronized(this) { 5501 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5502 if (r == null) { 5503 return null; 5504 } 5505 return r.intent.getComponent(); 5506 } 5507 } 5508 5509 @Override 5510 public String getPackageForToken(IBinder token) { 5511 synchronized(this) { 5512 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5513 if (r == null) { 5514 return null; 5515 } 5516 return r.packageName; 5517 } 5518 } 5519 5520 @Override 5521 public IIntentSender getIntentSender(int type, 5522 String packageName, IBinder token, String resultWho, 5523 int requestCode, Intent[] intents, String[] resolvedTypes, 5524 int flags, Bundle options, int userId) { 5525 enforceNotIsolatedCaller("getIntentSender"); 5526 // Refuse possible leaked file descriptors 5527 if (intents != null) { 5528 if (intents.length < 1) { 5529 throw new IllegalArgumentException("Intents array length must be >= 1"); 5530 } 5531 for (int i=0; i<intents.length; i++) { 5532 Intent intent = intents[i]; 5533 if (intent != null) { 5534 if (intent.hasFileDescriptors()) { 5535 throw new IllegalArgumentException("File descriptors passed in Intent"); 5536 } 5537 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5538 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5539 throw new IllegalArgumentException( 5540 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5541 } 5542 intents[i] = new Intent(intent); 5543 } 5544 } 5545 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5546 throw new IllegalArgumentException( 5547 "Intent array length does not match resolvedTypes length"); 5548 } 5549 } 5550 if (options != null) { 5551 if (options.hasFileDescriptors()) { 5552 throw new IllegalArgumentException("File descriptors passed in options"); 5553 } 5554 } 5555 5556 synchronized(this) { 5557 int callingUid = Binder.getCallingUid(); 5558 int origUserId = userId; 5559 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5560 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5561 "getIntentSender", null); 5562 if (origUserId == UserHandle.USER_CURRENT) { 5563 // We don't want to evaluate this until the pending intent is 5564 // actually executed. However, we do want to always do the 5565 // security checking for it above. 5566 userId = UserHandle.USER_CURRENT; 5567 } 5568 try { 5569 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5570 int uid = AppGlobals.getPackageManager() 5571 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5572 if (!UserHandle.isSameApp(callingUid, uid)) { 5573 String msg = "Permission Denial: getIntentSender() from pid=" 5574 + Binder.getCallingPid() 5575 + ", uid=" + Binder.getCallingUid() 5576 + ", (need uid=" + uid + ")" 5577 + " is not allowed to send as package " + packageName; 5578 Slog.w(TAG, msg); 5579 throw new SecurityException(msg); 5580 } 5581 } 5582 5583 return getIntentSenderLocked(type, packageName, callingUid, userId, 5584 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5585 5586 } catch (RemoteException e) { 5587 throw new SecurityException(e); 5588 } 5589 } 5590 } 5591 5592 IIntentSender getIntentSenderLocked(int type, String packageName, 5593 int callingUid, int userId, IBinder token, String resultWho, 5594 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5595 Bundle options) { 5596 if (DEBUG_MU) 5597 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5598 ActivityRecord activity = null; 5599 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5600 activity = ActivityRecord.isInStackLocked(token); 5601 if (activity == null) { 5602 return null; 5603 } 5604 if (activity.finishing) { 5605 return null; 5606 } 5607 } 5608 5609 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5610 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5611 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5612 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5613 |PendingIntent.FLAG_UPDATE_CURRENT); 5614 5615 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5616 type, packageName, activity, resultWho, 5617 requestCode, intents, resolvedTypes, flags, options, userId); 5618 WeakReference<PendingIntentRecord> ref; 5619 ref = mIntentSenderRecords.get(key); 5620 PendingIntentRecord rec = ref != null ? ref.get() : null; 5621 if (rec != null) { 5622 if (!cancelCurrent) { 5623 if (updateCurrent) { 5624 if (rec.key.requestIntent != null) { 5625 rec.key.requestIntent.replaceExtras(intents != null ? 5626 intents[intents.length - 1] : null); 5627 } 5628 if (intents != null) { 5629 intents[intents.length-1] = rec.key.requestIntent; 5630 rec.key.allIntents = intents; 5631 rec.key.allResolvedTypes = resolvedTypes; 5632 } else { 5633 rec.key.allIntents = null; 5634 rec.key.allResolvedTypes = null; 5635 } 5636 } 5637 return rec; 5638 } 5639 rec.canceled = true; 5640 mIntentSenderRecords.remove(key); 5641 } 5642 if (noCreate) { 5643 return rec; 5644 } 5645 rec = new PendingIntentRecord(this, key, callingUid); 5646 mIntentSenderRecords.put(key, rec.ref); 5647 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5648 if (activity.pendingResults == null) { 5649 activity.pendingResults 5650 = new HashSet<WeakReference<PendingIntentRecord>>(); 5651 } 5652 activity.pendingResults.add(rec.ref); 5653 } 5654 return rec; 5655 } 5656 5657 @Override 5658 public void cancelIntentSender(IIntentSender sender) { 5659 if (!(sender instanceof PendingIntentRecord)) { 5660 return; 5661 } 5662 synchronized(this) { 5663 PendingIntentRecord rec = (PendingIntentRecord)sender; 5664 try { 5665 int uid = AppGlobals.getPackageManager() 5666 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5667 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5668 String msg = "Permission Denial: cancelIntentSender() from pid=" 5669 + Binder.getCallingPid() 5670 + ", uid=" + Binder.getCallingUid() 5671 + " is not allowed to cancel packges " 5672 + rec.key.packageName; 5673 Slog.w(TAG, msg); 5674 throw new SecurityException(msg); 5675 } 5676 } catch (RemoteException e) { 5677 throw new SecurityException(e); 5678 } 5679 cancelIntentSenderLocked(rec, true); 5680 } 5681 } 5682 5683 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5684 rec.canceled = true; 5685 mIntentSenderRecords.remove(rec.key); 5686 if (cleanActivity && rec.key.activity != null) { 5687 rec.key.activity.pendingResults.remove(rec.ref); 5688 } 5689 } 5690 5691 @Override 5692 public String getPackageForIntentSender(IIntentSender pendingResult) { 5693 if (!(pendingResult instanceof PendingIntentRecord)) { 5694 return null; 5695 } 5696 try { 5697 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5698 return res.key.packageName; 5699 } catch (ClassCastException e) { 5700 } 5701 return null; 5702 } 5703 5704 @Override 5705 public int getUidForIntentSender(IIntentSender sender) { 5706 if (sender instanceof PendingIntentRecord) { 5707 try { 5708 PendingIntentRecord res = (PendingIntentRecord)sender; 5709 return res.uid; 5710 } catch (ClassCastException e) { 5711 } 5712 } 5713 return -1; 5714 } 5715 5716 @Override 5717 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5718 if (!(pendingResult instanceof PendingIntentRecord)) { 5719 return false; 5720 } 5721 try { 5722 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5723 if (res.key.allIntents == null) { 5724 return false; 5725 } 5726 for (int i=0; i<res.key.allIntents.length; i++) { 5727 Intent intent = res.key.allIntents[i]; 5728 if (intent.getPackage() != null && intent.getComponent() != null) { 5729 return false; 5730 } 5731 } 5732 return true; 5733 } catch (ClassCastException e) { 5734 } 5735 return false; 5736 } 5737 5738 @Override 5739 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5740 if (!(pendingResult instanceof PendingIntentRecord)) { 5741 return false; 5742 } 5743 try { 5744 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5745 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5746 return true; 5747 } 5748 return false; 5749 } catch (ClassCastException e) { 5750 } 5751 return false; 5752 } 5753 5754 @Override 5755 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5756 if (!(pendingResult instanceof PendingIntentRecord)) { 5757 return null; 5758 } 5759 try { 5760 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5761 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5762 } catch (ClassCastException e) { 5763 } 5764 return null; 5765 } 5766 5767 @Override 5768 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5769 if (!(pendingResult instanceof PendingIntentRecord)) { 5770 return null; 5771 } 5772 try { 5773 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5774 Intent intent = res.key.requestIntent; 5775 if (intent != null) { 5776 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5777 || res.lastTagPrefix.equals(prefix))) { 5778 return res.lastTag; 5779 } 5780 res.lastTagPrefix = prefix; 5781 StringBuilder sb = new StringBuilder(128); 5782 if (prefix != null) { 5783 sb.append(prefix); 5784 } 5785 if (intent.getAction() != null) { 5786 sb.append(intent.getAction()); 5787 } else if (intent.getComponent() != null) { 5788 intent.getComponent().appendShortString(sb); 5789 } else { 5790 sb.append("?"); 5791 } 5792 return res.lastTag = sb.toString(); 5793 } 5794 } catch (ClassCastException e) { 5795 } 5796 return null; 5797 } 5798 5799 @Override 5800 public void setProcessLimit(int max) { 5801 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5802 "setProcessLimit()"); 5803 synchronized (this) { 5804 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5805 mProcessLimitOverride = max; 5806 } 5807 trimApplications(); 5808 } 5809 5810 @Override 5811 public int getProcessLimit() { 5812 synchronized (this) { 5813 return mProcessLimitOverride; 5814 } 5815 } 5816 5817 void foregroundTokenDied(ForegroundToken token) { 5818 synchronized (ActivityManagerService.this) { 5819 synchronized (mPidsSelfLocked) { 5820 ForegroundToken cur 5821 = mForegroundProcesses.get(token.pid); 5822 if (cur != token) { 5823 return; 5824 } 5825 mForegroundProcesses.remove(token.pid); 5826 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5827 if (pr == null) { 5828 return; 5829 } 5830 pr.forcingToForeground = null; 5831 updateProcessForegroundLocked(pr, false, false); 5832 } 5833 updateOomAdjLocked(); 5834 } 5835 } 5836 5837 @Override 5838 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5839 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5840 "setProcessForeground()"); 5841 synchronized(this) { 5842 boolean changed = false; 5843 5844 synchronized (mPidsSelfLocked) { 5845 ProcessRecord pr = mPidsSelfLocked.get(pid); 5846 if (pr == null && isForeground) { 5847 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5848 return; 5849 } 5850 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5851 if (oldToken != null) { 5852 oldToken.token.unlinkToDeath(oldToken, 0); 5853 mForegroundProcesses.remove(pid); 5854 if (pr != null) { 5855 pr.forcingToForeground = null; 5856 } 5857 changed = true; 5858 } 5859 if (isForeground && token != null) { 5860 ForegroundToken newToken = new ForegroundToken() { 5861 @Override 5862 public void binderDied() { 5863 foregroundTokenDied(this); 5864 } 5865 }; 5866 newToken.pid = pid; 5867 newToken.token = token; 5868 try { 5869 token.linkToDeath(newToken, 0); 5870 mForegroundProcesses.put(pid, newToken); 5871 pr.forcingToForeground = token; 5872 changed = true; 5873 } catch (RemoteException e) { 5874 // If the process died while doing this, we will later 5875 // do the cleanup with the process death link. 5876 } 5877 } 5878 } 5879 5880 if (changed) { 5881 updateOomAdjLocked(); 5882 } 5883 } 5884 } 5885 5886 // ========================================================= 5887 // PERMISSIONS 5888 // ========================================================= 5889 5890 static class PermissionController extends IPermissionController.Stub { 5891 ActivityManagerService mActivityManagerService; 5892 PermissionController(ActivityManagerService activityManagerService) { 5893 mActivityManagerService = activityManagerService; 5894 } 5895 5896 @Override 5897 public boolean checkPermission(String permission, int pid, int uid) { 5898 return mActivityManagerService.checkPermission(permission, pid, 5899 uid) == PackageManager.PERMISSION_GRANTED; 5900 } 5901 } 5902 5903 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5904 @Override 5905 public int checkComponentPermission(String permission, int pid, int uid, 5906 int owningUid, boolean exported) { 5907 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5908 owningUid, exported); 5909 } 5910 5911 @Override 5912 public Object getAMSLock() { 5913 return ActivityManagerService.this; 5914 } 5915 } 5916 5917 /** 5918 * This can be called with or without the global lock held. 5919 */ 5920 int checkComponentPermission(String permission, int pid, int uid, 5921 int owningUid, boolean exported) { 5922 // We might be performing an operation on behalf of an indirect binder 5923 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5924 // client identity accordingly before proceeding. 5925 Identity tlsIdentity = sCallerIdentity.get(); 5926 if (tlsIdentity != null) { 5927 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5928 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5929 uid = tlsIdentity.uid; 5930 pid = tlsIdentity.pid; 5931 } 5932 5933 if (pid == MY_PID) { 5934 return PackageManager.PERMISSION_GRANTED; 5935 } 5936 5937 return ActivityManager.checkComponentPermission(permission, uid, 5938 owningUid, exported); 5939 } 5940 5941 /** 5942 * As the only public entry point for permissions checking, this method 5943 * can enforce the semantic that requesting a check on a null global 5944 * permission is automatically denied. (Internally a null permission 5945 * string is used when calling {@link #checkComponentPermission} in cases 5946 * when only uid-based security is needed.) 5947 * 5948 * This can be called with or without the global lock held. 5949 */ 5950 @Override 5951 public int checkPermission(String permission, int pid, int uid) { 5952 if (permission == null) { 5953 return PackageManager.PERMISSION_DENIED; 5954 } 5955 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5956 } 5957 5958 /** 5959 * Binder IPC calls go through the public entry point. 5960 * This can be called with or without the global lock held. 5961 */ 5962 int checkCallingPermission(String permission) { 5963 return checkPermission(permission, 5964 Binder.getCallingPid(), 5965 UserHandle.getAppId(Binder.getCallingUid())); 5966 } 5967 5968 /** 5969 * This can be called with or without the global lock held. 5970 */ 5971 void enforceCallingPermission(String permission, String func) { 5972 if (checkCallingPermission(permission) 5973 == PackageManager.PERMISSION_GRANTED) { 5974 return; 5975 } 5976 5977 String msg = "Permission Denial: " + func + " from pid=" 5978 + Binder.getCallingPid() 5979 + ", uid=" + Binder.getCallingUid() 5980 + " requires " + permission; 5981 Slog.w(TAG, msg); 5982 throw new SecurityException(msg); 5983 } 5984 5985 /** 5986 * Determine if UID is holding permissions required to access {@link Uri} in 5987 * the given {@link ProviderInfo}. Final permission checking is always done 5988 * in {@link ContentProvider}. 5989 */ 5990 private final boolean checkHoldingPermissionsLocked( 5991 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5992 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5993 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5994 5995 if (pi.applicationInfo.uid == uid) { 5996 return true; 5997 } else if (!pi.exported) { 5998 return false; 5999 } 6000 6001 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 6002 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 6003 try { 6004 // check if target holds top-level <provider> permissions 6005 if (!readMet && pi.readPermission != null 6006 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 6007 readMet = true; 6008 } 6009 if (!writeMet && pi.writePermission != null 6010 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 6011 writeMet = true; 6012 } 6013 6014 // track if unprotected read/write is allowed; any denied 6015 // <path-permission> below removes this ability 6016 boolean allowDefaultRead = pi.readPermission == null; 6017 boolean allowDefaultWrite = pi.writePermission == null; 6018 6019 // check if target holds any <path-permission> that match uri 6020 final PathPermission[] pps = pi.pathPermissions; 6021 if (pps != null) { 6022 final String path = uri.getPath(); 6023 int i = pps.length; 6024 while (i > 0 && (!readMet || !writeMet)) { 6025 i--; 6026 PathPermission pp = pps[i]; 6027 if (pp.match(path)) { 6028 if (!readMet) { 6029 final String pprperm = pp.getReadPermission(); 6030 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 6031 + pprperm + " for " + pp.getPath() 6032 + ": match=" + pp.match(path) 6033 + " check=" + pm.checkUidPermission(pprperm, uid)); 6034 if (pprperm != null) { 6035 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 6036 readMet = true; 6037 } else { 6038 allowDefaultRead = false; 6039 } 6040 } 6041 } 6042 if (!writeMet) { 6043 final String ppwperm = pp.getWritePermission(); 6044 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 6045 + ppwperm + " for " + pp.getPath() 6046 + ": match=" + pp.match(path) 6047 + " check=" + pm.checkUidPermission(ppwperm, uid)); 6048 if (ppwperm != null) { 6049 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 6050 writeMet = true; 6051 } else { 6052 allowDefaultWrite = false; 6053 } 6054 } 6055 } 6056 } 6057 } 6058 } 6059 6060 // grant unprotected <provider> read/write, if not blocked by 6061 // <path-permission> above 6062 if (allowDefaultRead) readMet = true; 6063 if (allowDefaultWrite) writeMet = true; 6064 6065 } catch (RemoteException e) { 6066 return false; 6067 } 6068 6069 return readMet && writeMet; 6070 } 6071 6072 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 6073 ProviderInfo pi = null; 6074 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 6075 if (cpr != null) { 6076 pi = cpr.info; 6077 } else { 6078 try { 6079 pi = AppGlobals.getPackageManager().resolveContentProvider( 6080 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 6081 } catch (RemoteException ex) { 6082 } 6083 } 6084 return pi; 6085 } 6086 6087 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 6088 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6089 if (targetUris != null) { 6090 return targetUris.get(uri); 6091 } 6092 return null; 6093 } 6094 6095 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 6096 String targetPkg, int targetUid, GrantUri uri) { 6097 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 6098 if (targetUris == null) { 6099 targetUris = Maps.newArrayMap(); 6100 mGrantedUriPermissions.put(targetUid, targetUris); 6101 } 6102 6103 UriPermission perm = targetUris.get(uri); 6104 if (perm == null) { 6105 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 6106 targetUris.put(uri, perm); 6107 } 6108 6109 return perm; 6110 } 6111 6112 private final boolean checkUriPermissionLocked(Uri uri, int uid, final int modeFlags) { 6113 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6114 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6115 : UriPermission.STRENGTH_OWNED; 6116 6117 // Root gets to do everything. 6118 if (uid == 0) { 6119 return true; 6120 } 6121 6122 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6123 if (perms == null) return false; 6124 6125 // First look for exact match 6126 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 6127 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 6128 return true; 6129 } 6130 6131 // No exact match, look for prefixes 6132 final int N = perms.size(); 6133 for (int i = 0; i < N; i++) { 6134 final UriPermission perm = perms.valueAt(i); 6135 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6136 && perm.getStrength(modeFlags) >= minStrength) { 6137 return true; 6138 } 6139 } 6140 6141 return false; 6142 } 6143 6144 @Override 6145 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6146 enforceNotIsolatedCaller("checkUriPermission"); 6147 6148 // Another redirected-binder-call permissions check as in 6149 // {@link checkComponentPermission}. 6150 Identity tlsIdentity = sCallerIdentity.get(); 6151 if (tlsIdentity != null) { 6152 uid = tlsIdentity.uid; 6153 pid = tlsIdentity.pid; 6154 } 6155 6156 // Our own process gets to do everything. 6157 if (pid == MY_PID) { 6158 return PackageManager.PERMISSION_GRANTED; 6159 } 6160 synchronized (this) { 6161 return checkUriPermissionLocked(uri, uid, modeFlags) 6162 ? PackageManager.PERMISSION_GRANTED 6163 : PackageManager.PERMISSION_DENIED; 6164 } 6165 } 6166 6167 /** 6168 * Check if the targetPkg can be granted permission to access uri by 6169 * the callingUid using the given modeFlags. Throws a security exception 6170 * if callingUid is not allowed to do this. Returns the uid of the target 6171 * if the URI permission grant should be performed; returns -1 if it is not 6172 * needed (for example targetPkg already has permission to access the URI). 6173 * If you already know the uid of the target, you can supply it in 6174 * lastTargetUid else set that to -1. 6175 */ 6176 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6177 Uri uri, final int modeFlags, int lastTargetUid) { 6178 if (!Intent.isAccessUriMode(modeFlags)) { 6179 return -1; 6180 } 6181 6182 if (targetPkg != null) { 6183 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6184 "Checking grant " + targetPkg + " permission to " + uri); 6185 } 6186 6187 final IPackageManager pm = AppGlobals.getPackageManager(); 6188 6189 // If this is not a content: uri, we can't do anything with it. 6190 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6191 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6192 "Can't grant URI permission for non-content URI: " + uri); 6193 return -1; 6194 } 6195 6196 final String authority = uri.getAuthority(); 6197 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6198 if (pi == null) { 6199 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6200 return -1; 6201 } 6202 6203 int targetUid = lastTargetUid; 6204 if (targetUid < 0 && targetPkg != null) { 6205 try { 6206 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6207 if (targetUid < 0) { 6208 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6209 "Can't grant URI permission no uid for: " + targetPkg); 6210 return -1; 6211 } 6212 } catch (RemoteException ex) { 6213 return -1; 6214 } 6215 } 6216 6217 if (targetUid >= 0) { 6218 // First... does the target actually need this permission? 6219 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6220 // No need to grant the target this permission. 6221 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6222 "Target " + targetPkg + " already has full permission to " + uri); 6223 return -1; 6224 } 6225 } else { 6226 // First... there is no target package, so can anyone access it? 6227 boolean allowed = pi.exported; 6228 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6229 if (pi.readPermission != null) { 6230 allowed = false; 6231 } 6232 } 6233 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6234 if (pi.writePermission != null) { 6235 allowed = false; 6236 } 6237 } 6238 if (allowed) { 6239 return -1; 6240 } 6241 } 6242 6243 // Second... is the provider allowing granting of URI permissions? 6244 if (!pi.grantUriPermissions) { 6245 throw new SecurityException("Provider " + pi.packageName 6246 + "/" + pi.name 6247 + " does not allow granting of Uri permissions (uri " 6248 + uri + ")"); 6249 } 6250 if (pi.uriPermissionPatterns != null) { 6251 final int N = pi.uriPermissionPatterns.length; 6252 boolean allowed = false; 6253 for (int i=0; i<N; i++) { 6254 if (pi.uriPermissionPatterns[i] != null 6255 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6256 allowed = true; 6257 break; 6258 } 6259 } 6260 if (!allowed) { 6261 throw new SecurityException("Provider " + pi.packageName 6262 + "/" + pi.name 6263 + " does not allow granting of permission to path of Uri " 6264 + uri); 6265 } 6266 } 6267 6268 // Third... does the caller itself have permission to access 6269 // this uri? 6270 if (callingUid != Process.myUid()) { 6271 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6272 // Require they hold a strong enough Uri permission 6273 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6274 throw new SecurityException("Uid " + callingUid 6275 + " does not have permission to uri " + uri); 6276 } 6277 } 6278 } 6279 6280 return targetUid; 6281 } 6282 6283 @Override 6284 public int checkGrantUriPermission(int callingUid, String targetPkg, 6285 Uri uri, final int modeFlags) { 6286 enforceNotIsolatedCaller("checkGrantUriPermission"); 6287 synchronized(this) { 6288 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6289 } 6290 } 6291 6292 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6293 final int modeFlags, UriPermissionOwner owner) { 6294 if (!Intent.isAccessUriMode(modeFlags)) { 6295 return; 6296 } 6297 6298 // So here we are: the caller has the assumed permission 6299 // to the uri, and the target doesn't. Let's now give this to 6300 // the target. 6301 6302 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6303 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6304 6305 final String authority = uri.getAuthority(); 6306 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6307 if (pi == null) { 6308 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6309 return; 6310 } 6311 6312 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6313 final UriPermission perm = findOrCreateUriPermissionLocked( 6314 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6315 perm.grantModes(modeFlags, owner); 6316 } 6317 6318 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6319 final int modeFlags, UriPermissionOwner owner) { 6320 if (targetPkg == null) { 6321 throw new NullPointerException("targetPkg"); 6322 } 6323 6324 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6325 if (targetUid < 0) { 6326 return; 6327 } 6328 6329 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6330 } 6331 6332 static class NeededUriGrants extends ArrayList<Uri> { 6333 final String targetPkg; 6334 final int targetUid; 6335 final int flags; 6336 6337 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6338 this.targetPkg = targetPkg; 6339 this.targetUid = targetUid; 6340 this.flags = flags; 6341 } 6342 } 6343 6344 /** 6345 * Like checkGrantUriPermissionLocked, but takes an Intent. 6346 */ 6347 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6348 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6349 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6350 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6351 + " clip=" + (intent != null ? intent.getClipData() : null) 6352 + " from " + intent + "; flags=0x" 6353 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6354 6355 if (targetPkg == null) { 6356 throw new NullPointerException("targetPkg"); 6357 } 6358 6359 if (intent == null) { 6360 return null; 6361 } 6362 Uri data = intent.getData(); 6363 ClipData clip = intent.getClipData(); 6364 if (data == null && clip == null) { 6365 return null; 6366 } 6367 6368 if (data != null) { 6369 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6370 mode, needed != null ? needed.targetUid : -1); 6371 if (targetUid > 0) { 6372 if (needed == null) { 6373 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6374 } 6375 needed.add(data); 6376 } 6377 } 6378 if (clip != null) { 6379 for (int i=0; i<clip.getItemCount(); i++) { 6380 Uri uri = clip.getItemAt(i).getUri(); 6381 if (uri != null) { 6382 int targetUid = -1; 6383 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6384 mode, needed != null ? needed.targetUid : -1); 6385 if (targetUid > 0) { 6386 if (needed == null) { 6387 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6388 } 6389 needed.add(uri); 6390 } 6391 } else { 6392 Intent clipIntent = clip.getItemAt(i).getIntent(); 6393 if (clipIntent != null) { 6394 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6395 callingUid, targetPkg, clipIntent, mode, needed); 6396 if (newNeeded != null) { 6397 needed = newNeeded; 6398 } 6399 } 6400 } 6401 } 6402 } 6403 6404 return needed; 6405 } 6406 6407 /** 6408 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6409 */ 6410 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6411 UriPermissionOwner owner) { 6412 if (needed != null) { 6413 for (int i=0; i<needed.size(); i++) { 6414 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6415 needed.get(i), needed.flags, owner); 6416 } 6417 } 6418 } 6419 6420 void grantUriPermissionFromIntentLocked(int callingUid, 6421 String targetPkg, Intent intent, UriPermissionOwner owner) { 6422 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6423 intent, intent != null ? intent.getFlags() : 0, null); 6424 if (needed == null) { 6425 return; 6426 } 6427 6428 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6429 } 6430 6431 @Override 6432 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6433 Uri uri, final int modeFlags) { 6434 enforceNotIsolatedCaller("grantUriPermission"); 6435 synchronized(this) { 6436 final ProcessRecord r = getRecordForAppLocked(caller); 6437 if (r == null) { 6438 throw new SecurityException("Unable to find app for caller " 6439 + caller 6440 + " when granting permission to uri " + uri); 6441 } 6442 if (targetPkg == null) { 6443 throw new IllegalArgumentException("null target"); 6444 } 6445 if (uri == null) { 6446 throw new IllegalArgumentException("null uri"); 6447 } 6448 6449 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6450 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6451 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6452 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6453 6454 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6455 } 6456 } 6457 6458 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6459 if (perm.modeFlags == 0) { 6460 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6461 perm.targetUid); 6462 if (perms != null) { 6463 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6464 "Removing " + perm.targetUid + " permission to " + perm.uri); 6465 6466 perms.remove(perm.uri); 6467 if (perms.isEmpty()) { 6468 mGrantedUriPermissions.remove(perm.targetUid); 6469 } 6470 } 6471 } 6472 } 6473 6474 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6475 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6476 6477 final IPackageManager pm = AppGlobals.getPackageManager(); 6478 final String authority = uri.getAuthority(); 6479 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6480 if (pi == null) { 6481 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6482 return; 6483 } 6484 6485 // Does the caller have this permission on the URI? 6486 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6487 // Right now, if you are not the original owner of the permission, 6488 // you are not allowed to revoke it. 6489 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6490 throw new SecurityException("Uid " + callingUid 6491 + " does not have permission to uri " + uri); 6492 //} 6493 } 6494 6495 boolean persistChanged = false; 6496 6497 // Go through all of the permissions and remove any that match. 6498 int N = mGrantedUriPermissions.size(); 6499 for (int i = 0; i < N; i++) { 6500 final int targetUid = mGrantedUriPermissions.keyAt(i); 6501 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6502 6503 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6504 final UriPermission perm = it.next(); 6505 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6506 if (DEBUG_URI_PERMISSION) 6507 Slog.v(TAG, 6508 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6509 persistChanged |= perm.revokeModes( 6510 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6511 if (perm.modeFlags == 0) { 6512 it.remove(); 6513 } 6514 } 6515 } 6516 6517 if (perms.isEmpty()) { 6518 mGrantedUriPermissions.remove(targetUid); 6519 N--; 6520 i--; 6521 } 6522 } 6523 6524 if (persistChanged) { 6525 schedulePersistUriGrants(); 6526 } 6527 } 6528 6529 @Override 6530 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6531 final int modeFlags) { 6532 enforceNotIsolatedCaller("revokeUriPermission"); 6533 synchronized(this) { 6534 final ProcessRecord r = getRecordForAppLocked(caller); 6535 if (r == null) { 6536 throw new SecurityException("Unable to find app for caller " 6537 + caller 6538 + " when revoking permission to uri " + uri); 6539 } 6540 if (uri == null) { 6541 Slog.w(TAG, "revokeUriPermission: null uri"); 6542 return; 6543 } 6544 6545 if (!Intent.isAccessUriMode(modeFlags)) { 6546 return; 6547 } 6548 6549 final IPackageManager pm = AppGlobals.getPackageManager(); 6550 final String authority = uri.getAuthority(); 6551 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6552 if (pi == null) { 6553 Slog.w(TAG, "No content provider found for permission revoke: " 6554 + uri.toSafeString()); 6555 return; 6556 } 6557 6558 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6559 } 6560 } 6561 6562 /** 6563 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6564 * given package. 6565 * 6566 * @param packageName Package name to match, or {@code null} to apply to all 6567 * packages. 6568 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6569 * to all users. 6570 * @param persistable If persistable grants should be removed. 6571 */ 6572 private void removeUriPermissionsForPackageLocked( 6573 String packageName, int userHandle, boolean persistable) { 6574 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6575 throw new IllegalArgumentException("Must narrow by either package or user"); 6576 } 6577 6578 boolean persistChanged = false; 6579 6580 int N = mGrantedUriPermissions.size(); 6581 for (int i = 0; i < N; i++) { 6582 final int targetUid = mGrantedUriPermissions.keyAt(i); 6583 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6584 6585 // Only inspect grants matching user 6586 if (userHandle == UserHandle.USER_ALL 6587 || userHandle == UserHandle.getUserId(targetUid)) { 6588 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6589 final UriPermission perm = it.next(); 6590 6591 // Only inspect grants matching package 6592 if (packageName == null || perm.sourcePkg.equals(packageName) 6593 || perm.targetPkg.equals(packageName)) { 6594 persistChanged |= perm.revokeModes( 6595 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6596 6597 // Only remove when no modes remain; any persisted grants 6598 // will keep this alive. 6599 if (perm.modeFlags == 0) { 6600 it.remove(); 6601 } 6602 } 6603 } 6604 6605 if (perms.isEmpty()) { 6606 mGrantedUriPermissions.remove(targetUid); 6607 N--; 6608 i--; 6609 } 6610 } 6611 } 6612 6613 if (persistChanged) { 6614 schedulePersistUriGrants(); 6615 } 6616 } 6617 6618 @Override 6619 public IBinder newUriPermissionOwner(String name) { 6620 enforceNotIsolatedCaller("newUriPermissionOwner"); 6621 synchronized(this) { 6622 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6623 return owner.getExternalTokenLocked(); 6624 } 6625 } 6626 6627 @Override 6628 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6629 Uri uri, final int modeFlags) { 6630 synchronized(this) { 6631 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6632 if (owner == null) { 6633 throw new IllegalArgumentException("Unknown owner: " + token); 6634 } 6635 if (fromUid != Binder.getCallingUid()) { 6636 if (Binder.getCallingUid() != Process.myUid()) { 6637 // Only system code can grant URI permissions on behalf 6638 // of other users. 6639 throw new SecurityException("nice try"); 6640 } 6641 } 6642 if (targetPkg == null) { 6643 throw new IllegalArgumentException("null target"); 6644 } 6645 if (uri == null) { 6646 throw new IllegalArgumentException("null uri"); 6647 } 6648 6649 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6650 } 6651 } 6652 6653 @Override 6654 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6655 synchronized(this) { 6656 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6657 if (owner == null) { 6658 throw new IllegalArgumentException("Unknown owner: " + token); 6659 } 6660 6661 if (uri == null) { 6662 owner.removeUriPermissionsLocked(mode); 6663 } else { 6664 owner.removeUriPermissionLocked(uri, mode); 6665 } 6666 } 6667 } 6668 6669 private void schedulePersistUriGrants() { 6670 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6671 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6672 10 * DateUtils.SECOND_IN_MILLIS); 6673 } 6674 } 6675 6676 private void writeGrantedUriPermissions() { 6677 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6678 6679 // Snapshot permissions so we can persist without lock 6680 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6681 synchronized (this) { 6682 final int size = mGrantedUriPermissions.size(); 6683 for (int i = 0; i < size; i++) { 6684 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6685 for (UriPermission perm : perms.values()) { 6686 if (perm.persistedModeFlags != 0) { 6687 persist.add(perm.snapshot()); 6688 } 6689 } 6690 } 6691 } 6692 6693 FileOutputStream fos = null; 6694 try { 6695 fos = mGrantFile.startWrite(); 6696 6697 XmlSerializer out = new FastXmlSerializer(); 6698 out.setOutput(fos, "utf-8"); 6699 out.startDocument(null, true); 6700 out.startTag(null, TAG_URI_GRANTS); 6701 for (UriPermission.Snapshot perm : persist) { 6702 out.startTag(null, TAG_URI_GRANT); 6703 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6704 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6705 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6706 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6707 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6708 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6709 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6710 out.endTag(null, TAG_URI_GRANT); 6711 } 6712 out.endTag(null, TAG_URI_GRANTS); 6713 out.endDocument(); 6714 6715 mGrantFile.finishWrite(fos); 6716 } catch (IOException e) { 6717 if (fos != null) { 6718 mGrantFile.failWrite(fos); 6719 } 6720 } 6721 } 6722 6723 private void readGrantedUriPermissionsLocked() { 6724 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6725 6726 final long now = System.currentTimeMillis(); 6727 6728 FileInputStream fis = null; 6729 try { 6730 fis = mGrantFile.openRead(); 6731 final XmlPullParser in = Xml.newPullParser(); 6732 in.setInput(fis, null); 6733 6734 int type; 6735 while ((type = in.next()) != END_DOCUMENT) { 6736 final String tag = in.getName(); 6737 if (type == START_TAG) { 6738 if (TAG_URI_GRANT.equals(tag)) { 6739 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6740 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6741 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6742 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6743 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6744 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6745 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6746 6747 // Sanity check that provider still belongs to source package 6748 final ProviderInfo pi = getProviderInfoLocked( 6749 uri.getAuthority(), userHandle); 6750 if (pi != null && sourcePkg.equals(pi.packageName)) { 6751 int targetUid = -1; 6752 try { 6753 targetUid = AppGlobals.getPackageManager() 6754 .getPackageUid(targetPkg, userHandle); 6755 } catch (RemoteException e) { 6756 } 6757 if (targetUid != -1) { 6758 final UriPermission perm = findOrCreateUriPermissionLocked( 6759 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6760 perm.initPersistedModes(modeFlags, createdTime); 6761 } 6762 } else { 6763 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6764 + " but instead found " + pi); 6765 } 6766 } 6767 } 6768 } 6769 } catch (FileNotFoundException e) { 6770 // Missing grants is okay 6771 } catch (IOException e) { 6772 Log.wtf(TAG, "Failed reading Uri grants", e); 6773 } catch (XmlPullParserException e) { 6774 Log.wtf(TAG, "Failed reading Uri grants", e); 6775 } finally { 6776 IoUtils.closeQuietly(fis); 6777 } 6778 } 6779 6780 @Override 6781 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6782 enforceNotIsolatedCaller("takePersistableUriPermission"); 6783 6784 Preconditions.checkFlagsArgument(modeFlags, 6785 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6786 6787 synchronized (this) { 6788 final int callingUid = Binder.getCallingUid(); 6789 boolean persistChanged = false; 6790 6791 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6792 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6793 6794 final boolean exactValid = (exactPerm != null) 6795 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6796 final boolean prefixValid = (prefixPerm != null) 6797 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6798 6799 if (!(exactValid || prefixValid)) { 6800 throw new SecurityException("No persistable permission grants found for UID " 6801 + callingUid + " and Uri " + uri.toSafeString()); 6802 } 6803 6804 if (exactValid) { 6805 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6806 } 6807 if (prefixValid) { 6808 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6809 } 6810 6811 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6812 6813 if (persistChanged) { 6814 schedulePersistUriGrants(); 6815 } 6816 } 6817 } 6818 6819 @Override 6820 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6821 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6822 6823 Preconditions.checkFlagsArgument(modeFlags, 6824 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6825 6826 synchronized (this) { 6827 final int callingUid = Binder.getCallingUid(); 6828 boolean persistChanged = false; 6829 6830 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6831 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6832 if (exactPerm == null && prefixPerm == null) { 6833 throw new SecurityException("No permission grants found for UID " + callingUid 6834 + " and Uri " + uri.toSafeString()); 6835 } 6836 6837 if (exactPerm != null) { 6838 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6839 removeUriPermissionIfNeededLocked(exactPerm); 6840 } 6841 if (prefixPerm != null) { 6842 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6843 removeUriPermissionIfNeededLocked(prefixPerm); 6844 } 6845 6846 if (persistChanged) { 6847 schedulePersistUriGrants(); 6848 } 6849 } 6850 } 6851 6852 /** 6853 * Prune any older {@link UriPermission} for the given UID until outstanding 6854 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6855 * 6856 * @return if any mutations occured that require persisting. 6857 */ 6858 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6859 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6860 if (perms == null) return false; 6861 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6862 6863 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6864 for (UriPermission perm : perms.values()) { 6865 if (perm.persistedModeFlags != 0) { 6866 persisted.add(perm); 6867 } 6868 } 6869 6870 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6871 if (trimCount <= 0) return false; 6872 6873 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6874 for (int i = 0; i < trimCount; i++) { 6875 final UriPermission perm = persisted.get(i); 6876 6877 if (DEBUG_URI_PERMISSION) { 6878 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6879 } 6880 6881 perm.releasePersistableModes(~0); 6882 removeUriPermissionIfNeededLocked(perm); 6883 } 6884 6885 return true; 6886 } 6887 6888 @Override 6889 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6890 String packageName, boolean incoming) { 6891 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6892 Preconditions.checkNotNull(packageName, "packageName"); 6893 6894 final int callingUid = Binder.getCallingUid(); 6895 final IPackageManager pm = AppGlobals.getPackageManager(); 6896 try { 6897 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6898 if (packageUid != callingUid) { 6899 throw new SecurityException( 6900 "Package " + packageName + " does not belong to calling UID " + callingUid); 6901 } 6902 } catch (RemoteException e) { 6903 throw new SecurityException("Failed to verify package name ownership"); 6904 } 6905 6906 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6907 synchronized (this) { 6908 if (incoming) { 6909 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6910 callingUid); 6911 if (perms == null) { 6912 Slog.w(TAG, "No permission grants found for " + packageName); 6913 } else { 6914 for (UriPermission perm : perms.values()) { 6915 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6916 result.add(perm.buildPersistedPublicApiObject()); 6917 } 6918 } 6919 } 6920 } else { 6921 final int size = mGrantedUriPermissions.size(); 6922 for (int i = 0; i < size; i++) { 6923 final ArrayMap<GrantUri, UriPermission> perms = 6924 mGrantedUriPermissions.valueAt(i); 6925 for (UriPermission perm : perms.values()) { 6926 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6927 result.add(perm.buildPersistedPublicApiObject()); 6928 } 6929 } 6930 } 6931 } 6932 } 6933 return new ParceledListSlice<android.content.UriPermission>(result); 6934 } 6935 6936 @Override 6937 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6938 synchronized (this) { 6939 ProcessRecord app = 6940 who != null ? getRecordForAppLocked(who) : null; 6941 if (app == null) return; 6942 6943 Message msg = Message.obtain(); 6944 msg.what = WAIT_FOR_DEBUGGER_MSG; 6945 msg.obj = app; 6946 msg.arg1 = waiting ? 1 : 0; 6947 mHandler.sendMessage(msg); 6948 } 6949 } 6950 6951 @Override 6952 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6953 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6954 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6955 outInfo.availMem = Process.getFreeMemory(); 6956 outInfo.totalMem = Process.getTotalMemory(); 6957 outInfo.threshold = homeAppMem; 6958 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6959 outInfo.hiddenAppThreshold = cachedAppMem; 6960 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6961 ProcessList.SERVICE_ADJ); 6962 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6963 ProcessList.VISIBLE_APP_ADJ); 6964 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6965 ProcessList.FOREGROUND_APP_ADJ); 6966 } 6967 6968 // ========================================================= 6969 // TASK MANAGEMENT 6970 // ========================================================= 6971 6972 @Override 6973 public List<RunningTaskInfo> getTasks(int maxNum, int flags) { 6974 final int callingUid = Binder.getCallingUid(); 6975 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6976 6977 synchronized(this) { 6978 if (localLOGV) Slog.v( 6979 TAG, "getTasks: max=" + maxNum + ", flags=" + flags); 6980 6981 final boolean allowed = checkCallingPermission( 6982 android.Manifest.permission.GET_TASKS) 6983 == PackageManager.PERMISSION_GRANTED; 6984 if (!allowed) { 6985 Slog.w(TAG, "getTasks: caller " + callingUid 6986 + " does not hold GET_TASKS; limiting output"); 6987 } 6988 6989 // TODO: Improve with MRU list from all ActivityStacks. 6990 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed); 6991 } 6992 6993 return list; 6994 } 6995 6996 TaskRecord getMostRecentTask() { 6997 return mRecentTasks.get(0); 6998 } 6999 7000 @Override 7001 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 7002 int flags, int userId) { 7003 final int callingUid = Binder.getCallingUid(); 7004 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 7005 false, true, "getRecentTasks", null); 7006 7007 synchronized (this) { 7008 final boolean allowed = checkCallingPermission( 7009 android.Manifest.permission.GET_TASKS) 7010 == PackageManager.PERMISSION_GRANTED; 7011 if (!allowed) { 7012 Slog.w(TAG, "getRecentTasks: caller " + callingUid 7013 + " does not hold GET_TASKS; limiting output"); 7014 } 7015 final boolean detailed = checkCallingPermission( 7016 android.Manifest.permission.GET_DETAILED_TASKS) 7017 == PackageManager.PERMISSION_GRANTED; 7018 7019 IPackageManager pm = AppGlobals.getPackageManager(); 7020 7021 final int N = mRecentTasks.size(); 7022 ArrayList<ActivityManager.RecentTaskInfo> res 7023 = new ArrayList<ActivityManager.RecentTaskInfo>( 7024 maxNum < N ? maxNum : N); 7025 7026 final Set<Integer> includedUsers; 7027 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 7028 includedUsers = getProfileIdsLocked(userId); 7029 } else { 7030 includedUsers = new HashSet<Integer>(); 7031 } 7032 includedUsers.add(Integer.valueOf(userId)); 7033 for (int i=0; i<N && maxNum > 0; i++) { 7034 TaskRecord tr = mRecentTasks.get(i); 7035 // Only add calling user or related users recent tasks 7036 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 7037 7038 // Return the entry if desired by the caller. We always return 7039 // the first entry, because callers always expect this to be the 7040 // foreground app. We may filter others if the caller has 7041 // not supplied RECENT_WITH_EXCLUDED and there is some reason 7042 // we should exclude the entry. 7043 7044 if (i == 0 7045 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 7046 || (tr.intent == null) 7047 || ((tr.intent.getFlags() 7048 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 7049 if (!allowed) { 7050 // If the caller doesn't have the GET_TASKS permission, then only 7051 // allow them to see a small subset of tasks -- their own and home. 7052 if (!tr.isHomeTask() && tr.creatorUid != callingUid) { 7053 continue; 7054 } 7055 } 7056 ActivityManager.RecentTaskInfo rti 7057 = new ActivityManager.RecentTaskInfo(); 7058 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 7059 rti.persistentId = tr.taskId; 7060 rti.baseIntent = new Intent( 7061 tr.intent != null ? tr.intent : tr.affinityIntent); 7062 if (!detailed) { 7063 rti.baseIntent.replaceExtras((Bundle)null); 7064 } 7065 rti.origActivity = tr.origActivity; 7066 rti.description = tr.lastDescription; 7067 rti.stackId = tr.stack.mStackId; 7068 rti.userId = tr.userId; 7069 7070 // Traverse upwards looking for any break between main task activities and 7071 // utility activities. 7072 final ArrayList<ActivityRecord> activities = tr.mActivities; 7073 int activityNdx; 7074 final int numActivities = activities.size(); 7075 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 7076 ++activityNdx) { 7077 final ActivityRecord r = activities.get(activityNdx); 7078 if (r.intent != null && 7079 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 7080 != 0) { 7081 break; 7082 } 7083 } 7084 if (activityNdx > 0) { 7085 // Traverse downwards starting below break looking for set label, icon. 7086 // Note that if there are activities in the task but none of them set the 7087 // recent activity values, then we do not fall back to the last set 7088 // values in the TaskRecord. 7089 rti.activityValues = new ActivityManager.RecentsActivityValues(); 7090 for (--activityNdx; activityNdx >= 0; --activityNdx) { 7091 final ActivityRecord r = activities.get(activityNdx); 7092 if (r.activityValues != null) { 7093 if (rti.activityValues.label == null) { 7094 rti.activityValues.label = r.activityValues.label; 7095 tr.lastActivityValues.label = r.activityValues.label; 7096 } 7097 if (rti.activityValues.icon == null) { 7098 rti.activityValues.icon = r.activityValues.icon; 7099 tr.lastActivityValues.icon = r.activityValues.icon; 7100 } 7101 if (rti.activityValues.colorPrimary == 0) { 7102 rti.activityValues.colorPrimary = r.activityValues.colorPrimary; 7103 tr.lastActivityValues.colorPrimary = r.activityValues.colorPrimary; 7104 } 7105 } 7106 } 7107 } else { 7108 // If there are no activity records in this task, then we use the last 7109 // resolved values 7110 rti.activityValues = 7111 new ActivityManager.RecentsActivityValues(tr.lastActivityValues); 7112 } 7113 7114 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 7115 // Check whether this activity is currently available. 7116 try { 7117 if (rti.origActivity != null) { 7118 if (pm.getActivityInfo(rti.origActivity, 0, userId) 7119 == null) { 7120 continue; 7121 } 7122 } else if (rti.baseIntent != null) { 7123 if (pm.queryIntentActivities(rti.baseIntent, 7124 null, 0, userId) == null) { 7125 continue; 7126 } 7127 } 7128 } catch (RemoteException e) { 7129 // Will never happen. 7130 } 7131 } 7132 7133 res.add(rti); 7134 maxNum--; 7135 } 7136 } 7137 return res; 7138 } 7139 } 7140 7141 private TaskRecord recentTaskForIdLocked(int id) { 7142 final int N = mRecentTasks.size(); 7143 for (int i=0; i<N; i++) { 7144 TaskRecord tr = mRecentTasks.get(i); 7145 if (tr.taskId == id) { 7146 return tr; 7147 } 7148 } 7149 return null; 7150 } 7151 7152 @Override 7153 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7154 synchronized (this) { 7155 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7156 "getTaskThumbnails()"); 7157 TaskRecord tr = recentTaskForIdLocked(id); 7158 if (tr != null) { 7159 return tr.getTaskThumbnailsLocked(); 7160 } 7161 } 7162 return null; 7163 } 7164 7165 @Override 7166 public Bitmap getTaskTopThumbnail(int id) { 7167 synchronized (this) { 7168 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7169 "getTaskTopThumbnail()"); 7170 TaskRecord tr = recentTaskForIdLocked(id); 7171 if (tr != null) { 7172 return tr.getTaskTopThumbnailLocked(); 7173 } 7174 } 7175 return null; 7176 } 7177 7178 @Override 7179 public void setRecentsActivityValues(IBinder token, ActivityManager.RecentsActivityValues rav) { 7180 synchronized (this) { 7181 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7182 if (r != null) { 7183 r.activityValues = rav; 7184 } 7185 } 7186 } 7187 7188 @Override 7189 public boolean removeSubTask(int taskId, int subTaskIndex) { 7190 synchronized (this) { 7191 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7192 "removeSubTask()"); 7193 long ident = Binder.clearCallingIdentity(); 7194 try { 7195 TaskRecord tr = recentTaskForIdLocked(taskId); 7196 if (tr != null) { 7197 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7198 } 7199 return false; 7200 } finally { 7201 Binder.restoreCallingIdentity(ident); 7202 } 7203 } 7204 } 7205 7206 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7207 if (!pr.killedByAm) { 7208 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7209 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7210 pr.processName, pr.setAdj, reason); 7211 pr.killedByAm = true; 7212 Process.killProcessQuiet(pr.pid); 7213 } 7214 } 7215 7216 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7217 tr.disposeThumbnail(); 7218 mRecentTasks.remove(tr); 7219 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7220 Intent baseIntent = new Intent( 7221 tr.intent != null ? tr.intent : tr.affinityIntent); 7222 ComponentName component = baseIntent.getComponent(); 7223 if (component == null) { 7224 Slog.w(TAG, "Now component for base intent of task: " + tr); 7225 return; 7226 } 7227 7228 // Find any running services associated with this app. 7229 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7230 7231 if (killProcesses) { 7232 // Find any running processes associated with this app. 7233 final String pkg = component.getPackageName(); 7234 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7235 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7236 for (int i=0; i<pmap.size(); i++) { 7237 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7238 for (int j=0; j<uids.size(); j++) { 7239 ProcessRecord proc = uids.valueAt(j); 7240 if (proc.userId != tr.userId) { 7241 continue; 7242 } 7243 if (!proc.pkgList.containsKey(pkg)) { 7244 continue; 7245 } 7246 procs.add(proc); 7247 } 7248 } 7249 7250 // Kill the running processes. 7251 for (int i=0; i<procs.size(); i++) { 7252 ProcessRecord pr = procs.get(i); 7253 if (pr == mHomeProcess) { 7254 // Don't kill the home process along with tasks from the same package. 7255 continue; 7256 } 7257 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7258 killUnneededProcessLocked(pr, "remove task"); 7259 } else { 7260 pr.waitingToKill = "remove task"; 7261 } 7262 } 7263 } 7264 } 7265 7266 /** 7267 * Removes the task with the specified task id. 7268 * 7269 * @param taskId Identifier of the task to be removed. 7270 * @param flags Additional operational flags. May be 0 or 7271 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}. 7272 * @return Returns true if the given task was found and removed. 7273 */ 7274 private boolean removeTaskByIdLocked(int taskId, int flags) { 7275 TaskRecord tr = recentTaskForIdLocked(taskId); 7276 if (tr != null) { 7277 tr.removeTaskActivitiesLocked(-1, false); 7278 cleanUpRemovedTaskLocked(tr, flags); 7279 return true; 7280 } 7281 return false; 7282 } 7283 7284 @Override 7285 public boolean removeTask(int taskId, int flags) { 7286 synchronized (this) { 7287 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7288 "removeTask()"); 7289 long ident = Binder.clearCallingIdentity(); 7290 try { 7291 return removeTaskByIdLocked(taskId, flags); 7292 } finally { 7293 Binder.restoreCallingIdentity(ident); 7294 } 7295 } 7296 } 7297 7298 /** 7299 * TODO: Add mController hook 7300 */ 7301 @Override 7302 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7303 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7304 "moveTaskToFront()"); 7305 7306 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7307 synchronized(this) { 7308 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7309 Binder.getCallingUid(), "Task to front")) { 7310 ActivityOptions.abort(options); 7311 return; 7312 } 7313 final long origId = Binder.clearCallingIdentity(); 7314 try { 7315 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7316 if (task == null) { 7317 return; 7318 } 7319 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7320 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7321 return; 7322 } 7323 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7324 } finally { 7325 Binder.restoreCallingIdentity(origId); 7326 } 7327 ActivityOptions.abort(options); 7328 } 7329 } 7330 7331 @Override 7332 public void moveTaskToBack(int taskId) { 7333 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7334 "moveTaskToBack()"); 7335 7336 synchronized(this) { 7337 TaskRecord tr = recentTaskForIdLocked(taskId); 7338 if (tr != null) { 7339 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7340 ActivityStack stack = tr.stack; 7341 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7342 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7343 Binder.getCallingUid(), "Task to back")) { 7344 return; 7345 } 7346 } 7347 final long origId = Binder.clearCallingIdentity(); 7348 try { 7349 stack.moveTaskToBackLocked(taskId, null); 7350 } finally { 7351 Binder.restoreCallingIdentity(origId); 7352 } 7353 } 7354 } 7355 } 7356 7357 /** 7358 * Moves an activity, and all of the other activities within the same task, to the bottom 7359 * of the history stack. The activity's order within the task is unchanged. 7360 * 7361 * @param token A reference to the activity we wish to move 7362 * @param nonRoot If false then this only works if the activity is the root 7363 * of a task; if true it will work for any activity in a task. 7364 * @return Returns true if the move completed, false if not. 7365 */ 7366 @Override 7367 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7368 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7369 synchronized(this) { 7370 final long origId = Binder.clearCallingIdentity(); 7371 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7372 if (taskId >= 0) { 7373 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7374 } 7375 Binder.restoreCallingIdentity(origId); 7376 } 7377 return false; 7378 } 7379 7380 @Override 7381 public void moveTaskBackwards(int task) { 7382 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7383 "moveTaskBackwards()"); 7384 7385 synchronized(this) { 7386 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7387 Binder.getCallingUid(), "Task backwards")) { 7388 return; 7389 } 7390 final long origId = Binder.clearCallingIdentity(); 7391 moveTaskBackwardsLocked(task); 7392 Binder.restoreCallingIdentity(origId); 7393 } 7394 } 7395 7396 private final void moveTaskBackwardsLocked(int task) { 7397 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7398 } 7399 7400 @Override 7401 public IBinder getHomeActivityToken() throws RemoteException { 7402 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7403 "getHomeActivityToken()"); 7404 synchronized (this) { 7405 return mStackSupervisor.getHomeActivityToken(); 7406 } 7407 } 7408 7409 @Override 7410 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7411 IActivityContainerCallback callback) throws RemoteException { 7412 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7413 "createActivityContainer()"); 7414 synchronized (this) { 7415 if (parentActivityToken == null) { 7416 throw new IllegalArgumentException("parent token must not be null"); 7417 } 7418 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7419 if (r == null) { 7420 return null; 7421 } 7422 if (callback == null) { 7423 throw new IllegalArgumentException("callback must not be null"); 7424 } 7425 return mStackSupervisor.createActivityContainer(r, callback); 7426 } 7427 } 7428 7429 @Override 7430 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7431 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7432 "deleteActivityContainer()"); 7433 synchronized (this) { 7434 mStackSupervisor.deleteActivityContainer(container); 7435 } 7436 } 7437 7438 @Override 7439 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7440 throws RemoteException { 7441 synchronized (this) { 7442 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7443 if (stack != null) { 7444 return stack.mActivityContainer; 7445 } 7446 return null; 7447 } 7448 } 7449 7450 @Override 7451 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7452 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7453 "moveTaskToStack()"); 7454 if (stackId == HOME_STACK_ID) { 7455 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7456 new RuntimeException("here").fillInStackTrace()); 7457 } 7458 synchronized (this) { 7459 long ident = Binder.clearCallingIdentity(); 7460 try { 7461 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7462 + stackId + " toTop=" + toTop); 7463 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7464 } finally { 7465 Binder.restoreCallingIdentity(ident); 7466 } 7467 } 7468 } 7469 7470 @Override 7471 public void resizeStack(int stackBoxId, Rect bounds) { 7472 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7473 "resizeStackBox()"); 7474 long ident = Binder.clearCallingIdentity(); 7475 try { 7476 mWindowManager.resizeStack(stackBoxId, bounds); 7477 } finally { 7478 Binder.restoreCallingIdentity(ident); 7479 } 7480 } 7481 7482 @Override 7483 public List<StackInfo> getAllStackInfos() { 7484 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7485 "getAllStackInfos()"); 7486 long ident = Binder.clearCallingIdentity(); 7487 try { 7488 synchronized (this) { 7489 return mStackSupervisor.getAllStackInfosLocked(); 7490 } 7491 } finally { 7492 Binder.restoreCallingIdentity(ident); 7493 } 7494 } 7495 7496 @Override 7497 public StackInfo getStackInfo(int stackId) { 7498 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7499 "getStackInfo()"); 7500 long ident = Binder.clearCallingIdentity(); 7501 try { 7502 synchronized (this) { 7503 return mStackSupervisor.getStackInfoLocked(stackId); 7504 } 7505 } finally { 7506 Binder.restoreCallingIdentity(ident); 7507 } 7508 } 7509 7510 @Override 7511 public boolean isInHomeStack(int taskId) { 7512 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7513 "getStackInfo()"); 7514 long ident = Binder.clearCallingIdentity(); 7515 try { 7516 synchronized (this) { 7517 TaskRecord tr = recentTaskForIdLocked(taskId); 7518 if (tr != null) { 7519 return tr.stack.isHomeStack(); 7520 } 7521 } 7522 } finally { 7523 Binder.restoreCallingIdentity(ident); 7524 } 7525 return false; 7526 } 7527 7528 @Override 7529 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7530 synchronized(this) { 7531 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7532 } 7533 } 7534 7535 private boolean isLockTaskAuthorized(ComponentName name) { 7536// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7537// "startLockTaskMode()"); 7538// DevicePolicyManager dpm = (DevicePolicyManager) 7539// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7540// return dpm != null && dpm.isLockTaskPermitted(name); 7541 return true; 7542 } 7543 7544 private void startLockTaskMode(TaskRecord task) { 7545 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7546 return; 7547 } 7548 long ident = Binder.clearCallingIdentity(); 7549 try { 7550 synchronized (this) { 7551 // Since we lost lock on task, make sure it is still there. 7552 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7553 if (task != null) { 7554 mStackSupervisor.setLockTaskModeLocked(task); 7555 } 7556 } 7557 } finally { 7558 Binder.restoreCallingIdentity(ident); 7559 } 7560 } 7561 7562 @Override 7563 public void startLockTaskMode(int taskId) { 7564 long ident = Binder.clearCallingIdentity(); 7565 try { 7566 final TaskRecord task; 7567 synchronized (this) { 7568 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7569 } 7570 if (task != null) { 7571 startLockTaskMode(task); 7572 } 7573 } finally { 7574 Binder.restoreCallingIdentity(ident); 7575 } 7576 } 7577 7578 @Override 7579 public void startLockTaskMode(IBinder token) { 7580 long ident = Binder.clearCallingIdentity(); 7581 try { 7582 final TaskRecord task; 7583 synchronized (this) { 7584 final ActivityRecord r = ActivityRecord.forToken(token); 7585 if (r == null) { 7586 return; 7587 } 7588 task = r.task; 7589 } 7590 if (task != null) { 7591 startLockTaskMode(task); 7592 } 7593 } finally { 7594 Binder.restoreCallingIdentity(ident); 7595 } 7596 } 7597 7598 @Override 7599 public void stopLockTaskMode() { 7600// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7601// "stopLockTaskMode()"); 7602 synchronized (this) { 7603 mStackSupervisor.setLockTaskModeLocked(null); 7604 } 7605 } 7606 7607 @Override 7608 public boolean isInLockTaskMode() { 7609 synchronized (this) { 7610 return mStackSupervisor.isInLockTaskMode(); 7611 } 7612 } 7613 7614 // ========================================================= 7615 // CONTENT PROVIDERS 7616 // ========================================================= 7617 7618 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7619 List<ProviderInfo> providers = null; 7620 try { 7621 providers = AppGlobals.getPackageManager(). 7622 queryContentProviders(app.processName, app.uid, 7623 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7624 } catch (RemoteException ex) { 7625 } 7626 if (DEBUG_MU) 7627 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7628 int userId = app.userId; 7629 if (providers != null) { 7630 int N = providers.size(); 7631 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7632 for (int i=0; i<N; i++) { 7633 ProviderInfo cpi = 7634 (ProviderInfo)providers.get(i); 7635 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7636 cpi.name, cpi.flags); 7637 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7638 // This is a singleton provider, but a user besides the 7639 // default user is asking to initialize a process it runs 7640 // in... well, no, it doesn't actually run in this process, 7641 // it runs in the process of the default user. Get rid of it. 7642 providers.remove(i); 7643 N--; 7644 i--; 7645 continue; 7646 } 7647 7648 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7649 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7650 if (cpr == null) { 7651 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7652 mProviderMap.putProviderByClass(comp, cpr); 7653 } 7654 if (DEBUG_MU) 7655 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7656 app.pubProviders.put(cpi.name, cpr); 7657 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7658 // Don't add this if it is a platform component that is marked 7659 // to run in multiple processes, because this is actually 7660 // part of the framework so doesn't make sense to track as a 7661 // separate apk in the process. 7662 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7663 } 7664 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7665 } 7666 } 7667 return providers; 7668 } 7669 7670 /** 7671 * Check if {@link ProcessRecord} has a possible chance at accessing the 7672 * given {@link ProviderInfo}. Final permission checking is always done 7673 * in {@link ContentProvider}. 7674 */ 7675 private final String checkContentProviderPermissionLocked( 7676 ProviderInfo cpi, ProcessRecord r) { 7677 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7678 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7679 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7680 cpi.applicationInfo.uid, cpi.exported) 7681 == PackageManager.PERMISSION_GRANTED) { 7682 return null; 7683 } 7684 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7685 cpi.applicationInfo.uid, cpi.exported) 7686 == PackageManager.PERMISSION_GRANTED) { 7687 return null; 7688 } 7689 7690 PathPermission[] pps = cpi.pathPermissions; 7691 if (pps != null) { 7692 int i = pps.length; 7693 while (i > 0) { 7694 i--; 7695 PathPermission pp = pps[i]; 7696 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7697 cpi.applicationInfo.uid, cpi.exported) 7698 == PackageManager.PERMISSION_GRANTED) { 7699 return null; 7700 } 7701 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7702 cpi.applicationInfo.uid, cpi.exported) 7703 == PackageManager.PERMISSION_GRANTED) { 7704 return null; 7705 } 7706 } 7707 } 7708 7709 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7710 if (perms != null) { 7711 for (GrantUri uri : perms.keySet()) { 7712 if (uri.uri.getAuthority().equals(cpi.authority)) { 7713 return null; 7714 } 7715 } 7716 } 7717 7718 String msg; 7719 if (!cpi.exported) { 7720 msg = "Permission Denial: opening provider " + cpi.name 7721 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7722 + ", uid=" + callingUid + ") that is not exported from uid " 7723 + cpi.applicationInfo.uid; 7724 } else { 7725 msg = "Permission Denial: opening provider " + cpi.name 7726 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7727 + ", uid=" + callingUid + ") requires " 7728 + cpi.readPermission + " or " + cpi.writePermission; 7729 } 7730 Slog.w(TAG, msg); 7731 return msg; 7732 } 7733 7734 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7735 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7736 if (r != null) { 7737 for (int i=0; i<r.conProviders.size(); i++) { 7738 ContentProviderConnection conn = r.conProviders.get(i); 7739 if (conn.provider == cpr) { 7740 if (DEBUG_PROVIDER) Slog.v(TAG, 7741 "Adding provider requested by " 7742 + r.processName + " from process " 7743 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7744 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7745 if (stable) { 7746 conn.stableCount++; 7747 conn.numStableIncs++; 7748 } else { 7749 conn.unstableCount++; 7750 conn.numUnstableIncs++; 7751 } 7752 return conn; 7753 } 7754 } 7755 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7756 if (stable) { 7757 conn.stableCount = 1; 7758 conn.numStableIncs = 1; 7759 } else { 7760 conn.unstableCount = 1; 7761 conn.numUnstableIncs = 1; 7762 } 7763 cpr.connections.add(conn); 7764 r.conProviders.add(conn); 7765 return conn; 7766 } 7767 cpr.addExternalProcessHandleLocked(externalProcessToken); 7768 return null; 7769 } 7770 7771 boolean decProviderCountLocked(ContentProviderConnection conn, 7772 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7773 if (conn != null) { 7774 cpr = conn.provider; 7775 if (DEBUG_PROVIDER) Slog.v(TAG, 7776 "Removing provider requested by " 7777 + conn.client.processName + " from process " 7778 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7779 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7780 if (stable) { 7781 conn.stableCount--; 7782 } else { 7783 conn.unstableCount--; 7784 } 7785 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7786 cpr.connections.remove(conn); 7787 conn.client.conProviders.remove(conn); 7788 return true; 7789 } 7790 return false; 7791 } 7792 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7793 return false; 7794 } 7795 7796 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7797 String name, IBinder token, boolean stable, int userId) { 7798 ContentProviderRecord cpr; 7799 ContentProviderConnection conn = null; 7800 ProviderInfo cpi = null; 7801 7802 synchronized(this) { 7803 ProcessRecord r = null; 7804 if (caller != null) { 7805 r = getRecordForAppLocked(caller); 7806 if (r == null) { 7807 throw new SecurityException( 7808 "Unable to find app for caller " + caller 7809 + " (pid=" + Binder.getCallingPid() 7810 + ") when getting content provider " + name); 7811 } 7812 } 7813 7814 // First check if this content provider has been published... 7815 cpr = mProviderMap.getProviderByName(name, userId); 7816 boolean providerRunning = cpr != null; 7817 if (providerRunning) { 7818 cpi = cpr.info; 7819 String msg; 7820 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7821 throw new SecurityException(msg); 7822 } 7823 7824 if (r != null && cpr.canRunHere(r)) { 7825 // This provider has been published or is in the process 7826 // of being published... but it is also allowed to run 7827 // in the caller's process, so don't make a connection 7828 // and just let the caller instantiate its own instance. 7829 ContentProviderHolder holder = cpr.newHolder(null); 7830 // don't give caller the provider object, it needs 7831 // to make its own. 7832 holder.provider = null; 7833 return holder; 7834 } 7835 7836 final long origId = Binder.clearCallingIdentity(); 7837 7838 // In this case the provider instance already exists, so we can 7839 // return it right away. 7840 conn = incProviderCountLocked(r, cpr, token, stable); 7841 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7842 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7843 // If this is a perceptible app accessing the provider, 7844 // make sure to count it as being accessed and thus 7845 // back up on the LRU list. This is good because 7846 // content providers are often expensive to start. 7847 updateLruProcessLocked(cpr.proc, false, null); 7848 } 7849 } 7850 7851 if (cpr.proc != null) { 7852 if (false) { 7853 if (cpr.name.flattenToShortString().equals( 7854 "com.android.providers.calendar/.CalendarProvider2")) { 7855 Slog.v(TAG, "****************** KILLING " 7856 + cpr.name.flattenToShortString()); 7857 Process.killProcess(cpr.proc.pid); 7858 } 7859 } 7860 boolean success = updateOomAdjLocked(cpr.proc); 7861 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7862 // NOTE: there is still a race here where a signal could be 7863 // pending on the process even though we managed to update its 7864 // adj level. Not sure what to do about this, but at least 7865 // the race is now smaller. 7866 if (!success) { 7867 // Uh oh... it looks like the provider's process 7868 // has been killed on us. We need to wait for a new 7869 // process to be started, and make sure its death 7870 // doesn't kill our process. 7871 Slog.i(TAG, 7872 "Existing provider " + cpr.name.flattenToShortString() 7873 + " is crashing; detaching " + r); 7874 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7875 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7876 if (!lastRef) { 7877 // This wasn't the last ref our process had on 7878 // the provider... we have now been killed, bail. 7879 return null; 7880 } 7881 providerRunning = false; 7882 conn = null; 7883 } 7884 } 7885 7886 Binder.restoreCallingIdentity(origId); 7887 } 7888 7889 boolean singleton; 7890 if (!providerRunning) { 7891 try { 7892 cpi = AppGlobals.getPackageManager(). 7893 resolveContentProvider(name, 7894 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7895 } catch (RemoteException ex) { 7896 } 7897 if (cpi == null) { 7898 return null; 7899 } 7900 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7901 cpi.name, cpi.flags); 7902 if (singleton) { 7903 userId = 0; 7904 } 7905 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7906 7907 String msg; 7908 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7909 throw new SecurityException(msg); 7910 } 7911 7912 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7913 && !cpi.processName.equals("system")) { 7914 // If this content provider does not run in the system 7915 // process, and the system is not yet ready to run other 7916 // processes, then fail fast instead of hanging. 7917 throw new IllegalArgumentException( 7918 "Attempt to launch content provider before system ready"); 7919 } 7920 7921 // Make sure that the user who owns this provider is started. If not, 7922 // we don't want to allow it to run. 7923 if (mStartedUsers.get(userId) == null) { 7924 Slog.w(TAG, "Unable to launch app " 7925 + cpi.applicationInfo.packageName + "/" 7926 + cpi.applicationInfo.uid + " for provider " 7927 + name + ": user " + userId + " is stopped"); 7928 return null; 7929 } 7930 7931 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7932 cpr = mProviderMap.getProviderByClass(comp, userId); 7933 final boolean firstClass = cpr == null; 7934 if (firstClass) { 7935 try { 7936 ApplicationInfo ai = 7937 AppGlobals.getPackageManager(). 7938 getApplicationInfo( 7939 cpi.applicationInfo.packageName, 7940 STOCK_PM_FLAGS, userId); 7941 if (ai == null) { 7942 Slog.w(TAG, "No package info for content provider " 7943 + cpi.name); 7944 return null; 7945 } 7946 ai = getAppInfoForUser(ai, userId); 7947 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7948 } catch (RemoteException ex) { 7949 // pm is in same process, this will never happen. 7950 } 7951 } 7952 7953 if (r != null && cpr.canRunHere(r)) { 7954 // If this is a multiprocess provider, then just return its 7955 // info and allow the caller to instantiate it. Only do 7956 // this if the provider is the same user as the caller's 7957 // process, or can run as root (so can be in any process). 7958 return cpr.newHolder(null); 7959 } 7960 7961 if (DEBUG_PROVIDER) { 7962 RuntimeException e = new RuntimeException("here"); 7963 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7964 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7965 } 7966 7967 // This is single process, and our app is now connecting to it. 7968 // See if we are already in the process of launching this 7969 // provider. 7970 final int N = mLaunchingProviders.size(); 7971 int i; 7972 for (i=0; i<N; i++) { 7973 if (mLaunchingProviders.get(i) == cpr) { 7974 break; 7975 } 7976 } 7977 7978 // If the provider is not already being launched, then get it 7979 // started. 7980 if (i >= N) { 7981 final long origId = Binder.clearCallingIdentity(); 7982 7983 try { 7984 // Content provider is now in use, its package can't be stopped. 7985 try { 7986 AppGlobals.getPackageManager().setPackageStoppedState( 7987 cpr.appInfo.packageName, false, userId); 7988 } catch (RemoteException e) { 7989 } catch (IllegalArgumentException e) { 7990 Slog.w(TAG, "Failed trying to unstop package " 7991 + cpr.appInfo.packageName + ": " + e); 7992 } 7993 7994 // Use existing process if already started 7995 ProcessRecord proc = getProcessRecordLocked( 7996 cpi.processName, cpr.appInfo.uid, false); 7997 if (proc != null && proc.thread != null) { 7998 if (DEBUG_PROVIDER) { 7999 Slog.d(TAG, "Installing in existing process " + proc); 8000 } 8001 proc.pubProviders.put(cpi.name, cpr); 8002 try { 8003 proc.thread.scheduleInstallProvider(cpi); 8004 } catch (RemoteException e) { 8005 } 8006 } else { 8007 proc = startProcessLocked(cpi.processName, 8008 cpr.appInfo, false, 0, "content provider", 8009 new ComponentName(cpi.applicationInfo.packageName, 8010 cpi.name), false, false, false); 8011 if (proc == null) { 8012 Slog.w(TAG, "Unable to launch app " 8013 + cpi.applicationInfo.packageName + "/" 8014 + cpi.applicationInfo.uid + " for provider " 8015 + name + ": process is bad"); 8016 return null; 8017 } 8018 } 8019 cpr.launchingApp = proc; 8020 mLaunchingProviders.add(cpr); 8021 } finally { 8022 Binder.restoreCallingIdentity(origId); 8023 } 8024 } 8025 8026 // Make sure the provider is published (the same provider class 8027 // may be published under multiple names). 8028 if (firstClass) { 8029 mProviderMap.putProviderByClass(comp, cpr); 8030 } 8031 8032 mProviderMap.putProviderByName(name, cpr); 8033 conn = incProviderCountLocked(r, cpr, token, stable); 8034 if (conn != null) { 8035 conn.waiting = true; 8036 } 8037 } 8038 } 8039 8040 // Wait for the provider to be published... 8041 synchronized (cpr) { 8042 while (cpr.provider == null) { 8043 if (cpr.launchingApp == null) { 8044 Slog.w(TAG, "Unable to launch app " 8045 + cpi.applicationInfo.packageName + "/" 8046 + cpi.applicationInfo.uid + " for provider " 8047 + name + ": launching app became null"); 8048 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8049 UserHandle.getUserId(cpi.applicationInfo.uid), 8050 cpi.applicationInfo.packageName, 8051 cpi.applicationInfo.uid, name); 8052 return null; 8053 } 8054 try { 8055 if (DEBUG_MU) { 8056 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8057 + cpr.launchingApp); 8058 } 8059 if (conn != null) { 8060 conn.waiting = true; 8061 } 8062 cpr.wait(); 8063 } catch (InterruptedException ex) { 8064 } finally { 8065 if (conn != null) { 8066 conn.waiting = false; 8067 } 8068 } 8069 } 8070 } 8071 return cpr != null ? cpr.newHolder(conn) : null; 8072 } 8073 8074 public final ContentProviderHolder getContentProvider( 8075 IApplicationThread caller, String name, int userId, boolean stable) { 8076 enforceNotIsolatedCaller("getContentProvider"); 8077 if (caller == null) { 8078 String msg = "null IApplicationThread when getting content provider " 8079 + name; 8080 Slog.w(TAG, msg); 8081 throw new SecurityException(msg); 8082 } 8083 8084 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8085 false, true, "getContentProvider", null); 8086 return getContentProviderImpl(caller, name, null, stable, userId); 8087 } 8088 8089 public ContentProviderHolder getContentProviderExternal( 8090 String name, int userId, IBinder token) { 8091 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8092 "Do not have permission in call getContentProviderExternal()"); 8093 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8094 false, true, "getContentProvider", null); 8095 return getContentProviderExternalUnchecked(name, token, userId); 8096 } 8097 8098 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8099 IBinder token, int userId) { 8100 return getContentProviderImpl(null, name, token, true, userId); 8101 } 8102 8103 /** 8104 * Drop a content provider from a ProcessRecord's bookkeeping 8105 */ 8106 public void removeContentProvider(IBinder connection, boolean stable) { 8107 enforceNotIsolatedCaller("removeContentProvider"); 8108 long ident = Binder.clearCallingIdentity(); 8109 try { 8110 synchronized (this) { 8111 ContentProviderConnection conn; 8112 try { 8113 conn = (ContentProviderConnection)connection; 8114 } catch (ClassCastException e) { 8115 String msg ="removeContentProvider: " + connection 8116 + " not a ContentProviderConnection"; 8117 Slog.w(TAG, msg); 8118 throw new IllegalArgumentException(msg); 8119 } 8120 if (conn == null) { 8121 throw new NullPointerException("connection is null"); 8122 } 8123 if (decProviderCountLocked(conn, null, null, stable)) { 8124 updateOomAdjLocked(); 8125 } 8126 } 8127 } finally { 8128 Binder.restoreCallingIdentity(ident); 8129 } 8130 } 8131 8132 public void removeContentProviderExternal(String name, IBinder token) { 8133 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8134 "Do not have permission in call removeContentProviderExternal()"); 8135 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8136 } 8137 8138 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8139 synchronized (this) { 8140 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8141 if(cpr == null) { 8142 //remove from mProvidersByClass 8143 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8144 return; 8145 } 8146 8147 //update content provider record entry info 8148 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8149 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8150 if (localCpr.hasExternalProcessHandles()) { 8151 if (localCpr.removeExternalProcessHandleLocked(token)) { 8152 updateOomAdjLocked(); 8153 } else { 8154 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8155 + " with no external reference for token: " 8156 + token + "."); 8157 } 8158 } else { 8159 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8160 + " with no external references."); 8161 } 8162 } 8163 } 8164 8165 public final void publishContentProviders(IApplicationThread caller, 8166 List<ContentProviderHolder> providers) { 8167 if (providers == null) { 8168 return; 8169 } 8170 8171 enforceNotIsolatedCaller("publishContentProviders"); 8172 synchronized (this) { 8173 final ProcessRecord r = getRecordForAppLocked(caller); 8174 if (DEBUG_MU) 8175 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8176 if (r == null) { 8177 throw new SecurityException( 8178 "Unable to find app for caller " + caller 8179 + " (pid=" + Binder.getCallingPid() 8180 + ") when publishing content providers"); 8181 } 8182 8183 final long origId = Binder.clearCallingIdentity(); 8184 8185 final int N = providers.size(); 8186 for (int i=0; i<N; i++) { 8187 ContentProviderHolder src = providers.get(i); 8188 if (src == null || src.info == null || src.provider == null) { 8189 continue; 8190 } 8191 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8192 if (DEBUG_MU) 8193 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8194 if (dst != null) { 8195 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8196 mProviderMap.putProviderByClass(comp, dst); 8197 String names[] = dst.info.authority.split(";"); 8198 for (int j = 0; j < names.length; j++) { 8199 mProviderMap.putProviderByName(names[j], dst); 8200 } 8201 8202 int NL = mLaunchingProviders.size(); 8203 int j; 8204 for (j=0; j<NL; j++) { 8205 if (mLaunchingProviders.get(j) == dst) { 8206 mLaunchingProviders.remove(j); 8207 j--; 8208 NL--; 8209 } 8210 } 8211 synchronized (dst) { 8212 dst.provider = src.provider; 8213 dst.proc = r; 8214 dst.notifyAll(); 8215 } 8216 updateOomAdjLocked(r); 8217 } 8218 } 8219 8220 Binder.restoreCallingIdentity(origId); 8221 } 8222 } 8223 8224 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8225 ContentProviderConnection conn; 8226 try { 8227 conn = (ContentProviderConnection)connection; 8228 } catch (ClassCastException e) { 8229 String msg ="refContentProvider: " + connection 8230 + " not a ContentProviderConnection"; 8231 Slog.w(TAG, msg); 8232 throw new IllegalArgumentException(msg); 8233 } 8234 if (conn == null) { 8235 throw new NullPointerException("connection is null"); 8236 } 8237 8238 synchronized (this) { 8239 if (stable > 0) { 8240 conn.numStableIncs += stable; 8241 } 8242 stable = conn.stableCount + stable; 8243 if (stable < 0) { 8244 throw new IllegalStateException("stableCount < 0: " + stable); 8245 } 8246 8247 if (unstable > 0) { 8248 conn.numUnstableIncs += unstable; 8249 } 8250 unstable = conn.unstableCount + unstable; 8251 if (unstable < 0) { 8252 throw new IllegalStateException("unstableCount < 0: " + unstable); 8253 } 8254 8255 if ((stable+unstable) <= 0) { 8256 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8257 + stable + " unstable=" + unstable); 8258 } 8259 conn.stableCount = stable; 8260 conn.unstableCount = unstable; 8261 return !conn.dead; 8262 } 8263 } 8264 8265 public void unstableProviderDied(IBinder connection) { 8266 ContentProviderConnection conn; 8267 try { 8268 conn = (ContentProviderConnection)connection; 8269 } catch (ClassCastException e) { 8270 String msg ="refContentProvider: " + connection 8271 + " not a ContentProviderConnection"; 8272 Slog.w(TAG, msg); 8273 throw new IllegalArgumentException(msg); 8274 } 8275 if (conn == null) { 8276 throw new NullPointerException("connection is null"); 8277 } 8278 8279 // Safely retrieve the content provider associated with the connection. 8280 IContentProvider provider; 8281 synchronized (this) { 8282 provider = conn.provider.provider; 8283 } 8284 8285 if (provider == null) { 8286 // Um, yeah, we're way ahead of you. 8287 return; 8288 } 8289 8290 // Make sure the caller is being honest with us. 8291 if (provider.asBinder().pingBinder()) { 8292 // Er, no, still looks good to us. 8293 synchronized (this) { 8294 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8295 + " says " + conn + " died, but we don't agree"); 8296 return; 8297 } 8298 } 8299 8300 // Well look at that! It's dead! 8301 synchronized (this) { 8302 if (conn.provider.provider != provider) { 8303 // But something changed... good enough. 8304 return; 8305 } 8306 8307 ProcessRecord proc = conn.provider.proc; 8308 if (proc == null || proc.thread == null) { 8309 // Seems like the process is already cleaned up. 8310 return; 8311 } 8312 8313 // As far as we're concerned, this is just like receiving a 8314 // death notification... just a bit prematurely. 8315 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8316 + ") early provider death"); 8317 final long ident = Binder.clearCallingIdentity(); 8318 try { 8319 appDiedLocked(proc, proc.pid, proc.thread); 8320 } finally { 8321 Binder.restoreCallingIdentity(ident); 8322 } 8323 } 8324 } 8325 8326 @Override 8327 public void appNotRespondingViaProvider(IBinder connection) { 8328 enforceCallingPermission( 8329 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8330 8331 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8332 if (conn == null) { 8333 Slog.w(TAG, "ContentProviderConnection is null"); 8334 return; 8335 } 8336 8337 final ProcessRecord host = conn.provider.proc; 8338 if (host == null) { 8339 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8340 return; 8341 } 8342 8343 final long token = Binder.clearCallingIdentity(); 8344 try { 8345 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8346 } finally { 8347 Binder.restoreCallingIdentity(token); 8348 } 8349 } 8350 8351 public final void installSystemProviders() { 8352 List<ProviderInfo> providers; 8353 synchronized (this) { 8354 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8355 providers = generateApplicationProvidersLocked(app); 8356 if (providers != null) { 8357 for (int i=providers.size()-1; i>=0; i--) { 8358 ProviderInfo pi = (ProviderInfo)providers.get(i); 8359 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8360 Slog.w(TAG, "Not installing system proc provider " + pi.name 8361 + ": not system .apk"); 8362 providers.remove(i); 8363 } 8364 } 8365 } 8366 } 8367 if (providers != null) { 8368 mSystemThread.installSystemProviders(providers); 8369 } 8370 8371 mCoreSettingsObserver = new CoreSettingsObserver(this); 8372 8373 mUsageStatsService.monitorPackages(); 8374 } 8375 8376 /** 8377 * Allows app to retrieve the MIME type of a URI without having permission 8378 * to access its content provider. 8379 * 8380 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8381 * 8382 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8383 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8384 */ 8385 public String getProviderMimeType(Uri uri, int userId) { 8386 enforceNotIsolatedCaller("getProviderMimeType"); 8387 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8388 userId, false, true, "getProviderMimeType", null); 8389 final String name = uri.getAuthority(); 8390 final long ident = Binder.clearCallingIdentity(); 8391 ContentProviderHolder holder = null; 8392 8393 try { 8394 holder = getContentProviderExternalUnchecked(name, null, userId); 8395 if (holder != null) { 8396 return holder.provider.getType(uri); 8397 } 8398 } catch (RemoteException e) { 8399 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8400 return null; 8401 } finally { 8402 if (holder != null) { 8403 removeContentProviderExternalUnchecked(name, null, userId); 8404 } 8405 Binder.restoreCallingIdentity(ident); 8406 } 8407 8408 return null; 8409 } 8410 8411 // ========================================================= 8412 // GLOBAL MANAGEMENT 8413 // ========================================================= 8414 8415 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8416 boolean isolated) { 8417 String proc = customProcess != null ? customProcess : info.processName; 8418 BatteryStatsImpl.Uid.Proc ps = null; 8419 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8420 int uid = info.uid; 8421 if (isolated) { 8422 int userId = UserHandle.getUserId(uid); 8423 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8424 while (true) { 8425 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8426 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8427 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8428 } 8429 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8430 mNextIsolatedProcessUid++; 8431 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8432 // No process for this uid, use it. 8433 break; 8434 } 8435 stepsLeft--; 8436 if (stepsLeft <= 0) { 8437 return null; 8438 } 8439 } 8440 } 8441 return new ProcessRecord(stats, info, proc, uid); 8442 } 8443 8444 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8445 ProcessRecord app; 8446 if (!isolated) { 8447 app = getProcessRecordLocked(info.processName, info.uid, true); 8448 } else { 8449 app = null; 8450 } 8451 8452 if (app == null) { 8453 app = newProcessRecordLocked(info, null, isolated); 8454 mProcessNames.put(info.processName, app.uid, app); 8455 if (isolated) { 8456 mIsolatedProcesses.put(app.uid, app); 8457 } 8458 updateLruProcessLocked(app, false, null); 8459 updateOomAdjLocked(); 8460 } 8461 8462 // This package really, really can not be stopped. 8463 try { 8464 AppGlobals.getPackageManager().setPackageStoppedState( 8465 info.packageName, false, UserHandle.getUserId(app.uid)); 8466 } catch (RemoteException e) { 8467 } catch (IllegalArgumentException e) { 8468 Slog.w(TAG, "Failed trying to unstop package " 8469 + info.packageName + ": " + e); 8470 } 8471 8472 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8473 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8474 app.persistent = true; 8475 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8476 } 8477 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8478 mPersistentStartingProcesses.add(app); 8479 startProcessLocked(app, "added application", app.processName); 8480 } 8481 8482 return app; 8483 } 8484 8485 public void unhandledBack() { 8486 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8487 "unhandledBack()"); 8488 8489 synchronized(this) { 8490 final long origId = Binder.clearCallingIdentity(); 8491 try { 8492 getFocusedStack().unhandledBackLocked(); 8493 } finally { 8494 Binder.restoreCallingIdentity(origId); 8495 } 8496 } 8497 } 8498 8499 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8500 enforceNotIsolatedCaller("openContentUri"); 8501 final int userId = UserHandle.getCallingUserId(); 8502 String name = uri.getAuthority(); 8503 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8504 ParcelFileDescriptor pfd = null; 8505 if (cph != null) { 8506 // We record the binder invoker's uid in thread-local storage before 8507 // going to the content provider to open the file. Later, in the code 8508 // that handles all permissions checks, we look for this uid and use 8509 // that rather than the Activity Manager's own uid. The effect is that 8510 // we do the check against the caller's permissions even though it looks 8511 // to the content provider like the Activity Manager itself is making 8512 // the request. 8513 sCallerIdentity.set(new Identity( 8514 Binder.getCallingPid(), Binder.getCallingUid())); 8515 try { 8516 pfd = cph.provider.openFile(null, uri, "r", null); 8517 } catch (FileNotFoundException e) { 8518 // do nothing; pfd will be returned null 8519 } finally { 8520 // Ensure that whatever happens, we clean up the identity state 8521 sCallerIdentity.remove(); 8522 } 8523 8524 // We've got the fd now, so we're done with the provider. 8525 removeContentProviderExternalUnchecked(name, null, userId); 8526 } else { 8527 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8528 } 8529 return pfd; 8530 } 8531 8532 // Actually is sleeping or shutting down or whatever else in the future 8533 // is an inactive state. 8534 public boolean isSleepingOrShuttingDown() { 8535 return mSleeping || mShuttingDown; 8536 } 8537 8538 public boolean isSleeping() { 8539 return mSleeping; 8540 } 8541 8542 void goingToSleep() { 8543 synchronized(this) { 8544 mWentToSleep = true; 8545 updateEventDispatchingLocked(); 8546 goToSleepIfNeededLocked(); 8547 } 8548 } 8549 8550 void finishRunningVoiceLocked() { 8551 if (mRunningVoice) { 8552 mRunningVoice = false; 8553 goToSleepIfNeededLocked(); 8554 } 8555 } 8556 8557 void goToSleepIfNeededLocked() { 8558 if (mWentToSleep && !mRunningVoice) { 8559 if (!mSleeping) { 8560 mSleeping = true; 8561 mStackSupervisor.goingToSleepLocked(); 8562 8563 // Initialize the wake times of all processes. 8564 checkExcessivePowerUsageLocked(false); 8565 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8566 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8567 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8568 } 8569 } 8570 } 8571 8572 @Override 8573 public boolean shutdown(int timeout) { 8574 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8575 != PackageManager.PERMISSION_GRANTED) { 8576 throw new SecurityException("Requires permission " 8577 + android.Manifest.permission.SHUTDOWN); 8578 } 8579 8580 boolean timedout = false; 8581 8582 synchronized(this) { 8583 mShuttingDown = true; 8584 updateEventDispatchingLocked(); 8585 timedout = mStackSupervisor.shutdownLocked(timeout); 8586 } 8587 8588 mAppOpsService.shutdown(); 8589 mUsageStatsService.shutdown(); 8590 mBatteryStatsService.shutdown(); 8591 synchronized (this) { 8592 mProcessStats.shutdownLocked(); 8593 } 8594 8595 return timedout; 8596 } 8597 8598 public final void activitySlept(IBinder token) { 8599 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8600 8601 final long origId = Binder.clearCallingIdentity(); 8602 8603 synchronized (this) { 8604 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8605 if (r != null) { 8606 mStackSupervisor.activitySleptLocked(r); 8607 } 8608 } 8609 8610 Binder.restoreCallingIdentity(origId); 8611 } 8612 8613 void logLockScreen(String msg) { 8614 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8615 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8616 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8617 mStackSupervisor.mDismissKeyguardOnNextActivity); 8618 } 8619 8620 private void comeOutOfSleepIfNeededLocked() { 8621 if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) { 8622 if (mSleeping) { 8623 mSleeping = false; 8624 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8625 } 8626 } 8627 } 8628 8629 void wakingUp() { 8630 synchronized(this) { 8631 mWentToSleep = false; 8632 updateEventDispatchingLocked(); 8633 comeOutOfSleepIfNeededLocked(); 8634 } 8635 } 8636 8637 void startRunningVoiceLocked() { 8638 if (!mRunningVoice) { 8639 mRunningVoice = true; 8640 comeOutOfSleepIfNeededLocked(); 8641 } 8642 } 8643 8644 private void updateEventDispatchingLocked() { 8645 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8646 } 8647 8648 public void setLockScreenShown(boolean shown) { 8649 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8650 != PackageManager.PERMISSION_GRANTED) { 8651 throw new SecurityException("Requires permission " 8652 + android.Manifest.permission.DEVICE_POWER); 8653 } 8654 8655 synchronized(this) { 8656 long ident = Binder.clearCallingIdentity(); 8657 try { 8658 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8659 mLockScreenShown = shown; 8660 comeOutOfSleepIfNeededLocked(); 8661 } finally { 8662 Binder.restoreCallingIdentity(ident); 8663 } 8664 } 8665 } 8666 8667 public void stopAppSwitches() { 8668 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8669 != PackageManager.PERMISSION_GRANTED) { 8670 throw new SecurityException("Requires permission " 8671 + android.Manifest.permission.STOP_APP_SWITCHES); 8672 } 8673 8674 synchronized(this) { 8675 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8676 + APP_SWITCH_DELAY_TIME; 8677 mDidAppSwitch = false; 8678 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8679 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8680 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8681 } 8682 } 8683 8684 public void resumeAppSwitches() { 8685 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8686 != PackageManager.PERMISSION_GRANTED) { 8687 throw new SecurityException("Requires permission " 8688 + android.Manifest.permission.STOP_APP_SWITCHES); 8689 } 8690 8691 synchronized(this) { 8692 // Note that we don't execute any pending app switches... we will 8693 // let those wait until either the timeout, or the next start 8694 // activity request. 8695 mAppSwitchesAllowedTime = 0; 8696 } 8697 } 8698 8699 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8700 String name) { 8701 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8702 return true; 8703 } 8704 8705 final int perm = checkComponentPermission( 8706 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8707 callingUid, -1, true); 8708 if (perm == PackageManager.PERMISSION_GRANTED) { 8709 return true; 8710 } 8711 8712 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8713 return false; 8714 } 8715 8716 public void setDebugApp(String packageName, boolean waitForDebugger, 8717 boolean persistent) { 8718 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8719 "setDebugApp()"); 8720 8721 long ident = Binder.clearCallingIdentity(); 8722 try { 8723 // Note that this is not really thread safe if there are multiple 8724 // callers into it at the same time, but that's not a situation we 8725 // care about. 8726 if (persistent) { 8727 final ContentResolver resolver = mContext.getContentResolver(); 8728 Settings.Global.putString( 8729 resolver, Settings.Global.DEBUG_APP, 8730 packageName); 8731 Settings.Global.putInt( 8732 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8733 waitForDebugger ? 1 : 0); 8734 } 8735 8736 synchronized (this) { 8737 if (!persistent) { 8738 mOrigDebugApp = mDebugApp; 8739 mOrigWaitForDebugger = mWaitForDebugger; 8740 } 8741 mDebugApp = packageName; 8742 mWaitForDebugger = waitForDebugger; 8743 mDebugTransient = !persistent; 8744 if (packageName != null) { 8745 forceStopPackageLocked(packageName, -1, false, false, true, true, 8746 false, UserHandle.USER_ALL, "set debug app"); 8747 } 8748 } 8749 } finally { 8750 Binder.restoreCallingIdentity(ident); 8751 } 8752 } 8753 8754 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8755 synchronized (this) { 8756 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8757 if (!isDebuggable) { 8758 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8759 throw new SecurityException("Process not debuggable: " + app.packageName); 8760 } 8761 } 8762 8763 mOpenGlTraceApp = processName; 8764 } 8765 } 8766 8767 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8768 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8769 synchronized (this) { 8770 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8771 if (!isDebuggable) { 8772 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8773 throw new SecurityException("Process not debuggable: " + app.packageName); 8774 } 8775 } 8776 mProfileApp = processName; 8777 mProfileFile = profileFile; 8778 if (mProfileFd != null) { 8779 try { 8780 mProfileFd.close(); 8781 } catch (IOException e) { 8782 } 8783 mProfileFd = null; 8784 } 8785 mProfileFd = profileFd; 8786 mProfileType = 0; 8787 mAutoStopProfiler = autoStopProfiler; 8788 } 8789 } 8790 8791 @Override 8792 public void setAlwaysFinish(boolean enabled) { 8793 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8794 "setAlwaysFinish()"); 8795 8796 Settings.Global.putInt( 8797 mContext.getContentResolver(), 8798 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8799 8800 synchronized (this) { 8801 mAlwaysFinishActivities = enabled; 8802 } 8803 } 8804 8805 @Override 8806 public void setActivityController(IActivityController controller) { 8807 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8808 "setActivityController()"); 8809 synchronized (this) { 8810 mController = controller; 8811 Watchdog.getInstance().setActivityController(controller); 8812 } 8813 } 8814 8815 @Override 8816 public void setUserIsMonkey(boolean userIsMonkey) { 8817 synchronized (this) { 8818 synchronized (mPidsSelfLocked) { 8819 final int callingPid = Binder.getCallingPid(); 8820 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8821 if (precessRecord == null) { 8822 throw new SecurityException("Unknown process: " + callingPid); 8823 } 8824 if (precessRecord.instrumentationUiAutomationConnection == null) { 8825 throw new SecurityException("Only an instrumentation process " 8826 + "with a UiAutomation can call setUserIsMonkey"); 8827 } 8828 } 8829 mUserIsMonkey = userIsMonkey; 8830 } 8831 } 8832 8833 @Override 8834 public boolean isUserAMonkey() { 8835 synchronized (this) { 8836 // If there is a controller also implies the user is a monkey. 8837 return (mUserIsMonkey || mController != null); 8838 } 8839 } 8840 8841 public void requestBugReport() { 8842 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8843 SystemProperties.set("ctl.start", "bugreport"); 8844 } 8845 8846 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8847 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8848 } 8849 8850 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8851 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8852 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8853 } 8854 return KEY_DISPATCHING_TIMEOUT; 8855 } 8856 8857 @Override 8858 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8859 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8860 != PackageManager.PERMISSION_GRANTED) { 8861 throw new SecurityException("Requires permission " 8862 + android.Manifest.permission.FILTER_EVENTS); 8863 } 8864 ProcessRecord proc; 8865 long timeout; 8866 synchronized (this) { 8867 synchronized (mPidsSelfLocked) { 8868 proc = mPidsSelfLocked.get(pid); 8869 } 8870 timeout = getInputDispatchingTimeoutLocked(proc); 8871 } 8872 8873 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8874 return -1; 8875 } 8876 8877 return timeout; 8878 } 8879 8880 /** 8881 * Handle input dispatching timeouts. 8882 * Returns whether input dispatching should be aborted or not. 8883 */ 8884 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8885 final ActivityRecord activity, final ActivityRecord parent, 8886 final boolean aboveSystem, String reason) { 8887 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8888 != PackageManager.PERMISSION_GRANTED) { 8889 throw new SecurityException("Requires permission " 8890 + android.Manifest.permission.FILTER_EVENTS); 8891 } 8892 8893 final String annotation; 8894 if (reason == null) { 8895 annotation = "Input dispatching timed out"; 8896 } else { 8897 annotation = "Input dispatching timed out (" + reason + ")"; 8898 } 8899 8900 if (proc != null) { 8901 synchronized (this) { 8902 if (proc.debugging) { 8903 return false; 8904 } 8905 8906 if (mDidDexOpt) { 8907 // Give more time since we were dexopting. 8908 mDidDexOpt = false; 8909 return false; 8910 } 8911 8912 if (proc.instrumentationClass != null) { 8913 Bundle info = new Bundle(); 8914 info.putString("shortMsg", "keyDispatchingTimedOut"); 8915 info.putString("longMsg", annotation); 8916 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8917 return true; 8918 } 8919 } 8920 mHandler.post(new Runnable() { 8921 @Override 8922 public void run() { 8923 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8924 } 8925 }); 8926 } 8927 8928 return true; 8929 } 8930 8931 public Bundle getAssistContextExtras(int requestType) { 8932 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8933 "getAssistContextExtras()"); 8934 PendingAssistExtras pae; 8935 Bundle extras = new Bundle(); 8936 synchronized (this) { 8937 ActivityRecord activity = getFocusedStack().mResumedActivity; 8938 if (activity == null) { 8939 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8940 return null; 8941 } 8942 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8943 if (activity.app == null || activity.app.thread == null) { 8944 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8945 return extras; 8946 } 8947 if (activity.app.pid == Binder.getCallingPid()) { 8948 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8949 return extras; 8950 } 8951 pae = new PendingAssistExtras(activity); 8952 try { 8953 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8954 requestType); 8955 mPendingAssistExtras.add(pae); 8956 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8957 } catch (RemoteException e) { 8958 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8959 return extras; 8960 } 8961 } 8962 synchronized (pae) { 8963 while (!pae.haveResult) { 8964 try { 8965 pae.wait(); 8966 } catch (InterruptedException e) { 8967 } 8968 } 8969 if (pae.result != null) { 8970 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8971 } 8972 } 8973 synchronized (this) { 8974 mPendingAssistExtras.remove(pae); 8975 mHandler.removeCallbacks(pae); 8976 } 8977 return extras; 8978 } 8979 8980 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8981 PendingAssistExtras pae = (PendingAssistExtras)token; 8982 synchronized (pae) { 8983 pae.result = extras; 8984 pae.haveResult = true; 8985 pae.notifyAll(); 8986 } 8987 } 8988 8989 public void registerProcessObserver(IProcessObserver observer) { 8990 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8991 "registerProcessObserver()"); 8992 synchronized (this) { 8993 mProcessObservers.register(observer); 8994 } 8995 } 8996 8997 @Override 8998 public void unregisterProcessObserver(IProcessObserver observer) { 8999 synchronized (this) { 9000 mProcessObservers.unregister(observer); 9001 } 9002 } 9003 9004 @Override 9005 public boolean convertFromTranslucent(IBinder token) { 9006 final long origId = Binder.clearCallingIdentity(); 9007 try { 9008 synchronized (this) { 9009 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9010 if (r == null) { 9011 return false; 9012 } 9013 if (r.changeWindowTranslucency(true)) { 9014 mWindowManager.setAppFullscreen(token, true); 9015 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9016 return true; 9017 } 9018 return false; 9019 } 9020 } finally { 9021 Binder.restoreCallingIdentity(origId); 9022 } 9023 } 9024 9025 @Override 9026 public boolean convertToTranslucent(IBinder token) { 9027 final long origId = Binder.clearCallingIdentity(); 9028 try { 9029 synchronized (this) { 9030 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9031 if (r == null) { 9032 return false; 9033 } 9034 if (r.changeWindowTranslucency(false)) { 9035 r.task.stack.convertToTranslucent(r); 9036 mWindowManager.setAppFullscreen(token, false); 9037 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 9038 return true; 9039 } 9040 return false; 9041 } 9042 } finally { 9043 Binder.restoreCallingIdentity(origId); 9044 } 9045 } 9046 9047 @Override 9048 public void setImmersive(IBinder token, boolean immersive) { 9049 synchronized(this) { 9050 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 9051 if (r == null) { 9052 throw new IllegalArgumentException(); 9053 } 9054 r.immersive = immersive; 9055 9056 // update associated state if we're frontmost 9057 if (r == mFocusedActivity) { 9058 if (DEBUG_IMMERSIVE) { 9059 Slog.d(TAG, "Frontmost changed immersion: "+ r); 9060 } 9061 applyUpdateLockStateLocked(r); 9062 } 9063 } 9064 } 9065 9066 @Override 9067 public boolean isImmersive(IBinder token) { 9068 synchronized (this) { 9069 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9070 if (r == null) { 9071 throw new IllegalArgumentException(); 9072 } 9073 return r.immersive; 9074 } 9075 } 9076 9077 public boolean isTopActivityImmersive() { 9078 enforceNotIsolatedCaller("startActivity"); 9079 synchronized (this) { 9080 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9081 return (r != null) ? r.immersive : false; 9082 } 9083 } 9084 9085 public final void enterSafeMode() { 9086 synchronized(this) { 9087 // It only makes sense to do this before the system is ready 9088 // and started launching other packages. 9089 if (!mSystemReady) { 9090 try { 9091 AppGlobals.getPackageManager().enterSafeMode(); 9092 } catch (RemoteException e) { 9093 } 9094 } 9095 9096 mSafeMode = true; 9097 } 9098 } 9099 9100 public final void showSafeModeOverlay() { 9101 View v = LayoutInflater.from(mContext).inflate( 9102 com.android.internal.R.layout.safe_mode, null); 9103 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9104 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9105 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9106 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9107 lp.gravity = Gravity.BOTTOM | Gravity.START; 9108 lp.format = v.getBackground().getOpacity(); 9109 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9110 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9111 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9112 ((WindowManager)mContext.getSystemService( 9113 Context.WINDOW_SERVICE)).addView(v, lp); 9114 } 9115 9116 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9117 if (!(sender instanceof PendingIntentRecord)) { 9118 return; 9119 } 9120 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9121 synchronized (stats) { 9122 if (mBatteryStatsService.isOnBattery()) { 9123 mBatteryStatsService.enforceCallingPermission(); 9124 PendingIntentRecord rec = (PendingIntentRecord)sender; 9125 int MY_UID = Binder.getCallingUid(); 9126 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9127 BatteryStatsImpl.Uid.Pkg pkg = 9128 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9129 sourcePkg != null ? sourcePkg : rec.key.packageName); 9130 pkg.incWakeupsLocked(); 9131 } 9132 } 9133 } 9134 9135 public boolean killPids(int[] pids, String pReason, boolean secure) { 9136 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9137 throw new SecurityException("killPids only available to the system"); 9138 } 9139 String reason = (pReason == null) ? "Unknown" : pReason; 9140 // XXX Note: don't acquire main activity lock here, because the window 9141 // manager calls in with its locks held. 9142 9143 boolean killed = false; 9144 synchronized (mPidsSelfLocked) { 9145 int[] types = new int[pids.length]; 9146 int worstType = 0; 9147 for (int i=0; i<pids.length; i++) { 9148 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9149 if (proc != null) { 9150 int type = proc.setAdj; 9151 types[i] = type; 9152 if (type > worstType) { 9153 worstType = type; 9154 } 9155 } 9156 } 9157 9158 // If the worst oom_adj is somewhere in the cached proc LRU range, 9159 // then constrain it so we will kill all cached procs. 9160 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9161 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9162 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9163 } 9164 9165 // If this is not a secure call, don't let it kill processes that 9166 // are important. 9167 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9168 worstType = ProcessList.SERVICE_ADJ; 9169 } 9170 9171 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9172 for (int i=0; i<pids.length; i++) { 9173 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9174 if (proc == null) { 9175 continue; 9176 } 9177 int adj = proc.setAdj; 9178 if (adj >= worstType && !proc.killedByAm) { 9179 killUnneededProcessLocked(proc, reason); 9180 killed = true; 9181 } 9182 } 9183 } 9184 return killed; 9185 } 9186 9187 @Override 9188 public void killUid(int uid, String reason) { 9189 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9190 throw new SecurityException("killUid only available to the system"); 9191 } 9192 synchronized (this) { 9193 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9194 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9195 reason != null ? reason : "kill uid"); 9196 } 9197 } 9198 9199 @Override 9200 public boolean killProcessesBelowForeground(String reason) { 9201 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9202 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9203 } 9204 9205 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9206 } 9207 9208 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9209 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9210 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9211 } 9212 9213 boolean killed = false; 9214 synchronized (mPidsSelfLocked) { 9215 final int size = mPidsSelfLocked.size(); 9216 for (int i = 0; i < size; i++) { 9217 final int pid = mPidsSelfLocked.keyAt(i); 9218 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9219 if (proc == null) continue; 9220 9221 final int adj = proc.setAdj; 9222 if (adj > belowAdj && !proc.killedByAm) { 9223 killUnneededProcessLocked(proc, reason); 9224 killed = true; 9225 } 9226 } 9227 } 9228 return killed; 9229 } 9230 9231 @Override 9232 public void hang(final IBinder who, boolean allowRestart) { 9233 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9234 != PackageManager.PERMISSION_GRANTED) { 9235 throw new SecurityException("Requires permission " 9236 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9237 } 9238 9239 final IBinder.DeathRecipient death = new DeathRecipient() { 9240 @Override 9241 public void binderDied() { 9242 synchronized (this) { 9243 notifyAll(); 9244 } 9245 } 9246 }; 9247 9248 try { 9249 who.linkToDeath(death, 0); 9250 } catch (RemoteException e) { 9251 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9252 return; 9253 } 9254 9255 synchronized (this) { 9256 Watchdog.getInstance().setAllowRestart(allowRestart); 9257 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9258 synchronized (death) { 9259 while (who.isBinderAlive()) { 9260 try { 9261 death.wait(); 9262 } catch (InterruptedException e) { 9263 } 9264 } 9265 } 9266 Watchdog.getInstance().setAllowRestart(true); 9267 } 9268 } 9269 9270 @Override 9271 public void restart() { 9272 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9273 != PackageManager.PERMISSION_GRANTED) { 9274 throw new SecurityException("Requires permission " 9275 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9276 } 9277 9278 Log.i(TAG, "Sending shutdown broadcast..."); 9279 9280 BroadcastReceiver br = new BroadcastReceiver() { 9281 @Override public void onReceive(Context context, Intent intent) { 9282 // Now the broadcast is done, finish up the low-level shutdown. 9283 Log.i(TAG, "Shutting down activity manager..."); 9284 shutdown(10000); 9285 Log.i(TAG, "Shutdown complete, restarting!"); 9286 Process.killProcess(Process.myPid()); 9287 System.exit(10); 9288 } 9289 }; 9290 9291 // First send the high-level shut down broadcast. 9292 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9293 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9294 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9295 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9296 mContext.sendOrderedBroadcastAsUser(intent, 9297 UserHandle.ALL, null, br, mHandler, 0, null, null); 9298 */ 9299 br.onReceive(mContext, intent); 9300 } 9301 9302 private long getLowRamTimeSinceIdle(long now) { 9303 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9304 } 9305 9306 @Override 9307 public void performIdleMaintenance() { 9308 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9309 != PackageManager.PERMISSION_GRANTED) { 9310 throw new SecurityException("Requires permission " 9311 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9312 } 9313 9314 synchronized (this) { 9315 final long now = SystemClock.uptimeMillis(); 9316 final long timeSinceLastIdle = now - mLastIdleTime; 9317 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9318 mLastIdleTime = now; 9319 mLowRamTimeSinceLastIdle = 0; 9320 if (mLowRamStartTime != 0) { 9321 mLowRamStartTime = now; 9322 } 9323 9324 StringBuilder sb = new StringBuilder(128); 9325 sb.append("Idle maintenance over "); 9326 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9327 sb.append(" low RAM for "); 9328 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9329 Slog.i(TAG, sb.toString()); 9330 9331 // If at least 1/3 of our time since the last idle period has been spent 9332 // with RAM low, then we want to kill processes. 9333 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9334 9335 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9336 ProcessRecord proc = mLruProcesses.get(i); 9337 if (proc.notCachedSinceIdle) { 9338 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9339 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9340 if (doKilling && proc.initialIdlePss != 0 9341 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9342 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9343 + " from " + proc.initialIdlePss + ")"); 9344 } 9345 } 9346 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9347 proc.notCachedSinceIdle = true; 9348 proc.initialIdlePss = 0; 9349 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9350 isSleeping(), now); 9351 } 9352 } 9353 9354 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9355 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9356 } 9357 } 9358 9359 private void retrieveSettings() { 9360 final ContentResolver resolver = mContext.getContentResolver(); 9361 String debugApp = Settings.Global.getString( 9362 resolver, Settings.Global.DEBUG_APP); 9363 boolean waitForDebugger = Settings.Global.getInt( 9364 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9365 boolean alwaysFinishActivities = Settings.Global.getInt( 9366 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9367 boolean forceRtl = Settings.Global.getInt( 9368 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9369 // Transfer any global setting for forcing RTL layout, into a System Property 9370 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9371 9372 Configuration configuration = new Configuration(); 9373 Settings.System.getConfiguration(resolver, configuration); 9374 if (forceRtl) { 9375 // This will take care of setting the correct layout direction flags 9376 configuration.setLayoutDirection(configuration.locale); 9377 } 9378 9379 synchronized (this) { 9380 mDebugApp = mOrigDebugApp = debugApp; 9381 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9382 mAlwaysFinishActivities = alwaysFinishActivities; 9383 // This happens before any activities are started, so we can 9384 // change mConfiguration in-place. 9385 updateConfigurationLocked(configuration, null, false, true); 9386 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9387 } 9388 } 9389 9390 public boolean testIsSystemReady() { 9391 // no need to synchronize(this) just to read & return the value 9392 return mSystemReady; 9393 } 9394 9395 private static File getCalledPreBootReceiversFile() { 9396 File dataDir = Environment.getDataDirectory(); 9397 File systemDir = new File(dataDir, "system"); 9398 File fname = new File(systemDir, "called_pre_boots.dat"); 9399 return fname; 9400 } 9401 9402 static final int LAST_DONE_VERSION = 10000; 9403 9404 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9405 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9406 File file = getCalledPreBootReceiversFile(); 9407 FileInputStream fis = null; 9408 try { 9409 fis = new FileInputStream(file); 9410 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9411 int fvers = dis.readInt(); 9412 if (fvers == LAST_DONE_VERSION) { 9413 String vers = dis.readUTF(); 9414 String codename = dis.readUTF(); 9415 String build = dis.readUTF(); 9416 if (android.os.Build.VERSION.RELEASE.equals(vers) 9417 && android.os.Build.VERSION.CODENAME.equals(codename) 9418 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9419 int num = dis.readInt(); 9420 while (num > 0) { 9421 num--; 9422 String pkg = dis.readUTF(); 9423 String cls = dis.readUTF(); 9424 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9425 } 9426 } 9427 } 9428 } catch (FileNotFoundException e) { 9429 } catch (IOException e) { 9430 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9431 } finally { 9432 if (fis != null) { 9433 try { 9434 fis.close(); 9435 } catch (IOException e) { 9436 } 9437 } 9438 } 9439 return lastDoneReceivers; 9440 } 9441 9442 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9443 File file = getCalledPreBootReceiversFile(); 9444 FileOutputStream fos = null; 9445 DataOutputStream dos = null; 9446 try { 9447 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9448 fos = new FileOutputStream(file); 9449 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9450 dos.writeInt(LAST_DONE_VERSION); 9451 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9452 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9453 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9454 dos.writeInt(list.size()); 9455 for (int i=0; i<list.size(); i++) { 9456 dos.writeUTF(list.get(i).getPackageName()); 9457 dos.writeUTF(list.get(i).getClassName()); 9458 } 9459 } catch (IOException e) { 9460 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9461 file.delete(); 9462 } finally { 9463 FileUtils.sync(fos); 9464 if (dos != null) { 9465 try { 9466 dos.close(); 9467 } catch (IOException e) { 9468 // TODO Auto-generated catch block 9469 e.printStackTrace(); 9470 } 9471 } 9472 } 9473 } 9474 9475 public void systemReady(final Runnable goingCallback) { 9476 synchronized(this) { 9477 if (mSystemReady) { 9478 if (goingCallback != null) goingCallback.run(); 9479 return; 9480 } 9481 9482 // Check to see if there are any update receivers to run. 9483 if (!mDidUpdate) { 9484 if (mWaitingUpdate) { 9485 return; 9486 } 9487 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9488 List<ResolveInfo> ris = null; 9489 try { 9490 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9491 intent, null, 0, 0); 9492 } catch (RemoteException e) { 9493 } 9494 if (ris != null) { 9495 for (int i=ris.size()-1; i>=0; i--) { 9496 if ((ris.get(i).activityInfo.applicationInfo.flags 9497 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9498 ris.remove(i); 9499 } 9500 } 9501 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9502 9503 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9504 9505 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9506 for (int i=0; i<ris.size(); i++) { 9507 ActivityInfo ai = ris.get(i).activityInfo; 9508 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9509 if (lastDoneReceivers.contains(comp)) { 9510 // We already did the pre boot receiver for this app with the current 9511 // platform version, so don't do it again... 9512 ris.remove(i); 9513 i--; 9514 // ...however, do keep it as one that has been done, so we don't 9515 // forget about it when rewriting the file of last done receivers. 9516 doneReceivers.add(comp); 9517 } 9518 } 9519 9520 final int[] users = getUsersLocked(); 9521 for (int i=0; i<ris.size(); i++) { 9522 ActivityInfo ai = ris.get(i).activityInfo; 9523 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9524 doneReceivers.add(comp); 9525 intent.setComponent(comp); 9526 for (int j=0; j<users.length; j++) { 9527 IIntentReceiver finisher = null; 9528 if (i == ris.size()-1 && j == users.length-1) { 9529 finisher = new IIntentReceiver.Stub() { 9530 public void performReceive(Intent intent, int resultCode, 9531 String data, Bundle extras, boolean ordered, 9532 boolean sticky, int sendingUser) { 9533 // The raw IIntentReceiver interface is called 9534 // with the AM lock held, so redispatch to 9535 // execute our code without the lock. 9536 mHandler.post(new Runnable() { 9537 public void run() { 9538 synchronized (ActivityManagerService.this) { 9539 mDidUpdate = true; 9540 } 9541 writeLastDonePreBootReceivers(doneReceivers); 9542 showBootMessage(mContext.getText( 9543 R.string.android_upgrading_complete), 9544 false); 9545 systemReady(goingCallback); 9546 } 9547 }); 9548 } 9549 }; 9550 } 9551 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9552 + " for user " + users[j]); 9553 broadcastIntentLocked(null, null, intent, null, finisher, 9554 0, null, null, null, AppOpsManager.OP_NONE, 9555 true, false, MY_PID, Process.SYSTEM_UID, 9556 users[j]); 9557 if (finisher != null) { 9558 mWaitingUpdate = true; 9559 } 9560 } 9561 } 9562 } 9563 if (mWaitingUpdate) { 9564 return; 9565 } 9566 mDidUpdate = true; 9567 } 9568 9569 mAppOpsService.systemReady(); 9570 mSystemReady = true; 9571 } 9572 9573 ArrayList<ProcessRecord> procsToKill = null; 9574 synchronized(mPidsSelfLocked) { 9575 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9576 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9577 if (!isAllowedWhileBooting(proc.info)){ 9578 if (procsToKill == null) { 9579 procsToKill = new ArrayList<ProcessRecord>(); 9580 } 9581 procsToKill.add(proc); 9582 } 9583 } 9584 } 9585 9586 synchronized(this) { 9587 if (procsToKill != null) { 9588 for (int i=procsToKill.size()-1; i>=0; i--) { 9589 ProcessRecord proc = procsToKill.get(i); 9590 Slog.i(TAG, "Removing system update proc: " + proc); 9591 removeProcessLocked(proc, true, false, "system update done"); 9592 } 9593 } 9594 9595 // Now that we have cleaned up any update processes, we 9596 // are ready to start launching real processes and know that 9597 // we won't trample on them any more. 9598 mProcessesReady = true; 9599 } 9600 9601 Slog.i(TAG, "System now ready"); 9602 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9603 SystemClock.uptimeMillis()); 9604 9605 synchronized(this) { 9606 // Make sure we have no pre-ready processes sitting around. 9607 9608 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9609 ResolveInfo ri = mContext.getPackageManager() 9610 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9611 STOCK_PM_FLAGS); 9612 CharSequence errorMsg = null; 9613 if (ri != null) { 9614 ActivityInfo ai = ri.activityInfo; 9615 ApplicationInfo app = ai.applicationInfo; 9616 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9617 mTopAction = Intent.ACTION_FACTORY_TEST; 9618 mTopData = null; 9619 mTopComponent = new ComponentName(app.packageName, 9620 ai.name); 9621 } else { 9622 errorMsg = mContext.getResources().getText( 9623 com.android.internal.R.string.factorytest_not_system); 9624 } 9625 } else { 9626 errorMsg = mContext.getResources().getText( 9627 com.android.internal.R.string.factorytest_no_action); 9628 } 9629 if (errorMsg != null) { 9630 mTopAction = null; 9631 mTopData = null; 9632 mTopComponent = null; 9633 Message msg = Message.obtain(); 9634 msg.what = SHOW_FACTORY_ERROR_MSG; 9635 msg.getData().putCharSequence("msg", errorMsg); 9636 mHandler.sendMessage(msg); 9637 } 9638 } 9639 } 9640 9641 retrieveSettings(); 9642 9643 synchronized (this) { 9644 readGrantedUriPermissionsLocked(); 9645 } 9646 9647 if (goingCallback != null) goingCallback.run(); 9648 9649 mSystemServiceManager.startUser(mCurrentUserId); 9650 9651 synchronized (this) { 9652 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9653 try { 9654 List apps = AppGlobals.getPackageManager(). 9655 getPersistentApplications(STOCK_PM_FLAGS); 9656 if (apps != null) { 9657 int N = apps.size(); 9658 int i; 9659 for (i=0; i<N; i++) { 9660 ApplicationInfo info 9661 = (ApplicationInfo)apps.get(i); 9662 if (info != null && 9663 !info.packageName.equals("android")) { 9664 addAppLocked(info, false); 9665 } 9666 } 9667 } 9668 } catch (RemoteException ex) { 9669 // pm is in same process, this will never happen. 9670 } 9671 } 9672 9673 // Start up initial activity. 9674 mBooting = true; 9675 9676 try { 9677 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9678 Message msg = Message.obtain(); 9679 msg.what = SHOW_UID_ERROR_MSG; 9680 mHandler.sendMessage(msg); 9681 } 9682 } catch (RemoteException e) { 9683 } 9684 9685 long ident = Binder.clearCallingIdentity(); 9686 try { 9687 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9688 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9689 | Intent.FLAG_RECEIVER_FOREGROUND); 9690 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9691 broadcastIntentLocked(null, null, intent, 9692 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9693 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9694 intent = new Intent(Intent.ACTION_USER_STARTING); 9695 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9696 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9697 broadcastIntentLocked(null, null, intent, 9698 null, new IIntentReceiver.Stub() { 9699 @Override 9700 public void performReceive(Intent intent, int resultCode, String data, 9701 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9702 throws RemoteException { 9703 } 9704 }, 0, null, null, 9705 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9706 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9707 } catch (Throwable t) { 9708 Slog.wtf(TAG, "Failed sending first user broadcasts", t); 9709 } finally { 9710 Binder.restoreCallingIdentity(ident); 9711 } 9712 mStackSupervisor.resumeTopActivitiesLocked(); 9713 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9714 } 9715 } 9716 9717 private boolean makeAppCrashingLocked(ProcessRecord app, 9718 String shortMsg, String longMsg, String stackTrace) { 9719 app.crashing = true; 9720 app.crashingReport = generateProcessError(app, 9721 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9722 startAppProblemLocked(app); 9723 app.stopFreezingAllLocked(); 9724 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9725 } 9726 9727 private void makeAppNotRespondingLocked(ProcessRecord app, 9728 String activity, String shortMsg, String longMsg) { 9729 app.notResponding = true; 9730 app.notRespondingReport = generateProcessError(app, 9731 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9732 activity, shortMsg, longMsg, null); 9733 startAppProblemLocked(app); 9734 app.stopFreezingAllLocked(); 9735 } 9736 9737 /** 9738 * Generate a process error record, suitable for attachment to a ProcessRecord. 9739 * 9740 * @param app The ProcessRecord in which the error occurred. 9741 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9742 * ActivityManager.AppErrorStateInfo 9743 * @param activity The activity associated with the crash, if known. 9744 * @param shortMsg Short message describing the crash. 9745 * @param longMsg Long message describing the crash. 9746 * @param stackTrace Full crash stack trace, may be null. 9747 * 9748 * @return Returns a fully-formed AppErrorStateInfo record. 9749 */ 9750 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9751 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9752 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9753 9754 report.condition = condition; 9755 report.processName = app.processName; 9756 report.pid = app.pid; 9757 report.uid = app.info.uid; 9758 report.tag = activity; 9759 report.shortMsg = shortMsg; 9760 report.longMsg = longMsg; 9761 report.stackTrace = stackTrace; 9762 9763 return report; 9764 } 9765 9766 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9767 synchronized (this) { 9768 app.crashing = false; 9769 app.crashingReport = null; 9770 app.notResponding = false; 9771 app.notRespondingReport = null; 9772 if (app.anrDialog == fromDialog) { 9773 app.anrDialog = null; 9774 } 9775 if (app.waitDialog == fromDialog) { 9776 app.waitDialog = null; 9777 } 9778 if (app.pid > 0 && app.pid != MY_PID) { 9779 handleAppCrashLocked(app, null, null, null); 9780 killUnneededProcessLocked(app, "user request after error"); 9781 } 9782 } 9783 } 9784 9785 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9786 String stackTrace) { 9787 long now = SystemClock.uptimeMillis(); 9788 9789 Long crashTime; 9790 if (!app.isolated) { 9791 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9792 } else { 9793 crashTime = null; 9794 } 9795 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9796 // This process loses! 9797 Slog.w(TAG, "Process " + app.info.processName 9798 + " has crashed too many times: killing!"); 9799 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9800 app.userId, app.info.processName, app.uid); 9801 mStackSupervisor.handleAppCrashLocked(app); 9802 if (!app.persistent) { 9803 // We don't want to start this process again until the user 9804 // explicitly does so... but for persistent process, we really 9805 // need to keep it running. If a persistent process is actually 9806 // repeatedly crashing, then badness for everyone. 9807 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9808 app.info.processName); 9809 if (!app.isolated) { 9810 // XXX We don't have a way to mark isolated processes 9811 // as bad, since they don't have a peristent identity. 9812 mBadProcesses.put(app.info.processName, app.uid, 9813 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9814 mProcessCrashTimes.remove(app.info.processName, app.uid); 9815 } 9816 app.bad = true; 9817 app.removed = true; 9818 // Don't let services in this process be restarted and potentially 9819 // annoy the user repeatedly. Unless it is persistent, since those 9820 // processes run critical code. 9821 removeProcessLocked(app, false, false, "crash"); 9822 mStackSupervisor.resumeTopActivitiesLocked(); 9823 return false; 9824 } 9825 mStackSupervisor.resumeTopActivitiesLocked(); 9826 } else { 9827 mStackSupervisor.finishTopRunningActivityLocked(app); 9828 } 9829 9830 // Bump up the crash count of any services currently running in the proc. 9831 for (int i=app.services.size()-1; i>=0; i--) { 9832 // Any services running in the application need to be placed 9833 // back in the pending list. 9834 ServiceRecord sr = app.services.valueAt(i); 9835 sr.crashCount++; 9836 } 9837 9838 // If the crashing process is what we consider to be the "home process" and it has been 9839 // replaced by a third-party app, clear the package preferred activities from packages 9840 // with a home activity running in the process to prevent a repeatedly crashing app 9841 // from blocking the user to manually clear the list. 9842 final ArrayList<ActivityRecord> activities = app.activities; 9843 if (app == mHomeProcess && activities.size() > 0 9844 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9845 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9846 final ActivityRecord r = activities.get(activityNdx); 9847 if (r.isHomeActivity()) { 9848 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9849 try { 9850 ActivityThread.getPackageManager() 9851 .clearPackagePreferredActivities(r.packageName); 9852 } catch (RemoteException c) { 9853 // pm is in same process, this will never happen. 9854 } 9855 } 9856 } 9857 } 9858 9859 if (!app.isolated) { 9860 // XXX Can't keep track of crash times for isolated processes, 9861 // because they don't have a perisistent identity. 9862 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9863 } 9864 9865 return true; 9866 } 9867 9868 void startAppProblemLocked(ProcessRecord app) { 9869 if (app.userId == mCurrentUserId) { 9870 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9871 mContext, app.info.packageName, app.info.flags); 9872 } else { 9873 // If this app is not running under the current user, then we 9874 // can't give it a report button because that would require 9875 // launching the report UI under a different user. 9876 app.errorReportReceiver = null; 9877 } 9878 skipCurrentReceiverLocked(app); 9879 } 9880 9881 void skipCurrentReceiverLocked(ProcessRecord app) { 9882 for (BroadcastQueue queue : mBroadcastQueues) { 9883 queue.skipCurrentReceiverLocked(app); 9884 } 9885 } 9886 9887 /** 9888 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9889 * The application process will exit immediately after this call returns. 9890 * @param app object of the crashing app, null for the system server 9891 * @param crashInfo describing the exception 9892 */ 9893 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9894 ProcessRecord r = findAppProcess(app, "Crash"); 9895 final String processName = app == null ? "system_server" 9896 : (r == null ? "unknown" : r.processName); 9897 9898 handleApplicationCrashInner("crash", r, processName, crashInfo); 9899 } 9900 9901 /* Native crash reporting uses this inner version because it needs to be somewhat 9902 * decoupled from the AM-managed cleanup lifecycle 9903 */ 9904 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9905 ApplicationErrorReport.CrashInfo crashInfo) { 9906 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9907 UserHandle.getUserId(Binder.getCallingUid()), processName, 9908 r == null ? -1 : r.info.flags, 9909 crashInfo.exceptionClassName, 9910 crashInfo.exceptionMessage, 9911 crashInfo.throwFileName, 9912 crashInfo.throwLineNumber); 9913 9914 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9915 9916 crashApplication(r, crashInfo); 9917 } 9918 9919 public void handleApplicationStrictModeViolation( 9920 IBinder app, 9921 int violationMask, 9922 StrictMode.ViolationInfo info) { 9923 ProcessRecord r = findAppProcess(app, "StrictMode"); 9924 if (r == null) { 9925 return; 9926 } 9927 9928 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9929 Integer stackFingerprint = info.hashCode(); 9930 boolean logIt = true; 9931 synchronized (mAlreadyLoggedViolatedStacks) { 9932 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9933 logIt = false; 9934 // TODO: sub-sample into EventLog for these, with 9935 // the info.durationMillis? Then we'd get 9936 // the relative pain numbers, without logging all 9937 // the stack traces repeatedly. We'd want to do 9938 // likewise in the client code, which also does 9939 // dup suppression, before the Binder call. 9940 } else { 9941 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9942 mAlreadyLoggedViolatedStacks.clear(); 9943 } 9944 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9945 } 9946 } 9947 if (logIt) { 9948 logStrictModeViolationToDropBox(r, info); 9949 } 9950 } 9951 9952 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9953 AppErrorResult result = new AppErrorResult(); 9954 synchronized (this) { 9955 final long origId = Binder.clearCallingIdentity(); 9956 9957 Message msg = Message.obtain(); 9958 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9959 HashMap<String, Object> data = new HashMap<String, Object>(); 9960 data.put("result", result); 9961 data.put("app", r); 9962 data.put("violationMask", violationMask); 9963 data.put("info", info); 9964 msg.obj = data; 9965 mHandler.sendMessage(msg); 9966 9967 Binder.restoreCallingIdentity(origId); 9968 } 9969 int res = result.get(); 9970 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9971 } 9972 } 9973 9974 // Depending on the policy in effect, there could be a bunch of 9975 // these in quick succession so we try to batch these together to 9976 // minimize disk writes, number of dropbox entries, and maximize 9977 // compression, by having more fewer, larger records. 9978 private void logStrictModeViolationToDropBox( 9979 ProcessRecord process, 9980 StrictMode.ViolationInfo info) { 9981 if (info == null) { 9982 return; 9983 } 9984 final boolean isSystemApp = process == null || 9985 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9986 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9987 final String processName = process == null ? "unknown" : process.processName; 9988 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9989 final DropBoxManager dbox = (DropBoxManager) 9990 mContext.getSystemService(Context.DROPBOX_SERVICE); 9991 9992 // Exit early if the dropbox isn't configured to accept this report type. 9993 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9994 9995 boolean bufferWasEmpty; 9996 boolean needsFlush; 9997 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9998 synchronized (sb) { 9999 bufferWasEmpty = sb.length() == 0; 10000 appendDropBoxProcessHeaders(process, processName, sb); 10001 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10002 sb.append("System-App: ").append(isSystemApp).append("\n"); 10003 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 10004 if (info.violationNumThisLoop != 0) { 10005 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 10006 } 10007 if (info.numAnimationsRunning != 0) { 10008 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 10009 } 10010 if (info.broadcastIntentAction != null) { 10011 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 10012 } 10013 if (info.durationMillis != -1) { 10014 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 10015 } 10016 if (info.numInstances != -1) { 10017 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 10018 } 10019 if (info.tags != null) { 10020 for (String tag : info.tags) { 10021 sb.append("Span-Tag: ").append(tag).append("\n"); 10022 } 10023 } 10024 sb.append("\n"); 10025 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 10026 sb.append(info.crashInfo.stackTrace); 10027 } 10028 sb.append("\n"); 10029 10030 // Only buffer up to ~64k. Various logging bits truncate 10031 // things at 128k. 10032 needsFlush = (sb.length() > 64 * 1024); 10033 } 10034 10035 // Flush immediately if the buffer's grown too large, or this 10036 // is a non-system app. Non-system apps are isolated with a 10037 // different tag & policy and not batched. 10038 // 10039 // Batching is useful during internal testing with 10040 // StrictMode settings turned up high. Without batching, 10041 // thousands of separate files could be created on boot. 10042 if (!isSystemApp || needsFlush) { 10043 new Thread("Error dump: " + dropboxTag) { 10044 @Override 10045 public void run() { 10046 String report; 10047 synchronized (sb) { 10048 report = sb.toString(); 10049 sb.delete(0, sb.length()); 10050 sb.trimToSize(); 10051 } 10052 if (report.length() != 0) { 10053 dbox.addText(dropboxTag, report); 10054 } 10055 } 10056 }.start(); 10057 return; 10058 } 10059 10060 // System app batching: 10061 if (!bufferWasEmpty) { 10062 // An existing dropbox-writing thread is outstanding, so 10063 // we don't need to start it up. The existing thread will 10064 // catch the buffer appends we just did. 10065 return; 10066 } 10067 10068 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10069 // (After this point, we shouldn't access AMS internal data structures.) 10070 new Thread("Error dump: " + dropboxTag) { 10071 @Override 10072 public void run() { 10073 // 5 second sleep to let stacks arrive and be batched together 10074 try { 10075 Thread.sleep(5000); // 5 seconds 10076 } catch (InterruptedException e) {} 10077 10078 String errorReport; 10079 synchronized (mStrictModeBuffer) { 10080 errorReport = mStrictModeBuffer.toString(); 10081 if (errorReport.length() == 0) { 10082 return; 10083 } 10084 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10085 mStrictModeBuffer.trimToSize(); 10086 } 10087 dbox.addText(dropboxTag, errorReport); 10088 } 10089 }.start(); 10090 } 10091 10092 /** 10093 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10094 * @param app object of the crashing app, null for the system server 10095 * @param tag reported by the caller 10096 * @param crashInfo describing the context of the error 10097 * @return true if the process should exit immediately (WTF is fatal) 10098 */ 10099 public boolean handleApplicationWtf(IBinder app, String tag, 10100 ApplicationErrorReport.CrashInfo crashInfo) { 10101 ProcessRecord r = findAppProcess(app, "WTF"); 10102 final String processName = app == null ? "system_server" 10103 : (r == null ? "unknown" : r.processName); 10104 10105 EventLog.writeEvent(EventLogTags.AM_WTF, 10106 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10107 processName, 10108 r == null ? -1 : r.info.flags, 10109 tag, crashInfo.exceptionMessage); 10110 10111 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10112 10113 if (r != null && r.pid != Process.myPid() && 10114 Settings.Global.getInt(mContext.getContentResolver(), 10115 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10116 crashApplication(r, crashInfo); 10117 return true; 10118 } else { 10119 return false; 10120 } 10121 } 10122 10123 /** 10124 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10125 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10126 */ 10127 private ProcessRecord findAppProcess(IBinder app, String reason) { 10128 if (app == null) { 10129 return null; 10130 } 10131 10132 synchronized (this) { 10133 final int NP = mProcessNames.getMap().size(); 10134 for (int ip=0; ip<NP; ip++) { 10135 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10136 final int NA = apps.size(); 10137 for (int ia=0; ia<NA; ia++) { 10138 ProcessRecord p = apps.valueAt(ia); 10139 if (p.thread != null && p.thread.asBinder() == app) { 10140 return p; 10141 } 10142 } 10143 } 10144 10145 Slog.w(TAG, "Can't find mystery application for " + reason 10146 + " from pid=" + Binder.getCallingPid() 10147 + " uid=" + Binder.getCallingUid() + ": " + app); 10148 return null; 10149 } 10150 } 10151 10152 /** 10153 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10154 * to append various headers to the dropbox log text. 10155 */ 10156 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10157 StringBuilder sb) { 10158 // Watchdog thread ends up invoking this function (with 10159 // a null ProcessRecord) to add the stack file to dropbox. 10160 // Do not acquire a lock on this (am) in such cases, as it 10161 // could cause a potential deadlock, if and when watchdog 10162 // is invoked due to unavailability of lock on am and it 10163 // would prevent watchdog from killing system_server. 10164 if (process == null) { 10165 sb.append("Process: ").append(processName).append("\n"); 10166 return; 10167 } 10168 // Note: ProcessRecord 'process' is guarded by the service 10169 // instance. (notably process.pkgList, which could otherwise change 10170 // concurrently during execution of this method) 10171 synchronized (this) { 10172 sb.append("Process: ").append(processName).append("\n"); 10173 int flags = process.info.flags; 10174 IPackageManager pm = AppGlobals.getPackageManager(); 10175 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10176 for (int ip=0; ip<process.pkgList.size(); ip++) { 10177 String pkg = process.pkgList.keyAt(ip); 10178 sb.append("Package: ").append(pkg); 10179 try { 10180 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10181 if (pi != null) { 10182 sb.append(" v").append(pi.versionCode); 10183 if (pi.versionName != null) { 10184 sb.append(" (").append(pi.versionName).append(")"); 10185 } 10186 } 10187 } catch (RemoteException e) { 10188 Slog.e(TAG, "Error getting package info: " + pkg, e); 10189 } 10190 sb.append("\n"); 10191 } 10192 } 10193 } 10194 10195 private static String processClass(ProcessRecord process) { 10196 if (process == null || process.pid == MY_PID) { 10197 return "system_server"; 10198 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10199 return "system_app"; 10200 } else { 10201 return "data_app"; 10202 } 10203 } 10204 10205 /** 10206 * Write a description of an error (crash, WTF, ANR) to the drop box. 10207 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10208 * @param process which caused the error, null means the system server 10209 * @param activity which triggered the error, null if unknown 10210 * @param parent activity related to the error, null if unknown 10211 * @param subject line related to the error, null if absent 10212 * @param report in long form describing the error, null if absent 10213 * @param logFile to include in the report, null if none 10214 * @param crashInfo giving an application stack trace, null if absent 10215 */ 10216 public void addErrorToDropBox(String eventType, 10217 ProcessRecord process, String processName, ActivityRecord activity, 10218 ActivityRecord parent, String subject, 10219 final String report, final File logFile, 10220 final ApplicationErrorReport.CrashInfo crashInfo) { 10221 // NOTE -- this must never acquire the ActivityManagerService lock, 10222 // otherwise the watchdog may be prevented from resetting the system. 10223 10224 final String dropboxTag = processClass(process) + "_" + eventType; 10225 final DropBoxManager dbox = (DropBoxManager) 10226 mContext.getSystemService(Context.DROPBOX_SERVICE); 10227 10228 // Exit early if the dropbox isn't configured to accept this report type. 10229 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10230 10231 final StringBuilder sb = new StringBuilder(1024); 10232 appendDropBoxProcessHeaders(process, processName, sb); 10233 if (activity != null) { 10234 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10235 } 10236 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10237 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10238 } 10239 if (parent != null && parent != activity) { 10240 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10241 } 10242 if (subject != null) { 10243 sb.append("Subject: ").append(subject).append("\n"); 10244 } 10245 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10246 if (Debug.isDebuggerConnected()) { 10247 sb.append("Debugger: Connected\n"); 10248 } 10249 sb.append("\n"); 10250 10251 // Do the rest in a worker thread to avoid blocking the caller on I/O 10252 // (After this point, we shouldn't access AMS internal data structures.) 10253 Thread worker = new Thread("Error dump: " + dropboxTag) { 10254 @Override 10255 public void run() { 10256 if (report != null) { 10257 sb.append(report); 10258 } 10259 if (logFile != null) { 10260 try { 10261 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10262 "\n\n[[TRUNCATED]]")); 10263 } catch (IOException e) { 10264 Slog.e(TAG, "Error reading " + logFile, e); 10265 } 10266 } 10267 if (crashInfo != null && crashInfo.stackTrace != null) { 10268 sb.append(crashInfo.stackTrace); 10269 } 10270 10271 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10272 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10273 if (lines > 0) { 10274 sb.append("\n"); 10275 10276 // Merge several logcat streams, and take the last N lines 10277 InputStreamReader input = null; 10278 try { 10279 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10280 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10281 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10282 10283 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10284 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10285 input = new InputStreamReader(logcat.getInputStream()); 10286 10287 int num; 10288 char[] buf = new char[8192]; 10289 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10290 } catch (IOException e) { 10291 Slog.e(TAG, "Error running logcat", e); 10292 } finally { 10293 if (input != null) try { input.close(); } catch (IOException e) {} 10294 } 10295 } 10296 10297 dbox.addText(dropboxTag, sb.toString()); 10298 } 10299 }; 10300 10301 if (process == null) { 10302 // If process is null, we are being called from some internal code 10303 // and may be about to die -- run this synchronously. 10304 worker.run(); 10305 } else { 10306 worker.start(); 10307 } 10308 } 10309 10310 /** 10311 * Bring up the "unexpected error" dialog box for a crashing app. 10312 * Deal with edge cases (intercepts from instrumented applications, 10313 * ActivityController, error intent receivers, that sort of thing). 10314 * @param r the application crashing 10315 * @param crashInfo describing the failure 10316 */ 10317 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10318 long timeMillis = System.currentTimeMillis(); 10319 String shortMsg = crashInfo.exceptionClassName; 10320 String longMsg = crashInfo.exceptionMessage; 10321 String stackTrace = crashInfo.stackTrace; 10322 if (shortMsg != null && longMsg != null) { 10323 longMsg = shortMsg + ": " + longMsg; 10324 } else if (shortMsg != null) { 10325 longMsg = shortMsg; 10326 } 10327 10328 AppErrorResult result = new AppErrorResult(); 10329 synchronized (this) { 10330 if (mController != null) { 10331 try { 10332 String name = r != null ? r.processName : null; 10333 int pid = r != null ? r.pid : Binder.getCallingPid(); 10334 if (!mController.appCrashed(name, pid, 10335 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10336 Slog.w(TAG, "Force-killing crashed app " + name 10337 + " at watcher's request"); 10338 Process.killProcess(pid); 10339 return; 10340 } 10341 } catch (RemoteException e) { 10342 mController = null; 10343 Watchdog.getInstance().setActivityController(null); 10344 } 10345 } 10346 10347 final long origId = Binder.clearCallingIdentity(); 10348 10349 // If this process is running instrumentation, finish it. 10350 if (r != null && r.instrumentationClass != null) { 10351 Slog.w(TAG, "Error in app " + r.processName 10352 + " running instrumentation " + r.instrumentationClass + ":"); 10353 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10354 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10355 Bundle info = new Bundle(); 10356 info.putString("shortMsg", shortMsg); 10357 info.putString("longMsg", longMsg); 10358 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10359 Binder.restoreCallingIdentity(origId); 10360 return; 10361 } 10362 10363 // If we can't identify the process or it's already exceeded its crash quota, 10364 // quit right away without showing a crash dialog. 10365 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10366 Binder.restoreCallingIdentity(origId); 10367 return; 10368 } 10369 10370 Message msg = Message.obtain(); 10371 msg.what = SHOW_ERROR_MSG; 10372 HashMap data = new HashMap(); 10373 data.put("result", result); 10374 data.put("app", r); 10375 msg.obj = data; 10376 mHandler.sendMessage(msg); 10377 10378 Binder.restoreCallingIdentity(origId); 10379 } 10380 10381 int res = result.get(); 10382 10383 Intent appErrorIntent = null; 10384 synchronized (this) { 10385 if (r != null && !r.isolated) { 10386 // XXX Can't keep track of crash time for isolated processes, 10387 // since they don't have a persistent identity. 10388 mProcessCrashTimes.put(r.info.processName, r.uid, 10389 SystemClock.uptimeMillis()); 10390 } 10391 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10392 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10393 } 10394 } 10395 10396 if (appErrorIntent != null) { 10397 try { 10398 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10399 } catch (ActivityNotFoundException e) { 10400 Slog.w(TAG, "bug report receiver dissappeared", e); 10401 } 10402 } 10403 } 10404 10405 Intent createAppErrorIntentLocked(ProcessRecord r, 10406 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10407 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10408 if (report == null) { 10409 return null; 10410 } 10411 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10412 result.setComponent(r.errorReportReceiver); 10413 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10414 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10415 return result; 10416 } 10417 10418 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10419 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10420 if (r.errorReportReceiver == null) { 10421 return null; 10422 } 10423 10424 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10425 return null; 10426 } 10427 10428 ApplicationErrorReport report = new ApplicationErrorReport(); 10429 report.packageName = r.info.packageName; 10430 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10431 report.processName = r.processName; 10432 report.time = timeMillis; 10433 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10434 10435 if (r.crashing || r.forceCrashReport) { 10436 report.type = ApplicationErrorReport.TYPE_CRASH; 10437 report.crashInfo = crashInfo; 10438 } else if (r.notResponding) { 10439 report.type = ApplicationErrorReport.TYPE_ANR; 10440 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10441 10442 report.anrInfo.activity = r.notRespondingReport.tag; 10443 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10444 report.anrInfo.info = r.notRespondingReport.longMsg; 10445 } 10446 10447 return report; 10448 } 10449 10450 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10451 enforceNotIsolatedCaller("getProcessesInErrorState"); 10452 // assume our apps are happy - lazy create the list 10453 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10454 10455 final boolean allUsers = ActivityManager.checkUidPermission( 10456 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10457 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10458 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10459 10460 synchronized (this) { 10461 10462 // iterate across all processes 10463 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10464 ProcessRecord app = mLruProcesses.get(i); 10465 if (!allUsers && app.userId != userId) { 10466 continue; 10467 } 10468 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10469 // This one's in trouble, so we'll generate a report for it 10470 // crashes are higher priority (in case there's a crash *and* an anr) 10471 ActivityManager.ProcessErrorStateInfo report = null; 10472 if (app.crashing) { 10473 report = app.crashingReport; 10474 } else if (app.notResponding) { 10475 report = app.notRespondingReport; 10476 } 10477 10478 if (report != null) { 10479 if (errList == null) { 10480 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10481 } 10482 errList.add(report); 10483 } else { 10484 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10485 " crashing = " + app.crashing + 10486 " notResponding = " + app.notResponding); 10487 } 10488 } 10489 } 10490 } 10491 10492 return errList; 10493 } 10494 10495 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10496 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10497 if (currApp != null) { 10498 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10499 } 10500 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10501 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10502 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10503 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10504 if (currApp != null) { 10505 currApp.lru = 0; 10506 } 10507 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10508 } else if (adj >= ProcessList.SERVICE_ADJ) { 10509 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10510 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10511 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10512 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10513 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10514 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10515 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10516 } else { 10517 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10518 } 10519 } 10520 10521 private void fillInProcMemInfo(ProcessRecord app, 10522 ActivityManager.RunningAppProcessInfo outInfo) { 10523 outInfo.pid = app.pid; 10524 outInfo.uid = app.info.uid; 10525 if (mHeavyWeightProcess == app) { 10526 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10527 } 10528 if (app.persistent) { 10529 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10530 } 10531 if (app.activities.size() > 0) { 10532 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10533 } 10534 outInfo.lastTrimLevel = app.trimMemoryLevel; 10535 int adj = app.curAdj; 10536 outInfo.importance = oomAdjToImportance(adj, outInfo); 10537 outInfo.importanceReasonCode = app.adjTypeCode; 10538 outInfo.processState = app.curProcState; 10539 } 10540 10541 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10542 enforceNotIsolatedCaller("getRunningAppProcesses"); 10543 // Lazy instantiation of list 10544 List<ActivityManager.RunningAppProcessInfo> runList = null; 10545 final boolean allUsers = ActivityManager.checkUidPermission( 10546 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10547 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10548 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10549 synchronized (this) { 10550 // Iterate across all processes 10551 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10552 ProcessRecord app = mLruProcesses.get(i); 10553 if (!allUsers && app.userId != userId) { 10554 continue; 10555 } 10556 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10557 // Generate process state info for running application 10558 ActivityManager.RunningAppProcessInfo currApp = 10559 new ActivityManager.RunningAppProcessInfo(app.processName, 10560 app.pid, app.getPackageList()); 10561 fillInProcMemInfo(app, currApp); 10562 if (app.adjSource instanceof ProcessRecord) { 10563 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10564 currApp.importanceReasonImportance = oomAdjToImportance( 10565 app.adjSourceOom, null); 10566 } else if (app.adjSource instanceof ActivityRecord) { 10567 ActivityRecord r = (ActivityRecord)app.adjSource; 10568 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10569 } 10570 if (app.adjTarget instanceof ComponentName) { 10571 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10572 } 10573 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10574 // + " lru=" + currApp.lru); 10575 if (runList == null) { 10576 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10577 } 10578 runList.add(currApp); 10579 } 10580 } 10581 } 10582 return runList; 10583 } 10584 10585 public List<ApplicationInfo> getRunningExternalApplications() { 10586 enforceNotIsolatedCaller("getRunningExternalApplications"); 10587 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10588 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10589 if (runningApps != null && runningApps.size() > 0) { 10590 Set<String> extList = new HashSet<String>(); 10591 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10592 if (app.pkgList != null) { 10593 for (String pkg : app.pkgList) { 10594 extList.add(pkg); 10595 } 10596 } 10597 } 10598 IPackageManager pm = AppGlobals.getPackageManager(); 10599 for (String pkg : extList) { 10600 try { 10601 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10602 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10603 retList.add(info); 10604 } 10605 } catch (RemoteException e) { 10606 } 10607 } 10608 } 10609 return retList; 10610 } 10611 10612 @Override 10613 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10614 enforceNotIsolatedCaller("getMyMemoryState"); 10615 synchronized (this) { 10616 ProcessRecord proc; 10617 synchronized (mPidsSelfLocked) { 10618 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10619 } 10620 fillInProcMemInfo(proc, outInfo); 10621 } 10622 } 10623 10624 @Override 10625 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10626 if (checkCallingPermission(android.Manifest.permission.DUMP) 10627 != PackageManager.PERMISSION_GRANTED) { 10628 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10629 + Binder.getCallingPid() 10630 + ", uid=" + Binder.getCallingUid() 10631 + " without permission " 10632 + android.Manifest.permission.DUMP); 10633 return; 10634 } 10635 10636 boolean dumpAll = false; 10637 boolean dumpClient = false; 10638 String dumpPackage = null; 10639 10640 int opti = 0; 10641 while (opti < args.length) { 10642 String opt = args[opti]; 10643 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10644 break; 10645 } 10646 opti++; 10647 if ("-a".equals(opt)) { 10648 dumpAll = true; 10649 } else if ("-c".equals(opt)) { 10650 dumpClient = true; 10651 } else if ("-h".equals(opt)) { 10652 pw.println("Activity manager dump options:"); 10653 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10654 pw.println(" cmd may be one of:"); 10655 pw.println(" a[ctivities]: activity stack state"); 10656 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10657 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10658 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10659 pw.println(" o[om]: out of memory management"); 10660 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10661 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10662 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10663 pw.println(" service [COMP_SPEC]: service client-side state"); 10664 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10665 pw.println(" all: dump all activities"); 10666 pw.println(" top: dump the top activity"); 10667 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10668 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10669 pw.println(" a partial substring in a component name, a"); 10670 pw.println(" hex object identifier."); 10671 pw.println(" -a: include all available server state."); 10672 pw.println(" -c: include client state."); 10673 return; 10674 } else { 10675 pw.println("Unknown argument: " + opt + "; use -h for help"); 10676 } 10677 } 10678 10679 long origId = Binder.clearCallingIdentity(); 10680 boolean more = false; 10681 // Is the caller requesting to dump a particular piece of data? 10682 if (opti < args.length) { 10683 String cmd = args[opti]; 10684 opti++; 10685 if ("activities".equals(cmd) || "a".equals(cmd)) { 10686 synchronized (this) { 10687 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10688 } 10689 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10690 String[] newArgs; 10691 String name; 10692 if (opti >= args.length) { 10693 name = null; 10694 newArgs = EMPTY_STRING_ARRAY; 10695 } else { 10696 name = args[opti]; 10697 opti++; 10698 newArgs = new String[args.length - opti]; 10699 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10700 args.length - opti); 10701 } 10702 synchronized (this) { 10703 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10704 } 10705 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10706 String[] newArgs; 10707 String name; 10708 if (opti >= args.length) { 10709 name = null; 10710 newArgs = EMPTY_STRING_ARRAY; 10711 } else { 10712 name = args[opti]; 10713 opti++; 10714 newArgs = new String[args.length - opti]; 10715 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10716 args.length - opti); 10717 } 10718 synchronized (this) { 10719 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10720 } 10721 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10722 String[] newArgs; 10723 String name; 10724 if (opti >= args.length) { 10725 name = null; 10726 newArgs = EMPTY_STRING_ARRAY; 10727 } else { 10728 name = args[opti]; 10729 opti++; 10730 newArgs = new String[args.length - opti]; 10731 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10732 args.length - opti); 10733 } 10734 synchronized (this) { 10735 dumpProcessesLocked(fd, pw, args, opti, true, name); 10736 } 10737 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10738 synchronized (this) { 10739 dumpOomLocked(fd, pw, args, opti, true); 10740 } 10741 } else if ("provider".equals(cmd)) { 10742 String[] newArgs; 10743 String name; 10744 if (opti >= args.length) { 10745 name = null; 10746 newArgs = EMPTY_STRING_ARRAY; 10747 } else { 10748 name = args[opti]; 10749 opti++; 10750 newArgs = new String[args.length - opti]; 10751 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10752 } 10753 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10754 pw.println("No providers match: " + name); 10755 pw.println("Use -h for help."); 10756 } 10757 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10758 synchronized (this) { 10759 dumpProvidersLocked(fd, pw, args, opti, true, null); 10760 } 10761 } else if ("service".equals(cmd)) { 10762 String[] newArgs; 10763 String name; 10764 if (opti >= args.length) { 10765 name = null; 10766 newArgs = EMPTY_STRING_ARRAY; 10767 } else { 10768 name = args[opti]; 10769 opti++; 10770 newArgs = new String[args.length - opti]; 10771 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10772 args.length - opti); 10773 } 10774 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10775 pw.println("No services match: " + name); 10776 pw.println("Use -h for help."); 10777 } 10778 } else if ("package".equals(cmd)) { 10779 String[] newArgs; 10780 if (opti >= args.length) { 10781 pw.println("package: no package name specified"); 10782 pw.println("Use -h for help."); 10783 } else { 10784 dumpPackage = args[opti]; 10785 opti++; 10786 newArgs = new String[args.length - opti]; 10787 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10788 args.length - opti); 10789 args = newArgs; 10790 opti = 0; 10791 more = true; 10792 } 10793 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10794 synchronized (this) { 10795 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10796 } 10797 } else { 10798 // Dumping a single activity? 10799 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10800 pw.println("Bad activity command, or no activities match: " + cmd); 10801 pw.println("Use -h for help."); 10802 } 10803 } 10804 if (!more) { 10805 Binder.restoreCallingIdentity(origId); 10806 return; 10807 } 10808 } 10809 10810 // No piece of data specified, dump everything. 10811 synchronized (this) { 10812 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10813 pw.println(); 10814 if (dumpAll) { 10815 pw.println("-------------------------------------------------------------------------------"); 10816 } 10817 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10818 pw.println(); 10819 if (dumpAll) { 10820 pw.println("-------------------------------------------------------------------------------"); 10821 } 10822 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10823 pw.println(); 10824 if (dumpAll) { 10825 pw.println("-------------------------------------------------------------------------------"); 10826 } 10827 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10828 pw.println(); 10829 if (dumpAll) { 10830 pw.println("-------------------------------------------------------------------------------"); 10831 } 10832 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10833 pw.println(); 10834 if (dumpAll) { 10835 pw.println("-------------------------------------------------------------------------------"); 10836 } 10837 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10838 } 10839 Binder.restoreCallingIdentity(origId); 10840 } 10841 10842 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10843 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10844 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10845 10846 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10847 dumpPackage); 10848 boolean needSep = printedAnything; 10849 10850 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10851 dumpPackage, needSep, " mFocusedActivity: "); 10852 if (printed) { 10853 printedAnything = true; 10854 needSep = false; 10855 } 10856 10857 if (dumpPackage == null) { 10858 if (needSep) { 10859 pw.println(); 10860 } 10861 needSep = true; 10862 printedAnything = true; 10863 mStackSupervisor.dump(pw, " "); 10864 } 10865 10866 if (mRecentTasks.size() > 0) { 10867 boolean printedHeader = false; 10868 10869 final int N = mRecentTasks.size(); 10870 for (int i=0; i<N; i++) { 10871 TaskRecord tr = mRecentTasks.get(i); 10872 if (dumpPackage != null) { 10873 if (tr.realActivity == null || 10874 !dumpPackage.equals(tr.realActivity)) { 10875 continue; 10876 } 10877 } 10878 if (!printedHeader) { 10879 if (needSep) { 10880 pw.println(); 10881 } 10882 pw.println(" Recent tasks:"); 10883 printedHeader = true; 10884 printedAnything = true; 10885 } 10886 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10887 pw.println(tr); 10888 if (dumpAll) { 10889 mRecentTasks.get(i).dump(pw, " "); 10890 } 10891 } 10892 } 10893 10894 if (!printedAnything) { 10895 pw.println(" (nothing)"); 10896 } 10897 } 10898 10899 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10900 int opti, boolean dumpAll, String dumpPackage) { 10901 boolean needSep = false; 10902 boolean printedAnything = false; 10903 int numPers = 0; 10904 10905 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10906 10907 if (dumpAll) { 10908 final int NP = mProcessNames.getMap().size(); 10909 for (int ip=0; ip<NP; ip++) { 10910 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10911 final int NA = procs.size(); 10912 for (int ia=0; ia<NA; ia++) { 10913 ProcessRecord r = procs.valueAt(ia); 10914 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10915 continue; 10916 } 10917 if (!needSep) { 10918 pw.println(" All known processes:"); 10919 needSep = true; 10920 printedAnything = true; 10921 } 10922 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10923 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10924 pw.print(" "); pw.println(r); 10925 r.dump(pw, " "); 10926 if (r.persistent) { 10927 numPers++; 10928 } 10929 } 10930 } 10931 } 10932 10933 if (mIsolatedProcesses.size() > 0) { 10934 boolean printed = false; 10935 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10936 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10937 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10938 continue; 10939 } 10940 if (!printed) { 10941 if (needSep) { 10942 pw.println(); 10943 } 10944 pw.println(" Isolated process list (sorted by uid):"); 10945 printedAnything = true; 10946 printed = true; 10947 needSep = true; 10948 } 10949 pw.println(String.format("%sIsolated #%2d: %s", 10950 " ", i, r.toString())); 10951 } 10952 } 10953 10954 if (mLruProcesses.size() > 0) { 10955 if (needSep) { 10956 pw.println(); 10957 } 10958 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10959 pw.print(" total, non-act at "); 10960 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10961 pw.print(", non-svc at "); 10962 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10963 pw.println("):"); 10964 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10965 needSep = true; 10966 printedAnything = true; 10967 } 10968 10969 if (dumpAll || dumpPackage != null) { 10970 synchronized (mPidsSelfLocked) { 10971 boolean printed = false; 10972 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10973 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10974 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10975 continue; 10976 } 10977 if (!printed) { 10978 if (needSep) pw.println(); 10979 needSep = true; 10980 pw.println(" PID mappings:"); 10981 printed = true; 10982 printedAnything = true; 10983 } 10984 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10985 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10986 } 10987 } 10988 } 10989 10990 if (mForegroundProcesses.size() > 0) { 10991 synchronized (mPidsSelfLocked) { 10992 boolean printed = false; 10993 for (int i=0; i<mForegroundProcesses.size(); i++) { 10994 ProcessRecord r = mPidsSelfLocked.get( 10995 mForegroundProcesses.valueAt(i).pid); 10996 if (dumpPackage != null && (r == null 10997 || !r.pkgList.containsKey(dumpPackage))) { 10998 continue; 10999 } 11000 if (!printed) { 11001 if (needSep) pw.println(); 11002 needSep = true; 11003 pw.println(" Foreground Processes:"); 11004 printed = true; 11005 printedAnything = true; 11006 } 11007 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 11008 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 11009 } 11010 } 11011 } 11012 11013 if (mPersistentStartingProcesses.size() > 0) { 11014 if (needSep) pw.println(); 11015 needSep = true; 11016 printedAnything = true; 11017 pw.println(" Persisent processes that are starting:"); 11018 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 11019 "Starting Norm", "Restarting PERS", dumpPackage); 11020 } 11021 11022 if (mRemovedProcesses.size() > 0) { 11023 if (needSep) pw.println(); 11024 needSep = true; 11025 printedAnything = true; 11026 pw.println(" Processes that are being removed:"); 11027 dumpProcessList(pw, this, mRemovedProcesses, " ", 11028 "Removed Norm", "Removed PERS", dumpPackage); 11029 } 11030 11031 if (mProcessesOnHold.size() > 0) { 11032 if (needSep) pw.println(); 11033 needSep = true; 11034 printedAnything = true; 11035 pw.println(" Processes that are on old until the system is ready:"); 11036 dumpProcessList(pw, this, mProcessesOnHold, " ", 11037 "OnHold Norm", "OnHold PERS", dumpPackage); 11038 } 11039 11040 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 11041 11042 if (mProcessCrashTimes.getMap().size() > 0) { 11043 boolean printed = false; 11044 long now = SystemClock.uptimeMillis(); 11045 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 11046 final int NP = pmap.size(); 11047 for (int ip=0; ip<NP; ip++) { 11048 String pname = pmap.keyAt(ip); 11049 SparseArray<Long> uids = pmap.valueAt(ip); 11050 final int N = uids.size(); 11051 for (int i=0; i<N; i++) { 11052 int puid = uids.keyAt(i); 11053 ProcessRecord r = mProcessNames.get(pname, puid); 11054 if (dumpPackage != null && (r == null 11055 || !r.pkgList.containsKey(dumpPackage))) { 11056 continue; 11057 } 11058 if (!printed) { 11059 if (needSep) pw.println(); 11060 needSep = true; 11061 pw.println(" Time since processes crashed:"); 11062 printed = true; 11063 printedAnything = true; 11064 } 11065 pw.print(" Process "); pw.print(pname); 11066 pw.print(" uid "); pw.print(puid); 11067 pw.print(": last crashed "); 11068 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 11069 pw.println(" ago"); 11070 } 11071 } 11072 } 11073 11074 if (mBadProcesses.getMap().size() > 0) { 11075 boolean printed = false; 11076 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11077 final int NP = pmap.size(); 11078 for (int ip=0; ip<NP; ip++) { 11079 String pname = pmap.keyAt(ip); 11080 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11081 final int N = uids.size(); 11082 for (int i=0; i<N; i++) { 11083 int puid = uids.keyAt(i); 11084 ProcessRecord r = mProcessNames.get(pname, puid); 11085 if (dumpPackage != null && (r == null 11086 || !r.pkgList.containsKey(dumpPackage))) { 11087 continue; 11088 } 11089 if (!printed) { 11090 if (needSep) pw.println(); 11091 needSep = true; 11092 pw.println(" Bad processes:"); 11093 printedAnything = true; 11094 } 11095 BadProcessInfo info = uids.valueAt(i); 11096 pw.print(" Bad process "); pw.print(pname); 11097 pw.print(" uid "); pw.print(puid); 11098 pw.print(": crashed at time "); pw.println(info.time); 11099 if (info.shortMsg != null) { 11100 pw.print(" Short msg: "); pw.println(info.shortMsg); 11101 } 11102 if (info.longMsg != null) { 11103 pw.print(" Long msg: "); pw.println(info.longMsg); 11104 } 11105 if (info.stack != null) { 11106 pw.println(" Stack:"); 11107 int lastPos = 0; 11108 for (int pos=0; pos<info.stack.length(); pos++) { 11109 if (info.stack.charAt(pos) == '\n') { 11110 pw.print(" "); 11111 pw.write(info.stack, lastPos, pos-lastPos); 11112 pw.println(); 11113 lastPos = pos+1; 11114 } 11115 } 11116 if (lastPos < info.stack.length()) { 11117 pw.print(" "); 11118 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11119 pw.println(); 11120 } 11121 } 11122 } 11123 } 11124 } 11125 11126 if (dumpPackage == null) { 11127 pw.println(); 11128 needSep = false; 11129 pw.println(" mStartedUsers:"); 11130 for (int i=0; i<mStartedUsers.size(); i++) { 11131 UserStartedState uss = mStartedUsers.valueAt(i); 11132 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11133 pw.print(": "); uss.dump("", pw); 11134 } 11135 pw.print(" mStartedUserArray: ["); 11136 for (int i=0; i<mStartedUserArray.length; i++) { 11137 if (i > 0) pw.print(", "); 11138 pw.print(mStartedUserArray[i]); 11139 } 11140 pw.println("]"); 11141 pw.print(" mUserLru: ["); 11142 for (int i=0; i<mUserLru.size(); i++) { 11143 if (i > 0) pw.print(", "); 11144 pw.print(mUserLru.get(i)); 11145 } 11146 pw.println("]"); 11147 if (dumpAll) { 11148 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11149 } 11150 } 11151 if (mHomeProcess != null && (dumpPackage == null 11152 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11153 if (needSep) { 11154 pw.println(); 11155 needSep = false; 11156 } 11157 pw.println(" mHomeProcess: " + mHomeProcess); 11158 } 11159 if (mPreviousProcess != null && (dumpPackage == null 11160 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11161 if (needSep) { 11162 pw.println(); 11163 needSep = false; 11164 } 11165 pw.println(" mPreviousProcess: " + mPreviousProcess); 11166 } 11167 if (dumpAll) { 11168 StringBuilder sb = new StringBuilder(128); 11169 sb.append(" mPreviousProcessVisibleTime: "); 11170 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11171 pw.println(sb); 11172 } 11173 if (mHeavyWeightProcess != null && (dumpPackage == null 11174 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11175 if (needSep) { 11176 pw.println(); 11177 needSep = false; 11178 } 11179 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11180 } 11181 if (dumpPackage == null) { 11182 pw.println(" mConfiguration: " + mConfiguration); 11183 } 11184 if (dumpAll) { 11185 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11186 if (mCompatModePackages.getPackages().size() > 0) { 11187 boolean printed = false; 11188 for (Map.Entry<String, Integer> entry 11189 : mCompatModePackages.getPackages().entrySet()) { 11190 String pkg = entry.getKey(); 11191 int mode = entry.getValue(); 11192 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11193 continue; 11194 } 11195 if (!printed) { 11196 pw.println(" mScreenCompatPackages:"); 11197 printed = true; 11198 } 11199 pw.print(" "); pw.print(pkg); pw.print(": "); 11200 pw.print(mode); pw.println(); 11201 } 11202 } 11203 } 11204 if (dumpPackage == null) { 11205 if (mSleeping || mWentToSleep || mLockScreenShown) { 11206 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11207 + " mLockScreenShown " + mLockScreenShown); 11208 } 11209 if (mShuttingDown || mRunningVoice) { 11210 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice); 11211 } 11212 } 11213 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11214 || mOrigWaitForDebugger) { 11215 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11216 || dumpPackage.equals(mOrigDebugApp)) { 11217 if (needSep) { 11218 pw.println(); 11219 needSep = false; 11220 } 11221 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11222 + " mDebugTransient=" + mDebugTransient 11223 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11224 } 11225 } 11226 if (mOpenGlTraceApp != null) { 11227 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11228 if (needSep) { 11229 pw.println(); 11230 needSep = false; 11231 } 11232 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11233 } 11234 } 11235 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11236 || mProfileFd != null) { 11237 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11238 if (needSep) { 11239 pw.println(); 11240 needSep = false; 11241 } 11242 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11243 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11244 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11245 + mAutoStopProfiler); 11246 } 11247 } 11248 if (dumpPackage == null) { 11249 if (mAlwaysFinishActivities || mController != null) { 11250 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11251 + " mController=" + mController); 11252 } 11253 if (dumpAll) { 11254 pw.println(" Total persistent processes: " + numPers); 11255 pw.println(" mProcessesReady=" + mProcessesReady 11256 + " mSystemReady=" + mSystemReady); 11257 pw.println(" mBooting=" + mBooting 11258 + " mBooted=" + mBooted 11259 + " mFactoryTest=" + mFactoryTest); 11260 pw.print(" mLastPowerCheckRealtime="); 11261 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11262 pw.println(""); 11263 pw.print(" mLastPowerCheckUptime="); 11264 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11265 pw.println(""); 11266 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11267 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11268 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11269 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11270 + " (" + mLruProcesses.size() + " total)" 11271 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11272 + " mNumServiceProcs=" + mNumServiceProcs 11273 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11274 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11275 + " mLastMemoryLevel" + mLastMemoryLevel 11276 + " mLastNumProcesses" + mLastNumProcesses); 11277 long now = SystemClock.uptimeMillis(); 11278 pw.print(" mLastIdleTime="); 11279 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11280 pw.print(" mLowRamSinceLastIdle="); 11281 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11282 pw.println(); 11283 } 11284 } 11285 11286 if (!printedAnything) { 11287 pw.println(" (nothing)"); 11288 } 11289 } 11290 11291 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11292 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11293 if (mProcessesToGc.size() > 0) { 11294 boolean printed = false; 11295 long now = SystemClock.uptimeMillis(); 11296 for (int i=0; i<mProcessesToGc.size(); i++) { 11297 ProcessRecord proc = mProcessesToGc.get(i); 11298 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11299 continue; 11300 } 11301 if (!printed) { 11302 if (needSep) pw.println(); 11303 needSep = true; 11304 pw.println(" Processes that are waiting to GC:"); 11305 printed = true; 11306 } 11307 pw.print(" Process "); pw.println(proc); 11308 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11309 pw.print(", last gced="); 11310 pw.print(now-proc.lastRequestedGc); 11311 pw.print(" ms ago, last lowMem="); 11312 pw.print(now-proc.lastLowMemory); 11313 pw.println(" ms ago"); 11314 11315 } 11316 } 11317 return needSep; 11318 } 11319 11320 void printOomLevel(PrintWriter pw, String name, int adj) { 11321 pw.print(" "); 11322 if (adj >= 0) { 11323 pw.print(' '); 11324 if (adj < 10) pw.print(' '); 11325 } else { 11326 if (adj > -10) pw.print(' '); 11327 } 11328 pw.print(adj); 11329 pw.print(": "); 11330 pw.print(name); 11331 pw.print(" ("); 11332 pw.print(mProcessList.getMemLevel(adj)/1024); 11333 pw.println(" kB)"); 11334 } 11335 11336 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11337 int opti, boolean dumpAll) { 11338 boolean needSep = false; 11339 11340 if (mLruProcesses.size() > 0) { 11341 if (needSep) pw.println(); 11342 needSep = true; 11343 pw.println(" OOM levels:"); 11344 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11345 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11346 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11347 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11348 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11349 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11350 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11351 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11352 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11353 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11354 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11355 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11356 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11357 11358 if (needSep) pw.println(); 11359 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11360 pw.print(" total, non-act at "); 11361 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11362 pw.print(", non-svc at "); 11363 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11364 pw.println("):"); 11365 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11366 needSep = true; 11367 } 11368 11369 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11370 11371 pw.println(); 11372 pw.println(" mHomeProcess: " + mHomeProcess); 11373 pw.println(" mPreviousProcess: " + mPreviousProcess); 11374 if (mHeavyWeightProcess != null) { 11375 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11376 } 11377 11378 return true; 11379 } 11380 11381 /** 11382 * There are three ways to call this: 11383 * - no provider specified: dump all the providers 11384 * - a flattened component name that matched an existing provider was specified as the 11385 * first arg: dump that one provider 11386 * - the first arg isn't the flattened component name of an existing provider: 11387 * dump all providers whose component contains the first arg as a substring 11388 */ 11389 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11390 int opti, boolean dumpAll) { 11391 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11392 } 11393 11394 static class ItemMatcher { 11395 ArrayList<ComponentName> components; 11396 ArrayList<String> strings; 11397 ArrayList<Integer> objects; 11398 boolean all; 11399 11400 ItemMatcher() { 11401 all = true; 11402 } 11403 11404 void build(String name) { 11405 ComponentName componentName = ComponentName.unflattenFromString(name); 11406 if (componentName != null) { 11407 if (components == null) { 11408 components = new ArrayList<ComponentName>(); 11409 } 11410 components.add(componentName); 11411 all = false; 11412 } else { 11413 int objectId = 0; 11414 // Not a '/' separated full component name; maybe an object ID? 11415 try { 11416 objectId = Integer.parseInt(name, 16); 11417 if (objects == null) { 11418 objects = new ArrayList<Integer>(); 11419 } 11420 objects.add(objectId); 11421 all = false; 11422 } catch (RuntimeException e) { 11423 // Not an integer; just do string match. 11424 if (strings == null) { 11425 strings = new ArrayList<String>(); 11426 } 11427 strings.add(name); 11428 all = false; 11429 } 11430 } 11431 } 11432 11433 int build(String[] args, int opti) { 11434 for (; opti<args.length; opti++) { 11435 String name = args[opti]; 11436 if ("--".equals(name)) { 11437 return opti+1; 11438 } 11439 build(name); 11440 } 11441 return opti; 11442 } 11443 11444 boolean match(Object object, ComponentName comp) { 11445 if (all) { 11446 return true; 11447 } 11448 if (components != null) { 11449 for (int i=0; i<components.size(); i++) { 11450 if (components.get(i).equals(comp)) { 11451 return true; 11452 } 11453 } 11454 } 11455 if (objects != null) { 11456 for (int i=0; i<objects.size(); i++) { 11457 if (System.identityHashCode(object) == objects.get(i)) { 11458 return true; 11459 } 11460 } 11461 } 11462 if (strings != null) { 11463 String flat = comp.flattenToString(); 11464 for (int i=0; i<strings.size(); i++) { 11465 if (flat.contains(strings.get(i))) { 11466 return true; 11467 } 11468 } 11469 } 11470 return false; 11471 } 11472 } 11473 11474 /** 11475 * There are three things that cmd can be: 11476 * - a flattened component name that matches an existing activity 11477 * - the cmd arg isn't the flattened component name of an existing activity: 11478 * dump all activity whose component contains the cmd as a substring 11479 * - A hex number of the ActivityRecord object instance. 11480 */ 11481 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11482 int opti, boolean dumpAll) { 11483 ArrayList<ActivityRecord> activities; 11484 11485 synchronized (this) { 11486 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11487 } 11488 11489 if (activities.size() <= 0) { 11490 return false; 11491 } 11492 11493 String[] newArgs = new String[args.length - opti]; 11494 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11495 11496 TaskRecord lastTask = null; 11497 boolean needSep = false; 11498 for (int i=activities.size()-1; i>=0; i--) { 11499 ActivityRecord r = activities.get(i); 11500 if (needSep) { 11501 pw.println(); 11502 } 11503 needSep = true; 11504 synchronized (this) { 11505 if (lastTask != r.task) { 11506 lastTask = r.task; 11507 pw.print("TASK "); pw.print(lastTask.affinity); 11508 pw.print(" id="); pw.println(lastTask.taskId); 11509 if (dumpAll) { 11510 lastTask.dump(pw, " "); 11511 } 11512 } 11513 } 11514 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11515 } 11516 return true; 11517 } 11518 11519 /** 11520 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11521 * there is a thread associated with the activity. 11522 */ 11523 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11524 final ActivityRecord r, String[] args, boolean dumpAll) { 11525 String innerPrefix = prefix + " "; 11526 synchronized (this) { 11527 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11528 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11529 pw.print(" pid="); 11530 if (r.app != null) pw.println(r.app.pid); 11531 else pw.println("(not running)"); 11532 if (dumpAll) { 11533 r.dump(pw, innerPrefix); 11534 } 11535 } 11536 if (r.app != null && r.app.thread != null) { 11537 // flush anything that is already in the PrintWriter since the thread is going 11538 // to write to the file descriptor directly 11539 pw.flush(); 11540 try { 11541 TransferPipe tp = new TransferPipe(); 11542 try { 11543 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11544 r.appToken, innerPrefix, args); 11545 tp.go(fd); 11546 } finally { 11547 tp.kill(); 11548 } 11549 } catch (IOException e) { 11550 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11551 } catch (RemoteException e) { 11552 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11553 } 11554 } 11555 } 11556 11557 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11558 int opti, boolean dumpAll, String dumpPackage) { 11559 boolean needSep = false; 11560 boolean onlyHistory = false; 11561 boolean printedAnything = false; 11562 11563 if ("history".equals(dumpPackage)) { 11564 if (opti < args.length && "-s".equals(args[opti])) { 11565 dumpAll = false; 11566 } 11567 onlyHistory = true; 11568 dumpPackage = null; 11569 } 11570 11571 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11572 if (!onlyHistory && dumpAll) { 11573 if (mRegisteredReceivers.size() > 0) { 11574 boolean printed = false; 11575 Iterator it = mRegisteredReceivers.values().iterator(); 11576 while (it.hasNext()) { 11577 ReceiverList r = (ReceiverList)it.next(); 11578 if (dumpPackage != null && (r.app == null || 11579 !dumpPackage.equals(r.app.info.packageName))) { 11580 continue; 11581 } 11582 if (!printed) { 11583 pw.println(" Registered Receivers:"); 11584 needSep = true; 11585 printed = true; 11586 printedAnything = true; 11587 } 11588 pw.print(" * "); pw.println(r); 11589 r.dump(pw, " "); 11590 } 11591 } 11592 11593 if (mReceiverResolver.dump(pw, needSep ? 11594 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11595 " ", dumpPackage, false)) { 11596 needSep = true; 11597 printedAnything = true; 11598 } 11599 } 11600 11601 for (BroadcastQueue q : mBroadcastQueues) { 11602 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11603 printedAnything |= needSep; 11604 } 11605 11606 needSep = true; 11607 11608 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11609 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11610 if (needSep) { 11611 pw.println(); 11612 } 11613 needSep = true; 11614 printedAnything = true; 11615 pw.print(" Sticky broadcasts for user "); 11616 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11617 StringBuilder sb = new StringBuilder(128); 11618 for (Map.Entry<String, ArrayList<Intent>> ent 11619 : mStickyBroadcasts.valueAt(user).entrySet()) { 11620 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11621 if (dumpAll) { 11622 pw.println(":"); 11623 ArrayList<Intent> intents = ent.getValue(); 11624 final int N = intents.size(); 11625 for (int i=0; i<N; i++) { 11626 sb.setLength(0); 11627 sb.append(" Intent: "); 11628 intents.get(i).toShortString(sb, false, true, false, false); 11629 pw.println(sb.toString()); 11630 Bundle bundle = intents.get(i).getExtras(); 11631 if (bundle != null) { 11632 pw.print(" "); 11633 pw.println(bundle.toString()); 11634 } 11635 } 11636 } else { 11637 pw.println(""); 11638 } 11639 } 11640 } 11641 } 11642 11643 if (!onlyHistory && dumpAll) { 11644 pw.println(); 11645 for (BroadcastQueue queue : mBroadcastQueues) { 11646 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11647 + queue.mBroadcastsScheduled); 11648 } 11649 pw.println(" mHandler:"); 11650 mHandler.dump(new PrintWriterPrinter(pw), " "); 11651 needSep = true; 11652 printedAnything = true; 11653 } 11654 11655 if (!printedAnything) { 11656 pw.println(" (nothing)"); 11657 } 11658 } 11659 11660 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11661 int opti, boolean dumpAll, String dumpPackage) { 11662 boolean needSep; 11663 boolean printedAnything = false; 11664 11665 ItemMatcher matcher = new ItemMatcher(); 11666 matcher.build(args, opti); 11667 11668 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11669 11670 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11671 printedAnything |= needSep; 11672 11673 if (mLaunchingProviders.size() > 0) { 11674 boolean printed = false; 11675 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11676 ContentProviderRecord r = mLaunchingProviders.get(i); 11677 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11678 continue; 11679 } 11680 if (!printed) { 11681 if (needSep) pw.println(); 11682 needSep = true; 11683 pw.println(" Launching content providers:"); 11684 printed = true; 11685 printedAnything = true; 11686 } 11687 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11688 pw.println(r); 11689 } 11690 } 11691 11692 if (mGrantedUriPermissions.size() > 0) { 11693 boolean printed = false; 11694 int dumpUid = -2; 11695 if (dumpPackage != null) { 11696 try { 11697 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11698 } catch (NameNotFoundException e) { 11699 dumpUid = -1; 11700 } 11701 } 11702 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11703 int uid = mGrantedUriPermissions.keyAt(i); 11704 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11705 continue; 11706 } 11707 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11708 if (!printed) { 11709 if (needSep) pw.println(); 11710 needSep = true; 11711 pw.println(" Granted Uri Permissions:"); 11712 printed = true; 11713 printedAnything = true; 11714 } 11715 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11716 for (UriPermission perm : perms.values()) { 11717 pw.print(" "); pw.println(perm); 11718 if (dumpAll) { 11719 perm.dump(pw, " "); 11720 } 11721 } 11722 } 11723 } 11724 11725 if (!printedAnything) { 11726 pw.println(" (nothing)"); 11727 } 11728 } 11729 11730 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11731 int opti, boolean dumpAll, String dumpPackage) { 11732 boolean printed = false; 11733 11734 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11735 11736 if (mIntentSenderRecords.size() > 0) { 11737 Iterator<WeakReference<PendingIntentRecord>> it 11738 = mIntentSenderRecords.values().iterator(); 11739 while (it.hasNext()) { 11740 WeakReference<PendingIntentRecord> ref = it.next(); 11741 PendingIntentRecord rec = ref != null ? ref.get(): null; 11742 if (dumpPackage != null && (rec == null 11743 || !dumpPackage.equals(rec.key.packageName))) { 11744 continue; 11745 } 11746 printed = true; 11747 if (rec != null) { 11748 pw.print(" * "); pw.println(rec); 11749 if (dumpAll) { 11750 rec.dump(pw, " "); 11751 } 11752 } else { 11753 pw.print(" * "); pw.println(ref); 11754 } 11755 } 11756 } 11757 11758 if (!printed) { 11759 pw.println(" (nothing)"); 11760 } 11761 } 11762 11763 private static final int dumpProcessList(PrintWriter pw, 11764 ActivityManagerService service, List list, 11765 String prefix, String normalLabel, String persistentLabel, 11766 String dumpPackage) { 11767 int numPers = 0; 11768 final int N = list.size()-1; 11769 for (int i=N; i>=0; i--) { 11770 ProcessRecord r = (ProcessRecord)list.get(i); 11771 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11772 continue; 11773 } 11774 pw.println(String.format("%s%s #%2d: %s", 11775 prefix, (r.persistent ? persistentLabel : normalLabel), 11776 i, r.toString())); 11777 if (r.persistent) { 11778 numPers++; 11779 } 11780 } 11781 return numPers; 11782 } 11783 11784 private static final boolean dumpProcessOomList(PrintWriter pw, 11785 ActivityManagerService service, List<ProcessRecord> origList, 11786 String prefix, String normalLabel, String persistentLabel, 11787 boolean inclDetails, String dumpPackage) { 11788 11789 ArrayList<Pair<ProcessRecord, Integer>> list 11790 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11791 for (int i=0; i<origList.size(); i++) { 11792 ProcessRecord r = origList.get(i); 11793 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11794 continue; 11795 } 11796 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11797 } 11798 11799 if (list.size() <= 0) { 11800 return false; 11801 } 11802 11803 Comparator<Pair<ProcessRecord, Integer>> comparator 11804 = new Comparator<Pair<ProcessRecord, Integer>>() { 11805 @Override 11806 public int compare(Pair<ProcessRecord, Integer> object1, 11807 Pair<ProcessRecord, Integer> object2) { 11808 if (object1.first.setAdj != object2.first.setAdj) { 11809 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11810 } 11811 if (object1.second.intValue() != object2.second.intValue()) { 11812 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11813 } 11814 return 0; 11815 } 11816 }; 11817 11818 Collections.sort(list, comparator); 11819 11820 final long curRealtime = SystemClock.elapsedRealtime(); 11821 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11822 final long curUptime = SystemClock.uptimeMillis(); 11823 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11824 11825 for (int i=list.size()-1; i>=0; i--) { 11826 ProcessRecord r = list.get(i).first; 11827 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11828 char schedGroup; 11829 switch (r.setSchedGroup) { 11830 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11831 schedGroup = 'B'; 11832 break; 11833 case Process.THREAD_GROUP_DEFAULT: 11834 schedGroup = 'F'; 11835 break; 11836 default: 11837 schedGroup = '?'; 11838 break; 11839 } 11840 char foreground; 11841 if (r.foregroundActivities) { 11842 foreground = 'A'; 11843 } else if (r.foregroundServices) { 11844 foreground = 'S'; 11845 } else { 11846 foreground = ' '; 11847 } 11848 String procState = ProcessList.makeProcStateString(r.curProcState); 11849 pw.print(prefix); 11850 pw.print(r.persistent ? persistentLabel : normalLabel); 11851 pw.print(" #"); 11852 int num = (origList.size()-1)-list.get(i).second; 11853 if (num < 10) pw.print(' '); 11854 pw.print(num); 11855 pw.print(": "); 11856 pw.print(oomAdj); 11857 pw.print(' '); 11858 pw.print(schedGroup); 11859 pw.print('/'); 11860 pw.print(foreground); 11861 pw.print('/'); 11862 pw.print(procState); 11863 pw.print(" trm:"); 11864 if (r.trimMemoryLevel < 10) pw.print(' '); 11865 pw.print(r.trimMemoryLevel); 11866 pw.print(' '); 11867 pw.print(r.toShortString()); 11868 pw.print(" ("); 11869 pw.print(r.adjType); 11870 pw.println(')'); 11871 if (r.adjSource != null || r.adjTarget != null) { 11872 pw.print(prefix); 11873 pw.print(" "); 11874 if (r.adjTarget instanceof ComponentName) { 11875 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11876 } else if (r.adjTarget != null) { 11877 pw.print(r.adjTarget.toString()); 11878 } else { 11879 pw.print("{null}"); 11880 } 11881 pw.print("<="); 11882 if (r.adjSource instanceof ProcessRecord) { 11883 pw.print("Proc{"); 11884 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11885 pw.println("}"); 11886 } else if (r.adjSource != null) { 11887 pw.println(r.adjSource.toString()); 11888 } else { 11889 pw.println("{null}"); 11890 } 11891 } 11892 if (inclDetails) { 11893 pw.print(prefix); 11894 pw.print(" "); 11895 pw.print("oom: max="); pw.print(r.maxAdj); 11896 pw.print(" curRaw="); pw.print(r.curRawAdj); 11897 pw.print(" setRaw="); pw.print(r.setRawAdj); 11898 pw.print(" cur="); pw.print(r.curAdj); 11899 pw.print(" set="); pw.println(r.setAdj); 11900 pw.print(prefix); 11901 pw.print(" "); 11902 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11903 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11904 pw.print(" lastPss="); pw.print(r.lastPss); 11905 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11906 pw.print(prefix); 11907 pw.print(" "); 11908 pw.print("keeping="); pw.print(r.keeping); 11909 pw.print(" cached="); pw.print(r.cached); 11910 pw.print(" empty="); pw.print(r.empty); 11911 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11912 11913 if (!r.keeping) { 11914 if (r.lastWakeTime != 0) { 11915 long wtime; 11916 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11917 synchronized (stats) { 11918 wtime = stats.getProcessWakeTime(r.info.uid, 11919 r.pid, curRealtime); 11920 } 11921 long timeUsed = wtime - r.lastWakeTime; 11922 pw.print(prefix); 11923 pw.print(" "); 11924 pw.print("keep awake over "); 11925 TimeUtils.formatDuration(realtimeSince, pw); 11926 pw.print(" used "); 11927 TimeUtils.formatDuration(timeUsed, pw); 11928 pw.print(" ("); 11929 pw.print((timeUsed*100)/realtimeSince); 11930 pw.println("%)"); 11931 } 11932 if (r.lastCpuTime != 0) { 11933 long timeUsed = r.curCpuTime - r.lastCpuTime; 11934 pw.print(prefix); 11935 pw.print(" "); 11936 pw.print("run cpu over "); 11937 TimeUtils.formatDuration(uptimeSince, pw); 11938 pw.print(" used "); 11939 TimeUtils.formatDuration(timeUsed, pw); 11940 pw.print(" ("); 11941 pw.print((timeUsed*100)/uptimeSince); 11942 pw.println("%)"); 11943 } 11944 } 11945 } 11946 } 11947 return true; 11948 } 11949 11950 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11951 ArrayList<ProcessRecord> procs; 11952 synchronized (this) { 11953 if (args != null && args.length > start 11954 && args[start].charAt(0) != '-') { 11955 procs = new ArrayList<ProcessRecord>(); 11956 int pid = -1; 11957 try { 11958 pid = Integer.parseInt(args[start]); 11959 } catch (NumberFormatException e) { 11960 } 11961 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11962 ProcessRecord proc = mLruProcesses.get(i); 11963 if (proc.pid == pid) { 11964 procs.add(proc); 11965 } else if (proc.processName.equals(args[start])) { 11966 procs.add(proc); 11967 } 11968 } 11969 if (procs.size() <= 0) { 11970 return null; 11971 } 11972 } else { 11973 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11974 } 11975 } 11976 return procs; 11977 } 11978 11979 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11980 PrintWriter pw, String[] args) { 11981 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11982 if (procs == null) { 11983 pw.println("No process found for: " + args[0]); 11984 return; 11985 } 11986 11987 long uptime = SystemClock.uptimeMillis(); 11988 long realtime = SystemClock.elapsedRealtime(); 11989 pw.println("Applications Graphics Acceleration Info:"); 11990 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11991 11992 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11993 ProcessRecord r = procs.get(i); 11994 if (r.thread != null) { 11995 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11996 pw.flush(); 11997 try { 11998 TransferPipe tp = new TransferPipe(); 11999 try { 12000 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 12001 tp.go(fd); 12002 } finally { 12003 tp.kill(); 12004 } 12005 } catch (IOException e) { 12006 pw.println("Failure while dumping the app: " + r); 12007 pw.flush(); 12008 } catch (RemoteException e) { 12009 pw.println("Got a RemoteException while dumping the app " + r); 12010 pw.flush(); 12011 } 12012 } 12013 } 12014 } 12015 12016 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 12017 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 12018 if (procs == null) { 12019 pw.println("No process found for: " + args[0]); 12020 return; 12021 } 12022 12023 pw.println("Applications Database Info:"); 12024 12025 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12026 ProcessRecord r = procs.get(i); 12027 if (r.thread != null) { 12028 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 12029 pw.flush(); 12030 try { 12031 TransferPipe tp = new TransferPipe(); 12032 try { 12033 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 12034 tp.go(fd); 12035 } finally { 12036 tp.kill(); 12037 } 12038 } catch (IOException e) { 12039 pw.println("Failure while dumping the app: " + r); 12040 pw.flush(); 12041 } catch (RemoteException e) { 12042 pw.println("Got a RemoteException while dumping the app " + r); 12043 pw.flush(); 12044 } 12045 } 12046 } 12047 } 12048 12049 final static class MemItem { 12050 final boolean isProc; 12051 final String label; 12052 final String shortLabel; 12053 final long pss; 12054 final int id; 12055 final boolean hasActivities; 12056 ArrayList<MemItem> subitems; 12057 12058 public MemItem(String _label, String _shortLabel, long _pss, int _id, 12059 boolean _hasActivities) { 12060 isProc = true; 12061 label = _label; 12062 shortLabel = _shortLabel; 12063 pss = _pss; 12064 id = _id; 12065 hasActivities = _hasActivities; 12066 } 12067 12068 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 12069 isProc = false; 12070 label = _label; 12071 shortLabel = _shortLabel; 12072 pss = _pss; 12073 id = _id; 12074 hasActivities = false; 12075 } 12076 } 12077 12078 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12079 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12080 if (sort && !isCompact) { 12081 Collections.sort(items, new Comparator<MemItem>() { 12082 @Override 12083 public int compare(MemItem lhs, MemItem rhs) { 12084 if (lhs.pss < rhs.pss) { 12085 return 1; 12086 } else if (lhs.pss > rhs.pss) { 12087 return -1; 12088 } 12089 return 0; 12090 } 12091 }); 12092 } 12093 12094 for (int i=0; i<items.size(); i++) { 12095 MemItem mi = items.get(i); 12096 if (!isCompact) { 12097 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12098 } else if (mi.isProc) { 12099 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12100 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12101 pw.println(mi.hasActivities ? ",a" : ",e"); 12102 } else { 12103 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12104 pw.println(mi.pss); 12105 } 12106 if (mi.subitems != null) { 12107 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12108 true, isCompact); 12109 } 12110 } 12111 } 12112 12113 // These are in KB. 12114 static final long[] DUMP_MEM_BUCKETS = new long[] { 12115 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12116 120*1024, 160*1024, 200*1024, 12117 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12118 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12119 }; 12120 12121 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12122 boolean stackLike) { 12123 int start = label.lastIndexOf('.'); 12124 if (start >= 0) start++; 12125 else start = 0; 12126 int end = label.length(); 12127 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12128 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12129 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12130 out.append(bucket); 12131 out.append(stackLike ? "MB." : "MB "); 12132 out.append(label, start, end); 12133 return; 12134 } 12135 } 12136 out.append(memKB/1024); 12137 out.append(stackLike ? "MB." : "MB "); 12138 out.append(label, start, end); 12139 } 12140 12141 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12142 ProcessList.NATIVE_ADJ, 12143 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12144 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12145 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12146 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12147 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12148 }; 12149 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12150 "Native", 12151 "System", "Persistent", "Foreground", 12152 "Visible", "Perceptible", 12153 "Heavy Weight", "Backup", 12154 "A Services", "Home", 12155 "Previous", "B Services", "Cached" 12156 }; 12157 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12158 "native", 12159 "sys", "pers", "fore", 12160 "vis", "percept", 12161 "heavy", "backup", 12162 "servicea", "home", 12163 "prev", "serviceb", "cached" 12164 }; 12165 12166 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12167 long realtime, boolean isCheckinRequest, boolean isCompact) { 12168 if (isCheckinRequest || isCompact) { 12169 // short checkin version 12170 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12171 } else { 12172 pw.println("Applications Memory Usage (kB):"); 12173 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12174 } 12175 } 12176 12177 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12178 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12179 boolean dumpDetails = false; 12180 boolean dumpFullDetails = false; 12181 boolean dumpDalvik = false; 12182 boolean oomOnly = false; 12183 boolean isCompact = false; 12184 boolean localOnly = false; 12185 12186 int opti = 0; 12187 while (opti < args.length) { 12188 String opt = args[opti]; 12189 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12190 break; 12191 } 12192 opti++; 12193 if ("-a".equals(opt)) { 12194 dumpDetails = true; 12195 dumpFullDetails = true; 12196 dumpDalvik = true; 12197 } else if ("-d".equals(opt)) { 12198 dumpDalvik = true; 12199 } else if ("-c".equals(opt)) { 12200 isCompact = true; 12201 } else if ("--oom".equals(opt)) { 12202 oomOnly = true; 12203 } else if ("--local".equals(opt)) { 12204 localOnly = true; 12205 } else if ("-h".equals(opt)) { 12206 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12207 pw.println(" -a: include all available information for each process."); 12208 pw.println(" -d: include dalvik details when dumping process details."); 12209 pw.println(" -c: dump in a compact machine-parseable representation."); 12210 pw.println(" --oom: only show processes organized by oom adj."); 12211 pw.println(" --local: only collect details locally, don't call process."); 12212 pw.println("If [process] is specified it can be the name or "); 12213 pw.println("pid of a specific process to dump."); 12214 return; 12215 } else { 12216 pw.println("Unknown argument: " + opt + "; use -h for help"); 12217 } 12218 } 12219 12220 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12221 long uptime = SystemClock.uptimeMillis(); 12222 long realtime = SystemClock.elapsedRealtime(); 12223 final long[] tmpLong = new long[1]; 12224 12225 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12226 if (procs == null) { 12227 // No Java processes. Maybe they want to print a native process. 12228 if (args != null && args.length > opti 12229 && args[opti].charAt(0) != '-') { 12230 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12231 = new ArrayList<ProcessCpuTracker.Stats>(); 12232 updateCpuStatsNow(); 12233 int findPid = -1; 12234 try { 12235 findPid = Integer.parseInt(args[opti]); 12236 } catch (NumberFormatException e) { 12237 } 12238 synchronized (mProcessCpuThread) { 12239 final int N = mProcessCpuTracker.countStats(); 12240 for (int i=0; i<N; i++) { 12241 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12242 if (st.pid == findPid || (st.baseName != null 12243 && st.baseName.equals(args[opti]))) { 12244 nativeProcs.add(st); 12245 } 12246 } 12247 } 12248 if (nativeProcs.size() > 0) { 12249 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12250 isCompact); 12251 Debug.MemoryInfo mi = null; 12252 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12253 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12254 final int pid = r.pid; 12255 if (!isCheckinRequest && dumpDetails) { 12256 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12257 } 12258 if (mi == null) { 12259 mi = new Debug.MemoryInfo(); 12260 } 12261 if (dumpDetails || (!brief && !oomOnly)) { 12262 Debug.getMemoryInfo(pid, mi); 12263 } else { 12264 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12265 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12266 } 12267 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12268 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12269 if (isCheckinRequest) { 12270 pw.println(); 12271 } 12272 } 12273 return; 12274 } 12275 } 12276 pw.println("No process found for: " + args[opti]); 12277 return; 12278 } 12279 12280 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12281 dumpDetails = true; 12282 } 12283 12284 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12285 12286 String[] innerArgs = new String[args.length-opti]; 12287 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12288 12289 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12290 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12291 long nativePss=0, dalvikPss=0, otherPss=0; 12292 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12293 12294 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12295 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12296 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12297 12298 long totalPss = 0; 12299 long cachedPss = 0; 12300 12301 Debug.MemoryInfo mi = null; 12302 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12303 final ProcessRecord r = procs.get(i); 12304 final IApplicationThread thread; 12305 final int pid; 12306 final int oomAdj; 12307 final boolean hasActivities; 12308 synchronized (this) { 12309 thread = r.thread; 12310 pid = r.pid; 12311 oomAdj = r.getSetAdjWithServices(); 12312 hasActivities = r.activities.size() > 0; 12313 } 12314 if (thread != null) { 12315 if (!isCheckinRequest && dumpDetails) { 12316 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12317 } 12318 if (mi == null) { 12319 mi = new Debug.MemoryInfo(); 12320 } 12321 if (dumpDetails || (!brief && !oomOnly)) { 12322 Debug.getMemoryInfo(pid, mi); 12323 } else { 12324 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12325 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12326 } 12327 if (dumpDetails) { 12328 if (localOnly) { 12329 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12330 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12331 if (isCheckinRequest) { 12332 pw.println(); 12333 } 12334 } else { 12335 try { 12336 pw.flush(); 12337 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12338 dumpDalvik, innerArgs); 12339 } catch (RemoteException e) { 12340 if (!isCheckinRequest) { 12341 pw.println("Got RemoteException!"); 12342 pw.flush(); 12343 } 12344 } 12345 } 12346 } 12347 12348 final long myTotalPss = mi.getTotalPss(); 12349 final long myTotalUss = mi.getTotalUss(); 12350 12351 synchronized (this) { 12352 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12353 // Record this for posterity if the process has been stable. 12354 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12355 } 12356 } 12357 12358 if (!isCheckinRequest && mi != null) { 12359 totalPss += myTotalPss; 12360 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12361 (hasActivities ? " / activities)" : ")"), 12362 r.processName, myTotalPss, pid, hasActivities); 12363 procMems.add(pssItem); 12364 procMemsMap.put(pid, pssItem); 12365 12366 nativePss += mi.nativePss; 12367 dalvikPss += mi.dalvikPss; 12368 otherPss += mi.otherPss; 12369 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12370 long mem = mi.getOtherPss(j); 12371 miscPss[j] += mem; 12372 otherPss -= mem; 12373 } 12374 12375 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12376 cachedPss += myTotalPss; 12377 } 12378 12379 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12380 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12381 || oomIndex == (oomPss.length-1)) { 12382 oomPss[oomIndex] += myTotalPss; 12383 if (oomProcs[oomIndex] == null) { 12384 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12385 } 12386 oomProcs[oomIndex].add(pssItem); 12387 break; 12388 } 12389 } 12390 } 12391 } 12392 } 12393 12394 if (!isCheckinRequest && procs.size() > 1) { 12395 // If we are showing aggregations, also look for native processes to 12396 // include so that our aggregations are more accurate. 12397 updateCpuStatsNow(); 12398 synchronized (mProcessCpuThread) { 12399 final int N = mProcessCpuTracker.countStats(); 12400 for (int i=0; i<N; i++) { 12401 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12402 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12403 if (mi == null) { 12404 mi = new Debug.MemoryInfo(); 12405 } 12406 if (!brief && !oomOnly) { 12407 Debug.getMemoryInfo(st.pid, mi); 12408 } else { 12409 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12410 mi.nativePrivateDirty = (int)tmpLong[0]; 12411 } 12412 12413 final long myTotalPss = mi.getTotalPss(); 12414 totalPss += myTotalPss; 12415 12416 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12417 st.name, myTotalPss, st.pid, false); 12418 procMems.add(pssItem); 12419 12420 nativePss += mi.nativePss; 12421 dalvikPss += mi.dalvikPss; 12422 otherPss += mi.otherPss; 12423 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12424 long mem = mi.getOtherPss(j); 12425 miscPss[j] += mem; 12426 otherPss -= mem; 12427 } 12428 oomPss[0] += myTotalPss; 12429 if (oomProcs[0] == null) { 12430 oomProcs[0] = new ArrayList<MemItem>(); 12431 } 12432 oomProcs[0].add(pssItem); 12433 } 12434 } 12435 } 12436 12437 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12438 12439 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12440 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12441 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12442 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12443 String label = Debug.MemoryInfo.getOtherLabel(j); 12444 catMems.add(new MemItem(label, label, miscPss[j], j)); 12445 } 12446 12447 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12448 for (int j=0; j<oomPss.length; j++) { 12449 if (oomPss[j] != 0) { 12450 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12451 : DUMP_MEM_OOM_LABEL[j]; 12452 MemItem item = new MemItem(label, label, oomPss[j], 12453 DUMP_MEM_OOM_ADJ[j]); 12454 item.subitems = oomProcs[j]; 12455 oomMems.add(item); 12456 } 12457 } 12458 12459 if (!brief && !oomOnly && !isCompact) { 12460 pw.println(); 12461 pw.println("Total PSS by process:"); 12462 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12463 pw.println(); 12464 } 12465 if (!isCompact) { 12466 pw.println("Total PSS by OOM adjustment:"); 12467 } 12468 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12469 if (!brief && !oomOnly) { 12470 PrintWriter out = categoryPw != null ? categoryPw : pw; 12471 if (!isCompact) { 12472 out.println(); 12473 out.println("Total PSS by category:"); 12474 } 12475 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12476 } 12477 if (!isCompact) { 12478 pw.println(); 12479 } 12480 MemInfoReader memInfo = new MemInfoReader(); 12481 memInfo.readMemInfo(); 12482 if (!brief) { 12483 if (!isCompact) { 12484 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12485 pw.print(" kB (status "); 12486 switch (mLastMemoryLevel) { 12487 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12488 pw.println("normal)"); 12489 break; 12490 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12491 pw.println("moderate)"); 12492 break; 12493 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12494 pw.println("low)"); 12495 break; 12496 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12497 pw.println("critical)"); 12498 break; 12499 default: 12500 pw.print(mLastMemoryLevel); 12501 pw.println(")"); 12502 break; 12503 } 12504 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12505 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12506 pw.print(cachedPss); pw.print(" cached pss + "); 12507 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12508 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12509 } else { 12510 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12511 pw.print(cachedPss + memInfo.getCachedSizeKb() 12512 + memInfo.getFreeSizeKb()); pw.print(","); 12513 pw.println(totalPss - cachedPss); 12514 } 12515 } 12516 if (!isCompact) { 12517 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12518 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12519 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12520 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12521 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12522 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12523 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12524 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12525 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12526 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12527 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12528 } 12529 if (!brief) { 12530 if (memInfo.getZramTotalSizeKb() != 0) { 12531 if (!isCompact) { 12532 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12533 pw.print(" kB physical used for "); 12534 pw.print(memInfo.getSwapTotalSizeKb() 12535 - memInfo.getSwapFreeSizeKb()); 12536 pw.print(" kB in swap ("); 12537 pw.print(memInfo.getSwapTotalSizeKb()); 12538 pw.println(" kB total swap)"); 12539 } else { 12540 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12541 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12542 pw.println(memInfo.getSwapFreeSizeKb()); 12543 } 12544 } 12545 final int[] SINGLE_LONG_FORMAT = new int[] { 12546 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12547 }; 12548 long[] longOut = new long[1]; 12549 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12550 SINGLE_LONG_FORMAT, null, longOut, null); 12551 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12552 longOut[0] = 0; 12553 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12554 SINGLE_LONG_FORMAT, null, longOut, null); 12555 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12556 longOut[0] = 0; 12557 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12558 SINGLE_LONG_FORMAT, null, longOut, null); 12559 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12560 longOut[0] = 0; 12561 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12562 SINGLE_LONG_FORMAT, null, longOut, null); 12563 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12564 if (!isCompact) { 12565 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12566 pw.print(" KSM: "); pw.print(sharing); 12567 pw.print(" kB saved from shared "); 12568 pw.print(shared); pw.println(" kB"); 12569 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12570 pw.print(voltile); pw.println(" kB volatile"); 12571 } 12572 pw.print(" Tuning: "); 12573 pw.print(ActivityManager.staticGetMemoryClass()); 12574 pw.print(" (large "); 12575 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12576 pw.print("), oom "); 12577 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12578 pw.print(" kB"); 12579 pw.print(", restore limit "); 12580 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12581 pw.print(" kB"); 12582 if (ActivityManager.isLowRamDeviceStatic()) { 12583 pw.print(" (low-ram)"); 12584 } 12585 if (ActivityManager.isHighEndGfx()) { 12586 pw.print(" (high-end-gfx)"); 12587 } 12588 pw.println(); 12589 } else { 12590 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12591 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12592 pw.println(voltile); 12593 pw.print("tuning,"); 12594 pw.print(ActivityManager.staticGetMemoryClass()); 12595 pw.print(','); 12596 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12597 pw.print(','); 12598 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12599 if (ActivityManager.isLowRamDeviceStatic()) { 12600 pw.print(",low-ram"); 12601 } 12602 if (ActivityManager.isHighEndGfx()) { 12603 pw.print(",high-end-gfx"); 12604 } 12605 pw.println(); 12606 } 12607 } 12608 } 12609 } 12610 12611 /** 12612 * Searches array of arguments for the specified string 12613 * @param args array of argument strings 12614 * @param value value to search for 12615 * @return true if the value is contained in the array 12616 */ 12617 private static boolean scanArgs(String[] args, String value) { 12618 if (args != null) { 12619 for (String arg : args) { 12620 if (value.equals(arg)) { 12621 return true; 12622 } 12623 } 12624 } 12625 return false; 12626 } 12627 12628 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12629 ContentProviderRecord cpr, boolean always) { 12630 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12631 12632 if (!inLaunching || always) { 12633 synchronized (cpr) { 12634 cpr.launchingApp = null; 12635 cpr.notifyAll(); 12636 } 12637 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12638 String names[] = cpr.info.authority.split(";"); 12639 for (int j = 0; j < names.length; j++) { 12640 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12641 } 12642 } 12643 12644 for (int i=0; i<cpr.connections.size(); i++) { 12645 ContentProviderConnection conn = cpr.connections.get(i); 12646 if (conn.waiting) { 12647 // If this connection is waiting for the provider, then we don't 12648 // need to mess with its process unless we are always removing 12649 // or for some reason the provider is not currently launching. 12650 if (inLaunching && !always) { 12651 continue; 12652 } 12653 } 12654 ProcessRecord capp = conn.client; 12655 conn.dead = true; 12656 if (conn.stableCount > 0) { 12657 if (!capp.persistent && capp.thread != null 12658 && capp.pid != 0 12659 && capp.pid != MY_PID) { 12660 killUnneededProcessLocked(capp, "depends on provider " 12661 + cpr.name.flattenToShortString() 12662 + " in dying proc " + (proc != null ? proc.processName : "??")); 12663 } 12664 } else if (capp.thread != null && conn.provider.provider != null) { 12665 try { 12666 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12667 } catch (RemoteException e) { 12668 } 12669 // In the protocol here, we don't expect the client to correctly 12670 // clean up this connection, we'll just remove it. 12671 cpr.connections.remove(i); 12672 conn.client.conProviders.remove(conn); 12673 } 12674 } 12675 12676 if (inLaunching && always) { 12677 mLaunchingProviders.remove(cpr); 12678 } 12679 return inLaunching; 12680 } 12681 12682 /** 12683 * Main code for cleaning up a process when it has gone away. This is 12684 * called both as a result of the process dying, or directly when stopping 12685 * a process when running in single process mode. 12686 */ 12687 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12688 boolean restarting, boolean allowRestart, int index) { 12689 if (index >= 0) { 12690 removeLruProcessLocked(app); 12691 ProcessList.remove(app.pid); 12692 } 12693 12694 mProcessesToGc.remove(app); 12695 mPendingPssProcesses.remove(app); 12696 12697 // Dismiss any open dialogs. 12698 if (app.crashDialog != null && !app.forceCrashReport) { 12699 app.crashDialog.dismiss(); 12700 app.crashDialog = null; 12701 } 12702 if (app.anrDialog != null) { 12703 app.anrDialog.dismiss(); 12704 app.anrDialog = null; 12705 } 12706 if (app.waitDialog != null) { 12707 app.waitDialog.dismiss(); 12708 app.waitDialog = null; 12709 } 12710 12711 app.crashing = false; 12712 app.notResponding = false; 12713 12714 app.resetPackageList(mProcessStats); 12715 app.unlinkDeathRecipient(); 12716 app.makeInactive(mProcessStats); 12717 app.forcingToForeground = null; 12718 updateProcessForegroundLocked(app, false, false); 12719 app.foregroundActivities = false; 12720 app.hasShownUi = false; 12721 app.treatLikeActivity = false; 12722 app.hasAboveClient = false; 12723 app.hasClientActivities = false; 12724 12725 mServices.killServicesLocked(app, allowRestart); 12726 12727 boolean restart = false; 12728 12729 // Remove published content providers. 12730 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12731 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12732 final boolean always = app.bad || !allowRestart; 12733 if (removeDyingProviderLocked(app, cpr, always) || always) { 12734 // We left the provider in the launching list, need to 12735 // restart it. 12736 restart = true; 12737 } 12738 12739 cpr.provider = null; 12740 cpr.proc = null; 12741 } 12742 app.pubProviders.clear(); 12743 12744 // Take care of any launching providers waiting for this process. 12745 if (checkAppInLaunchingProvidersLocked(app, false)) { 12746 restart = true; 12747 } 12748 12749 // Unregister from connected content providers. 12750 if (!app.conProviders.isEmpty()) { 12751 for (int i=0; i<app.conProviders.size(); i++) { 12752 ContentProviderConnection conn = app.conProviders.get(i); 12753 conn.provider.connections.remove(conn); 12754 } 12755 app.conProviders.clear(); 12756 } 12757 12758 // At this point there may be remaining entries in mLaunchingProviders 12759 // where we were the only one waiting, so they are no longer of use. 12760 // Look for these and clean up if found. 12761 // XXX Commented out for now. Trying to figure out a way to reproduce 12762 // the actual situation to identify what is actually going on. 12763 if (false) { 12764 for (int i=0; i<mLaunchingProviders.size(); i++) { 12765 ContentProviderRecord cpr = (ContentProviderRecord) 12766 mLaunchingProviders.get(i); 12767 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12768 synchronized (cpr) { 12769 cpr.launchingApp = null; 12770 cpr.notifyAll(); 12771 } 12772 } 12773 } 12774 } 12775 12776 skipCurrentReceiverLocked(app); 12777 12778 // Unregister any receivers. 12779 for (int i=app.receivers.size()-1; i>=0; i--) { 12780 removeReceiverLocked(app.receivers.valueAt(i)); 12781 } 12782 app.receivers.clear(); 12783 12784 // If the app is undergoing backup, tell the backup manager about it 12785 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12786 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12787 + mBackupTarget.appInfo + " died during backup"); 12788 try { 12789 IBackupManager bm = IBackupManager.Stub.asInterface( 12790 ServiceManager.getService(Context.BACKUP_SERVICE)); 12791 bm.agentDisconnected(app.info.packageName); 12792 } catch (RemoteException e) { 12793 // can't happen; backup manager is local 12794 } 12795 } 12796 12797 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12798 ProcessChangeItem item = mPendingProcessChanges.get(i); 12799 if (item.pid == app.pid) { 12800 mPendingProcessChanges.remove(i); 12801 mAvailProcessChanges.add(item); 12802 } 12803 } 12804 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12805 12806 // If the caller is restarting this app, then leave it in its 12807 // current lists and let the caller take care of it. 12808 if (restarting) { 12809 return; 12810 } 12811 12812 if (!app.persistent || app.isolated) { 12813 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12814 "Removing non-persistent process during cleanup: " + app); 12815 mProcessNames.remove(app.processName, app.uid); 12816 mIsolatedProcesses.remove(app.uid); 12817 if (mHeavyWeightProcess == app) { 12818 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12819 mHeavyWeightProcess.userId, 0)); 12820 mHeavyWeightProcess = null; 12821 } 12822 } else if (!app.removed) { 12823 // This app is persistent, so we need to keep its record around. 12824 // If it is not already on the pending app list, add it there 12825 // and start a new process for it. 12826 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12827 mPersistentStartingProcesses.add(app); 12828 restart = true; 12829 } 12830 } 12831 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12832 "Clean-up removing on hold: " + app); 12833 mProcessesOnHold.remove(app); 12834 12835 if (app == mHomeProcess) { 12836 mHomeProcess = null; 12837 } 12838 if (app == mPreviousProcess) { 12839 mPreviousProcess = null; 12840 } 12841 12842 if (restart && !app.isolated) { 12843 // We have components that still need to be running in the 12844 // process, so re-launch it. 12845 mProcessNames.put(app.processName, app.uid, app); 12846 startProcessLocked(app, "restart", app.processName); 12847 } else if (app.pid > 0 && app.pid != MY_PID) { 12848 // Goodbye! 12849 boolean removed; 12850 synchronized (mPidsSelfLocked) { 12851 mPidsSelfLocked.remove(app.pid); 12852 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12853 } 12854 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12855 app.processName, app.info.uid); 12856 if (app.isolated) { 12857 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12858 } 12859 app.setPid(0); 12860 } 12861 } 12862 12863 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12864 // Look through the content providers we are waiting to have launched, 12865 // and if any run in this process then either schedule a restart of 12866 // the process or kill the client waiting for it if this process has 12867 // gone bad. 12868 int NL = mLaunchingProviders.size(); 12869 boolean restart = false; 12870 for (int i=0; i<NL; i++) { 12871 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12872 if (cpr.launchingApp == app) { 12873 if (!alwaysBad && !app.bad) { 12874 restart = true; 12875 } else { 12876 removeDyingProviderLocked(app, cpr, true); 12877 // cpr should have been removed from mLaunchingProviders 12878 NL = mLaunchingProviders.size(); 12879 i--; 12880 } 12881 } 12882 } 12883 return restart; 12884 } 12885 12886 // ========================================================= 12887 // SERVICES 12888 // ========================================================= 12889 12890 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12891 int flags) { 12892 enforceNotIsolatedCaller("getServices"); 12893 synchronized (this) { 12894 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12895 } 12896 } 12897 12898 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12899 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12900 synchronized (this) { 12901 return mServices.getRunningServiceControlPanelLocked(name); 12902 } 12903 } 12904 12905 public ComponentName startService(IApplicationThread caller, Intent service, 12906 String resolvedType, int userId) { 12907 enforceNotIsolatedCaller("startService"); 12908 // Refuse possible leaked file descriptors 12909 if (service != null && service.hasFileDescriptors() == true) { 12910 throw new IllegalArgumentException("File descriptors passed in Intent"); 12911 } 12912 12913 if (DEBUG_SERVICE) 12914 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12915 synchronized(this) { 12916 final int callingPid = Binder.getCallingPid(); 12917 final int callingUid = Binder.getCallingUid(); 12918 final long origId = Binder.clearCallingIdentity(); 12919 ComponentName res = mServices.startServiceLocked(caller, service, 12920 resolvedType, callingPid, callingUid, userId); 12921 Binder.restoreCallingIdentity(origId); 12922 return res; 12923 } 12924 } 12925 12926 ComponentName startServiceInPackage(int uid, 12927 Intent service, String resolvedType, int userId) { 12928 synchronized(this) { 12929 if (DEBUG_SERVICE) 12930 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12931 final long origId = Binder.clearCallingIdentity(); 12932 ComponentName res = mServices.startServiceLocked(null, service, 12933 resolvedType, -1, uid, userId); 12934 Binder.restoreCallingIdentity(origId); 12935 return res; 12936 } 12937 } 12938 12939 public int stopService(IApplicationThread caller, Intent service, 12940 String resolvedType, int userId) { 12941 enforceNotIsolatedCaller("stopService"); 12942 // Refuse possible leaked file descriptors 12943 if (service != null && service.hasFileDescriptors() == true) { 12944 throw new IllegalArgumentException("File descriptors passed in Intent"); 12945 } 12946 12947 synchronized(this) { 12948 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12949 } 12950 } 12951 12952 public IBinder peekService(Intent service, String resolvedType) { 12953 enforceNotIsolatedCaller("peekService"); 12954 // Refuse possible leaked file descriptors 12955 if (service != null && service.hasFileDescriptors() == true) { 12956 throw new IllegalArgumentException("File descriptors passed in Intent"); 12957 } 12958 synchronized(this) { 12959 return mServices.peekServiceLocked(service, resolvedType); 12960 } 12961 } 12962 12963 public boolean stopServiceToken(ComponentName className, IBinder token, 12964 int startId) { 12965 synchronized(this) { 12966 return mServices.stopServiceTokenLocked(className, token, startId); 12967 } 12968 } 12969 12970 public void setServiceForeground(ComponentName className, IBinder token, 12971 int id, Notification notification, boolean removeNotification) { 12972 synchronized(this) { 12973 mServices.setServiceForegroundLocked(className, token, id, notification, 12974 removeNotification); 12975 } 12976 } 12977 12978 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12979 boolean requireFull, String name, String callerPackage) { 12980 final int callingUserId = UserHandle.getUserId(callingUid); 12981 if (callingUserId != userId) { 12982 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12983 if ((requireFull || checkComponentPermission( 12984 android.Manifest.permission.INTERACT_ACROSS_USERS, 12985 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12986 && checkComponentPermission( 12987 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12988 callingPid, callingUid, -1, true) 12989 != PackageManager.PERMISSION_GRANTED) { 12990 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12991 // In this case, they would like to just execute as their 12992 // owner user instead of failing. 12993 userId = callingUserId; 12994 } else { 12995 StringBuilder builder = new StringBuilder(128); 12996 builder.append("Permission Denial: "); 12997 builder.append(name); 12998 if (callerPackage != null) { 12999 builder.append(" from "); 13000 builder.append(callerPackage); 13001 } 13002 builder.append(" asks to run as user "); 13003 builder.append(userId); 13004 builder.append(" but is calling from user "); 13005 builder.append(UserHandle.getUserId(callingUid)); 13006 builder.append("; this requires "); 13007 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 13008 if (!requireFull) { 13009 builder.append(" or "); 13010 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 13011 } 13012 String msg = builder.toString(); 13013 Slog.w(TAG, msg); 13014 throw new SecurityException(msg); 13015 } 13016 } 13017 } 13018 if (userId == UserHandle.USER_CURRENT 13019 || userId == UserHandle.USER_CURRENT_OR_SELF) { 13020 // Note that we may be accessing this outside of a lock... 13021 // shouldn't be a big deal, if this is being called outside 13022 // of a locked context there is intrinsically a race with 13023 // the value the caller will receive and someone else changing it. 13024 userId = mCurrentUserId; 13025 } 13026 if (!allowAll && userId < 0) { 13027 throw new IllegalArgumentException( 13028 "Call does not support special user #" + userId); 13029 } 13030 } 13031 return userId; 13032 } 13033 13034 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 13035 String className, int flags) { 13036 boolean result = false; 13037 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 13038 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 13039 if (ActivityManager.checkUidPermission( 13040 android.Manifest.permission.INTERACT_ACROSS_USERS, 13041 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 13042 ComponentName comp = new ComponentName(aInfo.packageName, className); 13043 String msg = "Permission Denial: Component " + comp.flattenToShortString() 13044 + " requests FLAG_SINGLE_USER, but app does not hold " 13045 + android.Manifest.permission.INTERACT_ACROSS_USERS; 13046 Slog.w(TAG, msg); 13047 throw new SecurityException(msg); 13048 } 13049 result = true; 13050 } 13051 } else if (componentProcessName == aInfo.packageName) { 13052 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 13053 } else if ("system".equals(componentProcessName)) { 13054 result = true; 13055 } 13056 if (DEBUG_MU) { 13057 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 13058 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 13059 } 13060 return result; 13061 } 13062 13063 public int bindService(IApplicationThread caller, IBinder token, 13064 Intent service, String resolvedType, 13065 IServiceConnection connection, int flags, int userId) { 13066 enforceNotIsolatedCaller("bindService"); 13067 // Refuse possible leaked file descriptors 13068 if (service != null && service.hasFileDescriptors() == true) { 13069 throw new IllegalArgumentException("File descriptors passed in Intent"); 13070 } 13071 13072 synchronized(this) { 13073 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13074 connection, flags, userId); 13075 } 13076 } 13077 13078 public boolean unbindService(IServiceConnection connection) { 13079 synchronized (this) { 13080 return mServices.unbindServiceLocked(connection); 13081 } 13082 } 13083 13084 public void publishService(IBinder token, Intent intent, IBinder service) { 13085 // Refuse possible leaked file descriptors 13086 if (intent != null && intent.hasFileDescriptors() == true) { 13087 throw new IllegalArgumentException("File descriptors passed in Intent"); 13088 } 13089 13090 synchronized(this) { 13091 if (!(token instanceof ServiceRecord)) { 13092 throw new IllegalArgumentException("Invalid service token"); 13093 } 13094 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13095 } 13096 } 13097 13098 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13099 // Refuse possible leaked file descriptors 13100 if (intent != null && intent.hasFileDescriptors() == true) { 13101 throw new IllegalArgumentException("File descriptors passed in Intent"); 13102 } 13103 13104 synchronized(this) { 13105 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13106 } 13107 } 13108 13109 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13110 synchronized(this) { 13111 if (!(token instanceof ServiceRecord)) { 13112 throw new IllegalArgumentException("Invalid service token"); 13113 } 13114 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13115 } 13116 } 13117 13118 // ========================================================= 13119 // BACKUP AND RESTORE 13120 // ========================================================= 13121 13122 // Cause the target app to be launched if necessary and its backup agent 13123 // instantiated. The backup agent will invoke backupAgentCreated() on the 13124 // activity manager to announce its creation. 13125 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13126 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13127 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13128 13129 synchronized(this) { 13130 // !!! TODO: currently no check here that we're already bound 13131 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13132 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13133 synchronized (stats) { 13134 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13135 } 13136 13137 // Backup agent is now in use, its package can't be stopped. 13138 try { 13139 AppGlobals.getPackageManager().setPackageStoppedState( 13140 app.packageName, false, UserHandle.getUserId(app.uid)); 13141 } catch (RemoteException e) { 13142 } catch (IllegalArgumentException e) { 13143 Slog.w(TAG, "Failed trying to unstop package " 13144 + app.packageName + ": " + e); 13145 } 13146 13147 BackupRecord r = new BackupRecord(ss, app, backupMode); 13148 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13149 ? new ComponentName(app.packageName, app.backupAgentName) 13150 : new ComponentName("android", "FullBackupAgent"); 13151 // startProcessLocked() returns existing proc's record if it's already running 13152 ProcessRecord proc = startProcessLocked(app.processName, app, 13153 false, 0, "backup", hostingName, false, false, false); 13154 if (proc == null) { 13155 Slog.e(TAG, "Unable to start backup agent process " + r); 13156 return false; 13157 } 13158 13159 r.app = proc; 13160 mBackupTarget = r; 13161 mBackupAppName = app.packageName; 13162 13163 // Try not to kill the process during backup 13164 updateOomAdjLocked(proc); 13165 13166 // If the process is already attached, schedule the creation of the backup agent now. 13167 // If it is not yet live, this will be done when it attaches to the framework. 13168 if (proc.thread != null) { 13169 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13170 try { 13171 proc.thread.scheduleCreateBackupAgent(app, 13172 compatibilityInfoForPackageLocked(app), backupMode); 13173 } catch (RemoteException e) { 13174 // Will time out on the backup manager side 13175 } 13176 } else { 13177 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13178 } 13179 // Invariants: at this point, the target app process exists and the application 13180 // is either already running or in the process of coming up. mBackupTarget and 13181 // mBackupAppName describe the app, so that when it binds back to the AM we 13182 // know that it's scheduled for a backup-agent operation. 13183 } 13184 13185 return true; 13186 } 13187 13188 @Override 13189 public void clearPendingBackup() { 13190 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13191 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13192 13193 synchronized (this) { 13194 mBackupTarget = null; 13195 mBackupAppName = null; 13196 } 13197 } 13198 13199 // A backup agent has just come up 13200 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13201 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13202 + " = " + agent); 13203 13204 synchronized(this) { 13205 if (!agentPackageName.equals(mBackupAppName)) { 13206 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13207 return; 13208 } 13209 } 13210 13211 long oldIdent = Binder.clearCallingIdentity(); 13212 try { 13213 IBackupManager bm = IBackupManager.Stub.asInterface( 13214 ServiceManager.getService(Context.BACKUP_SERVICE)); 13215 bm.agentConnected(agentPackageName, agent); 13216 } catch (RemoteException e) { 13217 // can't happen; the backup manager service is local 13218 } catch (Exception e) { 13219 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13220 e.printStackTrace(); 13221 } finally { 13222 Binder.restoreCallingIdentity(oldIdent); 13223 } 13224 } 13225 13226 // done with this agent 13227 public void unbindBackupAgent(ApplicationInfo appInfo) { 13228 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13229 if (appInfo == null) { 13230 Slog.w(TAG, "unbind backup agent for null app"); 13231 return; 13232 } 13233 13234 synchronized(this) { 13235 try { 13236 if (mBackupAppName == null) { 13237 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13238 return; 13239 } 13240 13241 if (!mBackupAppName.equals(appInfo.packageName)) { 13242 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13243 return; 13244 } 13245 13246 // Not backing this app up any more; reset its OOM adjustment 13247 final ProcessRecord proc = mBackupTarget.app; 13248 updateOomAdjLocked(proc); 13249 13250 // If the app crashed during backup, 'thread' will be null here 13251 if (proc.thread != null) { 13252 try { 13253 proc.thread.scheduleDestroyBackupAgent(appInfo, 13254 compatibilityInfoForPackageLocked(appInfo)); 13255 } catch (Exception e) { 13256 Slog.e(TAG, "Exception when unbinding backup agent:"); 13257 e.printStackTrace(); 13258 } 13259 } 13260 } finally { 13261 mBackupTarget = null; 13262 mBackupAppName = null; 13263 } 13264 } 13265 } 13266 // ========================================================= 13267 // BROADCASTS 13268 // ========================================================= 13269 13270 private final List getStickiesLocked(String action, IntentFilter filter, 13271 List cur, int userId) { 13272 final ContentResolver resolver = mContext.getContentResolver(); 13273 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13274 if (stickies == null) { 13275 return cur; 13276 } 13277 final ArrayList<Intent> list = stickies.get(action); 13278 if (list == null) { 13279 return cur; 13280 } 13281 int N = list.size(); 13282 for (int i=0; i<N; i++) { 13283 Intent intent = list.get(i); 13284 if (filter.match(resolver, intent, true, TAG) >= 0) { 13285 if (cur == null) { 13286 cur = new ArrayList<Intent>(); 13287 } 13288 cur.add(intent); 13289 } 13290 } 13291 return cur; 13292 } 13293 13294 boolean isPendingBroadcastProcessLocked(int pid) { 13295 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13296 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13297 } 13298 13299 void skipPendingBroadcastLocked(int pid) { 13300 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13301 for (BroadcastQueue queue : mBroadcastQueues) { 13302 queue.skipPendingBroadcastLocked(pid); 13303 } 13304 } 13305 13306 // The app just attached; send any pending broadcasts that it should receive 13307 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13308 boolean didSomething = false; 13309 for (BroadcastQueue queue : mBroadcastQueues) { 13310 didSomething |= queue.sendPendingBroadcastsLocked(app); 13311 } 13312 return didSomething; 13313 } 13314 13315 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13316 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13317 enforceNotIsolatedCaller("registerReceiver"); 13318 int callingUid; 13319 int callingPid; 13320 synchronized(this) { 13321 ProcessRecord callerApp = null; 13322 if (caller != null) { 13323 callerApp = getRecordForAppLocked(caller); 13324 if (callerApp == null) { 13325 throw new SecurityException( 13326 "Unable to find app for caller " + caller 13327 + " (pid=" + Binder.getCallingPid() 13328 + ") when registering receiver " + receiver); 13329 } 13330 if (callerApp.info.uid != Process.SYSTEM_UID && 13331 !callerApp.pkgList.containsKey(callerPackage) && 13332 !"android".equals(callerPackage)) { 13333 throw new SecurityException("Given caller package " + callerPackage 13334 + " is not running in process " + callerApp); 13335 } 13336 callingUid = callerApp.info.uid; 13337 callingPid = callerApp.pid; 13338 } else { 13339 callerPackage = null; 13340 callingUid = Binder.getCallingUid(); 13341 callingPid = Binder.getCallingPid(); 13342 } 13343 13344 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13345 true, true, "registerReceiver", callerPackage); 13346 13347 List allSticky = null; 13348 13349 // Look for any matching sticky broadcasts... 13350 Iterator actions = filter.actionsIterator(); 13351 if (actions != null) { 13352 while (actions.hasNext()) { 13353 String action = (String)actions.next(); 13354 allSticky = getStickiesLocked(action, filter, allSticky, 13355 UserHandle.USER_ALL); 13356 allSticky = getStickiesLocked(action, filter, allSticky, 13357 UserHandle.getUserId(callingUid)); 13358 } 13359 } else { 13360 allSticky = getStickiesLocked(null, filter, allSticky, 13361 UserHandle.USER_ALL); 13362 allSticky = getStickiesLocked(null, filter, allSticky, 13363 UserHandle.getUserId(callingUid)); 13364 } 13365 13366 // The first sticky in the list is returned directly back to 13367 // the client. 13368 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13369 13370 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13371 + ": " + sticky); 13372 13373 if (receiver == null) { 13374 return sticky; 13375 } 13376 13377 ReceiverList rl 13378 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13379 if (rl == null) { 13380 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13381 userId, receiver); 13382 if (rl.app != null) { 13383 rl.app.receivers.add(rl); 13384 } else { 13385 try { 13386 receiver.asBinder().linkToDeath(rl, 0); 13387 } catch (RemoteException e) { 13388 return sticky; 13389 } 13390 rl.linkedToDeath = true; 13391 } 13392 mRegisteredReceivers.put(receiver.asBinder(), rl); 13393 } else if (rl.uid != callingUid) { 13394 throw new IllegalArgumentException( 13395 "Receiver requested to register for uid " + callingUid 13396 + " was previously registered for uid " + rl.uid); 13397 } else if (rl.pid != callingPid) { 13398 throw new IllegalArgumentException( 13399 "Receiver requested to register for pid " + callingPid 13400 + " was previously registered for pid " + rl.pid); 13401 } else if (rl.userId != userId) { 13402 throw new IllegalArgumentException( 13403 "Receiver requested to register for user " + userId 13404 + " was previously registered for user " + rl.userId); 13405 } 13406 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13407 permission, callingUid, userId); 13408 rl.add(bf); 13409 if (!bf.debugCheck()) { 13410 Slog.w(TAG, "==> For Dynamic broadast"); 13411 } 13412 mReceiverResolver.addFilter(bf); 13413 13414 // Enqueue broadcasts for all existing stickies that match 13415 // this filter. 13416 if (allSticky != null) { 13417 ArrayList receivers = new ArrayList(); 13418 receivers.add(bf); 13419 13420 int N = allSticky.size(); 13421 for (int i=0; i<N; i++) { 13422 Intent intent = (Intent)allSticky.get(i); 13423 BroadcastQueue queue = broadcastQueueForIntent(intent); 13424 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13425 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13426 null, null, false, true, true, -1); 13427 queue.enqueueParallelBroadcastLocked(r); 13428 queue.scheduleBroadcastsLocked(); 13429 } 13430 } 13431 13432 return sticky; 13433 } 13434 } 13435 13436 public void unregisterReceiver(IIntentReceiver receiver) { 13437 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13438 13439 final long origId = Binder.clearCallingIdentity(); 13440 try { 13441 boolean doTrim = false; 13442 13443 synchronized(this) { 13444 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13445 if (rl != null) { 13446 if (rl.curBroadcast != null) { 13447 BroadcastRecord r = rl.curBroadcast; 13448 final boolean doNext = finishReceiverLocked( 13449 receiver.asBinder(), r.resultCode, r.resultData, 13450 r.resultExtras, r.resultAbort); 13451 if (doNext) { 13452 doTrim = true; 13453 r.queue.processNextBroadcast(false); 13454 } 13455 } 13456 13457 if (rl.app != null) { 13458 rl.app.receivers.remove(rl); 13459 } 13460 removeReceiverLocked(rl); 13461 if (rl.linkedToDeath) { 13462 rl.linkedToDeath = false; 13463 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13464 } 13465 } 13466 } 13467 13468 // If we actually concluded any broadcasts, we might now be able 13469 // to trim the recipients' apps from our working set 13470 if (doTrim) { 13471 trimApplications(); 13472 return; 13473 } 13474 13475 } finally { 13476 Binder.restoreCallingIdentity(origId); 13477 } 13478 } 13479 13480 void removeReceiverLocked(ReceiverList rl) { 13481 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13482 int N = rl.size(); 13483 for (int i=0; i<N; i++) { 13484 mReceiverResolver.removeFilter(rl.get(i)); 13485 } 13486 } 13487 13488 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13489 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13490 ProcessRecord r = mLruProcesses.get(i); 13491 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13492 try { 13493 r.thread.dispatchPackageBroadcast(cmd, packages); 13494 } catch (RemoteException ex) { 13495 } 13496 } 13497 } 13498 } 13499 13500 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13501 int[] users) { 13502 List<ResolveInfo> receivers = null; 13503 try { 13504 HashSet<ComponentName> singleUserReceivers = null; 13505 boolean scannedFirstReceivers = false; 13506 for (int user : users) { 13507 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13508 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13509 if (user != 0 && newReceivers != null) { 13510 // If this is not the primary user, we need to check for 13511 // any receivers that should be filtered out. 13512 for (int i=0; i<newReceivers.size(); i++) { 13513 ResolveInfo ri = newReceivers.get(i); 13514 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13515 newReceivers.remove(i); 13516 i--; 13517 } 13518 } 13519 } 13520 if (newReceivers != null && newReceivers.size() == 0) { 13521 newReceivers = null; 13522 } 13523 if (receivers == null) { 13524 receivers = newReceivers; 13525 } else if (newReceivers != null) { 13526 // We need to concatenate the additional receivers 13527 // found with what we have do far. This would be easy, 13528 // but we also need to de-dup any receivers that are 13529 // singleUser. 13530 if (!scannedFirstReceivers) { 13531 // Collect any single user receivers we had already retrieved. 13532 scannedFirstReceivers = true; 13533 for (int i=0; i<receivers.size(); i++) { 13534 ResolveInfo ri = receivers.get(i); 13535 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13536 ComponentName cn = new ComponentName( 13537 ri.activityInfo.packageName, ri.activityInfo.name); 13538 if (singleUserReceivers == null) { 13539 singleUserReceivers = new HashSet<ComponentName>(); 13540 } 13541 singleUserReceivers.add(cn); 13542 } 13543 } 13544 } 13545 // Add the new results to the existing results, tracking 13546 // and de-dupping single user receivers. 13547 for (int i=0; i<newReceivers.size(); i++) { 13548 ResolveInfo ri = newReceivers.get(i); 13549 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13550 ComponentName cn = new ComponentName( 13551 ri.activityInfo.packageName, ri.activityInfo.name); 13552 if (singleUserReceivers == null) { 13553 singleUserReceivers = new HashSet<ComponentName>(); 13554 } 13555 if (!singleUserReceivers.contains(cn)) { 13556 singleUserReceivers.add(cn); 13557 receivers.add(ri); 13558 } 13559 } else { 13560 receivers.add(ri); 13561 } 13562 } 13563 } 13564 } 13565 } catch (RemoteException ex) { 13566 // pm is in same process, this will never happen. 13567 } 13568 return receivers; 13569 } 13570 13571 private final int broadcastIntentLocked(ProcessRecord callerApp, 13572 String callerPackage, Intent intent, String resolvedType, 13573 IIntentReceiver resultTo, int resultCode, String resultData, 13574 Bundle map, String requiredPermission, int appOp, 13575 boolean ordered, boolean sticky, int callingPid, int callingUid, 13576 int userId) { 13577 intent = new Intent(intent); 13578 13579 // By default broadcasts do not go to stopped apps. 13580 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13581 13582 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13583 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13584 + " ordered=" + ordered + " userid=" + userId); 13585 if ((resultTo != null) && !ordered) { 13586 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13587 } 13588 13589 userId = handleIncomingUser(callingPid, callingUid, userId, 13590 true, false, "broadcast", callerPackage); 13591 13592 // Make sure that the user who is receiving this broadcast is started. 13593 // If not, we will just skip it. 13594 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13595 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13596 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13597 Slog.w(TAG, "Skipping broadcast of " + intent 13598 + ": user " + userId + " is stopped"); 13599 return ActivityManager.BROADCAST_SUCCESS; 13600 } 13601 } 13602 13603 /* 13604 * Prevent non-system code (defined here to be non-persistent 13605 * processes) from sending protected broadcasts. 13606 */ 13607 int callingAppId = UserHandle.getAppId(callingUid); 13608 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13609 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13610 callingUid == 0) { 13611 // Always okay. 13612 } else if (callerApp == null || !callerApp.persistent) { 13613 try { 13614 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13615 intent.getAction())) { 13616 String msg = "Permission Denial: not allowed to send broadcast " 13617 + intent.getAction() + " from pid=" 13618 + callingPid + ", uid=" + callingUid; 13619 Slog.w(TAG, msg); 13620 throw new SecurityException(msg); 13621 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13622 // Special case for compatibility: we don't want apps to send this, 13623 // but historically it has not been protected and apps may be using it 13624 // to poke their own app widget. So, instead of making it protected, 13625 // just limit it to the caller. 13626 if (callerApp == null) { 13627 String msg = "Permission Denial: not allowed to send broadcast " 13628 + intent.getAction() + " from unknown caller."; 13629 Slog.w(TAG, msg); 13630 throw new SecurityException(msg); 13631 } else if (intent.getComponent() != null) { 13632 // They are good enough to send to an explicit component... verify 13633 // it is being sent to the calling app. 13634 if (!intent.getComponent().getPackageName().equals( 13635 callerApp.info.packageName)) { 13636 String msg = "Permission Denial: not allowed to send broadcast " 13637 + intent.getAction() + " to " 13638 + intent.getComponent().getPackageName() + " from " 13639 + callerApp.info.packageName; 13640 Slog.w(TAG, msg); 13641 throw new SecurityException(msg); 13642 } 13643 } else { 13644 // Limit broadcast to their own package. 13645 intent.setPackage(callerApp.info.packageName); 13646 } 13647 } 13648 } catch (RemoteException e) { 13649 Slog.w(TAG, "Remote exception", e); 13650 return ActivityManager.BROADCAST_SUCCESS; 13651 } 13652 } 13653 13654 // Handle special intents: if this broadcast is from the package 13655 // manager about a package being removed, we need to remove all of 13656 // its activities from the history stack. 13657 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13658 intent.getAction()); 13659 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13660 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13661 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13662 || uidRemoved) { 13663 if (checkComponentPermission( 13664 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13665 callingPid, callingUid, -1, true) 13666 == PackageManager.PERMISSION_GRANTED) { 13667 if (uidRemoved) { 13668 final Bundle intentExtras = intent.getExtras(); 13669 final int uid = intentExtras != null 13670 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13671 if (uid >= 0) { 13672 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13673 synchronized (bs) { 13674 bs.removeUidStatsLocked(uid); 13675 } 13676 mAppOpsService.uidRemoved(uid); 13677 } 13678 } else { 13679 // If resources are unavailable just force stop all 13680 // those packages and flush the attribute cache as well. 13681 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13682 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13683 if (list != null && (list.length > 0)) { 13684 for (String pkg : list) { 13685 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13686 "storage unmount"); 13687 } 13688 sendPackageBroadcastLocked( 13689 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13690 } 13691 } else { 13692 Uri data = intent.getData(); 13693 String ssp; 13694 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13695 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13696 intent.getAction()); 13697 boolean fullUninstall = removed && 13698 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13699 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13700 forceStopPackageLocked(ssp, UserHandle.getAppId( 13701 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13702 false, fullUninstall, userId, 13703 removed ? "pkg removed" : "pkg changed"); 13704 } 13705 if (removed) { 13706 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13707 new String[] {ssp}, userId); 13708 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13709 mAppOpsService.packageRemoved( 13710 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13711 13712 // Remove all permissions granted from/to this package 13713 removeUriPermissionsForPackageLocked(ssp, userId, true); 13714 } 13715 } 13716 } 13717 } 13718 } 13719 } else { 13720 String msg = "Permission Denial: " + intent.getAction() 13721 + " broadcast from " + callerPackage + " (pid=" + callingPid 13722 + ", uid=" + callingUid + ")" 13723 + " requires " 13724 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13725 Slog.w(TAG, msg); 13726 throw new SecurityException(msg); 13727 } 13728 13729 // Special case for adding a package: by default turn on compatibility 13730 // mode. 13731 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13732 Uri data = intent.getData(); 13733 String ssp; 13734 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13735 mCompatModePackages.handlePackageAddedLocked(ssp, 13736 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13737 } 13738 } 13739 13740 /* 13741 * If this is the time zone changed action, queue up a message that will reset the timezone 13742 * of all currently running processes. This message will get queued up before the broadcast 13743 * happens. 13744 */ 13745 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13746 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13747 } 13748 13749 /* 13750 * If the user set the time, let all running processes know. 13751 */ 13752 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13753 final int is24Hour = intent.getBooleanExtra( 13754 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13755 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13756 } 13757 13758 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13759 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13760 } 13761 13762 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13763 ProxyInfo proxy = intent.getParcelableExtra("proxy"); 13764 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13765 } 13766 13767 // Add to the sticky list if requested. 13768 if (sticky) { 13769 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13770 callingPid, callingUid) 13771 != PackageManager.PERMISSION_GRANTED) { 13772 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13773 + callingPid + ", uid=" + callingUid 13774 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13775 Slog.w(TAG, msg); 13776 throw new SecurityException(msg); 13777 } 13778 if (requiredPermission != null) { 13779 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13780 + " and enforce permission " + requiredPermission); 13781 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13782 } 13783 if (intent.getComponent() != null) { 13784 throw new SecurityException( 13785 "Sticky broadcasts can't target a specific component"); 13786 } 13787 // We use userId directly here, since the "all" target is maintained 13788 // as a separate set of sticky broadcasts. 13789 if (userId != UserHandle.USER_ALL) { 13790 // But first, if this is not a broadcast to all users, then 13791 // make sure it doesn't conflict with an existing broadcast to 13792 // all users. 13793 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13794 UserHandle.USER_ALL); 13795 if (stickies != null) { 13796 ArrayList<Intent> list = stickies.get(intent.getAction()); 13797 if (list != null) { 13798 int N = list.size(); 13799 int i; 13800 for (i=0; i<N; i++) { 13801 if (intent.filterEquals(list.get(i))) { 13802 throw new IllegalArgumentException( 13803 "Sticky broadcast " + intent + " for user " 13804 + userId + " conflicts with existing global broadcast"); 13805 } 13806 } 13807 } 13808 } 13809 } 13810 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13811 if (stickies == null) { 13812 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13813 mStickyBroadcasts.put(userId, stickies); 13814 } 13815 ArrayList<Intent> list = stickies.get(intent.getAction()); 13816 if (list == null) { 13817 list = new ArrayList<Intent>(); 13818 stickies.put(intent.getAction(), list); 13819 } 13820 int N = list.size(); 13821 int i; 13822 for (i=0; i<N; i++) { 13823 if (intent.filterEquals(list.get(i))) { 13824 // This sticky already exists, replace it. 13825 list.set(i, new Intent(intent)); 13826 break; 13827 } 13828 } 13829 if (i >= N) { 13830 list.add(new Intent(intent)); 13831 } 13832 } 13833 13834 int[] users; 13835 if (userId == UserHandle.USER_ALL) { 13836 // Caller wants broadcast to go to all started users. 13837 users = mStartedUserArray; 13838 } else { 13839 // Caller wants broadcast to go to one specific user. 13840 users = new int[] {userId}; 13841 } 13842 13843 // Figure out who all will receive this broadcast. 13844 List receivers = null; 13845 List<BroadcastFilter> registeredReceivers = null; 13846 // Need to resolve the intent to interested receivers... 13847 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13848 == 0) { 13849 receivers = collectReceiverComponents(intent, resolvedType, users); 13850 } 13851 if (intent.getComponent() == null) { 13852 registeredReceivers = mReceiverResolver.queryIntent(intent, 13853 resolvedType, false, userId); 13854 } 13855 13856 final boolean replacePending = 13857 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13858 13859 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13860 + " replacePending=" + replacePending); 13861 13862 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13863 if (!ordered && NR > 0) { 13864 // If we are not serializing this broadcast, then send the 13865 // registered receivers separately so they don't wait for the 13866 // components to be launched. 13867 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13868 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13869 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13870 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13871 ordered, sticky, false, userId); 13872 if (DEBUG_BROADCAST) Slog.v( 13873 TAG, "Enqueueing parallel broadcast " + r); 13874 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13875 if (!replaced) { 13876 queue.enqueueParallelBroadcastLocked(r); 13877 queue.scheduleBroadcastsLocked(); 13878 } 13879 registeredReceivers = null; 13880 NR = 0; 13881 } 13882 13883 // Merge into one list. 13884 int ir = 0; 13885 if (receivers != null) { 13886 // A special case for PACKAGE_ADDED: do not allow the package 13887 // being added to see this broadcast. This prevents them from 13888 // using this as a back door to get run as soon as they are 13889 // installed. Maybe in the future we want to have a special install 13890 // broadcast or such for apps, but we'd like to deliberately make 13891 // this decision. 13892 String skipPackages[] = null; 13893 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13894 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13895 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13896 Uri data = intent.getData(); 13897 if (data != null) { 13898 String pkgName = data.getSchemeSpecificPart(); 13899 if (pkgName != null) { 13900 skipPackages = new String[] { pkgName }; 13901 } 13902 } 13903 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13904 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13905 } 13906 if (skipPackages != null && (skipPackages.length > 0)) { 13907 for (String skipPackage : skipPackages) { 13908 if (skipPackage != null) { 13909 int NT = receivers.size(); 13910 for (int it=0; it<NT; it++) { 13911 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13912 if (curt.activityInfo.packageName.equals(skipPackage)) { 13913 receivers.remove(it); 13914 it--; 13915 NT--; 13916 } 13917 } 13918 } 13919 } 13920 } 13921 13922 int NT = receivers != null ? receivers.size() : 0; 13923 int it = 0; 13924 ResolveInfo curt = null; 13925 BroadcastFilter curr = null; 13926 while (it < NT && ir < NR) { 13927 if (curt == null) { 13928 curt = (ResolveInfo)receivers.get(it); 13929 } 13930 if (curr == null) { 13931 curr = registeredReceivers.get(ir); 13932 } 13933 if (curr.getPriority() >= curt.priority) { 13934 // Insert this broadcast record into the final list. 13935 receivers.add(it, curr); 13936 ir++; 13937 curr = null; 13938 it++; 13939 NT++; 13940 } else { 13941 // Skip to the next ResolveInfo in the final list. 13942 it++; 13943 curt = null; 13944 } 13945 } 13946 } 13947 while (ir < NR) { 13948 if (receivers == null) { 13949 receivers = new ArrayList(); 13950 } 13951 receivers.add(registeredReceivers.get(ir)); 13952 ir++; 13953 } 13954 13955 if ((receivers != null && receivers.size() > 0) 13956 || resultTo != null) { 13957 BroadcastQueue queue = broadcastQueueForIntent(intent); 13958 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13959 callerPackage, callingPid, callingUid, resolvedType, 13960 requiredPermission, appOp, receivers, resultTo, resultCode, 13961 resultData, map, ordered, sticky, false, userId); 13962 if (DEBUG_BROADCAST) Slog.v( 13963 TAG, "Enqueueing ordered broadcast " + r 13964 + ": prev had " + queue.mOrderedBroadcasts.size()); 13965 if (DEBUG_BROADCAST) { 13966 int seq = r.intent.getIntExtra("seq", -1); 13967 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13968 } 13969 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13970 if (!replaced) { 13971 queue.enqueueOrderedBroadcastLocked(r); 13972 queue.scheduleBroadcastsLocked(); 13973 } 13974 } 13975 13976 return ActivityManager.BROADCAST_SUCCESS; 13977 } 13978 13979 final Intent verifyBroadcastLocked(Intent intent) { 13980 // Refuse possible leaked file descriptors 13981 if (intent != null && intent.hasFileDescriptors() == true) { 13982 throw new IllegalArgumentException("File descriptors passed in Intent"); 13983 } 13984 13985 int flags = intent.getFlags(); 13986 13987 if (!mProcessesReady) { 13988 // if the caller really truly claims to know what they're doing, go 13989 // ahead and allow the broadcast without launching any receivers 13990 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13991 intent = new Intent(intent); 13992 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13993 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13994 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13995 + " before boot completion"); 13996 throw new IllegalStateException("Cannot broadcast before boot completed"); 13997 } 13998 } 13999 14000 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 14001 throw new IllegalArgumentException( 14002 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 14003 } 14004 14005 return intent; 14006 } 14007 14008 public final int broadcastIntent(IApplicationThread caller, 14009 Intent intent, String resolvedType, IIntentReceiver resultTo, 14010 int resultCode, String resultData, Bundle map, 14011 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 14012 enforceNotIsolatedCaller("broadcastIntent"); 14013 synchronized(this) { 14014 intent = verifyBroadcastLocked(intent); 14015 14016 final ProcessRecord callerApp = getRecordForAppLocked(caller); 14017 final int callingPid = Binder.getCallingPid(); 14018 final int callingUid = Binder.getCallingUid(); 14019 final long origId = Binder.clearCallingIdentity(); 14020 int res = broadcastIntentLocked(callerApp, 14021 callerApp != null ? callerApp.info.packageName : null, 14022 intent, resolvedType, resultTo, 14023 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 14024 callingPid, callingUid, userId); 14025 Binder.restoreCallingIdentity(origId); 14026 return res; 14027 } 14028 } 14029 14030 int broadcastIntentInPackage(String packageName, int uid, 14031 Intent intent, String resolvedType, IIntentReceiver resultTo, 14032 int resultCode, String resultData, Bundle map, 14033 String requiredPermission, boolean serialized, boolean sticky, int userId) { 14034 synchronized(this) { 14035 intent = verifyBroadcastLocked(intent); 14036 14037 final long origId = Binder.clearCallingIdentity(); 14038 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 14039 resultTo, resultCode, resultData, map, requiredPermission, 14040 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 14041 Binder.restoreCallingIdentity(origId); 14042 return res; 14043 } 14044 } 14045 14046 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 14047 // Refuse possible leaked file descriptors 14048 if (intent != null && intent.hasFileDescriptors() == true) { 14049 throw new IllegalArgumentException("File descriptors passed in Intent"); 14050 } 14051 14052 userId = handleIncomingUser(Binder.getCallingPid(), 14053 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 14054 14055 synchronized(this) { 14056 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 14057 != PackageManager.PERMISSION_GRANTED) { 14058 String msg = "Permission Denial: unbroadcastIntent() from pid=" 14059 + Binder.getCallingPid() 14060 + ", uid=" + Binder.getCallingUid() 14061 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 14062 Slog.w(TAG, msg); 14063 throw new SecurityException(msg); 14064 } 14065 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 14066 if (stickies != null) { 14067 ArrayList<Intent> list = stickies.get(intent.getAction()); 14068 if (list != null) { 14069 int N = list.size(); 14070 int i; 14071 for (i=0; i<N; i++) { 14072 if (intent.filterEquals(list.get(i))) { 14073 list.remove(i); 14074 break; 14075 } 14076 } 14077 if (list.size() <= 0) { 14078 stickies.remove(intent.getAction()); 14079 } 14080 } 14081 if (stickies.size() <= 0) { 14082 mStickyBroadcasts.remove(userId); 14083 } 14084 } 14085 } 14086 } 14087 14088 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14089 String resultData, Bundle resultExtras, boolean resultAbort) { 14090 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14091 if (r == null) { 14092 Slog.w(TAG, "finishReceiver called but not found on queue"); 14093 return false; 14094 } 14095 14096 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14097 } 14098 14099 void backgroundServicesFinishedLocked(int userId) { 14100 for (BroadcastQueue queue : mBroadcastQueues) { 14101 queue.backgroundServicesFinishedLocked(userId); 14102 } 14103 } 14104 14105 public void finishReceiver(IBinder who, int resultCode, String resultData, 14106 Bundle resultExtras, boolean resultAbort) { 14107 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14108 14109 // Refuse possible leaked file descriptors 14110 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14111 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14112 } 14113 14114 final long origId = Binder.clearCallingIdentity(); 14115 try { 14116 boolean doNext = false; 14117 BroadcastRecord r; 14118 14119 synchronized(this) { 14120 r = broadcastRecordForReceiverLocked(who); 14121 if (r != null) { 14122 doNext = r.queue.finishReceiverLocked(r, resultCode, 14123 resultData, resultExtras, resultAbort, true); 14124 } 14125 } 14126 14127 if (doNext) { 14128 r.queue.processNextBroadcast(false); 14129 } 14130 trimApplications(); 14131 } finally { 14132 Binder.restoreCallingIdentity(origId); 14133 } 14134 } 14135 14136 // ========================================================= 14137 // INSTRUMENTATION 14138 // ========================================================= 14139 14140 public boolean startInstrumentation(ComponentName className, 14141 String profileFile, int flags, Bundle arguments, 14142 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14143 int userId) { 14144 enforceNotIsolatedCaller("startInstrumentation"); 14145 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14146 userId, false, true, "startInstrumentation", null); 14147 // Refuse possible leaked file descriptors 14148 if (arguments != null && arguments.hasFileDescriptors()) { 14149 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14150 } 14151 14152 synchronized(this) { 14153 InstrumentationInfo ii = null; 14154 ApplicationInfo ai = null; 14155 try { 14156 ii = mContext.getPackageManager().getInstrumentationInfo( 14157 className, STOCK_PM_FLAGS); 14158 ai = AppGlobals.getPackageManager().getApplicationInfo( 14159 ii.targetPackage, STOCK_PM_FLAGS, userId); 14160 } catch (PackageManager.NameNotFoundException e) { 14161 } catch (RemoteException e) { 14162 } 14163 if (ii == null) { 14164 reportStartInstrumentationFailure(watcher, className, 14165 "Unable to find instrumentation info for: " + className); 14166 return false; 14167 } 14168 if (ai == null) { 14169 reportStartInstrumentationFailure(watcher, className, 14170 "Unable to find instrumentation target package: " + ii.targetPackage); 14171 return false; 14172 } 14173 14174 int match = mContext.getPackageManager().checkSignatures( 14175 ii.targetPackage, ii.packageName); 14176 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14177 String msg = "Permission Denial: starting instrumentation " 14178 + className + " from pid=" 14179 + Binder.getCallingPid() 14180 + ", uid=" + Binder.getCallingPid() 14181 + " not allowed because package " + ii.packageName 14182 + " does not have a signature matching the target " 14183 + ii.targetPackage; 14184 reportStartInstrumentationFailure(watcher, className, msg); 14185 throw new SecurityException(msg); 14186 } 14187 14188 final long origId = Binder.clearCallingIdentity(); 14189 // Instrumentation can kill and relaunch even persistent processes 14190 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14191 "start instr"); 14192 ProcessRecord app = addAppLocked(ai, false); 14193 app.instrumentationClass = className; 14194 app.instrumentationInfo = ai; 14195 app.instrumentationProfileFile = profileFile; 14196 app.instrumentationArguments = arguments; 14197 app.instrumentationWatcher = watcher; 14198 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14199 app.instrumentationResultClass = className; 14200 Binder.restoreCallingIdentity(origId); 14201 } 14202 14203 return true; 14204 } 14205 14206 /** 14207 * Report errors that occur while attempting to start Instrumentation. Always writes the 14208 * error to the logs, but if somebody is watching, send the report there too. This enables 14209 * the "am" command to report errors with more information. 14210 * 14211 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14212 * @param cn The component name of the instrumentation. 14213 * @param report The error report. 14214 */ 14215 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14216 ComponentName cn, String report) { 14217 Slog.w(TAG, report); 14218 try { 14219 if (watcher != null) { 14220 Bundle results = new Bundle(); 14221 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14222 results.putString("Error", report); 14223 watcher.instrumentationStatus(cn, -1, results); 14224 } 14225 } catch (RemoteException e) { 14226 Slog.w(TAG, e); 14227 } 14228 } 14229 14230 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14231 if (app.instrumentationWatcher != null) { 14232 try { 14233 // NOTE: IInstrumentationWatcher *must* be oneway here 14234 app.instrumentationWatcher.instrumentationFinished( 14235 app.instrumentationClass, 14236 resultCode, 14237 results); 14238 } catch (RemoteException e) { 14239 } 14240 } 14241 if (app.instrumentationUiAutomationConnection != null) { 14242 try { 14243 app.instrumentationUiAutomationConnection.shutdown(); 14244 } catch (RemoteException re) { 14245 /* ignore */ 14246 } 14247 // Only a UiAutomation can set this flag and now that 14248 // it is finished we make sure it is reset to its default. 14249 mUserIsMonkey = false; 14250 } 14251 app.instrumentationWatcher = null; 14252 app.instrumentationUiAutomationConnection = null; 14253 app.instrumentationClass = null; 14254 app.instrumentationInfo = null; 14255 app.instrumentationProfileFile = null; 14256 app.instrumentationArguments = null; 14257 14258 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14259 "finished inst"); 14260 } 14261 14262 public void finishInstrumentation(IApplicationThread target, 14263 int resultCode, Bundle results) { 14264 int userId = UserHandle.getCallingUserId(); 14265 // Refuse possible leaked file descriptors 14266 if (results != null && results.hasFileDescriptors()) { 14267 throw new IllegalArgumentException("File descriptors passed in Intent"); 14268 } 14269 14270 synchronized(this) { 14271 ProcessRecord app = getRecordForAppLocked(target); 14272 if (app == null) { 14273 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14274 return; 14275 } 14276 final long origId = Binder.clearCallingIdentity(); 14277 finishInstrumentationLocked(app, resultCode, results); 14278 Binder.restoreCallingIdentity(origId); 14279 } 14280 } 14281 14282 // ========================================================= 14283 // CONFIGURATION 14284 // ========================================================= 14285 14286 public ConfigurationInfo getDeviceConfigurationInfo() { 14287 ConfigurationInfo config = new ConfigurationInfo(); 14288 synchronized (this) { 14289 config.reqTouchScreen = mConfiguration.touchscreen; 14290 config.reqKeyboardType = mConfiguration.keyboard; 14291 config.reqNavigation = mConfiguration.navigation; 14292 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14293 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14294 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14295 } 14296 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14297 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14298 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14299 } 14300 config.reqGlEsVersion = GL_ES_VERSION; 14301 } 14302 return config; 14303 } 14304 14305 ActivityStack getFocusedStack() { 14306 return mStackSupervisor.getFocusedStack(); 14307 } 14308 14309 public Configuration getConfiguration() { 14310 Configuration ci; 14311 synchronized(this) { 14312 ci = new Configuration(mConfiguration); 14313 } 14314 return ci; 14315 } 14316 14317 public void updatePersistentConfiguration(Configuration values) { 14318 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14319 "updateConfiguration()"); 14320 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14321 "updateConfiguration()"); 14322 if (values == null) { 14323 throw new NullPointerException("Configuration must not be null"); 14324 } 14325 14326 synchronized(this) { 14327 final long origId = Binder.clearCallingIdentity(); 14328 updateConfigurationLocked(values, null, true, false); 14329 Binder.restoreCallingIdentity(origId); 14330 } 14331 } 14332 14333 public void updateConfiguration(Configuration values) { 14334 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14335 "updateConfiguration()"); 14336 14337 synchronized(this) { 14338 if (values == null && mWindowManager != null) { 14339 // sentinel: fetch the current configuration from the window manager 14340 values = mWindowManager.computeNewConfiguration(); 14341 } 14342 14343 if (mWindowManager != null) { 14344 mProcessList.applyDisplaySize(mWindowManager); 14345 } 14346 14347 final long origId = Binder.clearCallingIdentity(); 14348 if (values != null) { 14349 Settings.System.clearConfiguration(values); 14350 } 14351 updateConfigurationLocked(values, null, false, false); 14352 Binder.restoreCallingIdentity(origId); 14353 } 14354 } 14355 14356 /** 14357 * Do either or both things: (1) change the current configuration, and (2) 14358 * make sure the given activity is running with the (now) current 14359 * configuration. Returns true if the activity has been left running, or 14360 * false if <var>starting</var> is being destroyed to match the new 14361 * configuration. 14362 * @param persistent TODO 14363 */ 14364 boolean updateConfigurationLocked(Configuration values, 14365 ActivityRecord starting, boolean persistent, boolean initLocale) { 14366 int changes = 0; 14367 14368 if (values != null) { 14369 Configuration newConfig = new Configuration(mConfiguration); 14370 changes = newConfig.updateFrom(values); 14371 if (changes != 0) { 14372 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14373 Slog.i(TAG, "Updating configuration to: " + values); 14374 } 14375 14376 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14377 14378 if (values.locale != null && !initLocale) { 14379 saveLocaleLocked(values.locale, 14380 !values.locale.equals(mConfiguration.locale), 14381 values.userSetLocale); 14382 } 14383 14384 mConfigurationSeq++; 14385 if (mConfigurationSeq <= 0) { 14386 mConfigurationSeq = 1; 14387 } 14388 newConfig.seq = mConfigurationSeq; 14389 mConfiguration = newConfig; 14390 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14391 14392 final Configuration configCopy = new Configuration(mConfiguration); 14393 14394 // TODO: If our config changes, should we auto dismiss any currently 14395 // showing dialogs? 14396 mShowDialogs = shouldShowDialogs(newConfig); 14397 14398 AttributeCache ac = AttributeCache.instance(); 14399 if (ac != null) { 14400 ac.updateConfiguration(configCopy); 14401 } 14402 14403 // Make sure all resources in our process are updated 14404 // right now, so that anyone who is going to retrieve 14405 // resource values after we return will be sure to get 14406 // the new ones. This is especially important during 14407 // boot, where the first config change needs to guarantee 14408 // all resources have that config before following boot 14409 // code is executed. 14410 mSystemThread.applyConfigurationToResources(configCopy); 14411 14412 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14413 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14414 msg.obj = new Configuration(configCopy); 14415 mHandler.sendMessage(msg); 14416 } 14417 14418 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14419 ProcessRecord app = mLruProcesses.get(i); 14420 try { 14421 if (app.thread != null) { 14422 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14423 + app.processName + " new config " + mConfiguration); 14424 app.thread.scheduleConfigurationChanged(configCopy); 14425 } 14426 } catch (Exception e) { 14427 } 14428 } 14429 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14430 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14431 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14432 | Intent.FLAG_RECEIVER_FOREGROUND); 14433 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14434 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14435 Process.SYSTEM_UID, UserHandle.USER_ALL); 14436 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14437 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14438 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14439 broadcastIntentLocked(null, null, intent, 14440 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14441 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14442 } 14443 } 14444 } 14445 14446 boolean kept = true; 14447 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14448 // mainStack is null during startup. 14449 if (mainStack != null) { 14450 if (changes != 0 && starting == null) { 14451 // If the configuration changed, and the caller is not already 14452 // in the process of starting an activity, then find the top 14453 // activity to check if its configuration needs to change. 14454 starting = mainStack.topRunningActivityLocked(null); 14455 } 14456 14457 if (starting != null) { 14458 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14459 // And we need to make sure at this point that all other activities 14460 // are made visible with the correct configuration. 14461 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14462 } 14463 } 14464 14465 if (values != null && mWindowManager != null) { 14466 mWindowManager.setNewConfiguration(mConfiguration); 14467 } 14468 14469 return kept; 14470 } 14471 14472 /** 14473 * Decide based on the configuration whether we should shouw the ANR, 14474 * crash, etc dialogs. The idea is that if there is no affordnace to 14475 * press the on-screen buttons, we shouldn't show the dialog. 14476 * 14477 * A thought: SystemUI might also want to get told about this, the Power 14478 * dialog / global actions also might want different behaviors. 14479 */ 14480 private static final boolean shouldShowDialogs(Configuration config) { 14481 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14482 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14483 } 14484 14485 /** 14486 * Save the locale. You must be inside a synchronized (this) block. 14487 */ 14488 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14489 if(isDiff) { 14490 SystemProperties.set("user.language", l.getLanguage()); 14491 SystemProperties.set("user.region", l.getCountry()); 14492 } 14493 14494 if(isPersist) { 14495 SystemProperties.set("persist.sys.language", l.getLanguage()); 14496 SystemProperties.set("persist.sys.country", l.getCountry()); 14497 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14498 } 14499 } 14500 14501 @Override 14502 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14503 ActivityRecord srec = ActivityRecord.forToken(token); 14504 return srec != null && srec.task.affinity != null && 14505 srec.task.affinity.equals(destAffinity); 14506 } 14507 14508 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14509 Intent resultData) { 14510 14511 synchronized (this) { 14512 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14513 if (stack != null) { 14514 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14515 } 14516 return false; 14517 } 14518 } 14519 14520 public int getLaunchedFromUid(IBinder activityToken) { 14521 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14522 if (srec == null) { 14523 return -1; 14524 } 14525 return srec.launchedFromUid; 14526 } 14527 14528 public String getLaunchedFromPackage(IBinder activityToken) { 14529 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14530 if (srec == null) { 14531 return null; 14532 } 14533 return srec.launchedFromPackage; 14534 } 14535 14536 // ========================================================= 14537 // LIFETIME MANAGEMENT 14538 // ========================================================= 14539 14540 // Returns which broadcast queue the app is the current [or imminent] receiver 14541 // on, or 'null' if the app is not an active broadcast recipient. 14542 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14543 BroadcastRecord r = app.curReceiver; 14544 if (r != null) { 14545 return r.queue; 14546 } 14547 14548 // It's not the current receiver, but it might be starting up to become one 14549 synchronized (this) { 14550 for (BroadcastQueue queue : mBroadcastQueues) { 14551 r = queue.mPendingBroadcast; 14552 if (r != null && r.curApp == app) { 14553 // found it; report which queue it's in 14554 return queue; 14555 } 14556 } 14557 } 14558 14559 return null; 14560 } 14561 14562 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14563 boolean doingAll, long now) { 14564 if (mAdjSeq == app.adjSeq) { 14565 // This adjustment has already been computed. 14566 return app.curRawAdj; 14567 } 14568 14569 if (app.thread == null) { 14570 app.adjSeq = mAdjSeq; 14571 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14572 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14573 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14574 } 14575 14576 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14577 app.adjSource = null; 14578 app.adjTarget = null; 14579 app.empty = false; 14580 app.cached = false; 14581 14582 final int activitiesSize = app.activities.size(); 14583 14584 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14585 // The max adjustment doesn't allow this app to be anything 14586 // below foreground, so it is not worth doing work for it. 14587 app.adjType = "fixed"; 14588 app.adjSeq = mAdjSeq; 14589 app.curRawAdj = app.maxAdj; 14590 app.foregroundActivities = false; 14591 app.keeping = true; 14592 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14593 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14594 // System processes can do UI, and when they do we want to have 14595 // them trim their memory after the user leaves the UI. To 14596 // facilitate this, here we need to determine whether or not it 14597 // is currently showing UI. 14598 app.systemNoUi = true; 14599 if (app == TOP_APP) { 14600 app.systemNoUi = false; 14601 } else if (activitiesSize > 0) { 14602 for (int j = 0; j < activitiesSize; j++) { 14603 final ActivityRecord r = app.activities.get(j); 14604 if (r.visible) { 14605 app.systemNoUi = false; 14606 } 14607 } 14608 } 14609 if (!app.systemNoUi) { 14610 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14611 } 14612 return (app.curAdj=app.maxAdj); 14613 } 14614 14615 app.keeping = false; 14616 app.systemNoUi = false; 14617 14618 // Determine the importance of the process, starting with most 14619 // important to least, and assign an appropriate OOM adjustment. 14620 int adj; 14621 int schedGroup; 14622 int procState; 14623 boolean foregroundActivities = false; 14624 boolean interesting = false; 14625 BroadcastQueue queue; 14626 if (app == TOP_APP) { 14627 // The last app on the list is the foreground app. 14628 adj = ProcessList.FOREGROUND_APP_ADJ; 14629 schedGroup = Process.THREAD_GROUP_DEFAULT; 14630 app.adjType = "top-activity"; 14631 foregroundActivities = true; 14632 interesting = true; 14633 procState = ActivityManager.PROCESS_STATE_TOP; 14634 } else if (app.instrumentationClass != null) { 14635 // Don't want to kill running instrumentation. 14636 adj = ProcessList.FOREGROUND_APP_ADJ; 14637 schedGroup = Process.THREAD_GROUP_DEFAULT; 14638 app.adjType = "instrumentation"; 14639 interesting = true; 14640 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14641 } else if ((queue = isReceivingBroadcast(app)) != null) { 14642 // An app that is currently receiving a broadcast also 14643 // counts as being in the foreground for OOM killer purposes. 14644 // It's placed in a sched group based on the nature of the 14645 // broadcast as reflected by which queue it's active in. 14646 adj = ProcessList.FOREGROUND_APP_ADJ; 14647 schedGroup = (queue == mFgBroadcastQueue) 14648 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14649 app.adjType = "broadcast"; 14650 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14651 } else if (app.executingServices.size() > 0) { 14652 // An app that is currently executing a service callback also 14653 // counts as being in the foreground. 14654 adj = ProcessList.FOREGROUND_APP_ADJ; 14655 schedGroup = app.execServicesFg ? 14656 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14657 app.adjType = "exec-service"; 14658 procState = ActivityManager.PROCESS_STATE_SERVICE; 14659 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14660 } else { 14661 // As far as we know the process is empty. We may change our mind later. 14662 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14663 // At this point we don't actually know the adjustment. Use the cached adj 14664 // value that the caller wants us to. 14665 adj = cachedAdj; 14666 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14667 app.cached = true; 14668 app.empty = true; 14669 app.adjType = "cch-empty"; 14670 } 14671 14672 // Examine all activities if not already foreground. 14673 if (!foregroundActivities && activitiesSize > 0) { 14674 for (int j = 0; j < activitiesSize; j++) { 14675 final ActivityRecord r = app.activities.get(j); 14676 if (r.app != app) { 14677 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14678 + app + "?!?"); 14679 continue; 14680 } 14681 if (r.visible) { 14682 // App has a visible activity; only upgrade adjustment. 14683 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14684 adj = ProcessList.VISIBLE_APP_ADJ; 14685 app.adjType = "visible"; 14686 } 14687 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14688 procState = ActivityManager.PROCESS_STATE_TOP; 14689 } 14690 schedGroup = Process.THREAD_GROUP_DEFAULT; 14691 app.cached = false; 14692 app.empty = false; 14693 foregroundActivities = true; 14694 break; 14695 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14696 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14697 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14698 app.adjType = "pausing"; 14699 } 14700 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14701 procState = ActivityManager.PROCESS_STATE_TOP; 14702 } 14703 schedGroup = Process.THREAD_GROUP_DEFAULT; 14704 app.cached = false; 14705 app.empty = false; 14706 foregroundActivities = true; 14707 } else if (r.state == ActivityState.STOPPING) { 14708 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14709 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14710 app.adjType = "stopping"; 14711 } 14712 // For the process state, we will at this point consider the 14713 // process to be cached. It will be cached either as an activity 14714 // or empty depending on whether the activity is finishing. We do 14715 // this so that we can treat the process as cached for purposes of 14716 // memory trimming (determing current memory level, trim command to 14717 // send to process) since there can be an arbitrary number of stopping 14718 // processes and they should soon all go into the cached state. 14719 if (!r.finishing) { 14720 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14721 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14722 } 14723 } 14724 app.cached = false; 14725 app.empty = false; 14726 foregroundActivities = true; 14727 } else { 14728 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14729 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14730 app.adjType = "cch-act"; 14731 } 14732 } 14733 } 14734 } 14735 14736 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14737 if (app.foregroundServices) { 14738 // The user is aware of this app, so make it visible. 14739 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14740 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14741 app.cached = false; 14742 app.adjType = "fg-service"; 14743 schedGroup = Process.THREAD_GROUP_DEFAULT; 14744 } else if (app.forcingToForeground != null) { 14745 // The user is aware of this app, so make it visible. 14746 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14747 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14748 app.cached = false; 14749 app.adjType = "force-fg"; 14750 app.adjSource = app.forcingToForeground; 14751 schedGroup = Process.THREAD_GROUP_DEFAULT; 14752 } 14753 } 14754 14755 if (app.foregroundServices) { 14756 interesting = true; 14757 } 14758 14759 if (app == mHeavyWeightProcess) { 14760 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14761 // We don't want to kill the current heavy-weight process. 14762 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14763 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14764 app.cached = false; 14765 app.adjType = "heavy"; 14766 } 14767 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14768 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14769 } 14770 } 14771 14772 if (app == mHomeProcess) { 14773 if (adj > ProcessList.HOME_APP_ADJ) { 14774 // This process is hosting what we currently consider to be the 14775 // home app, so we don't want to let it go into the background. 14776 adj = ProcessList.HOME_APP_ADJ; 14777 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14778 app.cached = false; 14779 app.adjType = "home"; 14780 } 14781 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14782 procState = ActivityManager.PROCESS_STATE_HOME; 14783 } 14784 } 14785 14786 if (app == mPreviousProcess && app.activities.size() > 0) { 14787 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14788 // This was the previous process that showed UI to the user. 14789 // We want to try to keep it around more aggressively, to give 14790 // a good experience around switching between two apps. 14791 adj = ProcessList.PREVIOUS_APP_ADJ; 14792 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14793 app.cached = false; 14794 app.adjType = "previous"; 14795 } 14796 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14797 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14798 } 14799 } 14800 14801 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14802 + " reason=" + app.adjType); 14803 14804 // By default, we use the computed adjustment. It may be changed if 14805 // there are applications dependent on our services or providers, but 14806 // this gives us a baseline and makes sure we don't get into an 14807 // infinite recursion. 14808 app.adjSeq = mAdjSeq; 14809 app.curRawAdj = adj; 14810 app.hasStartedServices = false; 14811 14812 if (mBackupTarget != null && app == mBackupTarget.app) { 14813 // If possible we want to avoid killing apps while they're being backed up 14814 if (adj > ProcessList.BACKUP_APP_ADJ) { 14815 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14816 adj = ProcessList.BACKUP_APP_ADJ; 14817 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14818 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14819 } 14820 app.adjType = "backup"; 14821 app.cached = false; 14822 } 14823 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14824 procState = ActivityManager.PROCESS_STATE_BACKUP; 14825 } 14826 } 14827 14828 boolean mayBeTop = false; 14829 14830 for (int is = app.services.size()-1; 14831 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14832 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14833 || procState > ActivityManager.PROCESS_STATE_TOP); 14834 is--) { 14835 ServiceRecord s = app.services.valueAt(is); 14836 if (s.startRequested) { 14837 app.hasStartedServices = true; 14838 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14839 procState = ActivityManager.PROCESS_STATE_SERVICE; 14840 } 14841 if (app.hasShownUi && app != mHomeProcess) { 14842 // If this process has shown some UI, let it immediately 14843 // go to the LRU list because it may be pretty heavy with 14844 // UI stuff. We'll tag it with a label just to help 14845 // debug and understand what is going on. 14846 if (adj > ProcessList.SERVICE_ADJ) { 14847 app.adjType = "cch-started-ui-services"; 14848 } 14849 } else { 14850 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14851 // This service has seen some activity within 14852 // recent memory, so we will keep its process ahead 14853 // of the background processes. 14854 if (adj > ProcessList.SERVICE_ADJ) { 14855 adj = ProcessList.SERVICE_ADJ; 14856 app.adjType = "started-services"; 14857 app.cached = false; 14858 } 14859 } 14860 // If we have let the service slide into the background 14861 // state, still have some text describing what it is doing 14862 // even though the service no longer has an impact. 14863 if (adj > ProcessList.SERVICE_ADJ) { 14864 app.adjType = "cch-started-services"; 14865 } 14866 } 14867 // Don't kill this process because it is doing work; it 14868 // has said it is doing work. 14869 app.keeping = true; 14870 } 14871 for (int conni = s.connections.size()-1; 14872 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14873 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14874 || procState > ActivityManager.PROCESS_STATE_TOP); 14875 conni--) { 14876 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14877 for (int i = 0; 14878 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14879 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14880 || procState > ActivityManager.PROCESS_STATE_TOP); 14881 i++) { 14882 // XXX should compute this based on the max of 14883 // all connected clients. 14884 ConnectionRecord cr = clist.get(i); 14885 if (cr.binding.client == app) { 14886 // Binding to ourself is not interesting. 14887 continue; 14888 } 14889 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14890 ProcessRecord client = cr.binding.client; 14891 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14892 TOP_APP, doingAll, now); 14893 int clientProcState = client.curProcState; 14894 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14895 // If the other app is cached for any reason, for purposes here 14896 // we are going to consider it empty. The specific cached state 14897 // doesn't propagate except under certain conditions. 14898 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14899 } 14900 String adjType = null; 14901 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14902 // Not doing bind OOM management, so treat 14903 // this guy more like a started service. 14904 if (app.hasShownUi && app != mHomeProcess) { 14905 // If this process has shown some UI, let it immediately 14906 // go to the LRU list because it may be pretty heavy with 14907 // UI stuff. We'll tag it with a label just to help 14908 // debug and understand what is going on. 14909 if (adj > clientAdj) { 14910 adjType = "cch-bound-ui-services"; 14911 } 14912 app.cached = false; 14913 clientAdj = adj; 14914 clientProcState = procState; 14915 } else { 14916 if (now >= (s.lastActivity 14917 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14918 // This service has not seen activity within 14919 // recent memory, so allow it to drop to the 14920 // LRU list if there is no other reason to keep 14921 // it around. We'll also tag it with a label just 14922 // to help debug and undertand what is going on. 14923 if (adj > clientAdj) { 14924 adjType = "cch-bound-services"; 14925 } 14926 clientAdj = adj; 14927 } 14928 } 14929 } 14930 if (adj > clientAdj) { 14931 // If this process has recently shown UI, and 14932 // the process that is binding to it is less 14933 // important than being visible, then we don't 14934 // care about the binding as much as we care 14935 // about letting this process get into the LRU 14936 // list to be killed and restarted if needed for 14937 // memory. 14938 if (app.hasShownUi && app != mHomeProcess 14939 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14940 adjType = "cch-bound-ui-services"; 14941 } else { 14942 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14943 |Context.BIND_IMPORTANT)) != 0) { 14944 adj = clientAdj; 14945 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14946 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14947 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14948 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14949 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14950 adj = clientAdj; 14951 } else { 14952 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14953 adj = ProcessList.VISIBLE_APP_ADJ; 14954 } 14955 } 14956 if (!client.cached) { 14957 app.cached = false; 14958 } 14959 if (client.keeping) { 14960 app.keeping = true; 14961 } 14962 adjType = "service"; 14963 } 14964 } 14965 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14966 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14967 schedGroup = Process.THREAD_GROUP_DEFAULT; 14968 } 14969 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14970 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14971 // Special handling of clients who are in the top state. 14972 // We *may* want to consider this process to be in the 14973 // top state as well, but only if there is not another 14974 // reason for it to be running. Being on the top is a 14975 // special state, meaning you are specifically running 14976 // for the current top app. If the process is already 14977 // running in the background for some other reason, it 14978 // is more important to continue considering it to be 14979 // in the background state. 14980 mayBeTop = true; 14981 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14982 } else { 14983 // Special handling for above-top states (persistent 14984 // processes). These should not bring the current process 14985 // into the top state, since they are not on top. Instead 14986 // give them the best state after that. 14987 clientProcState = 14988 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14989 } 14990 } 14991 } else { 14992 if (clientProcState < 14993 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14994 clientProcState = 14995 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14996 } 14997 } 14998 if (procState > clientProcState) { 14999 procState = clientProcState; 15000 } 15001 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15002 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 15003 app.pendingUiClean = true; 15004 } 15005 if (adjType != null) { 15006 app.adjType = adjType; 15007 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15008 .REASON_SERVICE_IN_USE; 15009 app.adjSource = cr.binding.client; 15010 app.adjSourceOom = clientAdj; 15011 app.adjTarget = s.name; 15012 } 15013 } 15014 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 15015 app.treatLikeActivity = true; 15016 } 15017 final ActivityRecord a = cr.activity; 15018 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 15019 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 15020 (a.visible || a.state == ActivityState.RESUMED 15021 || a.state == ActivityState.PAUSING)) { 15022 adj = ProcessList.FOREGROUND_APP_ADJ; 15023 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 15024 schedGroup = Process.THREAD_GROUP_DEFAULT; 15025 } 15026 app.cached = false; 15027 app.adjType = "service"; 15028 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15029 .REASON_SERVICE_IN_USE; 15030 app.adjSource = a; 15031 app.adjSourceOom = adj; 15032 app.adjTarget = s.name; 15033 } 15034 } 15035 } 15036 } 15037 } 15038 15039 for (int provi = app.pubProviders.size()-1; 15040 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15041 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15042 || procState > ActivityManager.PROCESS_STATE_TOP); 15043 provi--) { 15044 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 15045 for (int i = cpr.connections.size()-1; 15046 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 15047 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 15048 || procState > ActivityManager.PROCESS_STATE_TOP); 15049 i--) { 15050 ContentProviderConnection conn = cpr.connections.get(i); 15051 ProcessRecord client = conn.client; 15052 if (client == app) { 15053 // Being our own client is not interesting. 15054 continue; 15055 } 15056 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 15057 int clientProcState = client.curProcState; 15058 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 15059 // If the other app is cached for any reason, for purposes here 15060 // we are going to consider it empty. 15061 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15062 } 15063 if (adj > clientAdj) { 15064 if (app.hasShownUi && app != mHomeProcess 15065 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 15066 app.adjType = "cch-ui-provider"; 15067 } else { 15068 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 15069 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15070 app.adjType = "provider"; 15071 } 15072 app.cached &= client.cached; 15073 app.keeping |= client.keeping; 15074 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15075 .REASON_PROVIDER_IN_USE; 15076 app.adjSource = client; 15077 app.adjSourceOom = clientAdj; 15078 app.adjTarget = cpr.name; 15079 } 15080 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15081 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15082 // Special handling of clients who are in the top state. 15083 // We *may* want to consider this process to be in the 15084 // top state as well, but only if there is not another 15085 // reason for it to be running. Being on the top is a 15086 // special state, meaning you are specifically running 15087 // for the current top app. If the process is already 15088 // running in the background for some other reason, it 15089 // is more important to continue considering it to be 15090 // in the background state. 15091 mayBeTop = true; 15092 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15093 } else { 15094 // Special handling for above-top states (persistent 15095 // processes). These should not bring the current process 15096 // into the top state, since they are not on top. Instead 15097 // give them the best state after that. 15098 clientProcState = 15099 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15100 } 15101 } 15102 if (procState > clientProcState) { 15103 procState = clientProcState; 15104 } 15105 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15106 schedGroup = Process.THREAD_GROUP_DEFAULT; 15107 } 15108 } 15109 // If the provider has external (non-framework) process 15110 // dependencies, ensure that its adjustment is at least 15111 // FOREGROUND_APP_ADJ. 15112 if (cpr.hasExternalProcessHandles()) { 15113 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15114 adj = ProcessList.FOREGROUND_APP_ADJ; 15115 schedGroup = Process.THREAD_GROUP_DEFAULT; 15116 app.cached = false; 15117 app.keeping = true; 15118 app.adjType = "provider"; 15119 app.adjTarget = cpr.name; 15120 } 15121 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15122 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15123 } 15124 } 15125 } 15126 15127 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15128 // A client of one of our services or providers is in the top state. We 15129 // *may* want to be in the top state, but not if we are already running in 15130 // the background for some other reason. For the decision here, we are going 15131 // to pick out a few specific states that we want to remain in when a client 15132 // is top (states that tend to be longer-term) and otherwise allow it to go 15133 // to the top state. 15134 switch (procState) { 15135 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15136 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15137 case ActivityManager.PROCESS_STATE_SERVICE: 15138 // These all are longer-term states, so pull them up to the top 15139 // of the background states, but not all the way to the top state. 15140 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15141 break; 15142 default: 15143 // Otherwise, top is a better choice, so take it. 15144 procState = ActivityManager.PROCESS_STATE_TOP; 15145 break; 15146 } 15147 } 15148 15149 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15150 if (app.hasClientActivities) { 15151 // This is a cached process, but with client activities. Mark it so. 15152 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15153 app.adjType = "cch-client-act"; 15154 } else if (app.treatLikeActivity) { 15155 // This is a cached process, but somebody wants us to treat it like it has 15156 // an activity, okay! 15157 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15158 app.adjType = "cch-as-act"; 15159 } 15160 } 15161 15162 if (adj == ProcessList.SERVICE_ADJ) { 15163 if (doingAll) { 15164 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15165 mNewNumServiceProcs++; 15166 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15167 if (!app.serviceb) { 15168 // This service isn't far enough down on the LRU list to 15169 // normally be a B service, but if we are low on RAM and it 15170 // is large we want to force it down since we would prefer to 15171 // keep launcher over it. 15172 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15173 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15174 app.serviceHighRam = true; 15175 app.serviceb = true; 15176 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15177 } else { 15178 mNewNumAServiceProcs++; 15179 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15180 } 15181 } else { 15182 app.serviceHighRam = false; 15183 } 15184 } 15185 if (app.serviceb) { 15186 adj = ProcessList.SERVICE_B_ADJ; 15187 } 15188 } 15189 15190 app.curRawAdj = adj; 15191 15192 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15193 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15194 if (adj > app.maxAdj) { 15195 adj = app.maxAdj; 15196 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15197 schedGroup = Process.THREAD_GROUP_DEFAULT; 15198 } 15199 } 15200 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15201 app.keeping = true; 15202 } 15203 15204 // Do final modification to adj. Everything we do between here and applying 15205 // the final setAdj must be done in this function, because we will also use 15206 // it when computing the final cached adj later. Note that we don't need to 15207 // worry about this for max adj above, since max adj will always be used to 15208 // keep it out of the cached vaues. 15209 app.curAdj = app.modifyRawOomAdj(adj); 15210 app.curSchedGroup = schedGroup; 15211 app.curProcState = procState; 15212 app.foregroundActivities = foregroundActivities; 15213 15214 return app.curRawAdj; 15215 } 15216 15217 /** 15218 * Schedule PSS collection of a process. 15219 */ 15220 void requestPssLocked(ProcessRecord proc, int procState) { 15221 if (mPendingPssProcesses.contains(proc)) { 15222 return; 15223 } 15224 if (mPendingPssProcesses.size() == 0) { 15225 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15226 } 15227 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15228 proc.pssProcState = procState; 15229 mPendingPssProcesses.add(proc); 15230 } 15231 15232 /** 15233 * Schedule PSS collection of all processes. 15234 */ 15235 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15236 if (!always) { 15237 if (now < (mLastFullPssTime + 15238 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15239 return; 15240 } 15241 } 15242 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15243 mLastFullPssTime = now; 15244 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15245 mPendingPssProcesses.clear(); 15246 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15247 ProcessRecord app = mLruProcesses.get(i); 15248 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15249 app.pssProcState = app.setProcState; 15250 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15251 isSleeping(), now); 15252 mPendingPssProcesses.add(app); 15253 } 15254 } 15255 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15256 } 15257 15258 /** 15259 * Ask a given process to GC right now. 15260 */ 15261 final void performAppGcLocked(ProcessRecord app) { 15262 try { 15263 app.lastRequestedGc = SystemClock.uptimeMillis(); 15264 if (app.thread != null) { 15265 if (app.reportLowMemory) { 15266 app.reportLowMemory = false; 15267 app.thread.scheduleLowMemory(); 15268 } else { 15269 app.thread.processInBackground(); 15270 } 15271 } 15272 } catch (Exception e) { 15273 // whatever. 15274 } 15275 } 15276 15277 /** 15278 * Returns true if things are idle enough to perform GCs. 15279 */ 15280 private final boolean canGcNowLocked() { 15281 boolean processingBroadcasts = false; 15282 for (BroadcastQueue q : mBroadcastQueues) { 15283 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15284 processingBroadcasts = true; 15285 } 15286 } 15287 return !processingBroadcasts 15288 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle()); 15289 } 15290 15291 /** 15292 * Perform GCs on all processes that are waiting for it, but only 15293 * if things are idle. 15294 */ 15295 final void performAppGcsLocked() { 15296 final int N = mProcessesToGc.size(); 15297 if (N <= 0) { 15298 return; 15299 } 15300 if (canGcNowLocked()) { 15301 while (mProcessesToGc.size() > 0) { 15302 ProcessRecord proc = mProcessesToGc.remove(0); 15303 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15304 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15305 <= SystemClock.uptimeMillis()) { 15306 // To avoid spamming the system, we will GC processes one 15307 // at a time, waiting a few seconds between each. 15308 performAppGcLocked(proc); 15309 scheduleAppGcsLocked(); 15310 return; 15311 } else { 15312 // It hasn't been long enough since we last GCed this 15313 // process... put it in the list to wait for its time. 15314 addProcessToGcListLocked(proc); 15315 break; 15316 } 15317 } 15318 } 15319 15320 scheduleAppGcsLocked(); 15321 } 15322 } 15323 15324 /** 15325 * If all looks good, perform GCs on all processes waiting for them. 15326 */ 15327 final void performAppGcsIfAppropriateLocked() { 15328 if (canGcNowLocked()) { 15329 performAppGcsLocked(); 15330 return; 15331 } 15332 // Still not idle, wait some more. 15333 scheduleAppGcsLocked(); 15334 } 15335 15336 /** 15337 * Schedule the execution of all pending app GCs. 15338 */ 15339 final void scheduleAppGcsLocked() { 15340 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15341 15342 if (mProcessesToGc.size() > 0) { 15343 // Schedule a GC for the time to the next process. 15344 ProcessRecord proc = mProcessesToGc.get(0); 15345 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15346 15347 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15348 long now = SystemClock.uptimeMillis(); 15349 if (when < (now+GC_TIMEOUT)) { 15350 when = now + GC_TIMEOUT; 15351 } 15352 mHandler.sendMessageAtTime(msg, when); 15353 } 15354 } 15355 15356 /** 15357 * Add a process to the array of processes waiting to be GCed. Keeps the 15358 * list in sorted order by the last GC time. The process can't already be 15359 * on the list. 15360 */ 15361 final void addProcessToGcListLocked(ProcessRecord proc) { 15362 boolean added = false; 15363 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15364 if (mProcessesToGc.get(i).lastRequestedGc < 15365 proc.lastRequestedGc) { 15366 added = true; 15367 mProcessesToGc.add(i+1, proc); 15368 break; 15369 } 15370 } 15371 if (!added) { 15372 mProcessesToGc.add(0, proc); 15373 } 15374 } 15375 15376 /** 15377 * Set up to ask a process to GC itself. This will either do it 15378 * immediately, or put it on the list of processes to gc the next 15379 * time things are idle. 15380 */ 15381 final void scheduleAppGcLocked(ProcessRecord app) { 15382 long now = SystemClock.uptimeMillis(); 15383 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15384 return; 15385 } 15386 if (!mProcessesToGc.contains(app)) { 15387 addProcessToGcListLocked(app); 15388 scheduleAppGcsLocked(); 15389 } 15390 } 15391 15392 final void checkExcessivePowerUsageLocked(boolean doKills) { 15393 updateCpuStatsNow(); 15394 15395 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15396 boolean doWakeKills = doKills; 15397 boolean doCpuKills = doKills; 15398 if (mLastPowerCheckRealtime == 0) { 15399 doWakeKills = false; 15400 } 15401 if (mLastPowerCheckUptime == 0) { 15402 doCpuKills = false; 15403 } 15404 if (stats.isScreenOn()) { 15405 doWakeKills = false; 15406 } 15407 final long curRealtime = SystemClock.elapsedRealtime(); 15408 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15409 final long curUptime = SystemClock.uptimeMillis(); 15410 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15411 mLastPowerCheckRealtime = curRealtime; 15412 mLastPowerCheckUptime = curUptime; 15413 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15414 doWakeKills = false; 15415 } 15416 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15417 doCpuKills = false; 15418 } 15419 int i = mLruProcesses.size(); 15420 while (i > 0) { 15421 i--; 15422 ProcessRecord app = mLruProcesses.get(i); 15423 if (!app.keeping) { 15424 long wtime; 15425 synchronized (stats) { 15426 wtime = stats.getProcessWakeTime(app.info.uid, 15427 app.pid, curRealtime); 15428 } 15429 long wtimeUsed = wtime - app.lastWakeTime; 15430 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15431 if (DEBUG_POWER) { 15432 StringBuilder sb = new StringBuilder(128); 15433 sb.append("Wake for "); 15434 app.toShortString(sb); 15435 sb.append(": over "); 15436 TimeUtils.formatDuration(realtimeSince, sb); 15437 sb.append(" used "); 15438 TimeUtils.formatDuration(wtimeUsed, sb); 15439 sb.append(" ("); 15440 sb.append((wtimeUsed*100)/realtimeSince); 15441 sb.append("%)"); 15442 Slog.i(TAG, sb.toString()); 15443 sb.setLength(0); 15444 sb.append("CPU for "); 15445 app.toShortString(sb); 15446 sb.append(": over "); 15447 TimeUtils.formatDuration(uptimeSince, sb); 15448 sb.append(" used "); 15449 TimeUtils.formatDuration(cputimeUsed, sb); 15450 sb.append(" ("); 15451 sb.append((cputimeUsed*100)/uptimeSince); 15452 sb.append("%)"); 15453 Slog.i(TAG, sb.toString()); 15454 } 15455 // If a process has held a wake lock for more 15456 // than 50% of the time during this period, 15457 // that sounds bad. Kill! 15458 if (doWakeKills && realtimeSince > 0 15459 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15460 synchronized (stats) { 15461 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15462 realtimeSince, wtimeUsed); 15463 } 15464 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15465 + " during " + realtimeSince); 15466 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15467 } else if (doCpuKills && uptimeSince > 0 15468 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15469 synchronized (stats) { 15470 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15471 uptimeSince, cputimeUsed); 15472 } 15473 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15474 + " during " + uptimeSince); 15475 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15476 } else { 15477 app.lastWakeTime = wtime; 15478 app.lastCpuTime = app.curCpuTime; 15479 } 15480 } 15481 } 15482 } 15483 15484 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15485 ProcessRecord TOP_APP, boolean doingAll, long now) { 15486 boolean success = true; 15487 15488 if (app.curRawAdj != app.setRawAdj) { 15489 if (wasKeeping && !app.keeping) { 15490 // This app is no longer something we want to keep. Note 15491 // its current wake lock time to later know to kill it if 15492 // it is not behaving well. 15493 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15494 synchronized (stats) { 15495 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15496 app.pid, SystemClock.elapsedRealtime()); 15497 } 15498 app.lastCpuTime = app.curCpuTime; 15499 } 15500 15501 app.setRawAdj = app.curRawAdj; 15502 } 15503 15504 int changes = 0; 15505 15506 if (app.curAdj != app.setAdj) { 15507 ProcessList.setOomAdj(app.pid, app.curAdj); 15508 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15509 TAG, "Set " + app.pid + " " + app.processName + 15510 " adj " + app.curAdj + ": " + app.adjType); 15511 app.setAdj = app.curAdj; 15512 } 15513 15514 if (app.setSchedGroup != app.curSchedGroup) { 15515 app.setSchedGroup = app.curSchedGroup; 15516 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15517 "Setting process group of " + app.processName 15518 + " to " + app.curSchedGroup); 15519 if (app.waitingToKill != null && 15520 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15521 killUnneededProcessLocked(app, app.waitingToKill); 15522 success = false; 15523 } else { 15524 if (true) { 15525 long oldId = Binder.clearCallingIdentity(); 15526 try { 15527 Process.setProcessGroup(app.pid, app.curSchedGroup); 15528 } catch (Exception e) { 15529 Slog.w(TAG, "Failed setting process group of " + app.pid 15530 + " to " + app.curSchedGroup); 15531 e.printStackTrace(); 15532 } finally { 15533 Binder.restoreCallingIdentity(oldId); 15534 } 15535 } else { 15536 if (app.thread != null) { 15537 try { 15538 app.thread.setSchedulingGroup(app.curSchedGroup); 15539 } catch (RemoteException e) { 15540 } 15541 } 15542 } 15543 Process.setSwappiness(app.pid, 15544 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15545 } 15546 } 15547 if (app.repForegroundActivities != app.foregroundActivities) { 15548 app.repForegroundActivities = app.foregroundActivities; 15549 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15550 } 15551 if (app.repProcState != app.curProcState) { 15552 app.repProcState = app.curProcState; 15553 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE; 15554 if (app.thread != null) { 15555 try { 15556 if (false) { 15557 //RuntimeException h = new RuntimeException("here"); 15558 Slog.i(TAG, "Sending new process state " + app.repProcState 15559 + " to " + app /*, h*/); 15560 } 15561 app.thread.setProcessState(app.repProcState); 15562 } catch (RemoteException e) { 15563 } 15564 } 15565 } 15566 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15567 app.setProcState)) { 15568 app.lastStateTime = now; 15569 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15570 isSleeping(), now); 15571 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15572 + ProcessList.makeProcStateString(app.setProcState) + " to " 15573 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15574 + (app.nextPssTime-now) + ": " + app); 15575 } else { 15576 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15577 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15578 requestPssLocked(app, app.setProcState); 15579 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15580 isSleeping(), now); 15581 } else if (false && DEBUG_PSS) { 15582 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15583 } 15584 } 15585 if (app.setProcState != app.curProcState) { 15586 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15587 "Proc state change of " + app.processName 15588 + " to " + app.curProcState); 15589 app.setProcState = app.curProcState; 15590 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15591 app.notCachedSinceIdle = false; 15592 } 15593 if (!doingAll) { 15594 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15595 } else { 15596 app.procStateChanged = true; 15597 } 15598 } 15599 15600 if (changes != 0) { 15601 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15602 int i = mPendingProcessChanges.size()-1; 15603 ProcessChangeItem item = null; 15604 while (i >= 0) { 15605 item = mPendingProcessChanges.get(i); 15606 if (item.pid == app.pid) { 15607 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15608 break; 15609 } 15610 i--; 15611 } 15612 if (i < 0) { 15613 // No existing item in pending changes; need a new one. 15614 final int NA = mAvailProcessChanges.size(); 15615 if (NA > 0) { 15616 item = mAvailProcessChanges.remove(NA-1); 15617 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15618 } else { 15619 item = new ProcessChangeItem(); 15620 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15621 } 15622 item.changes = 0; 15623 item.pid = app.pid; 15624 item.uid = app.info.uid; 15625 if (mPendingProcessChanges.size() == 0) { 15626 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15627 "*** Enqueueing dispatch processes changed!"); 15628 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15629 } 15630 mPendingProcessChanges.add(item); 15631 } 15632 item.changes |= changes; 15633 item.processState = app.repProcState; 15634 item.foregroundActivities = app.repForegroundActivities; 15635 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15636 + Integer.toHexString(System.identityHashCode(item)) 15637 + " " + app.toShortString() + ": changes=" + item.changes 15638 + " procState=" + item.processState 15639 + " foreground=" + item.foregroundActivities 15640 + " type=" + app.adjType + " source=" + app.adjSource 15641 + " target=" + app.adjTarget); 15642 } 15643 15644 return success; 15645 } 15646 15647 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15648 if (proc.thread != null && proc.baseProcessTracker != null) { 15649 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15650 } 15651 } 15652 15653 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15654 ProcessRecord TOP_APP, boolean doingAll, long now) { 15655 if (app.thread == null) { 15656 return false; 15657 } 15658 15659 final boolean wasKeeping = app.keeping; 15660 15661 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15662 15663 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now); 15664 } 15665 15666 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15667 boolean oomAdj) { 15668 if (isForeground != proc.foregroundServices) { 15669 proc.foregroundServices = isForeground; 15670 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15671 proc.info.uid); 15672 if (isForeground) { 15673 if (curProcs == null) { 15674 curProcs = new ArrayList<ProcessRecord>(); 15675 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15676 } 15677 if (!curProcs.contains(proc)) { 15678 curProcs.add(proc); 15679 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15680 proc.info.packageName, proc.info.uid); 15681 } 15682 } else { 15683 if (curProcs != null) { 15684 if (curProcs.remove(proc)) { 15685 mBatteryStatsService.noteEvent( 15686 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15687 proc.info.packageName, proc.info.uid); 15688 if (curProcs.size() <= 0) { 15689 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15690 } 15691 } 15692 } 15693 } 15694 if (oomAdj) { 15695 updateOomAdjLocked(); 15696 } 15697 } 15698 } 15699 15700 private final ActivityRecord resumedAppLocked() { 15701 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15702 String pkg; 15703 int uid; 15704 if (act != null && !act.sleeping) { 15705 pkg = act.packageName; 15706 uid = act.info.applicationInfo.uid; 15707 } else { 15708 pkg = null; 15709 uid = -1; 15710 } 15711 // Has the UID or resumed package name changed? 15712 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15713 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15714 if (mCurResumedPackage != null) { 15715 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15716 mCurResumedPackage, mCurResumedUid); 15717 } 15718 mCurResumedPackage = pkg; 15719 mCurResumedUid = uid; 15720 if (mCurResumedPackage != null) { 15721 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15722 mCurResumedPackage, mCurResumedUid); 15723 } 15724 } 15725 return act; 15726 } 15727 15728 final boolean updateOomAdjLocked(ProcessRecord app) { 15729 final ActivityRecord TOP_ACT = resumedAppLocked(); 15730 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15731 final boolean wasCached = app.cached; 15732 15733 mAdjSeq++; 15734 15735 // This is the desired cached adjusment we want to tell it to use. 15736 // If our app is currently cached, we know it, and that is it. Otherwise, 15737 // we don't know it yet, and it needs to now be cached we will then 15738 // need to do a complete oom adj. 15739 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15740 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15741 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, 15742 SystemClock.uptimeMillis()); 15743 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15744 // Changed to/from cached state, so apps after it in the LRU 15745 // list may also be changed. 15746 updateOomAdjLocked(); 15747 } 15748 return success; 15749 } 15750 15751 final void updateOomAdjLocked() { 15752 final ActivityRecord TOP_ACT = resumedAppLocked(); 15753 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15754 final long now = SystemClock.uptimeMillis(); 15755 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15756 final int N = mLruProcesses.size(); 15757 15758 if (false) { 15759 RuntimeException e = new RuntimeException(); 15760 e.fillInStackTrace(); 15761 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15762 } 15763 15764 mAdjSeq++; 15765 mNewNumServiceProcs = 0; 15766 mNewNumAServiceProcs = 0; 15767 15768 final int emptyProcessLimit; 15769 final int cachedProcessLimit; 15770 if (mProcessLimit <= 0) { 15771 emptyProcessLimit = cachedProcessLimit = 0; 15772 } else if (mProcessLimit == 1) { 15773 emptyProcessLimit = 1; 15774 cachedProcessLimit = 0; 15775 } else { 15776 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15777 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15778 } 15779 15780 // Let's determine how many processes we have running vs. 15781 // how many slots we have for background processes; we may want 15782 // to put multiple processes in a slot of there are enough of 15783 // them. 15784 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15785 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15786 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15787 if (numEmptyProcs > cachedProcessLimit) { 15788 // If there are more empty processes than our limit on cached 15789 // processes, then use the cached process limit for the factor. 15790 // This ensures that the really old empty processes get pushed 15791 // down to the bottom, so if we are running low on memory we will 15792 // have a better chance at keeping around more cached processes 15793 // instead of a gazillion empty processes. 15794 numEmptyProcs = cachedProcessLimit; 15795 } 15796 int emptyFactor = numEmptyProcs/numSlots; 15797 if (emptyFactor < 1) emptyFactor = 1; 15798 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15799 if (cachedFactor < 1) cachedFactor = 1; 15800 int stepCached = 0; 15801 int stepEmpty = 0; 15802 int numCached = 0; 15803 int numEmpty = 0; 15804 int numTrimming = 0; 15805 15806 mNumNonCachedProcs = 0; 15807 mNumCachedHiddenProcs = 0; 15808 15809 // First update the OOM adjustment for each of the 15810 // application processes based on their current state. 15811 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15812 int nextCachedAdj = curCachedAdj+1; 15813 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15814 int nextEmptyAdj = curEmptyAdj+2; 15815 for (int i=N-1; i>=0; i--) { 15816 ProcessRecord app = mLruProcesses.get(i); 15817 if (!app.killedByAm && app.thread != null) { 15818 app.procStateChanged = false; 15819 final boolean wasKeeping = app.keeping; 15820 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15821 15822 // If we haven't yet assigned the final cached adj 15823 // to the process, do that now. 15824 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15825 switch (app.curProcState) { 15826 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15827 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15828 // This process is a cached process holding activities... 15829 // assign it the next cached value for that type, and then 15830 // step that cached level. 15831 app.curRawAdj = curCachedAdj; 15832 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15833 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15834 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15835 + ")"); 15836 if (curCachedAdj != nextCachedAdj) { 15837 stepCached++; 15838 if (stepCached >= cachedFactor) { 15839 stepCached = 0; 15840 curCachedAdj = nextCachedAdj; 15841 nextCachedAdj += 2; 15842 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15843 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15844 } 15845 } 15846 } 15847 break; 15848 default: 15849 // For everything else, assign next empty cached process 15850 // level and bump that up. Note that this means that 15851 // long-running services that have dropped down to the 15852 // cached level will be treated as empty (since their process 15853 // state is still as a service), which is what we want. 15854 app.curRawAdj = curEmptyAdj; 15855 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15856 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15857 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15858 + ")"); 15859 if (curEmptyAdj != nextEmptyAdj) { 15860 stepEmpty++; 15861 if (stepEmpty >= emptyFactor) { 15862 stepEmpty = 0; 15863 curEmptyAdj = nextEmptyAdj; 15864 nextEmptyAdj += 2; 15865 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15866 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15867 } 15868 } 15869 } 15870 break; 15871 } 15872 } 15873 15874 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now); 15875 15876 // Count the number of process types. 15877 switch (app.curProcState) { 15878 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15879 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15880 mNumCachedHiddenProcs++; 15881 numCached++; 15882 if (numCached > cachedProcessLimit) { 15883 killUnneededProcessLocked(app, "cached #" + numCached); 15884 } 15885 break; 15886 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15887 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15888 && app.lastActivityTime < oldTime) { 15889 killUnneededProcessLocked(app, "empty for " 15890 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15891 / 1000) + "s"); 15892 } else { 15893 numEmpty++; 15894 if (numEmpty > emptyProcessLimit) { 15895 killUnneededProcessLocked(app, "empty #" + numEmpty); 15896 } 15897 } 15898 break; 15899 default: 15900 mNumNonCachedProcs++; 15901 break; 15902 } 15903 15904 if (app.isolated && app.services.size() <= 0) { 15905 // If this is an isolated process, and there are no 15906 // services running in it, then the process is no longer 15907 // needed. We agressively kill these because we can by 15908 // definition not re-use the same process again, and it is 15909 // good to avoid having whatever code was running in them 15910 // left sitting around after no longer needed. 15911 killUnneededProcessLocked(app, "isolated not needed"); 15912 } 15913 15914 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15915 && !app.killedByAm) { 15916 numTrimming++; 15917 } 15918 } 15919 } 15920 15921 mNumServiceProcs = mNewNumServiceProcs; 15922 15923 // Now determine the memory trimming level of background processes. 15924 // Unfortunately we need to start at the back of the list to do this 15925 // properly. We only do this if the number of background apps we 15926 // are managing to keep around is less than half the maximum we desire; 15927 // if we are keeping a good number around, we'll let them use whatever 15928 // memory they want. 15929 final int numCachedAndEmpty = numCached + numEmpty; 15930 int memFactor; 15931 if (numCached <= ProcessList.TRIM_CACHED_APPS 15932 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15933 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15934 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15935 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15936 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15937 } else { 15938 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15939 } 15940 } else { 15941 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15942 } 15943 // We always allow the memory level to go up (better). We only allow it to go 15944 // down if we are in a state where that is allowed, *and* the total number of processes 15945 // has gone down since last time. 15946 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15947 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15948 + " last=" + mLastNumProcesses); 15949 if (memFactor > mLastMemoryLevel) { 15950 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15951 memFactor = mLastMemoryLevel; 15952 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15953 } 15954 } 15955 mLastMemoryLevel = memFactor; 15956 mLastNumProcesses = mLruProcesses.size(); 15957 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now); 15958 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15959 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15960 if (mLowRamStartTime == 0) { 15961 mLowRamStartTime = now; 15962 } 15963 int step = 0; 15964 int fgTrimLevel; 15965 switch (memFactor) { 15966 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15967 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15968 break; 15969 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15970 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15971 break; 15972 default: 15973 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15974 break; 15975 } 15976 int factor = numTrimming/3; 15977 int minFactor = 2; 15978 if (mHomeProcess != null) minFactor++; 15979 if (mPreviousProcess != null) minFactor++; 15980 if (factor < minFactor) factor = minFactor; 15981 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15982 for (int i=N-1; i>=0; i--) { 15983 ProcessRecord app = mLruProcesses.get(i); 15984 if (allChanged || app.procStateChanged) { 15985 setProcessTrackerState(app, trackerMemFactor, now); 15986 app.procStateChanged = false; 15987 } 15988 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15989 && !app.killedByAm) { 15990 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15991 try { 15992 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15993 "Trimming memory of " + app.processName 15994 + " to " + curLevel); 15995 app.thread.scheduleTrimMemory(curLevel); 15996 } catch (RemoteException e) { 15997 } 15998 if (false) { 15999 // For now we won't do this; our memory trimming seems 16000 // to be good enough at this point that destroying 16001 // activities causes more harm than good. 16002 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 16003 && app != mHomeProcess && app != mPreviousProcess) { 16004 // Need to do this on its own message because the stack may not 16005 // be in a consistent state at this point. 16006 // For these apps we will also finish their activities 16007 // to help them free memory. 16008 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 16009 } 16010 } 16011 } 16012 app.trimMemoryLevel = curLevel; 16013 step++; 16014 if (step >= factor) { 16015 step = 0; 16016 switch (curLevel) { 16017 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 16018 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 16019 break; 16020 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 16021 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16022 break; 16023 } 16024 } 16025 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 16026 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 16027 && app.thread != null) { 16028 try { 16029 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16030 "Trimming memory of heavy-weight " + app.processName 16031 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16032 app.thread.scheduleTrimMemory( 16033 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 16034 } catch (RemoteException e) { 16035 } 16036 } 16037 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16038 } else { 16039 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16040 || app.systemNoUi) && app.pendingUiClean) { 16041 // If this application is now in the background and it 16042 // had done UI, then give it the special trim level to 16043 // have it free UI resources. 16044 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16045 if (app.trimMemoryLevel < level && app.thread != null) { 16046 try { 16047 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16048 "Trimming memory of bg-ui " + app.processName 16049 + " to " + level); 16050 app.thread.scheduleTrimMemory(level); 16051 } catch (RemoteException e) { 16052 } 16053 } 16054 app.pendingUiClean = false; 16055 } 16056 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16057 try { 16058 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16059 "Trimming memory of fg " + app.processName 16060 + " to " + fgTrimLevel); 16061 app.thread.scheduleTrimMemory(fgTrimLevel); 16062 } catch (RemoteException e) { 16063 } 16064 } 16065 app.trimMemoryLevel = fgTrimLevel; 16066 } 16067 } 16068 } else { 16069 if (mLowRamStartTime != 0) { 16070 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16071 mLowRamStartTime = 0; 16072 } 16073 for (int i=N-1; i>=0; i--) { 16074 ProcessRecord app = mLruProcesses.get(i); 16075 if (allChanged || app.procStateChanged) { 16076 setProcessTrackerState(app, trackerMemFactor, now); 16077 app.procStateChanged = false; 16078 } 16079 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16080 || app.systemNoUi) && app.pendingUiClean) { 16081 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16082 && app.thread != null) { 16083 try { 16084 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16085 "Trimming memory of ui hidden " + app.processName 16086 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16087 app.thread.scheduleTrimMemory( 16088 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16089 } catch (RemoteException e) { 16090 } 16091 } 16092 app.pendingUiClean = false; 16093 } 16094 app.trimMemoryLevel = 0; 16095 } 16096 } 16097 16098 if (mAlwaysFinishActivities) { 16099 // Need to do this on its own message because the stack may not 16100 // be in a consistent state at this point. 16101 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16102 } 16103 16104 if (allChanged) { 16105 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16106 } 16107 16108 if (mProcessStats.shouldWriteNowLocked(now)) { 16109 mHandler.post(new Runnable() { 16110 @Override public void run() { 16111 synchronized (ActivityManagerService.this) { 16112 mProcessStats.writeStateAsyncLocked(); 16113 } 16114 } 16115 }); 16116 } 16117 16118 if (DEBUG_OOM_ADJ) { 16119 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16120 } 16121 } 16122 16123 final void trimApplications() { 16124 synchronized (this) { 16125 int i; 16126 16127 // First remove any unused application processes whose package 16128 // has been removed. 16129 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16130 final ProcessRecord app = mRemovedProcesses.get(i); 16131 if (app.activities.size() == 0 16132 && app.curReceiver == null && app.services.size() == 0) { 16133 Slog.i( 16134 TAG, "Exiting empty application process " 16135 + app.processName + " (" 16136 + (app.thread != null ? app.thread.asBinder() : null) 16137 + ")\n"); 16138 if (app.pid > 0 && app.pid != MY_PID) { 16139 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16140 app.processName, app.setAdj, "empty"); 16141 app.killedByAm = true; 16142 Process.killProcessQuiet(app.pid); 16143 } else { 16144 try { 16145 app.thread.scheduleExit(); 16146 } catch (Exception e) { 16147 // Ignore exceptions. 16148 } 16149 } 16150 cleanUpApplicationRecordLocked(app, false, true, -1); 16151 mRemovedProcesses.remove(i); 16152 16153 if (app.persistent) { 16154 if (app.persistent) { 16155 addAppLocked(app.info, false); 16156 } 16157 } 16158 } 16159 } 16160 16161 // Now update the oom adj for all processes. 16162 updateOomAdjLocked(); 16163 } 16164 } 16165 16166 /** This method sends the specified signal to each of the persistent apps */ 16167 public void signalPersistentProcesses(int sig) throws RemoteException { 16168 if (sig != Process.SIGNAL_USR1) { 16169 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16170 } 16171 16172 synchronized (this) { 16173 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16174 != PackageManager.PERMISSION_GRANTED) { 16175 throw new SecurityException("Requires permission " 16176 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16177 } 16178 16179 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16180 ProcessRecord r = mLruProcesses.get(i); 16181 if (r.thread != null && r.persistent) { 16182 Process.sendSignal(r.pid, sig); 16183 } 16184 } 16185 } 16186 } 16187 16188 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16189 if (proc == null || proc == mProfileProc) { 16190 proc = mProfileProc; 16191 path = mProfileFile; 16192 profileType = mProfileType; 16193 clearProfilerLocked(); 16194 } 16195 if (proc == null) { 16196 return; 16197 } 16198 try { 16199 proc.thread.profilerControl(false, path, null, profileType); 16200 } catch (RemoteException e) { 16201 throw new IllegalStateException("Process disappeared"); 16202 } 16203 } 16204 16205 private void clearProfilerLocked() { 16206 if (mProfileFd != null) { 16207 try { 16208 mProfileFd.close(); 16209 } catch (IOException e) { 16210 } 16211 } 16212 mProfileApp = null; 16213 mProfileProc = null; 16214 mProfileFile = null; 16215 mProfileType = 0; 16216 mAutoStopProfiler = false; 16217 } 16218 16219 public boolean profileControl(String process, int userId, boolean start, 16220 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16221 16222 try { 16223 synchronized (this) { 16224 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16225 // its own permission. 16226 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16227 != PackageManager.PERMISSION_GRANTED) { 16228 throw new SecurityException("Requires permission " 16229 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16230 } 16231 16232 if (start && fd == null) { 16233 throw new IllegalArgumentException("null fd"); 16234 } 16235 16236 ProcessRecord proc = null; 16237 if (process != null) { 16238 proc = findProcessLocked(process, userId, "profileControl"); 16239 } 16240 16241 if (start && (proc == null || proc.thread == null)) { 16242 throw new IllegalArgumentException("Unknown process: " + process); 16243 } 16244 16245 if (start) { 16246 stopProfilerLocked(null, null, 0); 16247 setProfileApp(proc.info, proc.processName, path, fd, false); 16248 mProfileProc = proc; 16249 mProfileType = profileType; 16250 try { 16251 fd = fd.dup(); 16252 } catch (IOException e) { 16253 fd = null; 16254 } 16255 proc.thread.profilerControl(start, path, fd, profileType); 16256 fd = null; 16257 mProfileFd = null; 16258 } else { 16259 stopProfilerLocked(proc, path, profileType); 16260 if (fd != null) { 16261 try { 16262 fd.close(); 16263 } catch (IOException e) { 16264 } 16265 } 16266 } 16267 16268 return true; 16269 } 16270 } catch (RemoteException e) { 16271 throw new IllegalStateException("Process disappeared"); 16272 } finally { 16273 if (fd != null) { 16274 try { 16275 fd.close(); 16276 } catch (IOException e) { 16277 } 16278 } 16279 } 16280 } 16281 16282 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16283 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16284 userId, true, true, callName, null); 16285 ProcessRecord proc = null; 16286 try { 16287 int pid = Integer.parseInt(process); 16288 synchronized (mPidsSelfLocked) { 16289 proc = mPidsSelfLocked.get(pid); 16290 } 16291 } catch (NumberFormatException e) { 16292 } 16293 16294 if (proc == null) { 16295 ArrayMap<String, SparseArray<ProcessRecord>> all 16296 = mProcessNames.getMap(); 16297 SparseArray<ProcessRecord> procs = all.get(process); 16298 if (procs != null && procs.size() > 0) { 16299 proc = procs.valueAt(0); 16300 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16301 for (int i=1; i<procs.size(); i++) { 16302 ProcessRecord thisProc = procs.valueAt(i); 16303 if (thisProc.userId == userId) { 16304 proc = thisProc; 16305 break; 16306 } 16307 } 16308 } 16309 } 16310 } 16311 16312 return proc; 16313 } 16314 16315 public boolean dumpHeap(String process, int userId, boolean managed, 16316 String path, ParcelFileDescriptor fd) throws RemoteException { 16317 16318 try { 16319 synchronized (this) { 16320 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16321 // its own permission (same as profileControl). 16322 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16323 != PackageManager.PERMISSION_GRANTED) { 16324 throw new SecurityException("Requires permission " 16325 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16326 } 16327 16328 if (fd == null) { 16329 throw new IllegalArgumentException("null fd"); 16330 } 16331 16332 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16333 if (proc == null || proc.thread == null) { 16334 throw new IllegalArgumentException("Unknown process: " + process); 16335 } 16336 16337 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16338 if (!isDebuggable) { 16339 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16340 throw new SecurityException("Process not debuggable: " + proc); 16341 } 16342 } 16343 16344 proc.thread.dumpHeap(managed, path, fd); 16345 fd = null; 16346 return true; 16347 } 16348 } catch (RemoteException e) { 16349 throw new IllegalStateException("Process disappeared"); 16350 } finally { 16351 if (fd != null) { 16352 try { 16353 fd.close(); 16354 } catch (IOException e) { 16355 } 16356 } 16357 } 16358 } 16359 16360 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16361 public void monitor() { 16362 synchronized (this) { } 16363 } 16364 16365 void onCoreSettingsChange(Bundle settings) { 16366 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16367 ProcessRecord processRecord = mLruProcesses.get(i); 16368 try { 16369 if (processRecord.thread != null) { 16370 processRecord.thread.setCoreSettings(settings); 16371 } 16372 } catch (RemoteException re) { 16373 /* ignore */ 16374 } 16375 } 16376 } 16377 16378 // Multi-user methods 16379 16380 /** 16381 * Start user, if its not already running, but don't bring it to foreground. 16382 */ 16383 @Override 16384 public boolean startUserInBackground(final int userId) { 16385 return startUser(userId, /* foreground */ false); 16386 } 16387 16388 /** 16389 * Refreshes the list of users related to the current user when either a 16390 * user switch happens or when a new related user is started in the 16391 * background. 16392 */ 16393 private void updateCurrentProfileIdsLocked() { 16394 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16395 mCurrentUserId, false /* enabledOnly */); 16396 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16397 for (int i = 0; i < currentProfileIds.length; i++) { 16398 currentProfileIds[i] = profiles.get(i).id; 16399 } 16400 mCurrentProfileIds = currentProfileIds; 16401 } 16402 16403 private Set getProfileIdsLocked(int userId) { 16404 Set userIds = new HashSet<Integer>(); 16405 final List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16406 userId, false /* enabledOnly */); 16407 for (UserInfo user : profiles) { 16408 userIds.add(Integer.valueOf(user.id)); 16409 } 16410 return userIds; 16411 } 16412 16413 @Override 16414 public boolean switchUser(final int userId) { 16415 return startUser(userId, /* foregound */ true); 16416 } 16417 16418 private boolean startUser(final int userId, boolean foreground) { 16419 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16420 != PackageManager.PERMISSION_GRANTED) { 16421 String msg = "Permission Denial: switchUser() from pid=" 16422 + Binder.getCallingPid() 16423 + ", uid=" + Binder.getCallingUid() 16424 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16425 Slog.w(TAG, msg); 16426 throw new SecurityException(msg); 16427 } 16428 16429 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16430 16431 final long ident = Binder.clearCallingIdentity(); 16432 try { 16433 synchronized (this) { 16434 final int oldUserId = mCurrentUserId; 16435 if (oldUserId == userId) { 16436 return true; 16437 } 16438 16439 mStackSupervisor.setLockTaskModeLocked(null); 16440 16441 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16442 if (userInfo == null) { 16443 Slog.w(TAG, "No user info for user #" + userId); 16444 return false; 16445 } 16446 16447 if (foreground) { 16448 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16449 R.anim.screen_user_enter); 16450 } 16451 16452 boolean needStart = false; 16453 16454 // If the user we are switching to is not currently started, then 16455 // we need to start it now. 16456 if (mStartedUsers.get(userId) == null) { 16457 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16458 updateStartedUserArrayLocked(); 16459 needStart = true; 16460 } 16461 16462 final Integer userIdInt = Integer.valueOf(userId); 16463 mUserLru.remove(userIdInt); 16464 mUserLru.add(userIdInt); 16465 16466 if (foreground) { 16467 mCurrentUserId = userId; 16468 updateCurrentProfileIdsLocked(); 16469 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16470 // Once the internal notion of the active user has switched, we lock the device 16471 // with the option to show the user switcher on the keyguard. 16472 mWindowManager.lockNow(null); 16473 } else { 16474 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16475 updateCurrentProfileIdsLocked(); 16476 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16477 mUserLru.remove(currentUserIdInt); 16478 mUserLru.add(currentUserIdInt); 16479 } 16480 16481 final UserStartedState uss = mStartedUsers.get(userId); 16482 16483 // Make sure user is in the started state. If it is currently 16484 // stopping, we need to knock that off. 16485 if (uss.mState == UserStartedState.STATE_STOPPING) { 16486 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16487 // so we can just fairly silently bring the user back from 16488 // the almost-dead. 16489 uss.mState = UserStartedState.STATE_RUNNING; 16490 updateStartedUserArrayLocked(); 16491 needStart = true; 16492 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16493 // This means ACTION_SHUTDOWN has been sent, so we will 16494 // need to treat this as a new boot of the user. 16495 uss.mState = UserStartedState.STATE_BOOTING; 16496 updateStartedUserArrayLocked(); 16497 needStart = true; 16498 } 16499 16500 if (uss.mState == UserStartedState.STATE_BOOTING) { 16501 // Booting up a new user, need to tell system services about it. 16502 // Note that this is on the same handler as scheduling of broadcasts, 16503 // which is important because it needs to go first. 16504 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId)); 16505 } 16506 16507 if (foreground) { 16508 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId)); 16509 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16510 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16511 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16512 oldUserId, userId, uss)); 16513 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16514 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16515 } 16516 16517 if (needStart) { 16518 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16519 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16520 | Intent.FLAG_RECEIVER_FOREGROUND); 16521 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16522 broadcastIntentLocked(null, null, intent, 16523 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16524 false, false, MY_PID, Process.SYSTEM_UID, userId); 16525 } 16526 16527 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16528 if (userId != UserHandle.USER_OWNER) { 16529 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16530 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16531 broadcastIntentLocked(null, null, intent, null, 16532 new IIntentReceiver.Stub() { 16533 public void performReceive(Intent intent, int resultCode, 16534 String data, Bundle extras, boolean ordered, 16535 boolean sticky, int sendingUser) { 16536 userInitialized(uss, userId); 16537 } 16538 }, 0, null, null, null, AppOpsManager.OP_NONE, 16539 true, false, MY_PID, Process.SYSTEM_UID, 16540 userId); 16541 uss.initializing = true; 16542 } else { 16543 getUserManagerLocked().makeInitialized(userInfo.id); 16544 } 16545 } 16546 16547 if (foreground) { 16548 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16549 if (homeInFront) { 16550 startHomeActivityLocked(userId); 16551 } else { 16552 mStackSupervisor.resumeTopActivitiesLocked(); 16553 } 16554 EventLogTags.writeAmSwitchUser(userId); 16555 getUserManagerLocked().userForeground(userId); 16556 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16557 } else { 16558 mStackSupervisor.startBackgroundUserLocked(userId, uss); 16559 } 16560 16561 if (needStart) { 16562 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16563 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16564 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16565 broadcastIntentLocked(null, null, intent, 16566 null, new IIntentReceiver.Stub() { 16567 @Override 16568 public void performReceive(Intent intent, int resultCode, String data, 16569 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16570 throws RemoteException { 16571 } 16572 }, 0, null, null, 16573 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16574 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16575 } 16576 } 16577 } finally { 16578 Binder.restoreCallingIdentity(ident); 16579 } 16580 16581 return true; 16582 } 16583 16584 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16585 long ident = Binder.clearCallingIdentity(); 16586 try { 16587 Intent intent; 16588 if (oldUserId >= 0) { 16589 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16590 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16591 | Intent.FLAG_RECEIVER_FOREGROUND); 16592 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16593 broadcastIntentLocked(null, null, intent, 16594 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16595 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16596 } 16597 if (newUserId >= 0) { 16598 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16599 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16600 | Intent.FLAG_RECEIVER_FOREGROUND); 16601 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16602 broadcastIntentLocked(null, null, intent, 16603 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16604 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16605 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16606 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16607 | Intent.FLAG_RECEIVER_FOREGROUND); 16608 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16609 broadcastIntentLocked(null, null, intent, 16610 null, null, 0, null, null, 16611 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16612 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16613 } 16614 } finally { 16615 Binder.restoreCallingIdentity(ident); 16616 } 16617 } 16618 16619 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16620 final int newUserId) { 16621 final int N = mUserSwitchObservers.beginBroadcast(); 16622 if (N > 0) { 16623 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16624 int mCount = 0; 16625 @Override 16626 public void sendResult(Bundle data) throws RemoteException { 16627 synchronized (ActivityManagerService.this) { 16628 if (mCurUserSwitchCallback == this) { 16629 mCount++; 16630 if (mCount == N) { 16631 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16632 } 16633 } 16634 } 16635 } 16636 }; 16637 synchronized (this) { 16638 uss.switching = true; 16639 mCurUserSwitchCallback = callback; 16640 } 16641 for (int i=0; i<N; i++) { 16642 try { 16643 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16644 newUserId, callback); 16645 } catch (RemoteException e) { 16646 } 16647 } 16648 } else { 16649 synchronized (this) { 16650 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16651 } 16652 } 16653 mUserSwitchObservers.finishBroadcast(); 16654 } 16655 16656 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16657 synchronized (this) { 16658 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16659 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16660 } 16661 } 16662 16663 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16664 mCurUserSwitchCallback = null; 16665 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16666 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16667 oldUserId, newUserId, uss)); 16668 } 16669 16670 void userInitialized(UserStartedState uss, int newUserId) { 16671 completeSwitchAndInitalize(uss, newUserId, true, false); 16672 } 16673 16674 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16675 completeSwitchAndInitalize(uss, newUserId, false, true); 16676 } 16677 16678 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16679 boolean clearInitializing, boolean clearSwitching) { 16680 boolean unfrozen = false; 16681 synchronized (this) { 16682 if (clearInitializing) { 16683 uss.initializing = false; 16684 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16685 } 16686 if (clearSwitching) { 16687 uss.switching = false; 16688 } 16689 if (!uss.switching && !uss.initializing) { 16690 mWindowManager.stopFreezingScreen(); 16691 unfrozen = true; 16692 } 16693 } 16694 if (unfrozen) { 16695 final int N = mUserSwitchObservers.beginBroadcast(); 16696 for (int i=0; i<N; i++) { 16697 try { 16698 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16699 } catch (RemoteException e) { 16700 } 16701 } 16702 mUserSwitchObservers.finishBroadcast(); 16703 } 16704 } 16705 16706 void scheduleStartProfilesLocked() { 16707 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16708 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16709 DateUtils.SECOND_IN_MILLIS); 16710 } 16711 } 16712 16713 void startProfilesLocked() { 16714 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16715 List<UserInfo> profiles = getUserManagerLocked().getProfiles( 16716 mCurrentUserId, false /* enabledOnly */); 16717 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16718 for (UserInfo user : profiles) { 16719 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16720 && user.id != mCurrentUserId) { 16721 toStart.add(user); 16722 } 16723 } 16724 final int n = toStart.size(); 16725 int i = 0; 16726 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16727 startUserInBackground(toStart.get(i).id); 16728 } 16729 if (i < n) { 16730 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16731 } 16732 } 16733 16734 void finishUserBoot(UserStartedState uss) { 16735 synchronized (this) { 16736 if (uss.mState == UserStartedState.STATE_BOOTING 16737 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16738 uss.mState = UserStartedState.STATE_RUNNING; 16739 final int userId = uss.mHandle.getIdentifier(); 16740 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16741 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16742 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16743 broadcastIntentLocked(null, null, intent, 16744 null, null, 0, null, null, 16745 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16746 true, false, MY_PID, Process.SYSTEM_UID, userId); 16747 } 16748 } 16749 } 16750 16751 void finishUserSwitch(UserStartedState uss) { 16752 synchronized (this) { 16753 finishUserBoot(uss); 16754 16755 startProfilesLocked(); 16756 16757 int num = mUserLru.size(); 16758 int i = 0; 16759 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16760 Integer oldUserId = mUserLru.get(i); 16761 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16762 if (oldUss == null) { 16763 // Shouldn't happen, but be sane if it does. 16764 mUserLru.remove(i); 16765 num--; 16766 continue; 16767 } 16768 if (oldUss.mState == UserStartedState.STATE_STOPPING 16769 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16770 // This user is already stopping, doesn't count. 16771 num--; 16772 i++; 16773 continue; 16774 } 16775 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16776 // Owner and current can't be stopped, but count as running. 16777 i++; 16778 continue; 16779 } 16780 // This is a user to be stopped. 16781 stopUserLocked(oldUserId, null); 16782 num--; 16783 i++; 16784 } 16785 } 16786 } 16787 16788 @Override 16789 public int stopUser(final int userId, final IStopUserCallback callback) { 16790 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16791 != PackageManager.PERMISSION_GRANTED) { 16792 String msg = "Permission Denial: switchUser() from pid=" 16793 + Binder.getCallingPid() 16794 + ", uid=" + Binder.getCallingUid() 16795 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16796 Slog.w(TAG, msg); 16797 throw new SecurityException(msg); 16798 } 16799 if (userId <= 0) { 16800 throw new IllegalArgumentException("Can't stop primary user " + userId); 16801 } 16802 synchronized (this) { 16803 return stopUserLocked(userId, callback); 16804 } 16805 } 16806 16807 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16808 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16809 if (mCurrentUserId == userId) { 16810 return ActivityManager.USER_OP_IS_CURRENT; 16811 } 16812 16813 final UserStartedState uss = mStartedUsers.get(userId); 16814 if (uss == null) { 16815 // User is not started, nothing to do... but we do need to 16816 // callback if requested. 16817 if (callback != null) { 16818 mHandler.post(new Runnable() { 16819 @Override 16820 public void run() { 16821 try { 16822 callback.userStopped(userId); 16823 } catch (RemoteException e) { 16824 } 16825 } 16826 }); 16827 } 16828 return ActivityManager.USER_OP_SUCCESS; 16829 } 16830 16831 if (callback != null) { 16832 uss.mStopCallbacks.add(callback); 16833 } 16834 16835 if (uss.mState != UserStartedState.STATE_STOPPING 16836 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16837 uss.mState = UserStartedState.STATE_STOPPING; 16838 updateStartedUserArrayLocked(); 16839 16840 long ident = Binder.clearCallingIdentity(); 16841 try { 16842 // We are going to broadcast ACTION_USER_STOPPING and then 16843 // once that is done send a final ACTION_SHUTDOWN and then 16844 // stop the user. 16845 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16846 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16847 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16848 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16849 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16850 // This is the result receiver for the final shutdown broadcast. 16851 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16852 @Override 16853 public void performReceive(Intent intent, int resultCode, String data, 16854 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16855 finishUserStop(uss); 16856 } 16857 }; 16858 // This is the result receiver for the initial stopping broadcast. 16859 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16860 @Override 16861 public void performReceive(Intent intent, int resultCode, String data, 16862 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16863 // On to the next. 16864 synchronized (ActivityManagerService.this) { 16865 if (uss.mState != UserStartedState.STATE_STOPPING) { 16866 // Whoops, we are being started back up. Abort, abort! 16867 return; 16868 } 16869 uss.mState = UserStartedState.STATE_SHUTDOWN; 16870 } 16871 mSystemServiceManager.stopUser(userId); 16872 broadcastIntentLocked(null, null, shutdownIntent, 16873 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16874 true, false, MY_PID, Process.SYSTEM_UID, userId); 16875 } 16876 }; 16877 // Kick things off. 16878 broadcastIntentLocked(null, null, stoppingIntent, 16879 null, stoppingReceiver, 0, null, null, 16880 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16881 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16882 } finally { 16883 Binder.restoreCallingIdentity(ident); 16884 } 16885 } 16886 16887 return ActivityManager.USER_OP_SUCCESS; 16888 } 16889 16890 void finishUserStop(UserStartedState uss) { 16891 final int userId = uss.mHandle.getIdentifier(); 16892 boolean stopped; 16893 ArrayList<IStopUserCallback> callbacks; 16894 synchronized (this) { 16895 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16896 if (mStartedUsers.get(userId) != uss) { 16897 stopped = false; 16898 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16899 stopped = false; 16900 } else { 16901 stopped = true; 16902 // User can no longer run. 16903 mStartedUsers.remove(userId); 16904 mUserLru.remove(Integer.valueOf(userId)); 16905 updateStartedUserArrayLocked(); 16906 16907 // Clean up all state and processes associated with the user. 16908 // Kill all the processes for the user. 16909 forceStopUserLocked(userId, "finish user"); 16910 } 16911 } 16912 16913 for (int i=0; i<callbacks.size(); i++) { 16914 try { 16915 if (stopped) callbacks.get(i).userStopped(userId); 16916 else callbacks.get(i).userStopAborted(userId); 16917 } catch (RemoteException e) { 16918 } 16919 } 16920 16921 if (stopped) { 16922 mSystemServiceManager.cleanupUser(userId); 16923 synchronized (this) { 16924 mStackSupervisor.removeUserLocked(userId); 16925 } 16926 } 16927 } 16928 16929 @Override 16930 public UserInfo getCurrentUser() { 16931 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16932 != PackageManager.PERMISSION_GRANTED) && ( 16933 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16934 != PackageManager.PERMISSION_GRANTED)) { 16935 String msg = "Permission Denial: getCurrentUser() from pid=" 16936 + Binder.getCallingPid() 16937 + ", uid=" + Binder.getCallingUid() 16938 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16939 Slog.w(TAG, msg); 16940 throw new SecurityException(msg); 16941 } 16942 synchronized (this) { 16943 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16944 } 16945 } 16946 16947 int getCurrentUserIdLocked() { 16948 return mCurrentUserId; 16949 } 16950 16951 @Override 16952 public boolean isUserRunning(int userId, boolean orStopped) { 16953 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16954 != PackageManager.PERMISSION_GRANTED) { 16955 String msg = "Permission Denial: isUserRunning() from pid=" 16956 + Binder.getCallingPid() 16957 + ", uid=" + Binder.getCallingUid() 16958 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16959 Slog.w(TAG, msg); 16960 throw new SecurityException(msg); 16961 } 16962 synchronized (this) { 16963 return isUserRunningLocked(userId, orStopped); 16964 } 16965 } 16966 16967 boolean isUserRunningLocked(int userId, boolean orStopped) { 16968 UserStartedState state = mStartedUsers.get(userId); 16969 if (state == null) { 16970 return false; 16971 } 16972 if (orStopped) { 16973 return true; 16974 } 16975 return state.mState != UserStartedState.STATE_STOPPING 16976 && state.mState != UserStartedState.STATE_SHUTDOWN; 16977 } 16978 16979 @Override 16980 public int[] getRunningUserIds() { 16981 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16982 != PackageManager.PERMISSION_GRANTED) { 16983 String msg = "Permission Denial: isUserRunning() from pid=" 16984 + Binder.getCallingPid() 16985 + ", uid=" + Binder.getCallingUid() 16986 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16987 Slog.w(TAG, msg); 16988 throw new SecurityException(msg); 16989 } 16990 synchronized (this) { 16991 return mStartedUserArray; 16992 } 16993 } 16994 16995 private void updateStartedUserArrayLocked() { 16996 int num = 0; 16997 for (int i=0; i<mStartedUsers.size(); i++) { 16998 UserStartedState uss = mStartedUsers.valueAt(i); 16999 // This list does not include stopping users. 17000 if (uss.mState != UserStartedState.STATE_STOPPING 17001 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17002 num++; 17003 } 17004 } 17005 mStartedUserArray = new int[num]; 17006 num = 0; 17007 for (int i=0; i<mStartedUsers.size(); i++) { 17008 UserStartedState uss = mStartedUsers.valueAt(i); 17009 if (uss.mState != UserStartedState.STATE_STOPPING 17010 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 17011 mStartedUserArray[num] = mStartedUsers.keyAt(i); 17012 num++; 17013 } 17014 } 17015 } 17016 17017 @Override 17018 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 17019 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 17020 != PackageManager.PERMISSION_GRANTED) { 17021 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 17022 + Binder.getCallingPid() 17023 + ", uid=" + Binder.getCallingUid() 17024 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 17025 Slog.w(TAG, msg); 17026 throw new SecurityException(msg); 17027 } 17028 17029 mUserSwitchObservers.register(observer); 17030 } 17031 17032 @Override 17033 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 17034 mUserSwitchObservers.unregister(observer); 17035 } 17036 17037 private boolean userExists(int userId) { 17038 if (userId == 0) { 17039 return true; 17040 } 17041 UserManagerService ums = getUserManagerLocked(); 17042 return ums != null ? (ums.getUserInfo(userId) != null) : false; 17043 } 17044 17045 int[] getUsersLocked() { 17046 UserManagerService ums = getUserManagerLocked(); 17047 return ums != null ? ums.getUserIds() : new int[] { 0 }; 17048 } 17049 17050 UserManagerService getUserManagerLocked() { 17051 if (mUserManager == null) { 17052 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 17053 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 17054 } 17055 return mUserManager; 17056 } 17057 17058 private int applyUserId(int uid, int userId) { 17059 return UserHandle.getUid(userId, uid); 17060 } 17061 17062 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17063 if (info == null) return null; 17064 ApplicationInfo newInfo = new ApplicationInfo(info); 17065 newInfo.uid = applyUserId(info.uid, userId); 17066 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17067 + info.packageName; 17068 return newInfo; 17069 } 17070 17071 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17072 if (aInfo == null 17073 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17074 return aInfo; 17075 } 17076 17077 ActivityInfo info = new ActivityInfo(aInfo); 17078 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17079 return info; 17080 } 17081 17082 private final class LocalService extends ActivityManagerInternal { 17083 @Override 17084 public void goingToSleep() { 17085 ActivityManagerService.this.goingToSleep(); 17086 } 17087 17088 @Override 17089 public void wakingUp() { 17090 ActivityManagerService.this.wakingUp(); 17091 } 17092 } 17093} 17094