ActivityManagerService.java revision d00f47402cb886a43a3448128bdcd9dd2f348a2a
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.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack 1019 private UserManagerService mUserManager; 1020 1021 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1022 final ProcessRecord mApp; 1023 final int mPid; 1024 final IApplicationThread mAppThread; 1025 1026 AppDeathRecipient(ProcessRecord app, int pid, 1027 IApplicationThread thread) { 1028 if (localLOGV) Slog.v( 1029 TAG, "New death recipient " + this 1030 + " for thread " + thread.asBinder()); 1031 mApp = app; 1032 mPid = pid; 1033 mAppThread = thread; 1034 } 1035 1036 @Override 1037 public void binderDied() { 1038 if (localLOGV) Slog.v( 1039 TAG, "Death received in " + this 1040 + " for thread " + mAppThread.asBinder()); 1041 synchronized(ActivityManagerService.this) { 1042 appDiedLocked(mApp, mPid, mAppThread); 1043 } 1044 } 1045 } 1046 1047 static final int SHOW_ERROR_MSG = 1; 1048 static final int SHOW_NOT_RESPONDING_MSG = 2; 1049 static final int SHOW_FACTORY_ERROR_MSG = 3; 1050 static final int UPDATE_CONFIGURATION_MSG = 4; 1051 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1052 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1053 static final int SERVICE_TIMEOUT_MSG = 12; 1054 static final int UPDATE_TIME_ZONE = 13; 1055 static final int SHOW_UID_ERROR_MSG = 14; 1056 static final int IM_FEELING_LUCKY_MSG = 15; 1057 static final int PROC_START_TIMEOUT_MSG = 20; 1058 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1059 static final int KILL_APPLICATION_MSG = 22; 1060 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1061 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1062 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1063 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1064 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1065 static final int CLEAR_DNS_CACHE_MSG = 28; 1066 static final int UPDATE_HTTP_PROXY_MSG = 29; 1067 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1068 static final int DISPATCH_PROCESSES_CHANGED = 31; 1069 static final int DISPATCH_PROCESS_DIED = 32; 1070 static final int REPORT_MEM_USAGE_MSG = 33; 1071 static final int REPORT_USER_SWITCH_MSG = 34; 1072 static final int CONTINUE_USER_SWITCH_MSG = 35; 1073 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1074 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1075 static final int PERSIST_URI_GRANTS_MSG = 38; 1076 static final int REQUEST_ALL_PSS_MSG = 39; 1077 static final int START_RELATED_USERS_MSG = 40; 1078 static final int UPDATE_TIME = 41; 1079 1080 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1081 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1082 static final int FIRST_COMPAT_MODE_MSG = 300; 1083 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1084 1085 AlertDialog mUidAlert; 1086 CompatModeDialog mCompatModeDialog; 1087 long mLastMemUsageReportTime = 0; 1088 1089 /** 1090 * Flag whether the current user is a "monkey", i.e. whether 1091 * the UI is driven by a UI automation tool. 1092 */ 1093 private boolean mUserIsMonkey; 1094 1095 final ServiceThread mHandlerThread; 1096 final MainHandler mHandler; 1097 1098 final class MainHandler extends Handler { 1099 public MainHandler(Looper looper) { 1100 super(looper, null, true); 1101 } 1102 1103 @Override 1104 public void handleMessage(Message msg) { 1105 switch (msg.what) { 1106 case SHOW_ERROR_MSG: { 1107 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1108 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1109 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1110 synchronized (ActivityManagerService.this) { 1111 ProcessRecord proc = (ProcessRecord)data.get("app"); 1112 AppErrorResult res = (AppErrorResult) data.get("result"); 1113 if (proc != null && proc.crashDialog != null) { 1114 Slog.e(TAG, "App already has crash dialog: " + proc); 1115 if (res != null) { 1116 res.set(0); 1117 } 1118 return; 1119 } 1120 if (!showBackground && UserHandle.getAppId(proc.uid) 1121 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1122 && proc.pid != MY_PID) { 1123 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1124 if (res != null) { 1125 res.set(0); 1126 } 1127 return; 1128 } 1129 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1130 Dialog d = new AppErrorDialog(mContext, 1131 ActivityManagerService.this, res, proc); 1132 d.show(); 1133 proc.crashDialog = d; 1134 } else { 1135 // The device is asleep, so just pretend that the user 1136 // saw a crash dialog and hit "force quit". 1137 if (res != null) { 1138 res.set(0); 1139 } 1140 } 1141 } 1142 1143 ensureBootCompleted(); 1144 } break; 1145 case SHOW_NOT_RESPONDING_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1148 ProcessRecord proc = (ProcessRecord)data.get("app"); 1149 if (proc != null && proc.anrDialog != null) { 1150 Slog.e(TAG, "App already has anr dialog: " + proc); 1151 return; 1152 } 1153 1154 Intent intent = new Intent("android.intent.action.ANR"); 1155 if (!mProcessesReady) { 1156 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1157 | Intent.FLAG_RECEIVER_FOREGROUND); 1158 } 1159 broadcastIntentLocked(null, null, intent, 1160 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1161 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1162 1163 if (mShowDialogs) { 1164 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1165 mContext, proc, (ActivityRecord)data.get("activity"), 1166 msg.arg1 != 0); 1167 d.show(); 1168 proc.anrDialog = d; 1169 } else { 1170 // Just kill the app if there is no dialog to be shown. 1171 killAppAtUsersRequest(proc, null); 1172 } 1173 } 1174 1175 ensureBootCompleted(); 1176 } break; 1177 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1178 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1179 synchronized (ActivityManagerService.this) { 1180 ProcessRecord proc = (ProcessRecord) data.get("app"); 1181 if (proc == null) { 1182 Slog.e(TAG, "App not found when showing strict mode dialog."); 1183 break; 1184 } 1185 if (proc.crashDialog != null) { 1186 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1187 return; 1188 } 1189 AppErrorResult res = (AppErrorResult) data.get("result"); 1190 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1191 Dialog d = new StrictModeViolationDialog(mContext, 1192 ActivityManagerService.this, res, proc); 1193 d.show(); 1194 proc.crashDialog = d; 1195 } else { 1196 // The device is asleep, so just pretend that the user 1197 // saw a crash dialog and hit "force quit". 1198 res.set(0); 1199 } 1200 } 1201 ensureBootCompleted(); 1202 } break; 1203 case SHOW_FACTORY_ERROR_MSG: { 1204 Dialog d = new FactoryErrorDialog( 1205 mContext, msg.getData().getCharSequence("msg")); 1206 d.show(); 1207 ensureBootCompleted(); 1208 } break; 1209 case UPDATE_CONFIGURATION_MSG: { 1210 final ContentResolver resolver = mContext.getContentResolver(); 1211 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1212 } break; 1213 case GC_BACKGROUND_PROCESSES_MSG: { 1214 synchronized (ActivityManagerService.this) { 1215 performAppGcsIfAppropriateLocked(); 1216 } 1217 } break; 1218 case WAIT_FOR_DEBUGGER_MSG: { 1219 synchronized (ActivityManagerService.this) { 1220 ProcessRecord app = (ProcessRecord)msg.obj; 1221 if (msg.arg1 != 0) { 1222 if (!app.waitedForDebugger) { 1223 Dialog d = new AppWaitingForDebuggerDialog( 1224 ActivityManagerService.this, 1225 mContext, app); 1226 app.waitDialog = d; 1227 app.waitedForDebugger = true; 1228 d.show(); 1229 } 1230 } else { 1231 if (app.waitDialog != null) { 1232 app.waitDialog.dismiss(); 1233 app.waitDialog = null; 1234 } 1235 } 1236 } 1237 } break; 1238 case SERVICE_TIMEOUT_MSG: { 1239 if (mDidDexOpt) { 1240 mDidDexOpt = false; 1241 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1242 nmsg.obj = msg.obj; 1243 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1244 return; 1245 } 1246 mServices.serviceTimeout((ProcessRecord)msg.obj); 1247 } break; 1248 case UPDATE_TIME_ZONE: { 1249 synchronized (ActivityManagerService.this) { 1250 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1251 ProcessRecord r = mLruProcesses.get(i); 1252 if (r.thread != null) { 1253 try { 1254 r.thread.updateTimeZone(); 1255 } catch (RemoteException ex) { 1256 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1257 } 1258 } 1259 } 1260 } 1261 } break; 1262 case CLEAR_DNS_CACHE_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1265 ProcessRecord r = mLruProcesses.get(i); 1266 if (r.thread != null) { 1267 try { 1268 r.thread.clearDnsCache(); 1269 } catch (RemoteException ex) { 1270 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1271 } 1272 } 1273 } 1274 } 1275 } break; 1276 case UPDATE_HTTP_PROXY_MSG: { 1277 ProxyProperties proxy = (ProxyProperties)msg.obj; 1278 String host = ""; 1279 String port = ""; 1280 String exclList = ""; 1281 String pacFileUrl = null; 1282 if (proxy != null) { 1283 host = proxy.getHost(); 1284 port = Integer.toString(proxy.getPort()); 1285 exclList = proxy.getExclusionList(); 1286 pacFileUrl = proxy.getPacFileUrl(); 1287 } 1288 synchronized (ActivityManagerService.this) { 1289 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1290 ProcessRecord r = mLruProcesses.get(i); 1291 if (r.thread != null) { 1292 try { 1293 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1294 } catch (RemoteException ex) { 1295 Slog.w(TAG, "Failed to update http proxy for: " + 1296 r.info.processName); 1297 } 1298 } 1299 } 1300 } 1301 } break; 1302 case SHOW_UID_ERROR_MSG: { 1303 String title = "System UIDs Inconsistent"; 1304 String text = "UIDs on the system are inconsistent, you need to wipe your" 1305 + " data partition or your device will be unstable."; 1306 Log.e(TAG, title + ": " + text); 1307 if (mShowDialogs) { 1308 // XXX This is a temporary dialog, no need to localize. 1309 AlertDialog d = new BaseErrorDialog(mContext); 1310 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1311 d.setCancelable(false); 1312 d.setTitle(title); 1313 d.setMessage(text); 1314 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1315 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1316 mUidAlert = d; 1317 d.show(); 1318 } 1319 } break; 1320 case IM_FEELING_LUCKY_MSG: { 1321 if (mUidAlert != null) { 1322 mUidAlert.dismiss(); 1323 mUidAlert = null; 1324 } 1325 } break; 1326 case PROC_START_TIMEOUT_MSG: { 1327 if (mDidDexOpt) { 1328 mDidDexOpt = false; 1329 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1330 nmsg.obj = msg.obj; 1331 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1332 return; 1333 } 1334 ProcessRecord app = (ProcessRecord)msg.obj; 1335 synchronized (ActivityManagerService.this) { 1336 processStartTimedOutLocked(app); 1337 } 1338 } break; 1339 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1340 synchronized (ActivityManagerService.this) { 1341 doPendingActivityLaunchesLocked(true); 1342 } 1343 } break; 1344 case KILL_APPLICATION_MSG: { 1345 synchronized (ActivityManagerService.this) { 1346 int appid = msg.arg1; 1347 boolean restart = (msg.arg2 == 1); 1348 Bundle bundle = (Bundle)msg.obj; 1349 String pkg = bundle.getString("pkg"); 1350 String reason = bundle.getString("reason"); 1351 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1352 false, UserHandle.USER_ALL, reason); 1353 } 1354 } break; 1355 case FINALIZE_PENDING_INTENT_MSG: { 1356 ((PendingIntentRecord)msg.obj).completeFinalize(); 1357 } break; 1358 case POST_HEAVY_NOTIFICATION_MSG: { 1359 INotificationManager inm = NotificationManager.getService(); 1360 if (inm == null) { 1361 return; 1362 } 1363 1364 ActivityRecord root = (ActivityRecord)msg.obj; 1365 ProcessRecord process = root.app; 1366 if (process == null) { 1367 return; 1368 } 1369 1370 try { 1371 Context context = mContext.createPackageContext(process.info.packageName, 0); 1372 String text = mContext.getString(R.string.heavy_weight_notification, 1373 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1374 Notification notification = new Notification(); 1375 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1376 notification.when = 0; 1377 notification.flags = Notification.FLAG_ONGOING_EVENT; 1378 notification.tickerText = text; 1379 notification.defaults = 0; // please be quiet 1380 notification.sound = null; 1381 notification.vibrate = null; 1382 notification.setLatestEventInfo(context, text, 1383 mContext.getText(R.string.heavy_weight_notification_detail), 1384 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1385 PendingIntent.FLAG_CANCEL_CURRENT, null, 1386 new UserHandle(root.userId))); 1387 1388 try { 1389 int[] outId = new int[1]; 1390 inm.enqueueNotificationWithTag("android", "android", null, 1391 R.string.heavy_weight_notification, 1392 notification, outId, root.userId); 1393 } catch (RuntimeException e) { 1394 Slog.w(ActivityManagerService.TAG, 1395 "Error showing notification for heavy-weight app", e); 1396 } catch (RemoteException e) { 1397 } 1398 } catch (NameNotFoundException e) { 1399 Slog.w(TAG, "Unable to create context for heavy notification", e); 1400 } 1401 } break; 1402 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1403 INotificationManager inm = NotificationManager.getService(); 1404 if (inm == null) { 1405 return; 1406 } 1407 try { 1408 inm.cancelNotificationWithTag("android", null, 1409 R.string.heavy_weight_notification, msg.arg1); 1410 } catch (RuntimeException e) { 1411 Slog.w(ActivityManagerService.TAG, 1412 "Error canceling notification for service", e); 1413 } catch (RemoteException e) { 1414 } 1415 } break; 1416 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1417 synchronized (ActivityManagerService.this) { 1418 checkExcessivePowerUsageLocked(true); 1419 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1420 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1421 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1422 } 1423 } break; 1424 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 ActivityRecord ar = (ActivityRecord)msg.obj; 1427 if (mCompatModeDialog != null) { 1428 if (mCompatModeDialog.mAppInfo.packageName.equals( 1429 ar.info.applicationInfo.packageName)) { 1430 return; 1431 } 1432 mCompatModeDialog.dismiss(); 1433 mCompatModeDialog = null; 1434 } 1435 if (ar != null && false) { 1436 if (mCompatModePackages.getPackageAskCompatModeLocked( 1437 ar.packageName)) { 1438 int mode = mCompatModePackages.computeCompatModeLocked( 1439 ar.info.applicationInfo); 1440 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1441 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1442 mCompatModeDialog = new CompatModeDialog( 1443 ActivityManagerService.this, mContext, 1444 ar.info.applicationInfo); 1445 mCompatModeDialog.show(); 1446 } 1447 } 1448 } 1449 } 1450 break; 1451 } 1452 case DISPATCH_PROCESSES_CHANGED: { 1453 dispatchProcessesChanged(); 1454 break; 1455 } 1456 case DISPATCH_PROCESS_DIED: { 1457 final int pid = msg.arg1; 1458 final int uid = msg.arg2; 1459 dispatchProcessDied(pid, uid); 1460 break; 1461 } 1462 case REPORT_MEM_USAGE_MSG: { 1463 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1464 Thread thread = new Thread() { 1465 @Override public void run() { 1466 final SparseArray<ProcessMemInfo> infoMap 1467 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1468 for (int i=0, N=memInfos.size(); i<N; i++) { 1469 ProcessMemInfo mi = memInfos.get(i); 1470 infoMap.put(mi.pid, mi); 1471 } 1472 updateCpuStatsNow(); 1473 synchronized (mProcessCpuThread) { 1474 final int N = mProcessCpuTracker.countStats(); 1475 for (int i=0; i<N; i++) { 1476 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1477 if (st.vsize > 0) { 1478 long pss = Debug.getPss(st.pid, null); 1479 if (pss > 0) { 1480 if (infoMap.indexOfKey(st.pid) < 0) { 1481 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1482 ProcessList.NATIVE_ADJ, -1, "native", null); 1483 mi.pss = pss; 1484 memInfos.add(mi); 1485 } 1486 } 1487 } 1488 } 1489 } 1490 1491 long totalPss = 0; 1492 for (int i=0, N=memInfos.size(); i<N; i++) { 1493 ProcessMemInfo mi = memInfos.get(i); 1494 if (mi.pss == 0) { 1495 mi.pss = Debug.getPss(mi.pid, null); 1496 } 1497 totalPss += mi.pss; 1498 } 1499 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1500 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1501 if (lhs.oomAdj != rhs.oomAdj) { 1502 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1503 } 1504 if (lhs.pss != rhs.pss) { 1505 return lhs.pss < rhs.pss ? 1 : -1; 1506 } 1507 return 0; 1508 } 1509 }); 1510 1511 StringBuilder tag = new StringBuilder(128); 1512 StringBuilder stack = new StringBuilder(128); 1513 tag.append("Low on memory -- "); 1514 appendMemBucket(tag, totalPss, "total", false); 1515 appendMemBucket(stack, totalPss, "total", true); 1516 1517 StringBuilder logBuilder = new StringBuilder(1024); 1518 logBuilder.append("Low on memory:\n"); 1519 1520 boolean firstLine = true; 1521 int lastOomAdj = Integer.MIN_VALUE; 1522 for (int i=0, N=memInfos.size(); i<N; i++) { 1523 ProcessMemInfo mi = memInfos.get(i); 1524 1525 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1526 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1527 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1528 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1529 if (lastOomAdj != mi.oomAdj) { 1530 lastOomAdj = mi.oomAdj; 1531 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1532 tag.append(" / "); 1533 } 1534 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1535 if (firstLine) { 1536 stack.append(":"); 1537 firstLine = false; 1538 } 1539 stack.append("\n\t at "); 1540 } else { 1541 stack.append("$"); 1542 } 1543 } else { 1544 tag.append(" "); 1545 stack.append("$"); 1546 } 1547 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1548 appendMemBucket(tag, mi.pss, mi.name, false); 1549 } 1550 appendMemBucket(stack, mi.pss, mi.name, true); 1551 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1552 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1553 stack.append("("); 1554 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1555 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1556 stack.append(DUMP_MEM_OOM_LABEL[k]); 1557 stack.append(":"); 1558 stack.append(DUMP_MEM_OOM_ADJ[k]); 1559 } 1560 } 1561 stack.append(")"); 1562 } 1563 } 1564 1565 logBuilder.append(" "); 1566 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1567 logBuilder.append(' '); 1568 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1569 logBuilder.append(' '); 1570 ProcessList.appendRamKb(logBuilder, mi.pss); 1571 logBuilder.append(" kB: "); 1572 logBuilder.append(mi.name); 1573 logBuilder.append(" ("); 1574 logBuilder.append(mi.pid); 1575 logBuilder.append(") "); 1576 logBuilder.append(mi.adjType); 1577 logBuilder.append('\n'); 1578 if (mi.adjReason != null) { 1579 logBuilder.append(" "); 1580 logBuilder.append(mi.adjReason); 1581 logBuilder.append('\n'); 1582 } 1583 } 1584 1585 logBuilder.append(" "); 1586 ProcessList.appendRamKb(logBuilder, totalPss); 1587 logBuilder.append(" kB: TOTAL\n"); 1588 1589 long[] infos = new long[Debug.MEMINFO_COUNT]; 1590 Debug.getMemInfo(infos); 1591 logBuilder.append(" MemInfo: "); 1592 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1593 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1594 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1595 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1596 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1597 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1598 logBuilder.append(" ZRAM: "); 1599 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1600 logBuilder.append(" kB RAM, "); 1601 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1602 logBuilder.append(" kB swap total, "); 1603 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1604 logBuilder.append(" kB swap free\n"); 1605 } 1606 Slog.i(TAG, logBuilder.toString()); 1607 1608 StringBuilder dropBuilder = new StringBuilder(1024); 1609 /* 1610 StringWriter oomSw = new StringWriter(); 1611 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1612 StringWriter catSw = new StringWriter(); 1613 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1614 String[] emptyArgs = new String[] { }; 1615 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1616 oomPw.flush(); 1617 String oomString = oomSw.toString(); 1618 */ 1619 dropBuilder.append(stack); 1620 dropBuilder.append('\n'); 1621 dropBuilder.append('\n'); 1622 dropBuilder.append(logBuilder); 1623 dropBuilder.append('\n'); 1624 /* 1625 dropBuilder.append(oomString); 1626 dropBuilder.append('\n'); 1627 */ 1628 StringWriter catSw = new StringWriter(); 1629 synchronized (ActivityManagerService.this) { 1630 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1631 String[] emptyArgs = new String[] { }; 1632 catPw.println(); 1633 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1634 catPw.println(); 1635 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1636 false, false, null); 1637 catPw.println(); 1638 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1639 catPw.flush(); 1640 } 1641 dropBuilder.append(catSw.toString()); 1642 addErrorToDropBox("lowmem", null, "system_server", null, 1643 null, tag.toString(), dropBuilder.toString(), null, null); 1644 //Slog.i(TAG, "Sent to dropbox:"); 1645 //Slog.i(TAG, dropBuilder.toString()); 1646 synchronized (ActivityManagerService.this) { 1647 long now = SystemClock.uptimeMillis(); 1648 if (mLastMemUsageReportTime < now) { 1649 mLastMemUsageReportTime = now; 1650 } 1651 } 1652 } 1653 }; 1654 thread.start(); 1655 break; 1656 } 1657 case REPORT_USER_SWITCH_MSG: { 1658 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1659 break; 1660 } 1661 case CONTINUE_USER_SWITCH_MSG: { 1662 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1663 break; 1664 } 1665 case USER_SWITCH_TIMEOUT_MSG: { 1666 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1667 break; 1668 } 1669 case IMMERSIVE_MODE_LOCK_MSG: { 1670 final boolean nextState = (msg.arg1 != 0); 1671 if (mUpdateLock.isHeld() != nextState) { 1672 if (DEBUG_IMMERSIVE) { 1673 final ActivityRecord r = (ActivityRecord) msg.obj; 1674 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1675 } 1676 if (nextState) { 1677 mUpdateLock.acquire(); 1678 } else { 1679 mUpdateLock.release(); 1680 } 1681 } 1682 break; 1683 } 1684 case PERSIST_URI_GRANTS_MSG: { 1685 writeGrantedUriPermissions(); 1686 break; 1687 } 1688 case REQUEST_ALL_PSS_MSG: { 1689 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1690 break; 1691 } 1692 case START_RELATED_USERS_MSG: { 1693 synchronized (ActivityManagerService.this) { 1694 startRelatedUsersLocked(); 1695 } 1696 break; 1697 } 1698 case UPDATE_TIME: { 1699 synchronized (ActivityManagerService.this) { 1700 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1701 ProcessRecord r = mLruProcesses.get(i); 1702 if (r.thread != null) { 1703 try { 1704 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1705 } catch (RemoteException ex) { 1706 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1707 } 1708 } 1709 } 1710 } 1711 break; 1712 } 1713 } 1714 } 1715 }; 1716 1717 static final int COLLECT_PSS_BG_MSG = 1; 1718 1719 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1720 @Override 1721 public void handleMessage(Message msg) { 1722 switch (msg.what) { 1723 case COLLECT_PSS_BG_MSG: { 1724 int i=0, num=0; 1725 long start = SystemClock.uptimeMillis(); 1726 long[] tmp = new long[1]; 1727 do { 1728 ProcessRecord proc; 1729 int procState; 1730 int pid; 1731 synchronized (ActivityManagerService.this) { 1732 if (i >= mPendingPssProcesses.size()) { 1733 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1734 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1735 mPendingPssProcesses.clear(); 1736 return; 1737 } 1738 proc = mPendingPssProcesses.get(i); 1739 procState = proc.pssProcState; 1740 if (proc.thread != null && procState == proc.setProcState) { 1741 pid = proc.pid; 1742 } else { 1743 proc = null; 1744 pid = 0; 1745 } 1746 i++; 1747 } 1748 if (proc != null) { 1749 long pss = Debug.getPss(pid, tmp); 1750 synchronized (ActivityManagerService.this) { 1751 if (proc.thread != null && proc.setProcState == procState 1752 && proc.pid == pid) { 1753 num++; 1754 proc.lastPssTime = SystemClock.uptimeMillis(); 1755 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1756 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1757 + ": " + pss + " lastPss=" + proc.lastPss 1758 + " state=" + ProcessList.makeProcStateString(procState)); 1759 if (proc.initialIdlePss == 0) { 1760 proc.initialIdlePss = pss; 1761 } 1762 proc.lastPss = pss; 1763 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1764 proc.lastCachedPss = pss; 1765 } 1766 } 1767 } 1768 } 1769 } while (true); 1770 } 1771 } 1772 } 1773 }; 1774 1775 public void setSystemProcess() { 1776 try { 1777 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1778 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1779 ServiceManager.addService("meminfo", new MemBinder(this)); 1780 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1781 ServiceManager.addService("dbinfo", new DbBinder(this)); 1782 if (MONITOR_CPU_USAGE) { 1783 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1784 } 1785 ServiceManager.addService("permission", new PermissionController(this)); 1786 1787 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1788 "android", STOCK_PM_FLAGS); 1789 mSystemThread.installSystemApplicationInfo(info); 1790 1791 synchronized (this) { 1792 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1793 app.persistent = true; 1794 app.pid = MY_PID; 1795 app.maxAdj = ProcessList.SYSTEM_ADJ; 1796 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1797 mProcessNames.put(app.processName, app.uid, app); 1798 synchronized (mPidsSelfLocked) { 1799 mPidsSelfLocked.put(app.pid, app); 1800 } 1801 updateLruProcessLocked(app, false, null); 1802 updateOomAdjLocked(); 1803 } 1804 } catch (PackageManager.NameNotFoundException e) { 1805 throw new RuntimeException( 1806 "Unable to find android system package", e); 1807 } 1808 } 1809 1810 public void setWindowManager(WindowManagerService wm) { 1811 mWindowManager = wm; 1812 mStackSupervisor.setWindowManager(wm); 1813 } 1814 1815 public void startObservingNativeCrashes() { 1816 final NativeCrashListener ncl = new NativeCrashListener(this); 1817 ncl.start(); 1818 } 1819 1820 public IAppOpsService getAppOpsService() { 1821 return mAppOpsService; 1822 } 1823 1824 static class MemBinder extends Binder { 1825 ActivityManagerService mActivityManagerService; 1826 MemBinder(ActivityManagerService activityManagerService) { 1827 mActivityManagerService = activityManagerService; 1828 } 1829 1830 @Override 1831 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1832 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1833 != PackageManager.PERMISSION_GRANTED) { 1834 pw.println("Permission Denial: can't dump meminfo from from pid=" 1835 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1836 + " without permission " + android.Manifest.permission.DUMP); 1837 return; 1838 } 1839 1840 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1841 } 1842 } 1843 1844 static class GraphicsBinder extends Binder { 1845 ActivityManagerService mActivityManagerService; 1846 GraphicsBinder(ActivityManagerService activityManagerService) { 1847 mActivityManagerService = activityManagerService; 1848 } 1849 1850 @Override 1851 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1852 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1853 != PackageManager.PERMISSION_GRANTED) { 1854 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1855 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1856 + " without permission " + android.Manifest.permission.DUMP); 1857 return; 1858 } 1859 1860 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1861 } 1862 } 1863 1864 static class DbBinder extends Binder { 1865 ActivityManagerService mActivityManagerService; 1866 DbBinder(ActivityManagerService activityManagerService) { 1867 mActivityManagerService = activityManagerService; 1868 } 1869 1870 @Override 1871 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1872 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1873 != PackageManager.PERMISSION_GRANTED) { 1874 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1875 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1876 + " without permission " + android.Manifest.permission.DUMP); 1877 return; 1878 } 1879 1880 mActivityManagerService.dumpDbInfo(fd, pw, args); 1881 } 1882 } 1883 1884 static class CpuBinder extends Binder { 1885 ActivityManagerService mActivityManagerService; 1886 CpuBinder(ActivityManagerService activityManagerService) { 1887 mActivityManagerService = activityManagerService; 1888 } 1889 1890 @Override 1891 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1892 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1893 != PackageManager.PERMISSION_GRANTED) { 1894 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1895 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1896 + " without permission " + android.Manifest.permission.DUMP); 1897 return; 1898 } 1899 1900 synchronized (mActivityManagerService.mProcessCpuThread) { 1901 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1902 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1903 SystemClock.uptimeMillis())); 1904 } 1905 } 1906 } 1907 1908 public static final class Lifecycle extends SystemService { 1909 private final ActivityManagerService mService; 1910 1911 public Lifecycle(Context context) { 1912 super(context); 1913 mService = new ActivityManagerService(context); 1914 } 1915 1916 @Override 1917 public void onStart() { 1918 mService.start(); 1919 } 1920 1921 public ActivityManagerService getService() { 1922 return mService; 1923 } 1924 } 1925 1926 // Note: This method is invoked on the main thread but may need to attach various 1927 // handlers to other threads. So take care to be explicit about the looper. 1928 public ActivityManagerService(Context systemContext) { 1929 mContext = systemContext; 1930 mFactoryTest = FactoryTest.getMode(); 1931 mSystemThread = ActivityThread.currentActivityThread(); 1932 1933 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1934 1935 mHandlerThread = new ServiceThread(TAG, 1936 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1937 mHandlerThread.start(); 1938 mHandler = new MainHandler(mHandlerThread.getLooper()); 1939 1940 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1941 "foreground", BROADCAST_FG_TIMEOUT, false); 1942 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1943 "background", BROADCAST_BG_TIMEOUT, true); 1944 mBroadcastQueues[0] = mFgBroadcastQueue; 1945 mBroadcastQueues[1] = mBgBroadcastQueue; 1946 1947 mServices = new ActiveServices(this); 1948 mProviderMap = new ProviderMap(this); 1949 1950 // TODO: Move creation of battery stats service outside of activity manager service. 1951 File dataDir = Environment.getDataDirectory(); 1952 File systemDir = new File(dataDir, "system"); 1953 systemDir.mkdirs(); 1954 mBatteryStatsService = new BatteryStatsService(new File( 1955 systemDir, "batterystats.bin").toString(), mHandler); 1956 mBatteryStatsService.getActiveStatistics().readLocked(); 1957 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1958 mOnBattery = DEBUG_POWER ? true 1959 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1960 mBatteryStatsService.getActiveStatistics().setCallback(this); 1961 1962 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1963 1964 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1965 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1966 1967 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1968 1969 // User 0 is the first and only user that runs at boot. 1970 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1971 mUserLru.add(Integer.valueOf(0)); 1972 updateStartedUserArrayLocked(); 1973 1974 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1975 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1976 1977 mConfiguration.setToDefaults(); 1978 mConfiguration.setLocale(Locale.getDefault()); 1979 1980 mConfigurationSeq = mConfiguration.seq = 1; 1981 mProcessCpuTracker.init(); 1982 1983 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1984 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1985 mStackSupervisor = new ActivityStackSupervisor(this); 1986 1987 mProcessCpuThread = new Thread("CpuTracker") { 1988 @Override 1989 public void run() { 1990 while (true) { 1991 try { 1992 try { 1993 synchronized(this) { 1994 final long now = SystemClock.uptimeMillis(); 1995 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1996 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1997 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1998 // + ", write delay=" + nextWriteDelay); 1999 if (nextWriteDelay < nextCpuDelay) { 2000 nextCpuDelay = nextWriteDelay; 2001 } 2002 if (nextCpuDelay > 0) { 2003 mProcessCpuMutexFree.set(true); 2004 this.wait(nextCpuDelay); 2005 } 2006 } 2007 } catch (InterruptedException e) { 2008 } 2009 updateCpuStatsNow(); 2010 } catch (Exception e) { 2011 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2012 } 2013 } 2014 } 2015 }; 2016 2017 Watchdog.getInstance().addMonitor(this); 2018 Watchdog.getInstance().addThread(mHandler); 2019 } 2020 2021 private void start() { 2022 mProcessCpuThread.start(); 2023 2024 mBatteryStatsService.publish(mContext); 2025 mUsageStatsService.publish(mContext); 2026 mAppOpsService.publish(mContext); 2027 startRunning(null, null, null, null); 2028 } 2029 2030 @Override 2031 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2032 throws RemoteException { 2033 if (code == SYSPROPS_TRANSACTION) { 2034 // We need to tell all apps about the system property change. 2035 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2036 synchronized(this) { 2037 final int NP = mProcessNames.getMap().size(); 2038 for (int ip=0; ip<NP; ip++) { 2039 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2040 final int NA = apps.size(); 2041 for (int ia=0; ia<NA; ia++) { 2042 ProcessRecord app = apps.valueAt(ia); 2043 if (app.thread != null) { 2044 procs.add(app.thread.asBinder()); 2045 } 2046 } 2047 } 2048 } 2049 2050 int N = procs.size(); 2051 for (int i=0; i<N; i++) { 2052 Parcel data2 = Parcel.obtain(); 2053 try { 2054 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2055 } catch (RemoteException e) { 2056 } 2057 data2.recycle(); 2058 } 2059 } 2060 try { 2061 return super.onTransact(code, data, reply, flags); 2062 } catch (RuntimeException e) { 2063 // The activity manager only throws security exceptions, so let's 2064 // log all others. 2065 if (!(e instanceof SecurityException)) { 2066 Slog.wtf(TAG, "Activity Manager Crash", e); 2067 } 2068 throw e; 2069 } 2070 } 2071 2072 void updateCpuStats() { 2073 final long now = SystemClock.uptimeMillis(); 2074 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2075 return; 2076 } 2077 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2078 synchronized (mProcessCpuThread) { 2079 mProcessCpuThread.notify(); 2080 } 2081 } 2082 } 2083 2084 void updateCpuStatsNow() { 2085 synchronized (mProcessCpuThread) { 2086 mProcessCpuMutexFree.set(false); 2087 final long now = SystemClock.uptimeMillis(); 2088 boolean haveNewCpuStats = false; 2089 2090 if (MONITOR_CPU_USAGE && 2091 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2092 mLastCpuTime.set(now); 2093 haveNewCpuStats = true; 2094 mProcessCpuTracker.update(); 2095 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2096 //Slog.i(TAG, "Total CPU usage: " 2097 // + mProcessCpu.getTotalCpuPercent() + "%"); 2098 2099 // Slog the cpu usage if the property is set. 2100 if ("true".equals(SystemProperties.get("events.cpu"))) { 2101 int user = mProcessCpuTracker.getLastUserTime(); 2102 int system = mProcessCpuTracker.getLastSystemTime(); 2103 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2104 int irq = mProcessCpuTracker.getLastIrqTime(); 2105 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2106 int idle = mProcessCpuTracker.getLastIdleTime(); 2107 2108 int total = user + system + iowait + irq + softIrq + idle; 2109 if (total == 0) total = 1; 2110 2111 EventLog.writeEvent(EventLogTags.CPU, 2112 ((user+system+iowait+irq+softIrq) * 100) / total, 2113 (user * 100) / total, 2114 (system * 100) / total, 2115 (iowait * 100) / total, 2116 (irq * 100) / total, 2117 (softIrq * 100) / total); 2118 } 2119 } 2120 2121 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2122 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2123 synchronized(bstats) { 2124 synchronized(mPidsSelfLocked) { 2125 if (haveNewCpuStats) { 2126 if (mOnBattery) { 2127 int perc = bstats.startAddingCpuLocked(); 2128 int totalUTime = 0; 2129 int totalSTime = 0; 2130 final int N = mProcessCpuTracker.countStats(); 2131 for (int i=0; i<N; i++) { 2132 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2133 if (!st.working) { 2134 continue; 2135 } 2136 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2137 int otherUTime = (st.rel_utime*perc)/100; 2138 int otherSTime = (st.rel_stime*perc)/100; 2139 totalUTime += otherUTime; 2140 totalSTime += otherSTime; 2141 if (pr != null) { 2142 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2143 if (ps == null || !ps.isActive()) { 2144 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2145 pr.info.uid, pr.processName); 2146 } 2147 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2148 st.rel_stime-otherSTime); 2149 ps.addSpeedStepTimes(cpuSpeedTimes); 2150 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2151 } else { 2152 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2153 if (ps == null || !ps.isActive()) { 2154 st.batteryStats = ps = bstats.getProcessStatsLocked( 2155 bstats.mapUid(st.uid), st.name); 2156 } 2157 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2158 st.rel_stime-otherSTime); 2159 ps.addSpeedStepTimes(cpuSpeedTimes); 2160 } 2161 } 2162 bstats.finishAddingCpuLocked(perc, totalUTime, 2163 totalSTime, cpuSpeedTimes); 2164 } 2165 } 2166 } 2167 2168 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2169 mLastWriteTime = now; 2170 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2171 } 2172 } 2173 } 2174 } 2175 2176 @Override 2177 public void batteryNeedsCpuUpdate() { 2178 updateCpuStatsNow(); 2179 } 2180 2181 @Override 2182 public void batteryPowerChanged(boolean onBattery) { 2183 // When plugging in, update the CPU stats first before changing 2184 // the plug state. 2185 updateCpuStatsNow(); 2186 synchronized (this) { 2187 synchronized(mPidsSelfLocked) { 2188 mOnBattery = DEBUG_POWER ? true : onBattery; 2189 } 2190 } 2191 } 2192 2193 /** 2194 * Initialize the application bind args. These are passed to each 2195 * process when the bindApplication() IPC is sent to the process. They're 2196 * lazily setup to make sure the services are running when they're asked for. 2197 */ 2198 private HashMap<String, IBinder> getCommonServicesLocked() { 2199 if (mAppBindArgs == null) { 2200 mAppBindArgs = new HashMap<String, IBinder>(); 2201 2202 // Setup the application init args 2203 mAppBindArgs.put("package", ServiceManager.getService("package")); 2204 mAppBindArgs.put("window", ServiceManager.getService("window")); 2205 mAppBindArgs.put(Context.ALARM_SERVICE, 2206 ServiceManager.getService(Context.ALARM_SERVICE)); 2207 } 2208 return mAppBindArgs; 2209 } 2210 2211 final void setFocusedActivityLocked(ActivityRecord r) { 2212 if (mFocusedActivity != r) { 2213 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2214 mFocusedActivity = r; 2215 mStackSupervisor.setFocusedStack(r); 2216 if (r != null) { 2217 mWindowManager.setFocusedApp(r.appToken, true); 2218 } 2219 applyUpdateLockStateLocked(r); 2220 } 2221 } 2222 2223 @Override 2224 public void setFocusedStack(int stackId) { 2225 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2226 synchronized (ActivityManagerService.this) { 2227 ActivityStack stack = mStackSupervisor.getStack(stackId); 2228 if (stack != null) { 2229 ActivityRecord r = stack.topRunningActivityLocked(null); 2230 if (r != null) { 2231 setFocusedActivityLocked(r); 2232 } 2233 } 2234 } 2235 } 2236 2237 @Override 2238 public void notifyActivityDrawn(IBinder token) { 2239 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2240 synchronized (this) { 2241 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2242 if (r != null) { 2243 r.task.stack.notifyActivityDrawnLocked(r); 2244 } 2245 } 2246 } 2247 2248 final void applyUpdateLockStateLocked(ActivityRecord r) { 2249 // Modifications to the UpdateLock state are done on our handler, outside 2250 // the activity manager's locks. The new state is determined based on the 2251 // state *now* of the relevant activity record. The object is passed to 2252 // the handler solely for logging detail, not to be consulted/modified. 2253 final boolean nextState = r != null && r.immersive; 2254 mHandler.sendMessage( 2255 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2256 } 2257 2258 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2259 Message msg = Message.obtain(); 2260 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2261 msg.obj = r.task.askedCompatMode ? null : r; 2262 mHandler.sendMessage(msg); 2263 } 2264 2265 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2266 String what, Object obj, ProcessRecord srcApp) { 2267 app.lastActivityTime = now; 2268 2269 if (app.activities.size() > 0) { 2270 // Don't want to touch dependent processes that are hosting activities. 2271 return index; 2272 } 2273 2274 int lrui = mLruProcesses.lastIndexOf(app); 2275 if (lrui < 0) { 2276 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2277 + what + " " + obj + " from " + srcApp); 2278 return index; 2279 } 2280 2281 if (lrui >= index) { 2282 // Don't want to cause this to move dependent processes *back* in the 2283 // list as if they were less frequently used. 2284 return index; 2285 } 2286 2287 if (lrui >= mLruProcessActivityStart) { 2288 // Don't want to touch dependent processes that are hosting activities. 2289 return index; 2290 } 2291 2292 mLruProcesses.remove(lrui); 2293 if (index > 0) { 2294 index--; 2295 } 2296 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2297 + " in LRU list: " + app); 2298 mLruProcesses.add(index, app); 2299 return index; 2300 } 2301 2302 final void removeLruProcessLocked(ProcessRecord app) { 2303 int lrui = mLruProcesses.lastIndexOf(app); 2304 if (lrui >= 0) { 2305 if (lrui <= mLruProcessActivityStart) { 2306 mLruProcessActivityStart--; 2307 } 2308 if (lrui <= mLruProcessServiceStart) { 2309 mLruProcessServiceStart--; 2310 } 2311 mLruProcesses.remove(lrui); 2312 } 2313 } 2314 2315 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2316 ProcessRecord client) { 2317 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2318 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2319 if (!activityChange && hasActivity) { 2320 // The process has activties, so we are only going to allow activity-based 2321 // adjustments move it. It should be kept in the front of the list with other 2322 // processes that have activities, and we don't want those to change their 2323 // order except due to activity operations. 2324 return; 2325 } 2326 2327 mLruSeq++; 2328 final long now = SystemClock.uptimeMillis(); 2329 app.lastActivityTime = now; 2330 2331 // First a quick reject: if the app is already at the position we will 2332 // put it, then there is nothing to do. 2333 if (hasActivity) { 2334 final int N = mLruProcesses.size(); 2335 if (N > 0 && mLruProcesses.get(N-1) == app) { 2336 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2337 return; 2338 } 2339 } else { 2340 if (mLruProcessServiceStart > 0 2341 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2342 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2343 return; 2344 } 2345 } 2346 2347 int lrui = mLruProcesses.lastIndexOf(app); 2348 2349 if (app.persistent && lrui >= 0) { 2350 // We don't care about the position of persistent processes, as long as 2351 // they are in the list. 2352 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2353 return; 2354 } 2355 2356 /* In progress: compute new position first, so we can avoid doing work 2357 if the process is not actually going to move. Not yet working. 2358 int addIndex; 2359 int nextIndex; 2360 boolean inActivity = false, inService = false; 2361 if (hasActivity) { 2362 // Process has activities, put it at the very tipsy-top. 2363 addIndex = mLruProcesses.size(); 2364 nextIndex = mLruProcessServiceStart; 2365 inActivity = true; 2366 } else if (hasService) { 2367 // Process has services, put it at the top of the service list. 2368 addIndex = mLruProcessActivityStart; 2369 nextIndex = mLruProcessServiceStart; 2370 inActivity = true; 2371 inService = true; 2372 } else { 2373 // Process not otherwise of interest, it goes to the top of the non-service area. 2374 addIndex = mLruProcessServiceStart; 2375 if (client != null) { 2376 int clientIndex = mLruProcesses.lastIndexOf(client); 2377 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2378 + app); 2379 if (clientIndex >= 0 && addIndex > clientIndex) { 2380 addIndex = clientIndex; 2381 } 2382 } 2383 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2384 } 2385 2386 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2387 + mLruProcessActivityStart + "): " + app); 2388 */ 2389 2390 if (lrui >= 0) { 2391 if (lrui < mLruProcessActivityStart) { 2392 mLruProcessActivityStart--; 2393 } 2394 if (lrui < mLruProcessServiceStart) { 2395 mLruProcessServiceStart--; 2396 } 2397 /* 2398 if (addIndex > lrui) { 2399 addIndex--; 2400 } 2401 if (nextIndex > lrui) { 2402 nextIndex--; 2403 } 2404 */ 2405 mLruProcesses.remove(lrui); 2406 } 2407 2408 /* 2409 mLruProcesses.add(addIndex, app); 2410 if (inActivity) { 2411 mLruProcessActivityStart++; 2412 } 2413 if (inService) { 2414 mLruProcessActivityStart++; 2415 } 2416 */ 2417 2418 int nextIndex; 2419 if (hasActivity) { 2420 final int N = mLruProcesses.size(); 2421 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2422 // Process doesn't have activities, but has clients with 2423 // activities... move it up, but one below the top (the top 2424 // should always have a real activity). 2425 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2426 mLruProcesses.add(N-1, app); 2427 // To keep it from spamming the LRU list (by making a bunch of clients), 2428 // we will push down any other entries owned by the app. 2429 final int uid = app.info.uid; 2430 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2431 ProcessRecord subProc = mLruProcesses.get(i); 2432 if (subProc.info.uid == uid) { 2433 // We want to push this one down the list. If the process after 2434 // it is for the same uid, however, don't do so, because we don't 2435 // want them internally to be re-ordered. 2436 if (mLruProcesses.get(i-1).info.uid != uid) { 2437 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2438 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2439 ProcessRecord tmp = mLruProcesses.get(i); 2440 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2441 mLruProcesses.set(i-1, tmp); 2442 i--; 2443 } 2444 } else { 2445 // A gap, we can stop here. 2446 break; 2447 } 2448 } 2449 } else { 2450 // Process has activities, put it at the very tipsy-top. 2451 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2452 mLruProcesses.add(app); 2453 } 2454 nextIndex = mLruProcessServiceStart; 2455 } else if (hasService) { 2456 // Process has services, put it at the top of the service list. 2457 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2458 mLruProcesses.add(mLruProcessActivityStart, app); 2459 nextIndex = mLruProcessServiceStart; 2460 mLruProcessActivityStart++; 2461 } else { 2462 // Process not otherwise of interest, it goes to the top of the non-service area. 2463 int index = mLruProcessServiceStart; 2464 if (client != null) { 2465 // If there is a client, don't allow the process to be moved up higher 2466 // in the list than that client. 2467 int clientIndex = mLruProcesses.lastIndexOf(client); 2468 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2469 + " when updating " + app); 2470 if (clientIndex <= lrui) { 2471 // Don't allow the client index restriction to push it down farther in the 2472 // list than it already is. 2473 clientIndex = lrui; 2474 } 2475 if (clientIndex >= 0 && index > clientIndex) { 2476 index = clientIndex; 2477 } 2478 } 2479 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2480 mLruProcesses.add(index, app); 2481 nextIndex = index-1; 2482 mLruProcessActivityStart++; 2483 mLruProcessServiceStart++; 2484 } 2485 2486 // If the app is currently using a content provider or service, 2487 // bump those processes as well. 2488 for (int j=app.connections.size()-1; j>=0; j--) { 2489 ConnectionRecord cr = app.connections.valueAt(j); 2490 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2491 && cr.binding.service.app != null 2492 && cr.binding.service.app.lruSeq != mLruSeq 2493 && !cr.binding.service.app.persistent) { 2494 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2495 "service connection", cr, app); 2496 } 2497 } 2498 for (int j=app.conProviders.size()-1; j>=0; j--) { 2499 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2500 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2501 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2502 "provider reference", cpr, app); 2503 } 2504 } 2505 } 2506 2507 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2508 if (uid == Process.SYSTEM_UID) { 2509 // The system gets to run in any process. If there are multiple 2510 // processes with the same uid, just pick the first (this 2511 // should never happen). 2512 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2513 if (procs == null) return null; 2514 final int N = procs.size(); 2515 for (int i = 0; i < N; i++) { 2516 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2517 } 2518 } 2519 ProcessRecord proc = mProcessNames.get(processName, uid); 2520 if (false && proc != null && !keepIfLarge 2521 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2522 && proc.lastCachedPss >= 4000) { 2523 // Turn this condition on to cause killing to happen regularly, for testing. 2524 if (proc.baseProcessTracker != null) { 2525 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2526 } 2527 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2528 + "k from cached"); 2529 } else if (proc != null && !keepIfLarge 2530 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2531 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2532 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2533 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2534 if (proc.baseProcessTracker != null) { 2535 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2536 } 2537 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2538 + "k from cached"); 2539 } 2540 } 2541 return proc; 2542 } 2543 2544 void ensurePackageDexOpt(String packageName) { 2545 IPackageManager pm = AppGlobals.getPackageManager(); 2546 try { 2547 if (pm.performDexOpt(packageName)) { 2548 mDidDexOpt = true; 2549 } 2550 } catch (RemoteException e) { 2551 } 2552 } 2553 2554 boolean isNextTransitionForward() { 2555 int transit = mWindowManager.getPendingAppTransition(); 2556 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2557 || transit == AppTransition.TRANSIT_TASK_OPEN 2558 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2559 } 2560 2561 final ProcessRecord startProcessLocked(String processName, 2562 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2563 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2564 boolean isolated, boolean keepIfLarge) { 2565 ProcessRecord app; 2566 if (!isolated) { 2567 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2568 } else { 2569 // If this is an isolated process, it can't re-use an existing process. 2570 app = null; 2571 } 2572 // We don't have to do anything more if: 2573 // (1) There is an existing application record; and 2574 // (2) The caller doesn't think it is dead, OR there is no thread 2575 // object attached to it so we know it couldn't have crashed; and 2576 // (3) There is a pid assigned to it, so it is either starting or 2577 // already running. 2578 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2579 + " app=" + app + " knownToBeDead=" + knownToBeDead 2580 + " thread=" + (app != null ? app.thread : null) 2581 + " pid=" + (app != null ? app.pid : -1)); 2582 if (app != null && app.pid > 0) { 2583 if (!knownToBeDead || app.thread == null) { 2584 // We already have the app running, or are waiting for it to 2585 // come up (we have a pid but not yet its thread), so keep it. 2586 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2587 // If this is a new package in the process, add the package to the list 2588 app.addPackage(info.packageName, mProcessStats); 2589 return app; 2590 } 2591 2592 // An application record is attached to a previous process, 2593 // clean it up now. 2594 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2595 handleAppDiedLocked(app, true, true); 2596 } 2597 2598 String hostingNameStr = hostingName != null 2599 ? hostingName.flattenToShortString() : null; 2600 2601 if (!isolated) { 2602 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2603 // If we are in the background, then check to see if this process 2604 // is bad. If so, we will just silently fail. 2605 if (mBadProcesses.get(info.processName, info.uid) != null) { 2606 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2607 + "/" + info.processName); 2608 return null; 2609 } 2610 } else { 2611 // When the user is explicitly starting a process, then clear its 2612 // crash count so that we won't make it bad until they see at 2613 // least one crash dialog again, and make the process good again 2614 // if it had been bad. 2615 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2616 + "/" + info.processName); 2617 mProcessCrashTimes.remove(info.processName, info.uid); 2618 if (mBadProcesses.get(info.processName, info.uid) != null) { 2619 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2620 UserHandle.getUserId(info.uid), info.uid, 2621 info.processName); 2622 mBadProcesses.remove(info.processName, info.uid); 2623 if (app != null) { 2624 app.bad = false; 2625 } 2626 } 2627 } 2628 } 2629 2630 if (app == null) { 2631 app = newProcessRecordLocked(info, processName, isolated); 2632 if (app == null) { 2633 Slog.w(TAG, "Failed making new process record for " 2634 + processName + "/" + info.uid + " isolated=" + isolated); 2635 return null; 2636 } 2637 mProcessNames.put(processName, app.uid, app); 2638 if (isolated) { 2639 mIsolatedProcesses.put(app.uid, app); 2640 } 2641 } else { 2642 // If this is a new package in the process, add the package to the list 2643 app.addPackage(info.packageName, mProcessStats); 2644 } 2645 2646 // If the system is not ready yet, then hold off on starting this 2647 // process until it is. 2648 if (!mProcessesReady 2649 && !isAllowedWhileBooting(info) 2650 && !allowWhileBooting) { 2651 if (!mProcessesOnHold.contains(app)) { 2652 mProcessesOnHold.add(app); 2653 } 2654 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2655 return app; 2656 } 2657 2658 startProcessLocked(app, hostingType, hostingNameStr); 2659 return (app.pid != 0) ? app : null; 2660 } 2661 2662 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2663 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2664 } 2665 2666 private final void startProcessLocked(ProcessRecord app, 2667 String hostingType, String hostingNameStr) { 2668 if (app.pid > 0 && app.pid != MY_PID) { 2669 synchronized (mPidsSelfLocked) { 2670 mPidsSelfLocked.remove(app.pid); 2671 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2672 } 2673 app.setPid(0); 2674 } 2675 2676 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2677 "startProcessLocked removing on hold: " + app); 2678 mProcessesOnHold.remove(app); 2679 2680 updateCpuStats(); 2681 2682 try { 2683 int uid = app.uid; 2684 2685 int[] gids = null; 2686 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2687 if (!app.isolated) { 2688 int[] permGids = null; 2689 try { 2690 final PackageManager pm = mContext.getPackageManager(); 2691 permGids = pm.getPackageGids(app.info.packageName); 2692 2693 if (Environment.isExternalStorageEmulated()) { 2694 if (pm.checkPermission( 2695 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2696 app.info.packageName) == PERMISSION_GRANTED) { 2697 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2698 } else { 2699 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2700 } 2701 } 2702 } catch (PackageManager.NameNotFoundException e) { 2703 Slog.w(TAG, "Unable to retrieve gids", e); 2704 } 2705 2706 /* 2707 * Add shared application GID so applications can share some 2708 * resources like shared libraries 2709 */ 2710 if (permGids == null) { 2711 gids = new int[1]; 2712 } else { 2713 gids = new int[permGids.length + 1]; 2714 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2715 } 2716 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2717 } 2718 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2719 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2720 && mTopComponent != null 2721 && app.processName.equals(mTopComponent.getPackageName())) { 2722 uid = 0; 2723 } 2724 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2725 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2726 uid = 0; 2727 } 2728 } 2729 int debugFlags = 0; 2730 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2731 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2732 // Also turn on CheckJNI for debuggable apps. It's quite 2733 // awkward to turn on otherwise. 2734 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2735 } 2736 // Run the app in safe mode if its manifest requests so or the 2737 // system is booted in safe mode. 2738 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2739 Zygote.systemInSafeMode == true) { 2740 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2741 } 2742 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2743 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2744 } 2745 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2746 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2747 } 2748 if ("1".equals(SystemProperties.get("debug.assert"))) { 2749 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2750 } 2751 2752 // Start the process. It will either succeed and return a result containing 2753 // the PID of the new process, or else throw a RuntimeException. 2754 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2755 app.processName, uid, uid, gids, debugFlags, mountExternal, 2756 app.info.targetSdkVersion, app.info.seinfo, null); 2757 2758 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2759 synchronized (bs) { 2760 if (bs.isOnBattery()) { 2761 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2762 } 2763 } 2764 2765 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2766 UserHandle.getUserId(uid), startResult.pid, uid, 2767 app.processName, hostingType, 2768 hostingNameStr != null ? hostingNameStr : ""); 2769 2770 if (app.persistent) { 2771 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2772 } 2773 2774 StringBuilder buf = mStringBuilder; 2775 buf.setLength(0); 2776 buf.append("Start proc "); 2777 buf.append(app.processName); 2778 buf.append(" for "); 2779 buf.append(hostingType); 2780 if (hostingNameStr != null) { 2781 buf.append(" "); 2782 buf.append(hostingNameStr); 2783 } 2784 buf.append(": pid="); 2785 buf.append(startResult.pid); 2786 buf.append(" uid="); 2787 buf.append(uid); 2788 buf.append(" gids={"); 2789 if (gids != null) { 2790 for (int gi=0; gi<gids.length; gi++) { 2791 if (gi != 0) buf.append(", "); 2792 buf.append(gids[gi]); 2793 2794 } 2795 } 2796 buf.append("}"); 2797 Slog.i(TAG, buf.toString()); 2798 app.setPid(startResult.pid); 2799 app.usingWrapper = startResult.usingWrapper; 2800 app.removed = false; 2801 synchronized (mPidsSelfLocked) { 2802 this.mPidsSelfLocked.put(startResult.pid, app); 2803 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2804 msg.obj = app; 2805 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2806 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2807 } 2808 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2809 app.processName, app.info.uid); 2810 if (app.isolated) { 2811 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2812 } 2813 } catch (RuntimeException e) { 2814 // XXX do better error recovery. 2815 app.setPid(0); 2816 Slog.e(TAG, "Failure starting process " + app.processName, e); 2817 } 2818 } 2819 2820 void updateUsageStats(ActivityRecord component, boolean resumed) { 2821 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2822 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2823 if (resumed) { 2824 mUsageStatsService.noteResumeComponent(component.realActivity); 2825 synchronized (stats) { 2826 stats.noteActivityResumedLocked(component.app.uid); 2827 } 2828 } else { 2829 mUsageStatsService.notePauseComponent(component.realActivity); 2830 synchronized (stats) { 2831 stats.noteActivityPausedLocked(component.app.uid); 2832 } 2833 } 2834 } 2835 2836 Intent getHomeIntent() { 2837 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2838 intent.setComponent(mTopComponent); 2839 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2840 intent.addCategory(Intent.CATEGORY_HOME); 2841 } 2842 return intent; 2843 } 2844 2845 boolean startHomeActivityLocked(int userId) { 2846 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2847 && mTopAction == null) { 2848 // We are running in factory test mode, but unable to find 2849 // the factory test app, so just sit around displaying the 2850 // error message and don't try to start anything. 2851 return false; 2852 } 2853 Intent intent = getHomeIntent(); 2854 ActivityInfo aInfo = 2855 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2856 if (aInfo != null) { 2857 intent.setComponent(new ComponentName( 2858 aInfo.applicationInfo.packageName, aInfo.name)); 2859 // Don't do this if the home app is currently being 2860 // instrumented. 2861 aInfo = new ActivityInfo(aInfo); 2862 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2863 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2864 aInfo.applicationInfo.uid, true); 2865 if (app == null || app.instrumentationClass == null) { 2866 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2867 mStackSupervisor.startHomeActivity(intent, aInfo); 2868 } 2869 } 2870 2871 return true; 2872 } 2873 2874 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2875 ActivityInfo ai = null; 2876 ComponentName comp = intent.getComponent(); 2877 try { 2878 if (comp != null) { 2879 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2880 } else { 2881 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2882 intent, 2883 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2884 flags, userId); 2885 2886 if (info != null) { 2887 ai = info.activityInfo; 2888 } 2889 } 2890 } catch (RemoteException e) { 2891 // ignore 2892 } 2893 2894 return ai; 2895 } 2896 2897 /** 2898 * Starts the "new version setup screen" if appropriate. 2899 */ 2900 void startSetupActivityLocked() { 2901 // Only do this once per boot. 2902 if (mCheckedForSetup) { 2903 return; 2904 } 2905 2906 // We will show this screen if the current one is a different 2907 // version than the last one shown, and we are not running in 2908 // low-level factory test mode. 2909 final ContentResolver resolver = mContext.getContentResolver(); 2910 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2911 Settings.Global.getInt(resolver, 2912 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2913 mCheckedForSetup = true; 2914 2915 // See if we should be showing the platform update setup UI. 2916 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2917 List<ResolveInfo> ris = mContext.getPackageManager() 2918 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2919 2920 // We don't allow third party apps to replace this. 2921 ResolveInfo ri = null; 2922 for (int i=0; ris != null && i<ris.size(); i++) { 2923 if ((ris.get(i).activityInfo.applicationInfo.flags 2924 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2925 ri = ris.get(i); 2926 break; 2927 } 2928 } 2929 2930 if (ri != null) { 2931 String vers = ri.activityInfo.metaData != null 2932 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2933 : null; 2934 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2935 vers = ri.activityInfo.applicationInfo.metaData.getString( 2936 Intent.METADATA_SETUP_VERSION); 2937 } 2938 String lastVers = Settings.Secure.getString( 2939 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2940 if (vers != null && !vers.equals(lastVers)) { 2941 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2942 intent.setComponent(new ComponentName( 2943 ri.activityInfo.packageName, ri.activityInfo.name)); 2944 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2945 null, null, 0, 0, 0, null, 0, null, false, null, null); 2946 } 2947 } 2948 } 2949 } 2950 2951 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2952 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2953 } 2954 2955 void enforceNotIsolatedCaller(String caller) { 2956 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2957 throw new SecurityException("Isolated process not allowed to call " + caller); 2958 } 2959 } 2960 2961 @Override 2962 public int getFrontActivityScreenCompatMode() { 2963 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2964 synchronized (this) { 2965 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2966 } 2967 } 2968 2969 @Override 2970 public void setFrontActivityScreenCompatMode(int mode) { 2971 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2972 "setFrontActivityScreenCompatMode"); 2973 synchronized (this) { 2974 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2975 } 2976 } 2977 2978 @Override 2979 public int getPackageScreenCompatMode(String packageName) { 2980 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2981 synchronized (this) { 2982 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2983 } 2984 } 2985 2986 @Override 2987 public void setPackageScreenCompatMode(String packageName, int mode) { 2988 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2989 "setPackageScreenCompatMode"); 2990 synchronized (this) { 2991 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2992 } 2993 } 2994 2995 @Override 2996 public boolean getPackageAskScreenCompat(String packageName) { 2997 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2998 synchronized (this) { 2999 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3000 } 3001 } 3002 3003 @Override 3004 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3005 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3006 "setPackageAskScreenCompat"); 3007 synchronized (this) { 3008 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3009 } 3010 } 3011 3012 private void dispatchProcessesChanged() { 3013 int N; 3014 synchronized (this) { 3015 N = mPendingProcessChanges.size(); 3016 if (mActiveProcessChanges.length < N) { 3017 mActiveProcessChanges = new ProcessChangeItem[N]; 3018 } 3019 mPendingProcessChanges.toArray(mActiveProcessChanges); 3020 mAvailProcessChanges.addAll(mPendingProcessChanges); 3021 mPendingProcessChanges.clear(); 3022 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3023 } 3024 3025 int i = mProcessObservers.beginBroadcast(); 3026 while (i > 0) { 3027 i--; 3028 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3029 if (observer != null) { 3030 try { 3031 for (int j=0; j<N; j++) { 3032 ProcessChangeItem item = mActiveProcessChanges[j]; 3033 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3034 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3035 + item.pid + " uid=" + item.uid + ": " 3036 + item.foregroundActivities); 3037 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3038 item.foregroundActivities); 3039 } 3040 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3041 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3042 + item.pid + " uid=" + item.uid + ": " + item.importance); 3043 observer.onImportanceChanged(item.pid, item.uid, 3044 item.importance); 3045 } 3046 } 3047 } catch (RemoteException e) { 3048 } 3049 } 3050 } 3051 mProcessObservers.finishBroadcast(); 3052 } 3053 3054 private void dispatchProcessDied(int pid, int uid) { 3055 int i = mProcessObservers.beginBroadcast(); 3056 while (i > 0) { 3057 i--; 3058 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3059 if (observer != null) { 3060 try { 3061 observer.onProcessDied(pid, uid); 3062 } catch (RemoteException e) { 3063 } 3064 } 3065 } 3066 mProcessObservers.finishBroadcast(); 3067 } 3068 3069 final void doPendingActivityLaunchesLocked(boolean doResume) { 3070 final int N = mPendingActivityLaunches.size(); 3071 if (N <= 0) { 3072 return; 3073 } 3074 for (int i=0; i<N; i++) { 3075 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3076 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3077 doResume && i == (N-1), null); 3078 } 3079 mPendingActivityLaunches.clear(); 3080 } 3081 3082 @Override 3083 public final int startActivity(IApplicationThread caller, String callingPackage, 3084 Intent intent, String resolvedType, IBinder resultTo, 3085 String resultWho, int requestCode, int startFlags, 3086 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3087 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3088 resultWho, requestCode, 3089 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3090 } 3091 3092 @Override 3093 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3094 Intent intent, String resolvedType, IBinder resultTo, 3095 String resultWho, int requestCode, int startFlags, 3096 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3097 enforceNotIsolatedCaller("startActivity"); 3098 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3099 false, true, "startActivity", null); 3100 // TODO: Switch to user app stacks here. 3101 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3102 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3103 null, null, options, userId, null); 3104 } 3105 3106 @Override 3107 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3108 Intent intent, String resolvedType, IBinder resultTo, 3109 String resultWho, int requestCode, int startFlags, String profileFile, 3110 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3111 enforceNotIsolatedCaller("startActivityAndWait"); 3112 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3113 false, true, "startActivityAndWait", null); 3114 WaitResult res = new WaitResult(); 3115 // TODO: Switch to user app stacks here. 3116 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3117 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3118 res, null, options, UserHandle.getCallingUserId(), null); 3119 return res; 3120 } 3121 3122 @Override 3123 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3124 Intent intent, String resolvedType, IBinder resultTo, 3125 String resultWho, int requestCode, int startFlags, Configuration config, 3126 Bundle options, int userId) { 3127 enforceNotIsolatedCaller("startActivityWithConfig"); 3128 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3129 false, true, "startActivityWithConfig", null); 3130 // TODO: Switch to user app stacks here. 3131 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3132 resolvedType, resultTo, resultWho, requestCode, startFlags, 3133 null, null, null, config, options, userId, null); 3134 return ret; 3135 } 3136 3137 @Override 3138 public int startActivityIntentSender(IApplicationThread caller, 3139 IntentSender intent, Intent fillInIntent, String resolvedType, 3140 IBinder resultTo, String resultWho, int requestCode, 3141 int flagsMask, int flagsValues, Bundle options) { 3142 enforceNotIsolatedCaller("startActivityIntentSender"); 3143 // Refuse possible leaked file descriptors 3144 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3145 throw new IllegalArgumentException("File descriptors passed in Intent"); 3146 } 3147 3148 IIntentSender sender = intent.getTarget(); 3149 if (!(sender instanceof PendingIntentRecord)) { 3150 throw new IllegalArgumentException("Bad PendingIntent object"); 3151 } 3152 3153 PendingIntentRecord pir = (PendingIntentRecord)sender; 3154 3155 synchronized (this) { 3156 // If this is coming from the currently resumed activity, it is 3157 // effectively saying that app switches are allowed at this point. 3158 final ActivityStack stack = getFocusedStack(); 3159 if (stack.mResumedActivity != null && 3160 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3161 mAppSwitchesAllowedTime = 0; 3162 } 3163 } 3164 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3165 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3166 return ret; 3167 } 3168 3169 @Override 3170 public boolean startNextMatchingActivity(IBinder callingActivity, 3171 Intent intent, Bundle options) { 3172 // Refuse possible leaked file descriptors 3173 if (intent != null && intent.hasFileDescriptors() == true) { 3174 throw new IllegalArgumentException("File descriptors passed in Intent"); 3175 } 3176 3177 synchronized (this) { 3178 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3179 if (r == null) { 3180 ActivityOptions.abort(options); 3181 return false; 3182 } 3183 if (r.app == null || r.app.thread == null) { 3184 // The caller is not running... d'oh! 3185 ActivityOptions.abort(options); 3186 return false; 3187 } 3188 intent = new Intent(intent); 3189 // The caller is not allowed to change the data. 3190 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3191 // And we are resetting to find the next component... 3192 intent.setComponent(null); 3193 3194 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3195 3196 ActivityInfo aInfo = null; 3197 try { 3198 List<ResolveInfo> resolves = 3199 AppGlobals.getPackageManager().queryIntentActivities( 3200 intent, r.resolvedType, 3201 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3202 UserHandle.getCallingUserId()); 3203 3204 // Look for the original activity in the list... 3205 final int N = resolves != null ? resolves.size() : 0; 3206 for (int i=0; i<N; i++) { 3207 ResolveInfo rInfo = resolves.get(i); 3208 if (rInfo.activityInfo.packageName.equals(r.packageName) 3209 && rInfo.activityInfo.name.equals(r.info.name)) { 3210 // We found the current one... the next matching is 3211 // after it. 3212 i++; 3213 if (i<N) { 3214 aInfo = resolves.get(i).activityInfo; 3215 } 3216 if (debug) { 3217 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3218 + "/" + r.info.name); 3219 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3220 + "/" + aInfo.name); 3221 } 3222 break; 3223 } 3224 } 3225 } catch (RemoteException e) { 3226 } 3227 3228 if (aInfo == null) { 3229 // Nobody who is next! 3230 ActivityOptions.abort(options); 3231 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3232 return false; 3233 } 3234 3235 intent.setComponent(new ComponentName( 3236 aInfo.applicationInfo.packageName, aInfo.name)); 3237 intent.setFlags(intent.getFlags()&~( 3238 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3239 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3240 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3241 Intent.FLAG_ACTIVITY_NEW_TASK)); 3242 3243 // Okay now we need to start the new activity, replacing the 3244 // currently running activity. This is a little tricky because 3245 // we want to start the new one as if the current one is finished, 3246 // but not finish the current one first so that there is no flicker. 3247 // And thus... 3248 final boolean wasFinishing = r.finishing; 3249 r.finishing = true; 3250 3251 // Propagate reply information over to the new activity. 3252 final ActivityRecord resultTo = r.resultTo; 3253 final String resultWho = r.resultWho; 3254 final int requestCode = r.requestCode; 3255 r.resultTo = null; 3256 if (resultTo != null) { 3257 resultTo.removeResultsLocked(r, resultWho, requestCode); 3258 } 3259 3260 final long origId = Binder.clearCallingIdentity(); 3261 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3262 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3263 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3264 options, false, null, null); 3265 Binder.restoreCallingIdentity(origId); 3266 3267 r.finishing = wasFinishing; 3268 if (res != ActivityManager.START_SUCCESS) { 3269 return false; 3270 } 3271 return true; 3272 } 3273 } 3274 3275 final int startActivityInPackage(int uid, String callingPackage, 3276 Intent intent, String resolvedType, IBinder resultTo, 3277 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3278 IActivityContainer container) { 3279 3280 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3281 false, true, "startActivityInPackage", null); 3282 3283 // TODO: Switch to user app stacks here. 3284 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3285 resultTo, resultWho, requestCode, startFlags, 3286 null, null, null, null, options, userId, container); 3287 return ret; 3288 } 3289 3290 @Override 3291 public final int startActivities(IApplicationThread caller, String callingPackage, 3292 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3293 int userId) { 3294 enforceNotIsolatedCaller("startActivities"); 3295 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3296 false, true, "startActivity", null); 3297 // TODO: Switch to user app stacks here. 3298 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3299 resolvedTypes, resultTo, options, userId); 3300 return ret; 3301 } 3302 3303 final int startActivitiesInPackage(int uid, String callingPackage, 3304 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3305 Bundle options, int userId) { 3306 3307 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3308 false, true, "startActivityInPackage", null); 3309 // TODO: Switch to user app stacks here. 3310 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3311 resultTo, options, userId); 3312 return ret; 3313 } 3314 3315 final void addRecentTaskLocked(TaskRecord task) { 3316 int N = mRecentTasks.size(); 3317 // Quick case: check if the top-most recent task is the same. 3318 if (N > 0 && mRecentTasks.get(0) == task) { 3319 return; 3320 } 3321 // Remove any existing entries that are the same kind of task. 3322 final Intent intent = task.intent; 3323 final boolean document = intent != null && intent.isDocument(); 3324 for (int i=0; i<N; i++) { 3325 TaskRecord tr = mRecentTasks.get(i); 3326 if (task != tr) { 3327 if (task.userId != tr.userId) { 3328 continue; 3329 } 3330 final Intent trIntent = tr.intent; 3331 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3332 (intent == null || !intent.filterEquals(trIntent))) { 3333 continue; 3334 } 3335 if (document || trIntent != null && trIntent.isDocument()) { 3336 // Document tasks do not match other tasks. 3337 continue; 3338 } 3339 } 3340 3341 // Either task and tr are the same or, their affinities match or their intents match 3342 // and neither of them is a document. 3343 tr.disposeThumbnail(); 3344 mRecentTasks.remove(i); 3345 i--; 3346 N--; 3347 if (task.intent == null) { 3348 // If the new recent task we are adding is not fully 3349 // specified, then replace it with the existing recent task. 3350 task = tr; 3351 } 3352 } 3353 if (N >= MAX_RECENT_TASKS) { 3354 mRecentTasks.remove(N-1).disposeThumbnail(); 3355 } 3356 mRecentTasks.add(0, task); 3357 } 3358 3359 @Override 3360 public void reportActivityFullyDrawn(IBinder token) { 3361 synchronized (this) { 3362 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3363 if (r == null) { 3364 return; 3365 } 3366 r.reportFullyDrawnLocked(); 3367 } 3368 } 3369 3370 @Override 3371 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3372 synchronized (this) { 3373 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3374 if (r == null) { 3375 return; 3376 } 3377 final long origId = Binder.clearCallingIdentity(); 3378 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3379 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3380 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3381 if (config != null) { 3382 r.frozenBeforeDestroy = true; 3383 if (!updateConfigurationLocked(config, r, false, false)) { 3384 mStackSupervisor.resumeTopActivitiesLocked(); 3385 } 3386 } 3387 Binder.restoreCallingIdentity(origId); 3388 } 3389 } 3390 3391 @Override 3392 public int getRequestedOrientation(IBinder token) { 3393 synchronized (this) { 3394 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3395 if (r == null) { 3396 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3397 } 3398 return mWindowManager.getAppOrientation(r.appToken); 3399 } 3400 } 3401 3402 /** 3403 * This is the internal entry point for handling Activity.finish(). 3404 * 3405 * @param token The Binder token referencing the Activity we want to finish. 3406 * @param resultCode Result code, if any, from this Activity. 3407 * @param resultData Result data (Intent), if any, from this Activity. 3408 * 3409 * @return Returns true if the activity successfully finished, or false if it is still running. 3410 */ 3411 @Override 3412 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3413 // Refuse possible leaked file descriptors 3414 if (resultData != null && resultData.hasFileDescriptors() == true) { 3415 throw new IllegalArgumentException("File descriptors passed in Intent"); 3416 } 3417 3418 synchronized(this) { 3419 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3420 if (r == null) { 3421 return true; 3422 } 3423 if (mController != null) { 3424 // Find the first activity that is not finishing. 3425 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3426 if (next != null) { 3427 // ask watcher if this is allowed 3428 boolean resumeOK = true; 3429 try { 3430 resumeOK = mController.activityResuming(next.packageName); 3431 } catch (RemoteException e) { 3432 mController = null; 3433 Watchdog.getInstance().setActivityController(null); 3434 } 3435 3436 if (!resumeOK) { 3437 return false; 3438 } 3439 } 3440 } 3441 final long origId = Binder.clearCallingIdentity(); 3442 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3443 resultData, "app-request", true); 3444 Binder.restoreCallingIdentity(origId); 3445 return res; 3446 } 3447 } 3448 3449 @Override 3450 public final void finishHeavyWeightApp() { 3451 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3452 != PackageManager.PERMISSION_GRANTED) { 3453 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3454 + Binder.getCallingPid() 3455 + ", uid=" + Binder.getCallingUid() 3456 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3457 Slog.w(TAG, msg); 3458 throw new SecurityException(msg); 3459 } 3460 3461 synchronized(this) { 3462 if (mHeavyWeightProcess == null) { 3463 return; 3464 } 3465 3466 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3467 mHeavyWeightProcess.activities); 3468 for (int i=0; i<activities.size(); i++) { 3469 ActivityRecord r = activities.get(i); 3470 if (!r.finishing) { 3471 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3472 null, "finish-heavy", true); 3473 } 3474 } 3475 3476 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3477 mHeavyWeightProcess.userId, 0)); 3478 mHeavyWeightProcess = null; 3479 } 3480 } 3481 3482 @Override 3483 public void crashApplication(int uid, int initialPid, String packageName, 3484 String message) { 3485 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3486 != PackageManager.PERMISSION_GRANTED) { 3487 String msg = "Permission Denial: crashApplication() from pid=" 3488 + Binder.getCallingPid() 3489 + ", uid=" + Binder.getCallingUid() 3490 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3491 Slog.w(TAG, msg); 3492 throw new SecurityException(msg); 3493 } 3494 3495 synchronized(this) { 3496 ProcessRecord proc = null; 3497 3498 // Figure out which process to kill. We don't trust that initialPid 3499 // still has any relation to current pids, so must scan through the 3500 // list. 3501 synchronized (mPidsSelfLocked) { 3502 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3503 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3504 if (p.uid != uid) { 3505 continue; 3506 } 3507 if (p.pid == initialPid) { 3508 proc = p; 3509 break; 3510 } 3511 if (p.pkgList.containsKey(packageName)) { 3512 proc = p; 3513 } 3514 } 3515 } 3516 3517 if (proc == null) { 3518 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3519 + " initialPid=" + initialPid 3520 + " packageName=" + packageName); 3521 return; 3522 } 3523 3524 if (proc.thread != null) { 3525 if (proc.pid == Process.myPid()) { 3526 Log.w(TAG, "crashApplication: trying to crash self!"); 3527 return; 3528 } 3529 long ident = Binder.clearCallingIdentity(); 3530 try { 3531 proc.thread.scheduleCrash(message); 3532 } catch (RemoteException e) { 3533 } 3534 Binder.restoreCallingIdentity(ident); 3535 } 3536 } 3537 } 3538 3539 @Override 3540 public final void finishSubActivity(IBinder token, String resultWho, 3541 int requestCode) { 3542 synchronized(this) { 3543 final long origId = Binder.clearCallingIdentity(); 3544 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3545 if (r != null) { 3546 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3547 } 3548 Binder.restoreCallingIdentity(origId); 3549 } 3550 } 3551 3552 @Override 3553 public boolean finishActivityAffinity(IBinder token) { 3554 synchronized(this) { 3555 final long origId = Binder.clearCallingIdentity(); 3556 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3557 boolean res = false; 3558 if (r != null) { 3559 res = r.task.stack.finishActivityAffinityLocked(r); 3560 } 3561 Binder.restoreCallingIdentity(origId); 3562 return res; 3563 } 3564 } 3565 3566 @Override 3567 public boolean willActivityBeVisible(IBinder token) { 3568 synchronized(this) { 3569 ActivityStack stack = ActivityRecord.getStackLocked(token); 3570 if (stack != null) { 3571 return stack.willActivityBeVisibleLocked(token); 3572 } 3573 return false; 3574 } 3575 } 3576 3577 @Override 3578 public void overridePendingTransition(IBinder token, String packageName, 3579 int enterAnim, int exitAnim) { 3580 synchronized(this) { 3581 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3582 if (self == null) { 3583 return; 3584 } 3585 3586 final long origId = Binder.clearCallingIdentity(); 3587 3588 if (self.state == ActivityState.RESUMED 3589 || self.state == ActivityState.PAUSING) { 3590 mWindowManager.overridePendingAppTransition(packageName, 3591 enterAnim, exitAnim, null); 3592 } 3593 3594 Binder.restoreCallingIdentity(origId); 3595 } 3596 } 3597 3598 /** 3599 * Main function for removing an existing process from the activity manager 3600 * as a result of that process going away. Clears out all connections 3601 * to the process. 3602 */ 3603 private final void handleAppDiedLocked(ProcessRecord app, 3604 boolean restarting, boolean allowRestart) { 3605 int pid = app.pid; 3606 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3607 if (!restarting) { 3608 removeLruProcessLocked(app); 3609 if (pid > 0) { 3610 ProcessList.remove(pid); 3611 } 3612 } 3613 3614 if (mProfileProc == app) { 3615 clearProfilerLocked(); 3616 } 3617 3618 // Remove this application's activities from active lists. 3619 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3620 3621 app.activities.clear(); 3622 3623 if (app.instrumentationClass != null) { 3624 Slog.w(TAG, "Crash of app " + app.processName 3625 + " running instrumentation " + app.instrumentationClass); 3626 Bundle info = new Bundle(); 3627 info.putString("shortMsg", "Process crashed."); 3628 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3629 } 3630 3631 if (!restarting) { 3632 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3633 // If there was nothing to resume, and we are not already 3634 // restarting this process, but there is a visible activity that 3635 // is hosted by the process... then make sure all visible 3636 // activities are running, taking care of restarting this 3637 // process. 3638 if (hasVisibleActivities) { 3639 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3640 } 3641 } 3642 } 3643 } 3644 3645 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3646 IBinder threadBinder = thread.asBinder(); 3647 // Find the application record. 3648 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3649 ProcessRecord rec = mLruProcesses.get(i); 3650 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3651 return i; 3652 } 3653 } 3654 return -1; 3655 } 3656 3657 final ProcessRecord getRecordForAppLocked( 3658 IApplicationThread thread) { 3659 if (thread == null) { 3660 return null; 3661 } 3662 3663 int appIndex = getLRURecordIndexForAppLocked(thread); 3664 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3665 } 3666 3667 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3668 // If there are no longer any background processes running, 3669 // and the app that died was not running instrumentation, 3670 // then tell everyone we are now low on memory. 3671 boolean haveBg = false; 3672 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3673 ProcessRecord rec = mLruProcesses.get(i); 3674 if (rec.thread != null 3675 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3676 haveBg = true; 3677 break; 3678 } 3679 } 3680 3681 if (!haveBg) { 3682 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3683 if (doReport) { 3684 long now = SystemClock.uptimeMillis(); 3685 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3686 doReport = false; 3687 } else { 3688 mLastMemUsageReportTime = now; 3689 } 3690 } 3691 final ArrayList<ProcessMemInfo> memInfos 3692 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3693 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3694 long now = SystemClock.uptimeMillis(); 3695 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3696 ProcessRecord rec = mLruProcesses.get(i); 3697 if (rec == dyingProc || rec.thread == null) { 3698 continue; 3699 } 3700 if (doReport) { 3701 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3702 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3703 } 3704 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3705 // The low memory report is overriding any current 3706 // state for a GC request. Make sure to do 3707 // heavy/important/visible/foreground processes first. 3708 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3709 rec.lastRequestedGc = 0; 3710 } else { 3711 rec.lastRequestedGc = rec.lastLowMemory; 3712 } 3713 rec.reportLowMemory = true; 3714 rec.lastLowMemory = now; 3715 mProcessesToGc.remove(rec); 3716 addProcessToGcListLocked(rec); 3717 } 3718 } 3719 if (doReport) { 3720 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3721 mHandler.sendMessage(msg); 3722 } 3723 scheduleAppGcsLocked(); 3724 } 3725 } 3726 3727 final void appDiedLocked(ProcessRecord app, int pid, 3728 IApplicationThread thread) { 3729 3730 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3731 synchronized (stats) { 3732 stats.noteProcessDiedLocked(app.info.uid, pid); 3733 } 3734 3735 // Clean up already done if the process has been re-started. 3736 if (app.pid == pid && app.thread != null && 3737 app.thread.asBinder() == thread.asBinder()) { 3738 boolean doLowMem = app.instrumentationClass == null; 3739 boolean doOomAdj = doLowMem; 3740 if (!app.killedByAm) { 3741 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3742 + ") has died."); 3743 mAllowLowerMemLevel = true; 3744 } else { 3745 // Note that we always want to do oom adj to update our state with the 3746 // new number of procs. 3747 mAllowLowerMemLevel = false; 3748 doLowMem = false; 3749 } 3750 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3751 if (DEBUG_CLEANUP) Slog.v( 3752 TAG, "Dying app: " + app + ", pid: " + pid 3753 + ", thread: " + thread.asBinder()); 3754 handleAppDiedLocked(app, false, true); 3755 3756 if (doOomAdj) { 3757 updateOomAdjLocked(); 3758 } 3759 if (doLowMem) { 3760 doLowMemReportIfNeededLocked(app); 3761 } 3762 } else if (app.pid != pid) { 3763 // A new process has already been started. 3764 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3765 + ") has died and restarted (pid " + app.pid + ")."); 3766 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3767 } else if (DEBUG_PROCESSES) { 3768 Slog.d(TAG, "Received spurious death notification for thread " 3769 + thread.asBinder()); 3770 } 3771 } 3772 3773 /** 3774 * If a stack trace dump file is configured, dump process stack traces. 3775 * @param clearTraces causes the dump file to be erased prior to the new 3776 * traces being written, if true; when false, the new traces will be 3777 * appended to any existing file content. 3778 * @param firstPids of dalvik VM processes to dump stack traces for first 3779 * @param lastPids of dalvik VM processes to dump stack traces for last 3780 * @param nativeProcs optional list of native process names to dump stack crawls 3781 * @return file containing stack traces, or null if no dump file is configured 3782 */ 3783 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3784 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3785 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3786 if (tracesPath == null || tracesPath.length() == 0) { 3787 return null; 3788 } 3789 3790 File tracesFile = new File(tracesPath); 3791 try { 3792 File tracesDir = tracesFile.getParentFile(); 3793 if (!tracesDir.exists()) { 3794 tracesFile.mkdirs(); 3795 if (!SELinux.restorecon(tracesDir)) { 3796 return null; 3797 } 3798 } 3799 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3800 3801 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3802 tracesFile.createNewFile(); 3803 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3804 } catch (IOException e) { 3805 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3806 return null; 3807 } 3808 3809 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3810 return tracesFile; 3811 } 3812 3813 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3814 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3815 // Use a FileObserver to detect when traces finish writing. 3816 // The order of traces is considered important to maintain for legibility. 3817 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3818 @Override 3819 public synchronized void onEvent(int event, String path) { notify(); } 3820 }; 3821 3822 try { 3823 observer.startWatching(); 3824 3825 // First collect all of the stacks of the most important pids. 3826 if (firstPids != null) { 3827 try { 3828 int num = firstPids.size(); 3829 for (int i = 0; i < num; i++) { 3830 synchronized (observer) { 3831 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3832 observer.wait(200); // Wait for write-close, give up after 200msec 3833 } 3834 } 3835 } catch (InterruptedException e) { 3836 Log.wtf(TAG, e); 3837 } 3838 } 3839 3840 // Next collect the stacks of the native pids 3841 if (nativeProcs != null) { 3842 int[] pids = Process.getPidsForCommands(nativeProcs); 3843 if (pids != null) { 3844 for (int pid : pids) { 3845 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3846 } 3847 } 3848 } 3849 3850 // Lastly, measure CPU usage. 3851 if (processCpuTracker != null) { 3852 processCpuTracker.init(); 3853 System.gc(); 3854 processCpuTracker.update(); 3855 try { 3856 synchronized (processCpuTracker) { 3857 processCpuTracker.wait(500); // measure over 1/2 second. 3858 } 3859 } catch (InterruptedException e) { 3860 } 3861 processCpuTracker.update(); 3862 3863 // We'll take the stack crawls of just the top apps using CPU. 3864 final int N = processCpuTracker.countWorkingStats(); 3865 int numProcs = 0; 3866 for (int i=0; i<N && numProcs<5; i++) { 3867 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3868 if (lastPids.indexOfKey(stats.pid) >= 0) { 3869 numProcs++; 3870 try { 3871 synchronized (observer) { 3872 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3873 observer.wait(200); // Wait for write-close, give up after 200msec 3874 } 3875 } catch (InterruptedException e) { 3876 Log.wtf(TAG, e); 3877 } 3878 3879 } 3880 } 3881 } 3882 } finally { 3883 observer.stopWatching(); 3884 } 3885 } 3886 3887 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3888 if (true || IS_USER_BUILD) { 3889 return; 3890 } 3891 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3892 if (tracesPath == null || tracesPath.length() == 0) { 3893 return; 3894 } 3895 3896 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3897 StrictMode.allowThreadDiskWrites(); 3898 try { 3899 final File tracesFile = new File(tracesPath); 3900 final File tracesDir = tracesFile.getParentFile(); 3901 final File tracesTmp = new File(tracesDir, "__tmp__"); 3902 try { 3903 if (!tracesDir.exists()) { 3904 tracesFile.mkdirs(); 3905 if (!SELinux.restorecon(tracesDir.getPath())) { 3906 return; 3907 } 3908 } 3909 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3910 3911 if (tracesFile.exists()) { 3912 tracesTmp.delete(); 3913 tracesFile.renameTo(tracesTmp); 3914 } 3915 StringBuilder sb = new StringBuilder(); 3916 Time tobj = new Time(); 3917 tobj.set(System.currentTimeMillis()); 3918 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3919 sb.append(": "); 3920 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3921 sb.append(" since "); 3922 sb.append(msg); 3923 FileOutputStream fos = new FileOutputStream(tracesFile); 3924 fos.write(sb.toString().getBytes()); 3925 if (app == null) { 3926 fos.write("\n*** No application process!".getBytes()); 3927 } 3928 fos.close(); 3929 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3930 } catch (IOException e) { 3931 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3932 return; 3933 } 3934 3935 if (app != null) { 3936 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3937 firstPids.add(app.pid); 3938 dumpStackTraces(tracesPath, firstPids, null, null, null); 3939 } 3940 3941 File lastTracesFile = null; 3942 File curTracesFile = null; 3943 for (int i=9; i>=0; i--) { 3944 String name = String.format(Locale.US, "slow%02d.txt", i); 3945 curTracesFile = new File(tracesDir, name); 3946 if (curTracesFile.exists()) { 3947 if (lastTracesFile != null) { 3948 curTracesFile.renameTo(lastTracesFile); 3949 } else { 3950 curTracesFile.delete(); 3951 } 3952 } 3953 lastTracesFile = curTracesFile; 3954 } 3955 tracesFile.renameTo(curTracesFile); 3956 if (tracesTmp.exists()) { 3957 tracesTmp.renameTo(tracesFile); 3958 } 3959 } finally { 3960 StrictMode.setThreadPolicy(oldPolicy); 3961 } 3962 } 3963 3964 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3965 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3966 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3967 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3968 3969 if (mController != null) { 3970 try { 3971 // 0 == continue, -1 = kill process immediately 3972 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3973 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3974 } catch (RemoteException e) { 3975 mController = null; 3976 Watchdog.getInstance().setActivityController(null); 3977 } 3978 } 3979 3980 long anrTime = SystemClock.uptimeMillis(); 3981 if (MONITOR_CPU_USAGE) { 3982 updateCpuStatsNow(); 3983 } 3984 3985 synchronized (this) { 3986 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3987 if (mShuttingDown) { 3988 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3989 return; 3990 } else if (app.notResponding) { 3991 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3992 return; 3993 } else if (app.crashing) { 3994 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3995 return; 3996 } 3997 3998 // In case we come through here for the same app before completing 3999 // this one, mark as anring now so we will bail out. 4000 app.notResponding = true; 4001 4002 // Log the ANR to the event log. 4003 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4004 app.processName, app.info.flags, annotation); 4005 4006 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4007 firstPids.add(app.pid); 4008 4009 int parentPid = app.pid; 4010 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4011 if (parentPid != app.pid) firstPids.add(parentPid); 4012 4013 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4014 4015 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4016 ProcessRecord r = mLruProcesses.get(i); 4017 if (r != null && r.thread != null) { 4018 int pid = r.pid; 4019 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4020 if (r.persistent) { 4021 firstPids.add(pid); 4022 } else { 4023 lastPids.put(pid, Boolean.TRUE); 4024 } 4025 } 4026 } 4027 } 4028 } 4029 4030 // Log the ANR to the main log. 4031 StringBuilder info = new StringBuilder(); 4032 info.setLength(0); 4033 info.append("ANR in ").append(app.processName); 4034 if (activity != null && activity.shortComponentName != null) { 4035 info.append(" (").append(activity.shortComponentName).append(")"); 4036 } 4037 info.append("\n"); 4038 info.append("PID: ").append(app.pid).append("\n"); 4039 if (annotation != null) { 4040 info.append("Reason: ").append(annotation).append("\n"); 4041 } 4042 if (parent != null && parent != activity) { 4043 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4044 } 4045 4046 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4047 4048 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4049 NATIVE_STACKS_OF_INTEREST); 4050 4051 String cpuInfo = null; 4052 if (MONITOR_CPU_USAGE) { 4053 updateCpuStatsNow(); 4054 synchronized (mProcessCpuThread) { 4055 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4056 } 4057 info.append(processCpuTracker.printCurrentLoad()); 4058 info.append(cpuInfo); 4059 } 4060 4061 info.append(processCpuTracker.printCurrentState(anrTime)); 4062 4063 Slog.e(TAG, info.toString()); 4064 if (tracesFile == null) { 4065 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4066 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4067 } 4068 4069 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4070 cpuInfo, tracesFile, null); 4071 4072 if (mController != null) { 4073 try { 4074 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4075 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4076 if (res != 0) { 4077 if (res < 0 && app.pid != MY_PID) { 4078 Process.killProcess(app.pid); 4079 } else { 4080 synchronized (this) { 4081 mServices.scheduleServiceTimeoutLocked(app); 4082 } 4083 } 4084 return; 4085 } 4086 } catch (RemoteException e) { 4087 mController = null; 4088 Watchdog.getInstance().setActivityController(null); 4089 } 4090 } 4091 4092 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4093 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4094 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4095 4096 synchronized (this) { 4097 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4098 killUnneededProcessLocked(app, "background ANR"); 4099 return; 4100 } 4101 4102 // Set the app's notResponding state, and look up the errorReportReceiver 4103 makeAppNotRespondingLocked(app, 4104 activity != null ? activity.shortComponentName : null, 4105 annotation != null ? "ANR " + annotation : "ANR", 4106 info.toString()); 4107 4108 // Bring up the infamous App Not Responding dialog 4109 Message msg = Message.obtain(); 4110 HashMap<String, Object> map = new HashMap<String, Object>(); 4111 msg.what = SHOW_NOT_RESPONDING_MSG; 4112 msg.obj = map; 4113 msg.arg1 = aboveSystem ? 1 : 0; 4114 map.put("app", app); 4115 if (activity != null) { 4116 map.put("activity", activity); 4117 } 4118 4119 mHandler.sendMessage(msg); 4120 } 4121 } 4122 4123 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4124 if (!mLaunchWarningShown) { 4125 mLaunchWarningShown = true; 4126 mHandler.post(new Runnable() { 4127 @Override 4128 public void run() { 4129 synchronized (ActivityManagerService.this) { 4130 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4131 d.show(); 4132 mHandler.postDelayed(new Runnable() { 4133 @Override 4134 public void run() { 4135 synchronized (ActivityManagerService.this) { 4136 d.dismiss(); 4137 mLaunchWarningShown = false; 4138 } 4139 } 4140 }, 4000); 4141 } 4142 } 4143 }); 4144 } 4145 } 4146 4147 @Override 4148 public boolean clearApplicationUserData(final String packageName, 4149 final IPackageDataObserver observer, int userId) { 4150 enforceNotIsolatedCaller("clearApplicationUserData"); 4151 int uid = Binder.getCallingUid(); 4152 int pid = Binder.getCallingPid(); 4153 userId = handleIncomingUser(pid, uid, 4154 userId, false, true, "clearApplicationUserData", null); 4155 long callingId = Binder.clearCallingIdentity(); 4156 try { 4157 IPackageManager pm = AppGlobals.getPackageManager(); 4158 int pkgUid = -1; 4159 synchronized(this) { 4160 try { 4161 pkgUid = pm.getPackageUid(packageName, userId); 4162 } catch (RemoteException e) { 4163 } 4164 if (pkgUid == -1) { 4165 Slog.w(TAG, "Invalid packageName: " + packageName); 4166 if (observer != null) { 4167 try { 4168 observer.onRemoveCompleted(packageName, false); 4169 } catch (RemoteException e) { 4170 Slog.i(TAG, "Observer no longer exists."); 4171 } 4172 } 4173 return false; 4174 } 4175 if (uid == pkgUid || checkComponentPermission( 4176 android.Manifest.permission.CLEAR_APP_USER_DATA, 4177 pid, uid, -1, true) 4178 == PackageManager.PERMISSION_GRANTED) { 4179 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4180 } else { 4181 throw new SecurityException("PID " + pid + " does not have permission " 4182 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4183 + " of package " + packageName); 4184 } 4185 } 4186 4187 try { 4188 // Clear application user data 4189 pm.clearApplicationUserData(packageName, observer, userId); 4190 4191 // Remove all permissions granted from/to this package 4192 removeUriPermissionsForPackageLocked(packageName, userId, true); 4193 4194 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4195 Uri.fromParts("package", packageName, null)); 4196 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4197 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4198 null, null, 0, null, null, null, false, false, userId); 4199 } catch (RemoteException e) { 4200 } 4201 } finally { 4202 Binder.restoreCallingIdentity(callingId); 4203 } 4204 return true; 4205 } 4206 4207 @Override 4208 public void killBackgroundProcesses(final String packageName, int userId) { 4209 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4210 != PackageManager.PERMISSION_GRANTED && 4211 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4212 != PackageManager.PERMISSION_GRANTED) { 4213 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4214 + Binder.getCallingPid() 4215 + ", uid=" + Binder.getCallingUid() 4216 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4217 Slog.w(TAG, msg); 4218 throw new SecurityException(msg); 4219 } 4220 4221 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4222 userId, true, true, "killBackgroundProcesses", null); 4223 long callingId = Binder.clearCallingIdentity(); 4224 try { 4225 IPackageManager pm = AppGlobals.getPackageManager(); 4226 synchronized(this) { 4227 int appId = -1; 4228 try { 4229 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4230 } catch (RemoteException e) { 4231 } 4232 if (appId == -1) { 4233 Slog.w(TAG, "Invalid packageName: " + packageName); 4234 return; 4235 } 4236 killPackageProcessesLocked(packageName, appId, userId, 4237 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4238 } 4239 } finally { 4240 Binder.restoreCallingIdentity(callingId); 4241 } 4242 } 4243 4244 @Override 4245 public void killAllBackgroundProcesses() { 4246 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4247 != PackageManager.PERMISSION_GRANTED) { 4248 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4249 + Binder.getCallingPid() 4250 + ", uid=" + Binder.getCallingUid() 4251 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4252 Slog.w(TAG, msg); 4253 throw new SecurityException(msg); 4254 } 4255 4256 long callingId = Binder.clearCallingIdentity(); 4257 try { 4258 synchronized(this) { 4259 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4260 final int NP = mProcessNames.getMap().size(); 4261 for (int ip=0; ip<NP; ip++) { 4262 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4263 final int NA = apps.size(); 4264 for (int ia=0; ia<NA; ia++) { 4265 ProcessRecord app = apps.valueAt(ia); 4266 if (app.persistent) { 4267 // we don't kill persistent processes 4268 continue; 4269 } 4270 if (app.removed) { 4271 procs.add(app); 4272 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4273 app.removed = true; 4274 procs.add(app); 4275 } 4276 } 4277 } 4278 4279 int N = procs.size(); 4280 for (int i=0; i<N; i++) { 4281 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4282 } 4283 mAllowLowerMemLevel = true; 4284 updateOomAdjLocked(); 4285 doLowMemReportIfNeededLocked(null); 4286 } 4287 } finally { 4288 Binder.restoreCallingIdentity(callingId); 4289 } 4290 } 4291 4292 @Override 4293 public void forceStopPackage(final String packageName, int userId) { 4294 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4295 != PackageManager.PERMISSION_GRANTED) { 4296 String msg = "Permission Denial: forceStopPackage() from pid=" 4297 + Binder.getCallingPid() 4298 + ", uid=" + Binder.getCallingUid() 4299 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4300 Slog.w(TAG, msg); 4301 throw new SecurityException(msg); 4302 } 4303 final int callingPid = Binder.getCallingPid(); 4304 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4305 userId, true, true, "forceStopPackage", null); 4306 long callingId = Binder.clearCallingIdentity(); 4307 try { 4308 IPackageManager pm = AppGlobals.getPackageManager(); 4309 synchronized(this) { 4310 int[] users = userId == UserHandle.USER_ALL 4311 ? getUsersLocked() : new int[] { userId }; 4312 for (int user : users) { 4313 int pkgUid = -1; 4314 try { 4315 pkgUid = pm.getPackageUid(packageName, user); 4316 } catch (RemoteException e) { 4317 } 4318 if (pkgUid == -1) { 4319 Slog.w(TAG, "Invalid packageName: " + packageName); 4320 continue; 4321 } 4322 try { 4323 pm.setPackageStoppedState(packageName, true, user); 4324 } catch (RemoteException e) { 4325 } catch (IllegalArgumentException e) { 4326 Slog.w(TAG, "Failed trying to unstop package " 4327 + packageName + ": " + e); 4328 } 4329 if (isUserRunningLocked(user, false)) { 4330 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4331 } 4332 } 4333 } 4334 } finally { 4335 Binder.restoreCallingIdentity(callingId); 4336 } 4337 } 4338 4339 /* 4340 * The pkg name and app id have to be specified. 4341 */ 4342 @Override 4343 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4344 if (pkg == null) { 4345 return; 4346 } 4347 // Make sure the uid is valid. 4348 if (appid < 0) { 4349 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4350 return; 4351 } 4352 int callerUid = Binder.getCallingUid(); 4353 // Only the system server can kill an application 4354 if (callerUid == Process.SYSTEM_UID) { 4355 // Post an aysnc message to kill the application 4356 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4357 msg.arg1 = appid; 4358 msg.arg2 = 0; 4359 Bundle bundle = new Bundle(); 4360 bundle.putString("pkg", pkg); 4361 bundle.putString("reason", reason); 4362 msg.obj = bundle; 4363 mHandler.sendMessage(msg); 4364 } else { 4365 throw new SecurityException(callerUid + " cannot kill pkg: " + 4366 pkg); 4367 } 4368 } 4369 4370 @Override 4371 public void closeSystemDialogs(String reason) { 4372 enforceNotIsolatedCaller("closeSystemDialogs"); 4373 4374 final int pid = Binder.getCallingPid(); 4375 final int uid = Binder.getCallingUid(); 4376 final long origId = Binder.clearCallingIdentity(); 4377 try { 4378 synchronized (this) { 4379 // Only allow this from foreground processes, so that background 4380 // applications can't abuse it to prevent system UI from being shown. 4381 if (uid >= Process.FIRST_APPLICATION_UID) { 4382 ProcessRecord proc; 4383 synchronized (mPidsSelfLocked) { 4384 proc = mPidsSelfLocked.get(pid); 4385 } 4386 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4387 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4388 + " from background process " + proc); 4389 return; 4390 } 4391 } 4392 closeSystemDialogsLocked(reason); 4393 } 4394 } finally { 4395 Binder.restoreCallingIdentity(origId); 4396 } 4397 } 4398 4399 void closeSystemDialogsLocked(String reason) { 4400 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4401 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4402 | Intent.FLAG_RECEIVER_FOREGROUND); 4403 if (reason != null) { 4404 intent.putExtra("reason", reason); 4405 } 4406 mWindowManager.closeSystemDialogs(reason); 4407 4408 mStackSupervisor.closeSystemDialogsLocked(); 4409 4410 broadcastIntentLocked(null, null, intent, null, 4411 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4412 Process.SYSTEM_UID, UserHandle.USER_ALL); 4413 } 4414 4415 @Override 4416 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4417 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4418 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4419 for (int i=pids.length-1; i>=0; i--) { 4420 ProcessRecord proc; 4421 int oomAdj; 4422 synchronized (this) { 4423 synchronized (mPidsSelfLocked) { 4424 proc = mPidsSelfLocked.get(pids[i]); 4425 oomAdj = proc != null ? proc.setAdj : 0; 4426 } 4427 } 4428 infos[i] = new Debug.MemoryInfo(); 4429 Debug.getMemoryInfo(pids[i], infos[i]); 4430 if (proc != null) { 4431 synchronized (this) { 4432 if (proc.thread != null && proc.setAdj == oomAdj) { 4433 // Record this for posterity if the process has been stable. 4434 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4435 infos[i].getTotalUss(), false, proc.pkgList); 4436 } 4437 } 4438 } 4439 } 4440 return infos; 4441 } 4442 4443 @Override 4444 public long[] getProcessPss(int[] pids) { 4445 enforceNotIsolatedCaller("getProcessPss"); 4446 long[] pss = new long[pids.length]; 4447 for (int i=pids.length-1; i>=0; i--) { 4448 ProcessRecord proc; 4449 int oomAdj; 4450 synchronized (this) { 4451 synchronized (mPidsSelfLocked) { 4452 proc = mPidsSelfLocked.get(pids[i]); 4453 oomAdj = proc != null ? proc.setAdj : 0; 4454 } 4455 } 4456 long[] tmpUss = new long[1]; 4457 pss[i] = Debug.getPss(pids[i], tmpUss); 4458 if (proc != null) { 4459 synchronized (this) { 4460 if (proc.thread != null && proc.setAdj == oomAdj) { 4461 // Record this for posterity if the process has been stable. 4462 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4463 } 4464 } 4465 } 4466 } 4467 return pss; 4468 } 4469 4470 @Override 4471 public void killApplicationProcess(String processName, int uid) { 4472 if (processName == null) { 4473 return; 4474 } 4475 4476 int callerUid = Binder.getCallingUid(); 4477 // Only the system server can kill an application 4478 if (callerUid == Process.SYSTEM_UID) { 4479 synchronized (this) { 4480 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4481 if (app != null && app.thread != null) { 4482 try { 4483 app.thread.scheduleSuicide(); 4484 } catch (RemoteException e) { 4485 // If the other end already died, then our work here is done. 4486 } 4487 } else { 4488 Slog.w(TAG, "Process/uid not found attempting kill of " 4489 + processName + " / " + uid); 4490 } 4491 } 4492 } else { 4493 throw new SecurityException(callerUid + " cannot kill app process: " + 4494 processName); 4495 } 4496 } 4497 4498 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4499 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4500 false, true, false, false, UserHandle.getUserId(uid), reason); 4501 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4502 Uri.fromParts("package", packageName, null)); 4503 if (!mProcessesReady) { 4504 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4505 | Intent.FLAG_RECEIVER_FOREGROUND); 4506 } 4507 intent.putExtra(Intent.EXTRA_UID, uid); 4508 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4509 broadcastIntentLocked(null, null, intent, 4510 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4511 false, false, 4512 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4513 } 4514 4515 private void forceStopUserLocked(int userId, String reason) { 4516 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4517 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4518 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4519 | Intent.FLAG_RECEIVER_FOREGROUND); 4520 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4521 broadcastIntentLocked(null, null, intent, 4522 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4523 false, false, 4524 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4525 } 4526 4527 private final boolean killPackageProcessesLocked(String packageName, int appId, 4528 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4529 boolean doit, boolean evenPersistent, String reason) { 4530 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4531 4532 // Remove all processes this package may have touched: all with the 4533 // same UID (except for the system or root user), and all whose name 4534 // matches the package name. 4535 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4536 final int NP = mProcessNames.getMap().size(); 4537 for (int ip=0; ip<NP; ip++) { 4538 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4539 final int NA = apps.size(); 4540 for (int ia=0; ia<NA; ia++) { 4541 ProcessRecord app = apps.valueAt(ia); 4542 if (app.persistent && !evenPersistent) { 4543 // we don't kill persistent processes 4544 continue; 4545 } 4546 if (app.removed) { 4547 if (doit) { 4548 procs.add(app); 4549 } 4550 continue; 4551 } 4552 4553 // Skip process if it doesn't meet our oom adj requirement. 4554 if (app.setAdj < minOomAdj) { 4555 continue; 4556 } 4557 4558 // If no package is specified, we call all processes under the 4559 // give user id. 4560 if (packageName == null) { 4561 if (app.userId != userId) { 4562 continue; 4563 } 4564 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4565 continue; 4566 } 4567 // Package has been specified, we want to hit all processes 4568 // that match it. We need to qualify this by the processes 4569 // that are running under the specified app and user ID. 4570 } else { 4571 if (UserHandle.getAppId(app.uid) != appId) { 4572 continue; 4573 } 4574 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4575 continue; 4576 } 4577 if (!app.pkgList.containsKey(packageName)) { 4578 continue; 4579 } 4580 } 4581 4582 // Process has passed all conditions, kill it! 4583 if (!doit) { 4584 return true; 4585 } 4586 app.removed = true; 4587 procs.add(app); 4588 } 4589 } 4590 4591 int N = procs.size(); 4592 for (int i=0; i<N; i++) { 4593 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4594 } 4595 updateOomAdjLocked(); 4596 return N > 0; 4597 } 4598 4599 private final boolean forceStopPackageLocked(String name, int appId, 4600 boolean callerWillRestart, boolean purgeCache, boolean doit, 4601 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4602 int i; 4603 int N; 4604 4605 if (userId == UserHandle.USER_ALL && name == null) { 4606 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4607 } 4608 4609 if (appId < 0 && name != null) { 4610 try { 4611 appId = UserHandle.getAppId( 4612 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4613 } catch (RemoteException e) { 4614 } 4615 } 4616 4617 if (doit) { 4618 if (name != null) { 4619 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4620 + " user=" + userId + ": " + reason); 4621 } else { 4622 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4623 } 4624 4625 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4626 for (int ip=pmap.size()-1; ip>=0; ip--) { 4627 SparseArray<Long> ba = pmap.valueAt(ip); 4628 for (i=ba.size()-1; i>=0; i--) { 4629 boolean remove = false; 4630 final int entUid = ba.keyAt(i); 4631 if (name != null) { 4632 if (userId == UserHandle.USER_ALL) { 4633 if (UserHandle.getAppId(entUid) == appId) { 4634 remove = true; 4635 } 4636 } else { 4637 if (entUid == UserHandle.getUid(userId, appId)) { 4638 remove = true; 4639 } 4640 } 4641 } else if (UserHandle.getUserId(entUid) == userId) { 4642 remove = true; 4643 } 4644 if (remove) { 4645 ba.removeAt(i); 4646 } 4647 } 4648 if (ba.size() == 0) { 4649 pmap.removeAt(ip); 4650 } 4651 } 4652 } 4653 4654 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4655 -100, callerWillRestart, true, doit, evenPersistent, 4656 name == null ? ("stop user " + userId) : ("stop " + name)); 4657 4658 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4659 if (!doit) { 4660 return true; 4661 } 4662 didSomething = true; 4663 } 4664 4665 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4666 if (!doit) { 4667 return true; 4668 } 4669 didSomething = true; 4670 } 4671 4672 if (name == null) { 4673 // Remove all sticky broadcasts from this user. 4674 mStickyBroadcasts.remove(userId); 4675 } 4676 4677 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4678 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4679 userId, providers)) { 4680 if (!doit) { 4681 return true; 4682 } 4683 didSomething = true; 4684 } 4685 N = providers.size(); 4686 for (i=0; i<N; i++) { 4687 removeDyingProviderLocked(null, providers.get(i), true); 4688 } 4689 4690 // Remove transient permissions granted from/to this package/user 4691 removeUriPermissionsForPackageLocked(name, userId, false); 4692 4693 if (name == null || uninstalling) { 4694 // Remove pending intents. For now we only do this when force 4695 // stopping users, because we have some problems when doing this 4696 // for packages -- app widgets are not currently cleaned up for 4697 // such packages, so they can be left with bad pending intents. 4698 if (mIntentSenderRecords.size() > 0) { 4699 Iterator<WeakReference<PendingIntentRecord>> it 4700 = mIntentSenderRecords.values().iterator(); 4701 while (it.hasNext()) { 4702 WeakReference<PendingIntentRecord> wpir = it.next(); 4703 if (wpir == null) { 4704 it.remove(); 4705 continue; 4706 } 4707 PendingIntentRecord pir = wpir.get(); 4708 if (pir == null) { 4709 it.remove(); 4710 continue; 4711 } 4712 if (name == null) { 4713 // Stopping user, remove all objects for the user. 4714 if (pir.key.userId != userId) { 4715 // Not the same user, skip it. 4716 continue; 4717 } 4718 } else { 4719 if (UserHandle.getAppId(pir.uid) != appId) { 4720 // Different app id, skip it. 4721 continue; 4722 } 4723 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4724 // Different user, skip it. 4725 continue; 4726 } 4727 if (!pir.key.packageName.equals(name)) { 4728 // Different package, skip it. 4729 continue; 4730 } 4731 } 4732 if (!doit) { 4733 return true; 4734 } 4735 didSomething = true; 4736 it.remove(); 4737 pir.canceled = true; 4738 if (pir.key.activity != null) { 4739 pir.key.activity.pendingResults.remove(pir.ref); 4740 } 4741 } 4742 } 4743 } 4744 4745 if (doit) { 4746 if (purgeCache && name != null) { 4747 AttributeCache ac = AttributeCache.instance(); 4748 if (ac != null) { 4749 ac.removePackage(name); 4750 } 4751 } 4752 if (mBooted) { 4753 mStackSupervisor.resumeTopActivitiesLocked(); 4754 mStackSupervisor.scheduleIdleLocked(); 4755 } 4756 } 4757 4758 return didSomething; 4759 } 4760 4761 private final boolean removeProcessLocked(ProcessRecord app, 4762 boolean callerWillRestart, boolean allowRestart, String reason) { 4763 final String name = app.processName; 4764 final int uid = app.uid; 4765 if (DEBUG_PROCESSES) Slog.d( 4766 TAG, "Force removing proc " + app.toShortString() + " (" + name 4767 + "/" + uid + ")"); 4768 4769 mProcessNames.remove(name, uid); 4770 mIsolatedProcesses.remove(app.uid); 4771 if (mHeavyWeightProcess == app) { 4772 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4773 mHeavyWeightProcess.userId, 0)); 4774 mHeavyWeightProcess = null; 4775 } 4776 boolean needRestart = false; 4777 if (app.pid > 0 && app.pid != MY_PID) { 4778 int pid = app.pid; 4779 synchronized (mPidsSelfLocked) { 4780 mPidsSelfLocked.remove(pid); 4781 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4782 } 4783 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4784 app.processName, app.info.uid); 4785 if (app.isolated) { 4786 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4787 } 4788 killUnneededProcessLocked(app, reason); 4789 handleAppDiedLocked(app, true, allowRestart); 4790 removeLruProcessLocked(app); 4791 4792 if (app.persistent && !app.isolated) { 4793 if (!callerWillRestart) { 4794 addAppLocked(app.info, false); 4795 } else { 4796 needRestart = true; 4797 } 4798 } 4799 } else { 4800 mRemovedProcesses.add(app); 4801 } 4802 4803 return needRestart; 4804 } 4805 4806 private final void processStartTimedOutLocked(ProcessRecord app) { 4807 final int pid = app.pid; 4808 boolean gone = false; 4809 synchronized (mPidsSelfLocked) { 4810 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4811 if (knownApp != null && knownApp.thread == null) { 4812 mPidsSelfLocked.remove(pid); 4813 gone = true; 4814 } 4815 } 4816 4817 if (gone) { 4818 Slog.w(TAG, "Process " + app + " failed to attach"); 4819 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4820 pid, app.uid, app.processName); 4821 mProcessNames.remove(app.processName, app.uid); 4822 mIsolatedProcesses.remove(app.uid); 4823 if (mHeavyWeightProcess == app) { 4824 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4825 mHeavyWeightProcess.userId, 0)); 4826 mHeavyWeightProcess = null; 4827 } 4828 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4829 app.processName, app.info.uid); 4830 if (app.isolated) { 4831 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4832 } 4833 // Take care of any launching providers waiting for this process. 4834 checkAppInLaunchingProvidersLocked(app, true); 4835 // Take care of any services that are waiting for the process. 4836 mServices.processStartTimedOutLocked(app); 4837 killUnneededProcessLocked(app, "start timeout"); 4838 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4839 Slog.w(TAG, "Unattached app died before backup, skipping"); 4840 try { 4841 IBackupManager bm = IBackupManager.Stub.asInterface( 4842 ServiceManager.getService(Context.BACKUP_SERVICE)); 4843 bm.agentDisconnected(app.info.packageName); 4844 } catch (RemoteException e) { 4845 // Can't happen; the backup manager is local 4846 } 4847 } 4848 if (isPendingBroadcastProcessLocked(pid)) { 4849 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4850 skipPendingBroadcastLocked(pid); 4851 } 4852 } else { 4853 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4854 } 4855 } 4856 4857 private final boolean attachApplicationLocked(IApplicationThread thread, 4858 int pid) { 4859 4860 // Find the application record that is being attached... either via 4861 // the pid if we are running in multiple processes, or just pull the 4862 // next app record if we are emulating process with anonymous threads. 4863 ProcessRecord app; 4864 if (pid != MY_PID && pid >= 0) { 4865 synchronized (mPidsSelfLocked) { 4866 app = mPidsSelfLocked.get(pid); 4867 } 4868 } else { 4869 app = null; 4870 } 4871 4872 if (app == null) { 4873 Slog.w(TAG, "No pending application record for pid " + pid 4874 + " (IApplicationThread " + thread + "); dropping process"); 4875 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4876 if (pid > 0 && pid != MY_PID) { 4877 Process.killProcessQuiet(pid); 4878 } else { 4879 try { 4880 thread.scheduleExit(); 4881 } catch (Exception e) { 4882 // Ignore exceptions. 4883 } 4884 } 4885 return false; 4886 } 4887 4888 // If this application record is still attached to a previous 4889 // process, clean it up now. 4890 if (app.thread != null) { 4891 handleAppDiedLocked(app, true, true); 4892 } 4893 4894 // Tell the process all about itself. 4895 4896 if (localLOGV) Slog.v( 4897 TAG, "Binding process pid " + pid + " to record " + app); 4898 4899 final String processName = app.processName; 4900 try { 4901 AppDeathRecipient adr = new AppDeathRecipient( 4902 app, pid, thread); 4903 thread.asBinder().linkToDeath(adr, 0); 4904 app.deathRecipient = adr; 4905 } catch (RemoteException e) { 4906 app.resetPackageList(mProcessStats); 4907 startProcessLocked(app, "link fail", processName); 4908 return false; 4909 } 4910 4911 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4912 4913 app.makeActive(thread, mProcessStats); 4914 app.curAdj = app.setAdj = -100; 4915 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4916 app.forcingToForeground = null; 4917 updateProcessForegroundLocked(app, false, false); 4918 app.hasShownUi = false; 4919 app.debugging = false; 4920 app.cached = false; 4921 4922 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4923 4924 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4925 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4926 4927 if (!normalMode) { 4928 Slog.i(TAG, "Launching preboot mode app: " + app); 4929 } 4930 4931 if (localLOGV) Slog.v( 4932 TAG, "New app record " + app 4933 + " thread=" + thread.asBinder() + " pid=" + pid); 4934 try { 4935 int testMode = IApplicationThread.DEBUG_OFF; 4936 if (mDebugApp != null && mDebugApp.equals(processName)) { 4937 testMode = mWaitForDebugger 4938 ? IApplicationThread.DEBUG_WAIT 4939 : IApplicationThread.DEBUG_ON; 4940 app.debugging = true; 4941 if (mDebugTransient) { 4942 mDebugApp = mOrigDebugApp; 4943 mWaitForDebugger = mOrigWaitForDebugger; 4944 } 4945 } 4946 String profileFile = app.instrumentationProfileFile; 4947 ParcelFileDescriptor profileFd = null; 4948 boolean profileAutoStop = false; 4949 if (mProfileApp != null && mProfileApp.equals(processName)) { 4950 mProfileProc = app; 4951 profileFile = mProfileFile; 4952 profileFd = mProfileFd; 4953 profileAutoStop = mAutoStopProfiler; 4954 } 4955 boolean enableOpenGlTrace = false; 4956 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4957 enableOpenGlTrace = true; 4958 mOpenGlTraceApp = null; 4959 } 4960 4961 // If the app is being launched for restore or full backup, set it up specially 4962 boolean isRestrictedBackupMode = false; 4963 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4964 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4965 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4966 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4967 } 4968 4969 ensurePackageDexOpt(app.instrumentationInfo != null 4970 ? app.instrumentationInfo.packageName 4971 : app.info.packageName); 4972 if (app.instrumentationClass != null) { 4973 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4974 } 4975 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4976 + processName + " with config " + mConfiguration); 4977 ApplicationInfo appInfo = app.instrumentationInfo != null 4978 ? app.instrumentationInfo : app.info; 4979 app.compat = compatibilityInfoForPackageLocked(appInfo); 4980 if (profileFd != null) { 4981 profileFd = profileFd.dup(); 4982 } 4983 thread.bindApplication(processName, appInfo, providers, 4984 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4985 app.instrumentationArguments, app.instrumentationWatcher, 4986 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4987 isRestrictedBackupMode || !normalMode, app.persistent, 4988 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4989 mCoreSettingsObserver.getCoreSettingsLocked()); 4990 updateLruProcessLocked(app, false, null); 4991 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4992 } catch (Exception e) { 4993 // todo: Yikes! What should we do? For now we will try to 4994 // start another process, but that could easily get us in 4995 // an infinite loop of restarting processes... 4996 Slog.w(TAG, "Exception thrown during bind!", e); 4997 4998 app.resetPackageList(mProcessStats); 4999 app.unlinkDeathRecipient(); 5000 startProcessLocked(app, "bind fail", processName); 5001 return false; 5002 } 5003 5004 // Remove this record from the list of starting applications. 5005 mPersistentStartingProcesses.remove(app); 5006 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5007 "Attach application locked removing on hold: " + app); 5008 mProcessesOnHold.remove(app); 5009 5010 boolean badApp = false; 5011 boolean didSomething = false; 5012 5013 // See if the top visible activity is waiting to run in this process... 5014 if (normalMode) { 5015 try { 5016 if (mStackSupervisor.attachApplicationLocked(app)) { 5017 didSomething = true; 5018 } 5019 } catch (Exception e) { 5020 badApp = true; 5021 } 5022 } 5023 5024 // Find any services that should be running in this process... 5025 if (!badApp) { 5026 try { 5027 didSomething |= mServices.attachApplicationLocked(app, processName); 5028 } catch (Exception e) { 5029 badApp = true; 5030 } 5031 } 5032 5033 // Check if a next-broadcast receiver is in this process... 5034 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5035 try { 5036 didSomething |= sendPendingBroadcastsLocked(app); 5037 } catch (Exception e) { 5038 // If the app died trying to launch the receiver we declare it 'bad' 5039 badApp = true; 5040 } 5041 } 5042 5043 // Check whether the next backup agent is in this process... 5044 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5045 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5046 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5047 try { 5048 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5049 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5050 mBackupTarget.backupMode); 5051 } catch (Exception e) { 5052 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5053 e.printStackTrace(); 5054 } 5055 } 5056 5057 if (badApp) { 5058 // todo: Also need to kill application to deal with all 5059 // kinds of exceptions. 5060 handleAppDiedLocked(app, false, true); 5061 return false; 5062 } 5063 5064 if (!didSomething) { 5065 updateOomAdjLocked(); 5066 } 5067 5068 return true; 5069 } 5070 5071 @Override 5072 public final void attachApplication(IApplicationThread thread) { 5073 synchronized (this) { 5074 int callingPid = Binder.getCallingPid(); 5075 final long origId = Binder.clearCallingIdentity(); 5076 attachApplicationLocked(thread, callingPid); 5077 Binder.restoreCallingIdentity(origId); 5078 } 5079 } 5080 5081 @Override 5082 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5083 final long origId = Binder.clearCallingIdentity(); 5084 synchronized (this) { 5085 ActivityStack stack = ActivityRecord.getStackLocked(token); 5086 if (stack != null) { 5087 ActivityRecord r = 5088 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5089 if (stopProfiling) { 5090 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5091 try { 5092 mProfileFd.close(); 5093 } catch (IOException e) { 5094 } 5095 clearProfilerLocked(); 5096 } 5097 } 5098 } 5099 } 5100 Binder.restoreCallingIdentity(origId); 5101 } 5102 5103 void enableScreenAfterBoot() { 5104 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5105 SystemClock.uptimeMillis()); 5106 mWindowManager.enableScreenAfterBoot(); 5107 5108 synchronized (this) { 5109 updateEventDispatchingLocked(); 5110 } 5111 } 5112 5113 @Override 5114 public void showBootMessage(final CharSequence msg, final boolean always) { 5115 enforceNotIsolatedCaller("showBootMessage"); 5116 mWindowManager.showBootMessage(msg, always); 5117 } 5118 5119 @Override 5120 public void dismissKeyguardOnNextActivity() { 5121 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5122 final long token = Binder.clearCallingIdentity(); 5123 try { 5124 synchronized (this) { 5125 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5126 if (mLockScreenShown) { 5127 mLockScreenShown = false; 5128 comeOutOfSleepIfNeededLocked(); 5129 } 5130 mStackSupervisor.setDismissKeyguard(true); 5131 } 5132 } finally { 5133 Binder.restoreCallingIdentity(token); 5134 } 5135 } 5136 5137 final void finishBooting() { 5138 IntentFilter pkgFilter = new IntentFilter(); 5139 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5140 pkgFilter.addDataScheme("package"); 5141 mContext.registerReceiver(new BroadcastReceiver() { 5142 @Override 5143 public void onReceive(Context context, Intent intent) { 5144 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5145 if (pkgs != null) { 5146 for (String pkg : pkgs) { 5147 synchronized (ActivityManagerService.this) { 5148 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5149 "finished booting")) { 5150 setResultCode(Activity.RESULT_OK); 5151 return; 5152 } 5153 } 5154 } 5155 } 5156 } 5157 }, pkgFilter); 5158 5159 synchronized (this) { 5160 // Ensure that any processes we had put on hold are now started 5161 // up. 5162 final int NP = mProcessesOnHold.size(); 5163 if (NP > 0) { 5164 ArrayList<ProcessRecord> procs = 5165 new ArrayList<ProcessRecord>(mProcessesOnHold); 5166 for (int ip=0; ip<NP; ip++) { 5167 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5168 + procs.get(ip)); 5169 startProcessLocked(procs.get(ip), "on-hold", null); 5170 } 5171 } 5172 5173 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5174 // Start looking for apps that are abusing wake locks. 5175 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5176 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5177 // Tell anyone interested that we are done booting! 5178 SystemProperties.set("sys.boot_completed", "1"); 5179 SystemProperties.set("dev.bootcomplete", "1"); 5180 for (int i=0; i<mStartedUsers.size(); i++) { 5181 UserStartedState uss = mStartedUsers.valueAt(i); 5182 if (uss.mState == UserStartedState.STATE_BOOTING) { 5183 uss.mState = UserStartedState.STATE_RUNNING; 5184 final int userId = mStartedUsers.keyAt(i); 5185 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5186 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5187 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5188 broadcastIntentLocked(null, null, intent, null, 5189 new IIntentReceiver.Stub() { 5190 @Override 5191 public void performReceive(Intent intent, int resultCode, 5192 String data, Bundle extras, boolean ordered, 5193 boolean sticky, int sendingUser) { 5194 synchronized (ActivityManagerService.this) { 5195 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5196 true, false); 5197 } 5198 } 5199 }, 5200 0, null, null, 5201 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5202 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5203 userId); 5204 } 5205 } 5206 scheduleStartRelatedUsersLocked(); 5207 } 5208 } 5209 } 5210 5211 final void ensureBootCompleted() { 5212 boolean booting; 5213 boolean enableScreen; 5214 synchronized (this) { 5215 booting = mBooting; 5216 mBooting = false; 5217 enableScreen = !mBooted; 5218 mBooted = true; 5219 } 5220 5221 if (booting) { 5222 finishBooting(); 5223 } 5224 5225 if (enableScreen) { 5226 enableScreenAfterBoot(); 5227 } 5228 } 5229 5230 @Override 5231 public final void activityResumed(IBinder token) { 5232 final long origId = Binder.clearCallingIdentity(); 5233 synchronized(this) { 5234 ActivityStack stack = ActivityRecord.getStackLocked(token); 5235 if (stack != null) { 5236 ActivityRecord.activityResumedLocked(token); 5237 } 5238 } 5239 Binder.restoreCallingIdentity(origId); 5240 } 5241 5242 @Override 5243 public final void activityPaused(IBinder token) { 5244 final long origId = Binder.clearCallingIdentity(); 5245 synchronized(this) { 5246 ActivityStack stack = ActivityRecord.getStackLocked(token); 5247 if (stack != null) { 5248 stack.activityPausedLocked(token, false); 5249 } 5250 } 5251 Binder.restoreCallingIdentity(origId); 5252 } 5253 5254 @Override 5255 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5256 CharSequence description) { 5257 if (localLOGV) Slog.v( 5258 TAG, "Activity stopped: token=" + token); 5259 5260 // Refuse possible leaked file descriptors 5261 if (icicle != null && icicle.hasFileDescriptors()) { 5262 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5263 } 5264 5265 ActivityRecord r = null; 5266 5267 final long origId = Binder.clearCallingIdentity(); 5268 5269 synchronized (this) { 5270 r = ActivityRecord.isInStackLocked(token); 5271 if (r != null) { 5272 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5273 } 5274 } 5275 5276 if (r != null) { 5277 sendPendingThumbnail(r, null, null, null, false); 5278 } 5279 5280 trimApplications(); 5281 5282 Binder.restoreCallingIdentity(origId); 5283 } 5284 5285 @Override 5286 public final void activityDestroyed(IBinder token) { 5287 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5288 synchronized (this) { 5289 ActivityStack stack = ActivityRecord.getStackLocked(token); 5290 if (stack != null) { 5291 stack.activityDestroyedLocked(token); 5292 } 5293 } 5294 } 5295 5296 @Override 5297 public String getCallingPackage(IBinder token) { 5298 synchronized (this) { 5299 ActivityRecord r = getCallingRecordLocked(token); 5300 return r != null ? r.info.packageName : null; 5301 } 5302 } 5303 5304 @Override 5305 public ComponentName getCallingActivity(IBinder token) { 5306 synchronized (this) { 5307 ActivityRecord r = getCallingRecordLocked(token); 5308 return r != null ? r.intent.getComponent() : null; 5309 } 5310 } 5311 5312 private ActivityRecord getCallingRecordLocked(IBinder token) { 5313 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5314 if (r == null) { 5315 return null; 5316 } 5317 return r.resultTo; 5318 } 5319 5320 @Override 5321 public ComponentName getActivityClassForToken(IBinder token) { 5322 synchronized(this) { 5323 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5324 if (r == null) { 5325 return null; 5326 } 5327 return r.intent.getComponent(); 5328 } 5329 } 5330 5331 @Override 5332 public String getPackageForToken(IBinder token) { 5333 synchronized(this) { 5334 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5335 if (r == null) { 5336 return null; 5337 } 5338 return r.packageName; 5339 } 5340 } 5341 5342 @Override 5343 public IIntentSender getIntentSender(int type, 5344 String packageName, IBinder token, String resultWho, 5345 int requestCode, Intent[] intents, String[] resolvedTypes, 5346 int flags, Bundle options, int userId) { 5347 enforceNotIsolatedCaller("getIntentSender"); 5348 // Refuse possible leaked file descriptors 5349 if (intents != null) { 5350 if (intents.length < 1) { 5351 throw new IllegalArgumentException("Intents array length must be >= 1"); 5352 } 5353 for (int i=0; i<intents.length; i++) { 5354 Intent intent = intents[i]; 5355 if (intent != null) { 5356 if (intent.hasFileDescriptors()) { 5357 throw new IllegalArgumentException("File descriptors passed in Intent"); 5358 } 5359 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5360 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5361 throw new IllegalArgumentException( 5362 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5363 } 5364 intents[i] = new Intent(intent); 5365 } 5366 } 5367 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5368 throw new IllegalArgumentException( 5369 "Intent array length does not match resolvedTypes length"); 5370 } 5371 } 5372 if (options != null) { 5373 if (options.hasFileDescriptors()) { 5374 throw new IllegalArgumentException("File descriptors passed in options"); 5375 } 5376 } 5377 5378 synchronized(this) { 5379 int callingUid = Binder.getCallingUid(); 5380 int origUserId = userId; 5381 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5382 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5383 "getIntentSender", null); 5384 if (origUserId == UserHandle.USER_CURRENT) { 5385 // We don't want to evaluate this until the pending intent is 5386 // actually executed. However, we do want to always do the 5387 // security checking for it above. 5388 userId = UserHandle.USER_CURRENT; 5389 } 5390 try { 5391 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5392 int uid = AppGlobals.getPackageManager() 5393 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5394 if (!UserHandle.isSameApp(callingUid, uid)) { 5395 String msg = "Permission Denial: getIntentSender() from pid=" 5396 + Binder.getCallingPid() 5397 + ", uid=" + Binder.getCallingUid() 5398 + ", (need uid=" + uid + ")" 5399 + " is not allowed to send as package " + packageName; 5400 Slog.w(TAG, msg); 5401 throw new SecurityException(msg); 5402 } 5403 } 5404 5405 return getIntentSenderLocked(type, packageName, callingUid, userId, 5406 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5407 5408 } catch (RemoteException e) { 5409 throw new SecurityException(e); 5410 } 5411 } 5412 } 5413 5414 IIntentSender getIntentSenderLocked(int type, String packageName, 5415 int callingUid, int userId, IBinder token, String resultWho, 5416 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5417 Bundle options) { 5418 if (DEBUG_MU) 5419 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5420 ActivityRecord activity = null; 5421 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5422 activity = ActivityRecord.isInStackLocked(token); 5423 if (activity == null) { 5424 return null; 5425 } 5426 if (activity.finishing) { 5427 return null; 5428 } 5429 } 5430 5431 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5432 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5433 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5434 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5435 |PendingIntent.FLAG_UPDATE_CURRENT); 5436 5437 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5438 type, packageName, activity, resultWho, 5439 requestCode, intents, resolvedTypes, flags, options, userId); 5440 WeakReference<PendingIntentRecord> ref; 5441 ref = mIntentSenderRecords.get(key); 5442 PendingIntentRecord rec = ref != null ? ref.get() : null; 5443 if (rec != null) { 5444 if (!cancelCurrent) { 5445 if (updateCurrent) { 5446 if (rec.key.requestIntent != null) { 5447 rec.key.requestIntent.replaceExtras(intents != null ? 5448 intents[intents.length - 1] : null); 5449 } 5450 if (intents != null) { 5451 intents[intents.length-1] = rec.key.requestIntent; 5452 rec.key.allIntents = intents; 5453 rec.key.allResolvedTypes = resolvedTypes; 5454 } else { 5455 rec.key.allIntents = null; 5456 rec.key.allResolvedTypes = null; 5457 } 5458 } 5459 return rec; 5460 } 5461 rec.canceled = true; 5462 mIntentSenderRecords.remove(key); 5463 } 5464 if (noCreate) { 5465 return rec; 5466 } 5467 rec = new PendingIntentRecord(this, key, callingUid); 5468 mIntentSenderRecords.put(key, rec.ref); 5469 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5470 if (activity.pendingResults == null) { 5471 activity.pendingResults 5472 = new HashSet<WeakReference<PendingIntentRecord>>(); 5473 } 5474 activity.pendingResults.add(rec.ref); 5475 } 5476 return rec; 5477 } 5478 5479 @Override 5480 public void cancelIntentSender(IIntentSender sender) { 5481 if (!(sender instanceof PendingIntentRecord)) { 5482 return; 5483 } 5484 synchronized(this) { 5485 PendingIntentRecord rec = (PendingIntentRecord)sender; 5486 try { 5487 int uid = AppGlobals.getPackageManager() 5488 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5489 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5490 String msg = "Permission Denial: cancelIntentSender() from pid=" 5491 + Binder.getCallingPid() 5492 + ", uid=" + Binder.getCallingUid() 5493 + " is not allowed to cancel packges " 5494 + rec.key.packageName; 5495 Slog.w(TAG, msg); 5496 throw new SecurityException(msg); 5497 } 5498 } catch (RemoteException e) { 5499 throw new SecurityException(e); 5500 } 5501 cancelIntentSenderLocked(rec, true); 5502 } 5503 } 5504 5505 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5506 rec.canceled = true; 5507 mIntentSenderRecords.remove(rec.key); 5508 if (cleanActivity && rec.key.activity != null) { 5509 rec.key.activity.pendingResults.remove(rec.ref); 5510 } 5511 } 5512 5513 @Override 5514 public String getPackageForIntentSender(IIntentSender pendingResult) { 5515 if (!(pendingResult instanceof PendingIntentRecord)) { 5516 return null; 5517 } 5518 try { 5519 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5520 return res.key.packageName; 5521 } catch (ClassCastException e) { 5522 } 5523 return null; 5524 } 5525 5526 @Override 5527 public int getUidForIntentSender(IIntentSender sender) { 5528 if (sender instanceof PendingIntentRecord) { 5529 try { 5530 PendingIntentRecord res = (PendingIntentRecord)sender; 5531 return res.uid; 5532 } catch (ClassCastException e) { 5533 } 5534 } 5535 return -1; 5536 } 5537 5538 @Override 5539 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5540 if (!(pendingResult instanceof PendingIntentRecord)) { 5541 return false; 5542 } 5543 try { 5544 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5545 if (res.key.allIntents == null) { 5546 return false; 5547 } 5548 for (int i=0; i<res.key.allIntents.length; i++) { 5549 Intent intent = res.key.allIntents[i]; 5550 if (intent.getPackage() != null && intent.getComponent() != null) { 5551 return false; 5552 } 5553 } 5554 return true; 5555 } catch (ClassCastException e) { 5556 } 5557 return false; 5558 } 5559 5560 @Override 5561 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5562 if (!(pendingResult instanceof PendingIntentRecord)) { 5563 return false; 5564 } 5565 try { 5566 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5567 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5568 return true; 5569 } 5570 return false; 5571 } catch (ClassCastException e) { 5572 } 5573 return false; 5574 } 5575 5576 @Override 5577 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5578 if (!(pendingResult instanceof PendingIntentRecord)) { 5579 return null; 5580 } 5581 try { 5582 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5583 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5584 } catch (ClassCastException e) { 5585 } 5586 return null; 5587 } 5588 5589 @Override 5590 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5591 if (!(pendingResult instanceof PendingIntentRecord)) { 5592 return null; 5593 } 5594 try { 5595 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5596 Intent intent = res.key.requestIntent; 5597 if (intent != null) { 5598 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5599 || res.lastTagPrefix.equals(prefix))) { 5600 return res.lastTag; 5601 } 5602 res.lastTagPrefix = prefix; 5603 StringBuilder sb = new StringBuilder(128); 5604 if (prefix != null) { 5605 sb.append(prefix); 5606 } 5607 if (intent.getAction() != null) { 5608 sb.append(intent.getAction()); 5609 } else if (intent.getComponent() != null) { 5610 intent.getComponent().appendShortString(sb); 5611 } else { 5612 sb.append("?"); 5613 } 5614 return res.lastTag = sb.toString(); 5615 } 5616 } catch (ClassCastException e) { 5617 } 5618 return null; 5619 } 5620 5621 @Override 5622 public void setProcessLimit(int max) { 5623 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5624 "setProcessLimit()"); 5625 synchronized (this) { 5626 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5627 mProcessLimitOverride = max; 5628 } 5629 trimApplications(); 5630 } 5631 5632 @Override 5633 public int getProcessLimit() { 5634 synchronized (this) { 5635 return mProcessLimitOverride; 5636 } 5637 } 5638 5639 void foregroundTokenDied(ForegroundToken token) { 5640 synchronized (ActivityManagerService.this) { 5641 synchronized (mPidsSelfLocked) { 5642 ForegroundToken cur 5643 = mForegroundProcesses.get(token.pid); 5644 if (cur != token) { 5645 return; 5646 } 5647 mForegroundProcesses.remove(token.pid); 5648 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5649 if (pr == null) { 5650 return; 5651 } 5652 pr.forcingToForeground = null; 5653 updateProcessForegroundLocked(pr, false, false); 5654 } 5655 updateOomAdjLocked(); 5656 } 5657 } 5658 5659 @Override 5660 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5661 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5662 "setProcessForeground()"); 5663 synchronized(this) { 5664 boolean changed = false; 5665 5666 synchronized (mPidsSelfLocked) { 5667 ProcessRecord pr = mPidsSelfLocked.get(pid); 5668 if (pr == null && isForeground) { 5669 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5670 return; 5671 } 5672 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5673 if (oldToken != null) { 5674 oldToken.token.unlinkToDeath(oldToken, 0); 5675 mForegroundProcesses.remove(pid); 5676 if (pr != null) { 5677 pr.forcingToForeground = null; 5678 } 5679 changed = true; 5680 } 5681 if (isForeground && token != null) { 5682 ForegroundToken newToken = new ForegroundToken() { 5683 @Override 5684 public void binderDied() { 5685 foregroundTokenDied(this); 5686 } 5687 }; 5688 newToken.pid = pid; 5689 newToken.token = token; 5690 try { 5691 token.linkToDeath(newToken, 0); 5692 mForegroundProcesses.put(pid, newToken); 5693 pr.forcingToForeground = token; 5694 changed = true; 5695 } catch (RemoteException e) { 5696 // If the process died while doing this, we will later 5697 // do the cleanup with the process death link. 5698 } 5699 } 5700 } 5701 5702 if (changed) { 5703 updateOomAdjLocked(); 5704 } 5705 } 5706 } 5707 5708 // ========================================================= 5709 // PERMISSIONS 5710 // ========================================================= 5711 5712 static class PermissionController extends IPermissionController.Stub { 5713 ActivityManagerService mActivityManagerService; 5714 PermissionController(ActivityManagerService activityManagerService) { 5715 mActivityManagerService = activityManagerService; 5716 } 5717 5718 @Override 5719 public boolean checkPermission(String permission, int pid, int uid) { 5720 return mActivityManagerService.checkPermission(permission, pid, 5721 uid) == PackageManager.PERMISSION_GRANTED; 5722 } 5723 } 5724 5725 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5726 @Override 5727 public int checkComponentPermission(String permission, int pid, int uid, 5728 int owningUid, boolean exported) { 5729 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5730 owningUid, exported); 5731 } 5732 5733 @Override 5734 public Object getAMSLock() { 5735 return ActivityManagerService.this; 5736 } 5737 } 5738 5739 /** 5740 * This can be called with or without the global lock held. 5741 */ 5742 int checkComponentPermission(String permission, int pid, int uid, 5743 int owningUid, boolean exported) { 5744 // We might be performing an operation on behalf of an indirect binder 5745 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5746 // client identity accordingly before proceeding. 5747 Identity tlsIdentity = sCallerIdentity.get(); 5748 if (tlsIdentity != null) { 5749 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5750 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5751 uid = tlsIdentity.uid; 5752 pid = tlsIdentity.pid; 5753 } 5754 5755 if (pid == MY_PID) { 5756 return PackageManager.PERMISSION_GRANTED; 5757 } 5758 5759 return ActivityManager.checkComponentPermission(permission, uid, 5760 owningUid, exported); 5761 } 5762 5763 /** 5764 * As the only public entry point for permissions checking, this method 5765 * can enforce the semantic that requesting a check on a null global 5766 * permission is automatically denied. (Internally a null permission 5767 * string is used when calling {@link #checkComponentPermission} in cases 5768 * when only uid-based security is needed.) 5769 * 5770 * This can be called with or without the global lock held. 5771 */ 5772 @Override 5773 public int checkPermission(String permission, int pid, int uid) { 5774 if (permission == null) { 5775 return PackageManager.PERMISSION_DENIED; 5776 } 5777 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5778 } 5779 5780 /** 5781 * Binder IPC calls go through the public entry point. 5782 * This can be called with or without the global lock held. 5783 */ 5784 int checkCallingPermission(String permission) { 5785 return checkPermission(permission, 5786 Binder.getCallingPid(), 5787 UserHandle.getAppId(Binder.getCallingUid())); 5788 } 5789 5790 /** 5791 * This can be called with or without the global lock held. 5792 */ 5793 void enforceCallingPermission(String permission, String func) { 5794 if (checkCallingPermission(permission) 5795 == PackageManager.PERMISSION_GRANTED) { 5796 return; 5797 } 5798 5799 String msg = "Permission Denial: " + func + " from pid=" 5800 + Binder.getCallingPid() 5801 + ", uid=" + Binder.getCallingUid() 5802 + " requires " + permission; 5803 Slog.w(TAG, msg); 5804 throw new SecurityException(msg); 5805 } 5806 5807 /** 5808 * Determine if UID is holding permissions required to access {@link Uri} in 5809 * the given {@link ProviderInfo}. Final permission checking is always done 5810 * in {@link ContentProvider}. 5811 */ 5812 private final boolean checkHoldingPermissionsLocked( 5813 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5814 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5815 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5816 5817 if (pi.applicationInfo.uid == uid) { 5818 return true; 5819 } else if (!pi.exported) { 5820 return false; 5821 } 5822 5823 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5824 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5825 try { 5826 // check if target holds top-level <provider> permissions 5827 if (!readMet && pi.readPermission != null 5828 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5829 readMet = true; 5830 } 5831 if (!writeMet && pi.writePermission != null 5832 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5833 writeMet = true; 5834 } 5835 5836 // track if unprotected read/write is allowed; any denied 5837 // <path-permission> below removes this ability 5838 boolean allowDefaultRead = pi.readPermission == null; 5839 boolean allowDefaultWrite = pi.writePermission == null; 5840 5841 // check if target holds any <path-permission> that match uri 5842 final PathPermission[] pps = pi.pathPermissions; 5843 if (pps != null) { 5844 final String path = uri.getPath(); 5845 int i = pps.length; 5846 while (i > 0 && (!readMet || !writeMet)) { 5847 i--; 5848 PathPermission pp = pps[i]; 5849 if (pp.match(path)) { 5850 if (!readMet) { 5851 final String pprperm = pp.getReadPermission(); 5852 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5853 + pprperm + " for " + pp.getPath() 5854 + ": match=" + pp.match(path) 5855 + " check=" + pm.checkUidPermission(pprperm, uid)); 5856 if (pprperm != null) { 5857 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5858 readMet = true; 5859 } else { 5860 allowDefaultRead = false; 5861 } 5862 } 5863 } 5864 if (!writeMet) { 5865 final String ppwperm = pp.getWritePermission(); 5866 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5867 + ppwperm + " for " + pp.getPath() 5868 + ": match=" + pp.match(path) 5869 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5870 if (ppwperm != null) { 5871 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5872 writeMet = true; 5873 } else { 5874 allowDefaultWrite = false; 5875 } 5876 } 5877 } 5878 } 5879 } 5880 } 5881 5882 // grant unprotected <provider> read/write, if not blocked by 5883 // <path-permission> above 5884 if (allowDefaultRead) readMet = true; 5885 if (allowDefaultWrite) writeMet = true; 5886 5887 } catch (RemoteException e) { 5888 return false; 5889 } 5890 5891 return readMet && writeMet; 5892 } 5893 5894 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5895 ProviderInfo pi = null; 5896 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5897 if (cpr != null) { 5898 pi = cpr.info; 5899 } else { 5900 try { 5901 pi = AppGlobals.getPackageManager().resolveContentProvider( 5902 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5903 } catch (RemoteException ex) { 5904 } 5905 } 5906 return pi; 5907 } 5908 5909 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5910 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5911 if (targetUris != null) { 5912 return targetUris.get(uri); 5913 } else { 5914 return null; 5915 } 5916 } 5917 5918 private UriPermission findOrCreateUriPermissionLocked( 5919 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5920 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5921 if (targetUris == null) { 5922 targetUris = Maps.newArrayMap(); 5923 mGrantedUriPermissions.put(targetUid, targetUris); 5924 } 5925 5926 UriPermission perm = targetUris.get(uri); 5927 if (perm == null) { 5928 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5929 targetUris.put(uri, perm); 5930 } 5931 5932 return perm; 5933 } 5934 5935 private final boolean checkUriPermissionLocked( 5936 Uri uri, int uid, int modeFlags, int minStrength) { 5937 // Root gets to do everything. 5938 if (uid == 0) { 5939 return true; 5940 } 5941 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5942 if (perms == null) return false; 5943 UriPermission perm = perms.get(uri); 5944 if (perm == null) return false; 5945 return perm.getStrength(modeFlags) >= minStrength; 5946 } 5947 5948 @Override 5949 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5950 enforceNotIsolatedCaller("checkUriPermission"); 5951 5952 // Another redirected-binder-call permissions check as in 5953 // {@link checkComponentPermission}. 5954 Identity tlsIdentity = sCallerIdentity.get(); 5955 if (tlsIdentity != null) { 5956 uid = tlsIdentity.uid; 5957 pid = tlsIdentity.pid; 5958 } 5959 5960 // Our own process gets to do everything. 5961 if (pid == MY_PID) { 5962 return PackageManager.PERMISSION_GRANTED; 5963 } 5964 synchronized(this) { 5965 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5966 ? PackageManager.PERMISSION_GRANTED 5967 : PackageManager.PERMISSION_DENIED; 5968 } 5969 } 5970 5971 /** 5972 * Check if the targetPkg can be granted permission to access uri by 5973 * the callingUid using the given modeFlags. Throws a security exception 5974 * if callingUid is not allowed to do this. Returns the uid of the target 5975 * if the URI permission grant should be performed; returns -1 if it is not 5976 * needed (for example targetPkg already has permission to access the URI). 5977 * If you already know the uid of the target, you can supply it in 5978 * lastTargetUid else set that to -1. 5979 */ 5980 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5981 Uri uri, int modeFlags, int lastTargetUid) { 5982 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5983 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5984 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5985 if (modeFlags == 0) { 5986 return -1; 5987 } 5988 5989 if (targetPkg != null) { 5990 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5991 "Checking grant " + targetPkg + " permission to " + uri); 5992 } 5993 5994 final IPackageManager pm = AppGlobals.getPackageManager(); 5995 5996 // If this is not a content: uri, we can't do anything with it. 5997 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5998 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5999 "Can't grant URI permission for non-content URI: " + uri); 6000 return -1; 6001 } 6002 6003 final String authority = uri.getAuthority(); 6004 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6005 if (pi == null) { 6006 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6007 return -1; 6008 } 6009 6010 int targetUid = lastTargetUid; 6011 if (targetUid < 0 && targetPkg != null) { 6012 try { 6013 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6014 if (targetUid < 0) { 6015 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6016 "Can't grant URI permission no uid for: " + targetPkg); 6017 return -1; 6018 } 6019 } catch (RemoteException ex) { 6020 return -1; 6021 } 6022 } 6023 6024 if (targetUid >= 0) { 6025 // First... does the target actually need this permission? 6026 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6027 // No need to grant the target this permission. 6028 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6029 "Target " + targetPkg + " already has full permission to " + uri); 6030 return -1; 6031 } 6032 } else { 6033 // First... there is no target package, so can anyone access it? 6034 boolean allowed = pi.exported; 6035 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6036 if (pi.readPermission != null) { 6037 allowed = false; 6038 } 6039 } 6040 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6041 if (pi.writePermission != null) { 6042 allowed = false; 6043 } 6044 } 6045 if (allowed) { 6046 return -1; 6047 } 6048 } 6049 6050 // Second... is the provider allowing granting of URI permissions? 6051 if (!pi.grantUriPermissions) { 6052 throw new SecurityException("Provider " + pi.packageName 6053 + "/" + pi.name 6054 + " does not allow granting of Uri permissions (uri " 6055 + uri + ")"); 6056 } 6057 if (pi.uriPermissionPatterns != null) { 6058 final int N = pi.uriPermissionPatterns.length; 6059 boolean allowed = false; 6060 for (int i=0; i<N; i++) { 6061 if (pi.uriPermissionPatterns[i] != null 6062 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6063 allowed = true; 6064 break; 6065 } 6066 } 6067 if (!allowed) { 6068 throw new SecurityException("Provider " + pi.packageName 6069 + "/" + pi.name 6070 + " does not allow granting of permission to path of Uri " 6071 + uri); 6072 } 6073 } 6074 6075 // Third... does the caller itself have permission to access 6076 // this uri? 6077 if (callingUid != Process.myUid()) { 6078 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6079 // Require they hold a strong enough Uri permission 6080 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6081 : UriPermission.STRENGTH_OWNED; 6082 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6083 throw new SecurityException("Uid " + callingUid 6084 + " does not have permission to uri " + uri); 6085 } 6086 } 6087 } 6088 6089 return targetUid; 6090 } 6091 6092 @Override 6093 public int checkGrantUriPermission(int callingUid, String targetPkg, 6094 Uri uri, int modeFlags) { 6095 enforceNotIsolatedCaller("checkGrantUriPermission"); 6096 synchronized(this) { 6097 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6098 } 6099 } 6100 6101 void grantUriPermissionUncheckedLocked( 6102 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6103 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6104 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6105 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6106 if (modeFlags == 0) { 6107 return; 6108 } 6109 6110 // So here we are: the caller has the assumed permission 6111 // to the uri, and the target doesn't. Let's now give this to 6112 // the target. 6113 6114 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6115 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6116 6117 final String authority = uri.getAuthority(); 6118 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6119 if (pi == null) { 6120 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6121 return; 6122 } 6123 6124 final UriPermission perm = findOrCreateUriPermissionLocked( 6125 pi.packageName, targetPkg, targetUid, uri); 6126 perm.grantModes(modeFlags, persistable, owner); 6127 } 6128 6129 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6130 int modeFlags, UriPermissionOwner owner) { 6131 if (targetPkg == null) { 6132 throw new NullPointerException("targetPkg"); 6133 } 6134 6135 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6136 if (targetUid < 0) { 6137 return; 6138 } 6139 6140 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6141 } 6142 6143 static class NeededUriGrants extends ArrayList<Uri> { 6144 final String targetPkg; 6145 final int targetUid; 6146 final int flags; 6147 6148 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6149 this.targetPkg = targetPkg; 6150 this.targetUid = targetUid; 6151 this.flags = flags; 6152 } 6153 } 6154 6155 /** 6156 * Like checkGrantUriPermissionLocked, but takes an Intent. 6157 */ 6158 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6159 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6160 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6161 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6162 + " clip=" + (intent != null ? intent.getClipData() : null) 6163 + " from " + intent + "; flags=0x" 6164 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6165 6166 if (targetPkg == null) { 6167 throw new NullPointerException("targetPkg"); 6168 } 6169 6170 if (intent == null) { 6171 return null; 6172 } 6173 Uri data = intent.getData(); 6174 ClipData clip = intent.getClipData(); 6175 if (data == null && clip == null) { 6176 return null; 6177 } 6178 6179 if (data != null) { 6180 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6181 mode, needed != null ? needed.targetUid : -1); 6182 if (targetUid > 0) { 6183 if (needed == null) { 6184 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6185 } 6186 needed.add(data); 6187 } 6188 } 6189 if (clip != null) { 6190 for (int i=0; i<clip.getItemCount(); i++) { 6191 Uri uri = clip.getItemAt(i).getUri(); 6192 if (uri != null) { 6193 int targetUid = -1; 6194 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6195 mode, needed != null ? needed.targetUid : -1); 6196 if (targetUid > 0) { 6197 if (needed == null) { 6198 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6199 } 6200 needed.add(uri); 6201 } 6202 } else { 6203 Intent clipIntent = clip.getItemAt(i).getIntent(); 6204 if (clipIntent != null) { 6205 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6206 callingUid, targetPkg, clipIntent, mode, needed); 6207 if (newNeeded != null) { 6208 needed = newNeeded; 6209 } 6210 } 6211 } 6212 } 6213 } 6214 6215 return needed; 6216 } 6217 6218 /** 6219 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6220 */ 6221 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6222 UriPermissionOwner owner) { 6223 if (needed != null) { 6224 for (int i=0; i<needed.size(); i++) { 6225 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6226 needed.get(i), needed.flags, owner); 6227 } 6228 } 6229 } 6230 6231 void grantUriPermissionFromIntentLocked(int callingUid, 6232 String targetPkg, Intent intent, UriPermissionOwner owner) { 6233 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6234 intent, intent != null ? intent.getFlags() : 0, null); 6235 if (needed == null) { 6236 return; 6237 } 6238 6239 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6240 } 6241 6242 @Override 6243 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6244 Uri uri, int modeFlags) { 6245 enforceNotIsolatedCaller("grantUriPermission"); 6246 synchronized(this) { 6247 final ProcessRecord r = getRecordForAppLocked(caller); 6248 if (r == null) { 6249 throw new SecurityException("Unable to find app for caller " 6250 + caller 6251 + " when granting permission to uri " + uri); 6252 } 6253 if (targetPkg == null) { 6254 throw new IllegalArgumentException("null target"); 6255 } 6256 if (uri == null) { 6257 throw new IllegalArgumentException("null uri"); 6258 } 6259 6260 // Persistable only supported through Intents 6261 Preconditions.checkFlagsArgument(modeFlags, 6262 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6263 6264 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6265 null); 6266 } 6267 } 6268 6269 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6270 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6271 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6272 ArrayMap<Uri, UriPermission> perms 6273 = mGrantedUriPermissions.get(perm.targetUid); 6274 if (perms != null) { 6275 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6276 "Removing " + perm.targetUid + " permission to " + perm.uri); 6277 perms.remove(perm.uri); 6278 if (perms.size() == 0) { 6279 mGrantedUriPermissions.remove(perm.targetUid); 6280 } 6281 } 6282 } 6283 } 6284 6285 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6286 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6287 6288 final IPackageManager pm = AppGlobals.getPackageManager(); 6289 final String authority = uri.getAuthority(); 6290 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6291 if (pi == null) { 6292 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6293 return; 6294 } 6295 6296 // Does the caller have this permission on the URI? 6297 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6298 // Right now, if you are not the original owner of the permission, 6299 // you are not allowed to revoke it. 6300 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6301 throw new SecurityException("Uid " + callingUid 6302 + " does not have permission to uri " + uri); 6303 //} 6304 } 6305 6306 boolean persistChanged = false; 6307 6308 // Go through all of the permissions and remove any that match. 6309 final List<String> SEGMENTS = uri.getPathSegments(); 6310 if (SEGMENTS != null) { 6311 final int NS = SEGMENTS.size(); 6312 int N = mGrantedUriPermissions.size(); 6313 for (int i=0; i<N; i++) { 6314 ArrayMap<Uri, UriPermission> perms 6315 = mGrantedUriPermissions.valueAt(i); 6316 Iterator<UriPermission> it = perms.values().iterator(); 6317 toploop: 6318 while (it.hasNext()) { 6319 UriPermission perm = it.next(); 6320 Uri targetUri = perm.uri; 6321 if (!authority.equals(targetUri.getAuthority())) { 6322 continue; 6323 } 6324 List<String> targetSegments = targetUri.getPathSegments(); 6325 if (targetSegments == null) { 6326 continue; 6327 } 6328 if (targetSegments.size() < NS) { 6329 continue; 6330 } 6331 for (int j=0; j<NS; j++) { 6332 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6333 continue toploop; 6334 } 6335 } 6336 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6337 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6338 persistChanged |= perm.clearModes(modeFlags, true); 6339 if (perm.modeFlags == 0) { 6340 it.remove(); 6341 } 6342 } 6343 if (perms.size() == 0) { 6344 mGrantedUriPermissions.remove( 6345 mGrantedUriPermissions.keyAt(i)); 6346 N--; 6347 i--; 6348 } 6349 } 6350 } 6351 6352 if (persistChanged) { 6353 schedulePersistUriGrants(); 6354 } 6355 } 6356 6357 @Override 6358 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6359 int modeFlags) { 6360 enforceNotIsolatedCaller("revokeUriPermission"); 6361 synchronized(this) { 6362 final ProcessRecord r = getRecordForAppLocked(caller); 6363 if (r == null) { 6364 throw new SecurityException("Unable to find app for caller " 6365 + caller 6366 + " when revoking permission to uri " + uri); 6367 } 6368 if (uri == null) { 6369 Slog.w(TAG, "revokeUriPermission: null uri"); 6370 return; 6371 } 6372 6373 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6374 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6375 if (modeFlags == 0) { 6376 return; 6377 } 6378 6379 final IPackageManager pm = AppGlobals.getPackageManager(); 6380 final String authority = uri.getAuthority(); 6381 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6382 if (pi == null) { 6383 Slog.w(TAG, "No content provider found for permission revoke: " 6384 + uri.toSafeString()); 6385 return; 6386 } 6387 6388 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6389 } 6390 } 6391 6392 /** 6393 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6394 * given package. 6395 * 6396 * @param packageName Package name to match, or {@code null} to apply to all 6397 * packages. 6398 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6399 * to all users. 6400 * @param persistable If persistable grants should be removed. 6401 */ 6402 private void removeUriPermissionsForPackageLocked( 6403 String packageName, int userHandle, boolean persistable) { 6404 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6405 throw new IllegalArgumentException("Must narrow by either package or user"); 6406 } 6407 6408 boolean persistChanged = false; 6409 6410 final int size = mGrantedUriPermissions.size(); 6411 for (int i = 0; i < size; i++) { 6412 // Only inspect grants matching user 6413 if (userHandle == UserHandle.USER_ALL 6414 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6415 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6416 .values().iterator(); 6417 while (it.hasNext()) { 6418 final UriPermission perm = it.next(); 6419 6420 // Only inspect grants matching package 6421 if (packageName == null || perm.sourcePkg.equals(packageName) 6422 || perm.targetPkg.equals(packageName)) { 6423 persistChanged |= perm.clearModes(~0, persistable); 6424 6425 // Only remove when no modes remain; any persisted grants 6426 // will keep this alive. 6427 if (perm.modeFlags == 0) { 6428 it.remove(); 6429 } 6430 } 6431 } 6432 } 6433 } 6434 6435 if (persistChanged) { 6436 schedulePersistUriGrants(); 6437 } 6438 } 6439 6440 @Override 6441 public IBinder newUriPermissionOwner(String name) { 6442 enforceNotIsolatedCaller("newUriPermissionOwner"); 6443 synchronized(this) { 6444 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6445 return owner.getExternalTokenLocked(); 6446 } 6447 } 6448 6449 @Override 6450 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6451 Uri uri, int modeFlags) { 6452 synchronized(this) { 6453 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6454 if (owner == null) { 6455 throw new IllegalArgumentException("Unknown owner: " + token); 6456 } 6457 if (fromUid != Binder.getCallingUid()) { 6458 if (Binder.getCallingUid() != Process.myUid()) { 6459 // Only system code can grant URI permissions on behalf 6460 // of other users. 6461 throw new SecurityException("nice try"); 6462 } 6463 } 6464 if (targetPkg == null) { 6465 throw new IllegalArgumentException("null target"); 6466 } 6467 if (uri == null) { 6468 throw new IllegalArgumentException("null uri"); 6469 } 6470 6471 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6472 } 6473 } 6474 6475 @Override 6476 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6477 synchronized(this) { 6478 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6479 if (owner == null) { 6480 throw new IllegalArgumentException("Unknown owner: " + token); 6481 } 6482 6483 if (uri == null) { 6484 owner.removeUriPermissionsLocked(mode); 6485 } else { 6486 owner.removeUriPermissionLocked(uri, mode); 6487 } 6488 } 6489 } 6490 6491 private void schedulePersistUriGrants() { 6492 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6493 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6494 10 * DateUtils.SECOND_IN_MILLIS); 6495 } 6496 } 6497 6498 private void writeGrantedUriPermissions() { 6499 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6500 6501 // Snapshot permissions so we can persist without lock 6502 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6503 synchronized (this) { 6504 final int size = mGrantedUriPermissions.size(); 6505 for (int i = 0 ; i < size; i++) { 6506 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6507 if (perm.persistedModeFlags != 0) { 6508 persist.add(perm.snapshot()); 6509 } 6510 } 6511 } 6512 } 6513 6514 FileOutputStream fos = null; 6515 try { 6516 fos = mGrantFile.startWrite(); 6517 6518 XmlSerializer out = new FastXmlSerializer(); 6519 out.setOutput(fos, "utf-8"); 6520 out.startDocument(null, true); 6521 out.startTag(null, TAG_URI_GRANTS); 6522 for (UriPermission.Snapshot perm : persist) { 6523 out.startTag(null, TAG_URI_GRANT); 6524 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6525 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6526 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6527 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6528 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6529 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6530 out.endTag(null, TAG_URI_GRANT); 6531 } 6532 out.endTag(null, TAG_URI_GRANTS); 6533 out.endDocument(); 6534 6535 mGrantFile.finishWrite(fos); 6536 } catch (IOException e) { 6537 if (fos != null) { 6538 mGrantFile.failWrite(fos); 6539 } 6540 } 6541 } 6542 6543 private void readGrantedUriPermissionsLocked() { 6544 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6545 6546 final long now = System.currentTimeMillis(); 6547 6548 FileInputStream fis = null; 6549 try { 6550 fis = mGrantFile.openRead(); 6551 final XmlPullParser in = Xml.newPullParser(); 6552 in.setInput(fis, null); 6553 6554 int type; 6555 while ((type = in.next()) != END_DOCUMENT) { 6556 final String tag = in.getName(); 6557 if (type == START_TAG) { 6558 if (TAG_URI_GRANT.equals(tag)) { 6559 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6560 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6561 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6562 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6563 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6564 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6565 6566 // Sanity check that provider still belongs to source package 6567 final ProviderInfo pi = getProviderInfoLocked( 6568 uri.getAuthority(), userHandle); 6569 if (pi != null && sourcePkg.equals(pi.packageName)) { 6570 int targetUid = -1; 6571 try { 6572 targetUid = AppGlobals.getPackageManager() 6573 .getPackageUid(targetPkg, userHandle); 6574 } catch (RemoteException e) { 6575 } 6576 if (targetUid != -1) { 6577 final UriPermission perm = findOrCreateUriPermissionLocked( 6578 sourcePkg, targetPkg, targetUid, uri); 6579 perm.initPersistedModes(modeFlags, createdTime); 6580 } 6581 } else { 6582 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6583 + " but instead found " + pi); 6584 } 6585 } 6586 } 6587 } 6588 } catch (FileNotFoundException e) { 6589 // Missing grants is okay 6590 } catch (IOException e) { 6591 Log.wtf(TAG, "Failed reading Uri grants", e); 6592 } catch (XmlPullParserException e) { 6593 Log.wtf(TAG, "Failed reading Uri grants", e); 6594 } finally { 6595 IoUtils.closeQuietly(fis); 6596 } 6597 } 6598 6599 @Override 6600 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6601 enforceNotIsolatedCaller("takePersistableUriPermission"); 6602 6603 Preconditions.checkFlagsArgument(modeFlags, 6604 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6605 6606 synchronized (this) { 6607 final int callingUid = Binder.getCallingUid(); 6608 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6609 if (perm == null) { 6610 throw new SecurityException("No permission grant found for UID " + callingUid 6611 + " and Uri " + uri.toSafeString()); 6612 } 6613 6614 boolean persistChanged = perm.takePersistableModes(modeFlags); 6615 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6616 6617 if (persistChanged) { 6618 schedulePersistUriGrants(); 6619 } 6620 } 6621 } 6622 6623 @Override 6624 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6625 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6626 6627 Preconditions.checkFlagsArgument(modeFlags, 6628 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6629 6630 synchronized (this) { 6631 final int callingUid = Binder.getCallingUid(); 6632 6633 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6634 if (perm == null) { 6635 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6636 + uri.toSafeString()); 6637 return; 6638 } 6639 6640 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6641 removeUriPermissionIfNeededLocked(perm); 6642 if (persistChanged) { 6643 schedulePersistUriGrants(); 6644 } 6645 } 6646 } 6647 6648 /** 6649 * Prune any older {@link UriPermission} for the given UID until outstanding 6650 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6651 * 6652 * @return if any mutations occured that require persisting. 6653 */ 6654 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6655 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6656 if (perms == null) return false; 6657 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6658 6659 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6660 for (UriPermission perm : perms.values()) { 6661 if (perm.persistedModeFlags != 0) { 6662 persisted.add(perm); 6663 } 6664 } 6665 6666 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6667 if (trimCount <= 0) return false; 6668 6669 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6670 for (int i = 0; i < trimCount; i++) { 6671 final UriPermission perm = persisted.get(i); 6672 6673 if (DEBUG_URI_PERMISSION) { 6674 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6675 } 6676 6677 perm.releasePersistableModes(~0); 6678 removeUriPermissionIfNeededLocked(perm); 6679 } 6680 6681 return true; 6682 } 6683 6684 @Override 6685 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6686 String packageName, boolean incoming) { 6687 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6688 Preconditions.checkNotNull(packageName, "packageName"); 6689 6690 final int callingUid = Binder.getCallingUid(); 6691 final IPackageManager pm = AppGlobals.getPackageManager(); 6692 try { 6693 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6694 if (packageUid != callingUid) { 6695 throw new SecurityException( 6696 "Package " + packageName + " does not belong to calling UID " + callingUid); 6697 } 6698 } catch (RemoteException e) { 6699 throw new SecurityException("Failed to verify package name ownership"); 6700 } 6701 6702 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6703 synchronized (this) { 6704 if (incoming) { 6705 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6706 if (perms == null) { 6707 Slog.w(TAG, "No permission grants found for " + packageName); 6708 } else { 6709 final int size = perms.size(); 6710 for (int i = 0; i < size; i++) { 6711 final UriPermission perm = perms.valueAt(i); 6712 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6713 result.add(perm.buildPersistedPublicApiObject()); 6714 } 6715 } 6716 } 6717 } else { 6718 final int size = mGrantedUriPermissions.size(); 6719 for (int i = 0; i < size; i++) { 6720 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6721 final int permsSize = perms.size(); 6722 for (int j = 0; j < permsSize; j++) { 6723 final UriPermission perm = perms.valueAt(j); 6724 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6725 result.add(perm.buildPersistedPublicApiObject()); 6726 } 6727 } 6728 } 6729 } 6730 } 6731 return new ParceledListSlice<android.content.UriPermission>(result); 6732 } 6733 6734 @Override 6735 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6736 synchronized (this) { 6737 ProcessRecord app = 6738 who != null ? getRecordForAppLocked(who) : null; 6739 if (app == null) return; 6740 6741 Message msg = Message.obtain(); 6742 msg.what = WAIT_FOR_DEBUGGER_MSG; 6743 msg.obj = app; 6744 msg.arg1 = waiting ? 1 : 0; 6745 mHandler.sendMessage(msg); 6746 } 6747 } 6748 6749 @Override 6750 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6751 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6752 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6753 outInfo.availMem = Process.getFreeMemory(); 6754 outInfo.totalMem = Process.getTotalMemory(); 6755 outInfo.threshold = homeAppMem; 6756 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6757 outInfo.hiddenAppThreshold = cachedAppMem; 6758 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6759 ProcessList.SERVICE_ADJ); 6760 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6761 ProcessList.VISIBLE_APP_ADJ); 6762 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6763 ProcessList.FOREGROUND_APP_ADJ); 6764 } 6765 6766 // ========================================================= 6767 // TASK MANAGEMENT 6768 // ========================================================= 6769 6770 @Override 6771 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6772 IThumbnailReceiver receiver) { 6773 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6774 6775 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6776 ActivityRecord topRecord = null; 6777 6778 synchronized(this) { 6779 if (localLOGV) Slog.v( 6780 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6781 + ", receiver=" + receiver); 6782 6783 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6784 != PackageManager.PERMISSION_GRANTED) { 6785 if (receiver != null) { 6786 // If the caller wants to wait for pending thumbnails, 6787 // it ain't gonna get them. 6788 try { 6789 receiver.finished(); 6790 } catch (RemoteException ex) { 6791 } 6792 } 6793 String msg = "Permission Denial: getTasks() from pid=" 6794 + Binder.getCallingPid() 6795 + ", uid=" + Binder.getCallingUid() 6796 + " requires " + android.Manifest.permission.GET_TASKS; 6797 Slog.w(TAG, msg); 6798 throw new SecurityException(msg); 6799 } 6800 6801 // TODO: Improve with MRU list from all ActivityStacks. 6802 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6803 6804 if (!pending.pendingRecords.isEmpty()) { 6805 mPendingThumbnails.add(pending); 6806 } 6807 } 6808 6809 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6810 6811 if (topRecord != null) { 6812 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6813 try { 6814 IApplicationThread topThumbnail = topRecord.app.thread; 6815 topThumbnail.requestThumbnail(topRecord.appToken); 6816 } catch (Exception e) { 6817 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6818 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6819 } 6820 } 6821 6822 if (pending == null && receiver != null) { 6823 // In this case all thumbnails were available and the client 6824 // is being asked to be told when the remaining ones come in... 6825 // which is unusually, since the top-most currently running 6826 // activity should never have a canned thumbnail! Oh well. 6827 try { 6828 receiver.finished(); 6829 } catch (RemoteException ex) { 6830 } 6831 } 6832 6833 return list; 6834 } 6835 6836 TaskRecord getMostRecentTask() { 6837 return mRecentTasks.get(0); 6838 } 6839 6840 @Override 6841 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6842 int flags, int userId) { 6843 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6844 false, true, "getRecentTasks", null); 6845 6846 synchronized (this) { 6847 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6848 "getRecentTasks()"); 6849 final boolean detailed = checkCallingPermission( 6850 android.Manifest.permission.GET_DETAILED_TASKS) 6851 == PackageManager.PERMISSION_GRANTED; 6852 6853 IPackageManager pm = AppGlobals.getPackageManager(); 6854 6855 final int N = mRecentTasks.size(); 6856 ArrayList<ActivityManager.RecentTaskInfo> res 6857 = new ArrayList<ActivityManager.RecentTaskInfo>( 6858 maxNum < N ? maxNum : N); 6859 for (int i=0; i<N && maxNum > 0; i++) { 6860 TaskRecord tr = mRecentTasks.get(i); 6861 // Only add calling user's recent tasks 6862 if (tr.userId != userId) continue; 6863 // Return the entry if desired by the caller. We always return 6864 // the first entry, because callers always expect this to be the 6865 // foreground app. We may filter others if the caller has 6866 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6867 // we should exclude the entry. 6868 6869 if (i == 0 6870 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6871 || (tr.intent == null) 6872 || ((tr.intent.getFlags() 6873 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6874 ActivityManager.RecentTaskInfo rti 6875 = new ActivityManager.RecentTaskInfo(); 6876 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6877 rti.persistentId = tr.taskId; 6878 rti.baseIntent = new Intent( 6879 tr.intent != null ? tr.intent : tr.affinityIntent); 6880 if (!detailed) { 6881 rti.baseIntent.replaceExtras((Bundle)null); 6882 } 6883 rti.origActivity = tr.origActivity; 6884 rti.description = tr.lastDescription; 6885 rti.stackId = tr.stack.mStackId; 6886 6887 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6888 // Check whether this activity is currently available. 6889 try { 6890 if (rti.origActivity != null) { 6891 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6892 == null) { 6893 continue; 6894 } 6895 } else if (rti.baseIntent != null) { 6896 if (pm.queryIntentActivities(rti.baseIntent, 6897 null, 0, userId) == null) { 6898 continue; 6899 } 6900 } 6901 } catch (RemoteException e) { 6902 // Will never happen. 6903 } 6904 } 6905 6906 res.add(rti); 6907 maxNum--; 6908 } 6909 } 6910 return res; 6911 } 6912 } 6913 6914 private TaskRecord recentTaskForIdLocked(int id) { 6915 final int N = mRecentTasks.size(); 6916 for (int i=0; i<N; i++) { 6917 TaskRecord tr = mRecentTasks.get(i); 6918 if (tr.taskId == id) { 6919 return tr; 6920 } 6921 } 6922 return null; 6923 } 6924 6925 @Override 6926 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6927 synchronized (this) { 6928 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6929 "getTaskThumbnails()"); 6930 TaskRecord tr = recentTaskForIdLocked(id); 6931 if (tr != null) { 6932 return tr.getTaskThumbnailsLocked(); 6933 } 6934 } 6935 return null; 6936 } 6937 6938 @Override 6939 public Bitmap getTaskTopThumbnail(int id) { 6940 synchronized (this) { 6941 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6942 "getTaskTopThumbnail()"); 6943 TaskRecord tr = recentTaskForIdLocked(id); 6944 if (tr != null) { 6945 return tr.getTaskTopThumbnailLocked(); 6946 } 6947 } 6948 return null; 6949 } 6950 6951 @Override 6952 public boolean removeSubTask(int taskId, int subTaskIndex) { 6953 synchronized (this) { 6954 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6955 "removeSubTask()"); 6956 long ident = Binder.clearCallingIdentity(); 6957 try { 6958 TaskRecord tr = recentTaskForIdLocked(taskId); 6959 if (tr != null) { 6960 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6961 } 6962 return false; 6963 } finally { 6964 Binder.restoreCallingIdentity(ident); 6965 } 6966 } 6967 } 6968 6969 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6970 if (!pr.killedByAm) { 6971 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6972 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6973 pr.processName, pr.setAdj, reason); 6974 pr.killedByAm = true; 6975 Process.killProcessQuiet(pr.pid); 6976 } 6977 } 6978 6979 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6980 tr.disposeThumbnail(); 6981 mRecentTasks.remove(tr); 6982 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6983 Intent baseIntent = new Intent( 6984 tr.intent != null ? tr.intent : tr.affinityIntent); 6985 ComponentName component = baseIntent.getComponent(); 6986 if (component == null) { 6987 Slog.w(TAG, "Now component for base intent of task: " + tr); 6988 return; 6989 } 6990 6991 // Find any running services associated with this app. 6992 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6993 6994 if (killProcesses) { 6995 // Find any running processes associated with this app. 6996 final String pkg = component.getPackageName(); 6997 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6998 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6999 for (int i=0; i<pmap.size(); i++) { 7000 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7001 for (int j=0; j<uids.size(); j++) { 7002 ProcessRecord proc = uids.valueAt(j); 7003 if (proc.userId != tr.userId) { 7004 continue; 7005 } 7006 if (!proc.pkgList.containsKey(pkg)) { 7007 continue; 7008 } 7009 procs.add(proc); 7010 } 7011 } 7012 7013 // Kill the running processes. 7014 for (int i=0; i<procs.size(); i++) { 7015 ProcessRecord pr = procs.get(i); 7016 if (pr == mHomeProcess) { 7017 // Don't kill the home process along with tasks from the same package. 7018 continue; 7019 } 7020 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7021 killUnneededProcessLocked(pr, "remove task"); 7022 } else { 7023 pr.waitingToKill = "remove task"; 7024 } 7025 } 7026 } 7027 } 7028 7029 @Override 7030 public boolean removeTask(int taskId, int flags) { 7031 synchronized (this) { 7032 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7033 "removeTask()"); 7034 long ident = Binder.clearCallingIdentity(); 7035 try { 7036 TaskRecord tr = recentTaskForIdLocked(taskId); 7037 if (tr != null) { 7038 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7039 if (r != null) { 7040 cleanUpRemovedTaskLocked(tr, flags); 7041 return true; 7042 } 7043 if (tr.mActivities.size() == 0) { 7044 // Caller is just removing a recent task that is 7045 // not actively running. That is easy! 7046 cleanUpRemovedTaskLocked(tr, flags); 7047 return true; 7048 } 7049 Slog.w(TAG, "removeTask: task " + taskId 7050 + " does not have activities to remove, " 7051 + " but numActivities=" + tr.numActivities 7052 + ": " + tr); 7053 } 7054 } finally { 7055 Binder.restoreCallingIdentity(ident); 7056 } 7057 } 7058 return false; 7059 } 7060 7061 /** 7062 * TODO: Add mController hook 7063 */ 7064 @Override 7065 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7066 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7067 "moveTaskToFront()"); 7068 7069 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7070 synchronized(this) { 7071 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7072 Binder.getCallingUid(), "Task to front")) { 7073 ActivityOptions.abort(options); 7074 return; 7075 } 7076 final long origId = Binder.clearCallingIdentity(); 7077 try { 7078 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7079 if (task == null) { 7080 return; 7081 } 7082 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7083 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7084 return; 7085 } 7086 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7087 } finally { 7088 Binder.restoreCallingIdentity(origId); 7089 } 7090 ActivityOptions.abort(options); 7091 } 7092 } 7093 7094 @Override 7095 public void moveTaskToBack(int taskId) { 7096 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7097 "moveTaskToBack()"); 7098 7099 synchronized(this) { 7100 TaskRecord tr = recentTaskForIdLocked(taskId); 7101 if (tr != null) { 7102 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7103 ActivityStack stack = tr.stack; 7104 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7105 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7106 Binder.getCallingUid(), "Task to back")) { 7107 return; 7108 } 7109 } 7110 final long origId = Binder.clearCallingIdentity(); 7111 try { 7112 stack.moveTaskToBackLocked(taskId, null); 7113 } finally { 7114 Binder.restoreCallingIdentity(origId); 7115 } 7116 } 7117 } 7118 } 7119 7120 /** 7121 * Moves an activity, and all of the other activities within the same task, to the bottom 7122 * of the history stack. The activity's order within the task is unchanged. 7123 * 7124 * @param token A reference to the activity we wish to move 7125 * @param nonRoot If false then this only works if the activity is the root 7126 * of a task; if true it will work for any activity in a task. 7127 * @return Returns true if the move completed, false if not. 7128 */ 7129 @Override 7130 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7131 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7132 synchronized(this) { 7133 final long origId = Binder.clearCallingIdentity(); 7134 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7135 if (taskId >= 0) { 7136 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7137 } 7138 Binder.restoreCallingIdentity(origId); 7139 } 7140 return false; 7141 } 7142 7143 @Override 7144 public void moveTaskBackwards(int task) { 7145 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7146 "moveTaskBackwards()"); 7147 7148 synchronized(this) { 7149 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7150 Binder.getCallingUid(), "Task backwards")) { 7151 return; 7152 } 7153 final long origId = Binder.clearCallingIdentity(); 7154 moveTaskBackwardsLocked(task); 7155 Binder.restoreCallingIdentity(origId); 7156 } 7157 } 7158 7159 private final void moveTaskBackwardsLocked(int task) { 7160 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7161 } 7162 7163 @Override 7164 public IBinder getHomeActivityToken() throws RemoteException { 7165 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7166 "getHomeActivityToken()"); 7167 synchronized (this) { 7168 return mStackSupervisor.getHomeActivityToken(); 7169 } 7170 } 7171 7172 @Override 7173 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7174 IActivityContainerCallback callback) throws RemoteException { 7175 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7176 "createActivityContainer()"); 7177 synchronized (this) { 7178 if (parentActivityToken == null) { 7179 throw new IllegalArgumentException("parent token must not be null"); 7180 } 7181 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7182 if (r == null) { 7183 return null; 7184 } 7185 return mStackSupervisor.createActivityContainer(r, callback); 7186 } 7187 } 7188 7189 @Override 7190 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7191 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7192 "deleteActivityContainer()"); 7193 synchronized (this) { 7194 mStackSupervisor.deleteActivityContainer(container); 7195 } 7196 } 7197 7198 @Override 7199 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7200 throws RemoteException { 7201 synchronized (this) { 7202 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7203 if (stack != null) { 7204 return stack.mActivityContainer; 7205 } 7206 return null; 7207 } 7208 } 7209 7210 @Override 7211 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7212 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7213 "moveTaskToStack()"); 7214 if (stackId == HOME_STACK_ID) { 7215 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7216 new RuntimeException("here").fillInStackTrace()); 7217 } 7218 synchronized (this) { 7219 long ident = Binder.clearCallingIdentity(); 7220 try { 7221 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7222 + stackId + " toTop=" + toTop); 7223 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7224 } finally { 7225 Binder.restoreCallingIdentity(ident); 7226 } 7227 } 7228 } 7229 7230 @Override 7231 public void resizeStack(int stackBoxId, Rect bounds) { 7232 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7233 "resizeStackBox()"); 7234 long ident = Binder.clearCallingIdentity(); 7235 try { 7236 mWindowManager.resizeStack(stackBoxId, bounds); 7237 } finally { 7238 Binder.restoreCallingIdentity(ident); 7239 } 7240 } 7241 7242 @Override 7243 public List<StackInfo> getAllStackInfos() { 7244 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7245 "getAllStackInfos()"); 7246 long ident = Binder.clearCallingIdentity(); 7247 try { 7248 synchronized (this) { 7249 return mStackSupervisor.getAllStackInfosLocked(); 7250 } 7251 } finally { 7252 Binder.restoreCallingIdentity(ident); 7253 } 7254 } 7255 7256 @Override 7257 public StackInfo getStackInfo(int stackId) { 7258 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7259 "getStackInfo()"); 7260 long ident = Binder.clearCallingIdentity(); 7261 try { 7262 synchronized (this) { 7263 return mStackSupervisor.getStackInfoLocked(stackId); 7264 } 7265 } finally { 7266 Binder.restoreCallingIdentity(ident); 7267 } 7268 } 7269 7270 @Override 7271 public boolean isInHomeStack(int taskId) { 7272 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7273 "getStackInfo()"); 7274 long ident = Binder.clearCallingIdentity(); 7275 try { 7276 synchronized (this) { 7277 TaskRecord tr = recentTaskForIdLocked(taskId); 7278 if (tr != null) { 7279 return tr.stack.isHomeStack(); 7280 } 7281 } 7282 } finally { 7283 Binder.restoreCallingIdentity(ident); 7284 } 7285 return false; 7286 } 7287 7288 @Override 7289 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7290 synchronized(this) { 7291 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7292 } 7293 } 7294 7295 private boolean isLockTaskAuthorized(ComponentName name) { 7296// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7297// "startLockTaskMode()"); 7298// DevicePolicyManager dpm = (DevicePolicyManager) 7299// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7300// return dpm != null && dpm.isLockTaskPermitted(name); 7301 return true; 7302 } 7303 7304 private void startLockTaskMode(TaskRecord task) { 7305 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7306 return; 7307 } 7308 long ident = Binder.clearCallingIdentity(); 7309 try { 7310 synchronized (this) { 7311 // Since we lost lock on task, make sure it is still there. 7312 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7313 if (task != null) { 7314 mStackSupervisor.setLockTaskModeLocked(task); 7315 } 7316 } 7317 } finally { 7318 Binder.restoreCallingIdentity(ident); 7319 } 7320 } 7321 7322 @Override 7323 public void startLockTaskMode(int taskId) { 7324 long ident = Binder.clearCallingIdentity(); 7325 try { 7326 final TaskRecord task; 7327 synchronized (this) { 7328 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7329 } 7330 if (task != null) { 7331 startLockTaskMode(task); 7332 } 7333 } finally { 7334 Binder.restoreCallingIdentity(ident); 7335 } 7336 } 7337 7338 @Override 7339 public void startLockTaskMode(IBinder token) { 7340 long ident = Binder.clearCallingIdentity(); 7341 try { 7342 final TaskRecord task; 7343 synchronized (this) { 7344 final ActivityRecord r = ActivityRecord.forToken(token); 7345 if (r == null) { 7346 return; 7347 } 7348 task = r.task; 7349 } 7350 if (task != null) { 7351 startLockTaskMode(task); 7352 } 7353 } finally { 7354 Binder.restoreCallingIdentity(ident); 7355 } 7356 } 7357 7358 @Override 7359 public void stopLockTaskMode() { 7360// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7361// "stopLockTaskMode()"); 7362 synchronized (this) { 7363 mStackSupervisor.setLockTaskModeLocked(null); 7364 } 7365 } 7366 7367 @Override 7368 public boolean isInLockTaskMode() { 7369 synchronized (this) { 7370 return mStackSupervisor.isInLockTaskMode(); 7371 } 7372 } 7373 7374 // ========================================================= 7375 // THUMBNAILS 7376 // ========================================================= 7377 7378 public void reportThumbnail(IBinder token, 7379 Bitmap thumbnail, CharSequence description) { 7380 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7381 final long origId = Binder.clearCallingIdentity(); 7382 sendPendingThumbnail(null, token, thumbnail, description, true); 7383 Binder.restoreCallingIdentity(origId); 7384 } 7385 7386 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7387 Bitmap thumbnail, CharSequence description, boolean always) { 7388 TaskRecord task; 7389 ArrayList<PendingThumbnailsRecord> receivers = null; 7390 7391 //System.out.println("Send pending thumbnail: " + r); 7392 7393 synchronized(this) { 7394 if (r == null) { 7395 r = ActivityRecord.isInStackLocked(token); 7396 if (r == null) { 7397 return; 7398 } 7399 } 7400 if (thumbnail == null && r.thumbHolder != null) { 7401 thumbnail = r.thumbHolder.lastThumbnail; 7402 description = r.thumbHolder.lastDescription; 7403 } 7404 if (thumbnail == null && !always) { 7405 // If there is no thumbnail, and this entry is not actually 7406 // going away, then abort for now and pick up the next 7407 // thumbnail we get. 7408 return; 7409 } 7410 task = r.task; 7411 7412 int N = mPendingThumbnails.size(); 7413 int i=0; 7414 while (i<N) { 7415 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7416 //System.out.println("Looking in " + pr.pendingRecords); 7417 if (pr.pendingRecords.remove(r)) { 7418 if (receivers == null) { 7419 receivers = new ArrayList<PendingThumbnailsRecord>(); 7420 } 7421 receivers.add(pr); 7422 if (pr.pendingRecords.size() == 0) { 7423 pr.finished = true; 7424 mPendingThumbnails.remove(i); 7425 N--; 7426 continue; 7427 } 7428 } 7429 i++; 7430 } 7431 } 7432 7433 if (receivers != null) { 7434 final int N = receivers.size(); 7435 for (int i=0; i<N; i++) { 7436 try { 7437 PendingThumbnailsRecord pr = receivers.get(i); 7438 pr.receiver.newThumbnail( 7439 task != null ? task.taskId : -1, thumbnail, description); 7440 if (pr.finished) { 7441 pr.receiver.finished(); 7442 } 7443 } catch (Exception e) { 7444 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7445 } 7446 } 7447 } 7448 } 7449 7450 // ========================================================= 7451 // CONTENT PROVIDERS 7452 // ========================================================= 7453 7454 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7455 List<ProviderInfo> providers = null; 7456 try { 7457 providers = AppGlobals.getPackageManager(). 7458 queryContentProviders(app.processName, app.uid, 7459 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7460 } catch (RemoteException ex) { 7461 } 7462 if (DEBUG_MU) 7463 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7464 int userId = app.userId; 7465 if (providers != null) { 7466 int N = providers.size(); 7467 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7468 for (int i=0; i<N; i++) { 7469 ProviderInfo cpi = 7470 (ProviderInfo)providers.get(i); 7471 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7472 cpi.name, cpi.flags); 7473 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7474 // This is a singleton provider, but a user besides the 7475 // default user is asking to initialize a process it runs 7476 // in... well, no, it doesn't actually run in this process, 7477 // it runs in the process of the default user. Get rid of it. 7478 providers.remove(i); 7479 N--; 7480 i--; 7481 continue; 7482 } 7483 7484 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7485 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7486 if (cpr == null) { 7487 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7488 mProviderMap.putProviderByClass(comp, cpr); 7489 } 7490 if (DEBUG_MU) 7491 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7492 app.pubProviders.put(cpi.name, cpr); 7493 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7494 // Don't add this if it is a platform component that is marked 7495 // to run in multiple processes, because this is actually 7496 // part of the framework so doesn't make sense to track as a 7497 // separate apk in the process. 7498 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7499 } 7500 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7501 } 7502 } 7503 return providers; 7504 } 7505 7506 /** 7507 * Check if {@link ProcessRecord} has a possible chance at accessing the 7508 * given {@link ProviderInfo}. Final permission checking is always done 7509 * in {@link ContentProvider}. 7510 */ 7511 private final String checkContentProviderPermissionLocked( 7512 ProviderInfo cpi, ProcessRecord r) { 7513 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7514 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7515 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7516 cpi.applicationInfo.uid, cpi.exported) 7517 == PackageManager.PERMISSION_GRANTED) { 7518 return null; 7519 } 7520 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7521 cpi.applicationInfo.uid, cpi.exported) 7522 == PackageManager.PERMISSION_GRANTED) { 7523 return null; 7524 } 7525 7526 PathPermission[] pps = cpi.pathPermissions; 7527 if (pps != null) { 7528 int i = pps.length; 7529 while (i > 0) { 7530 i--; 7531 PathPermission pp = pps[i]; 7532 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7533 cpi.applicationInfo.uid, cpi.exported) 7534 == PackageManager.PERMISSION_GRANTED) { 7535 return null; 7536 } 7537 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7538 cpi.applicationInfo.uid, cpi.exported) 7539 == PackageManager.PERMISSION_GRANTED) { 7540 return null; 7541 } 7542 } 7543 } 7544 7545 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7546 if (perms != null) { 7547 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7548 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7549 return null; 7550 } 7551 } 7552 } 7553 7554 String msg; 7555 if (!cpi.exported) { 7556 msg = "Permission Denial: opening provider " + cpi.name 7557 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7558 + ", uid=" + callingUid + ") that is not exported from uid " 7559 + cpi.applicationInfo.uid; 7560 } else { 7561 msg = "Permission Denial: opening provider " + cpi.name 7562 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7563 + ", uid=" + callingUid + ") requires " 7564 + cpi.readPermission + " or " + cpi.writePermission; 7565 } 7566 Slog.w(TAG, msg); 7567 return msg; 7568 } 7569 7570 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7571 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7572 if (r != null) { 7573 for (int i=0; i<r.conProviders.size(); i++) { 7574 ContentProviderConnection conn = r.conProviders.get(i); 7575 if (conn.provider == cpr) { 7576 if (DEBUG_PROVIDER) Slog.v(TAG, 7577 "Adding provider requested by " 7578 + r.processName + " from process " 7579 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7580 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7581 if (stable) { 7582 conn.stableCount++; 7583 conn.numStableIncs++; 7584 } else { 7585 conn.unstableCount++; 7586 conn.numUnstableIncs++; 7587 } 7588 return conn; 7589 } 7590 } 7591 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7592 if (stable) { 7593 conn.stableCount = 1; 7594 conn.numStableIncs = 1; 7595 } else { 7596 conn.unstableCount = 1; 7597 conn.numUnstableIncs = 1; 7598 } 7599 cpr.connections.add(conn); 7600 r.conProviders.add(conn); 7601 return conn; 7602 } 7603 cpr.addExternalProcessHandleLocked(externalProcessToken); 7604 return null; 7605 } 7606 7607 boolean decProviderCountLocked(ContentProviderConnection conn, 7608 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7609 if (conn != null) { 7610 cpr = conn.provider; 7611 if (DEBUG_PROVIDER) Slog.v(TAG, 7612 "Removing provider requested by " 7613 + conn.client.processName + " from process " 7614 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7615 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7616 if (stable) { 7617 conn.stableCount--; 7618 } else { 7619 conn.unstableCount--; 7620 } 7621 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7622 cpr.connections.remove(conn); 7623 conn.client.conProviders.remove(conn); 7624 return true; 7625 } 7626 return false; 7627 } 7628 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7629 return false; 7630 } 7631 7632 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7633 String name, IBinder token, boolean stable, int userId) { 7634 ContentProviderRecord cpr; 7635 ContentProviderConnection conn = null; 7636 ProviderInfo cpi = null; 7637 7638 synchronized(this) { 7639 ProcessRecord r = null; 7640 if (caller != null) { 7641 r = getRecordForAppLocked(caller); 7642 if (r == null) { 7643 throw new SecurityException( 7644 "Unable to find app for caller " + caller 7645 + " (pid=" + Binder.getCallingPid() 7646 + ") when getting content provider " + name); 7647 } 7648 } 7649 7650 // First check if this content provider has been published... 7651 cpr = mProviderMap.getProviderByName(name, userId); 7652 boolean providerRunning = cpr != null; 7653 if (providerRunning) { 7654 cpi = cpr.info; 7655 String msg; 7656 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7657 throw new SecurityException(msg); 7658 } 7659 7660 if (r != null && cpr.canRunHere(r)) { 7661 // This provider has been published or is in the process 7662 // of being published... but it is also allowed to run 7663 // in the caller's process, so don't make a connection 7664 // and just let the caller instantiate its own instance. 7665 ContentProviderHolder holder = cpr.newHolder(null); 7666 // don't give caller the provider object, it needs 7667 // to make its own. 7668 holder.provider = null; 7669 return holder; 7670 } 7671 7672 final long origId = Binder.clearCallingIdentity(); 7673 7674 // In this case the provider instance already exists, so we can 7675 // return it right away. 7676 conn = incProviderCountLocked(r, cpr, token, stable); 7677 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7678 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7679 // If this is a perceptible app accessing the provider, 7680 // make sure to count it as being accessed and thus 7681 // back up on the LRU list. This is good because 7682 // content providers are often expensive to start. 7683 updateLruProcessLocked(cpr.proc, false, null); 7684 } 7685 } 7686 7687 if (cpr.proc != null) { 7688 if (false) { 7689 if (cpr.name.flattenToShortString().equals( 7690 "com.android.providers.calendar/.CalendarProvider2")) { 7691 Slog.v(TAG, "****************** KILLING " 7692 + cpr.name.flattenToShortString()); 7693 Process.killProcess(cpr.proc.pid); 7694 } 7695 } 7696 boolean success = updateOomAdjLocked(cpr.proc); 7697 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7698 // NOTE: there is still a race here where a signal could be 7699 // pending on the process even though we managed to update its 7700 // adj level. Not sure what to do about this, but at least 7701 // the race is now smaller. 7702 if (!success) { 7703 // Uh oh... it looks like the provider's process 7704 // has been killed on us. We need to wait for a new 7705 // process to be started, and make sure its death 7706 // doesn't kill our process. 7707 Slog.i(TAG, 7708 "Existing provider " + cpr.name.flattenToShortString() 7709 + " is crashing; detaching " + r); 7710 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7711 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7712 if (!lastRef) { 7713 // This wasn't the last ref our process had on 7714 // the provider... we have now been killed, bail. 7715 return null; 7716 } 7717 providerRunning = false; 7718 conn = null; 7719 } 7720 } 7721 7722 Binder.restoreCallingIdentity(origId); 7723 } 7724 7725 boolean singleton; 7726 if (!providerRunning) { 7727 try { 7728 cpi = AppGlobals.getPackageManager(). 7729 resolveContentProvider(name, 7730 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7731 } catch (RemoteException ex) { 7732 } 7733 if (cpi == null) { 7734 return null; 7735 } 7736 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7737 cpi.name, cpi.flags); 7738 if (singleton) { 7739 userId = 0; 7740 } 7741 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7742 7743 String msg; 7744 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7745 throw new SecurityException(msg); 7746 } 7747 7748 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7749 && !cpi.processName.equals("system")) { 7750 // If this content provider does not run in the system 7751 // process, and the system is not yet ready to run other 7752 // processes, then fail fast instead of hanging. 7753 throw new IllegalArgumentException( 7754 "Attempt to launch content provider before system ready"); 7755 } 7756 7757 // Make sure that the user who owns this provider is started. If not, 7758 // we don't want to allow it to run. 7759 if (mStartedUsers.get(userId) == null) { 7760 Slog.w(TAG, "Unable to launch app " 7761 + cpi.applicationInfo.packageName + "/" 7762 + cpi.applicationInfo.uid + " for provider " 7763 + name + ": user " + userId + " is stopped"); 7764 return null; 7765 } 7766 7767 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7768 cpr = mProviderMap.getProviderByClass(comp, userId); 7769 final boolean firstClass = cpr == null; 7770 if (firstClass) { 7771 try { 7772 ApplicationInfo ai = 7773 AppGlobals.getPackageManager(). 7774 getApplicationInfo( 7775 cpi.applicationInfo.packageName, 7776 STOCK_PM_FLAGS, userId); 7777 if (ai == null) { 7778 Slog.w(TAG, "No package info for content provider " 7779 + cpi.name); 7780 return null; 7781 } 7782 ai = getAppInfoForUser(ai, userId); 7783 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7784 } catch (RemoteException ex) { 7785 // pm is in same process, this will never happen. 7786 } 7787 } 7788 7789 if (r != null && cpr.canRunHere(r)) { 7790 // If this is a multiprocess provider, then just return its 7791 // info and allow the caller to instantiate it. Only do 7792 // this if the provider is the same user as the caller's 7793 // process, or can run as root (so can be in any process). 7794 return cpr.newHolder(null); 7795 } 7796 7797 if (DEBUG_PROVIDER) { 7798 RuntimeException e = new RuntimeException("here"); 7799 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7800 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7801 } 7802 7803 // This is single process, and our app is now connecting to it. 7804 // See if we are already in the process of launching this 7805 // provider. 7806 final int N = mLaunchingProviders.size(); 7807 int i; 7808 for (i=0; i<N; i++) { 7809 if (mLaunchingProviders.get(i) == cpr) { 7810 break; 7811 } 7812 } 7813 7814 // If the provider is not already being launched, then get it 7815 // started. 7816 if (i >= N) { 7817 final long origId = Binder.clearCallingIdentity(); 7818 7819 try { 7820 // Content provider is now in use, its package can't be stopped. 7821 try { 7822 AppGlobals.getPackageManager().setPackageStoppedState( 7823 cpr.appInfo.packageName, false, userId); 7824 } catch (RemoteException e) { 7825 } catch (IllegalArgumentException e) { 7826 Slog.w(TAG, "Failed trying to unstop package " 7827 + cpr.appInfo.packageName + ": " + e); 7828 } 7829 7830 // Use existing process if already started 7831 ProcessRecord proc = getProcessRecordLocked( 7832 cpi.processName, cpr.appInfo.uid, false); 7833 if (proc != null && proc.thread != null) { 7834 if (DEBUG_PROVIDER) { 7835 Slog.d(TAG, "Installing in existing process " + proc); 7836 } 7837 proc.pubProviders.put(cpi.name, cpr); 7838 try { 7839 proc.thread.scheduleInstallProvider(cpi); 7840 } catch (RemoteException e) { 7841 } 7842 } else { 7843 proc = startProcessLocked(cpi.processName, 7844 cpr.appInfo, false, 0, "content provider", 7845 new ComponentName(cpi.applicationInfo.packageName, 7846 cpi.name), false, false, false); 7847 if (proc == null) { 7848 Slog.w(TAG, "Unable to launch app " 7849 + cpi.applicationInfo.packageName + "/" 7850 + cpi.applicationInfo.uid + " for provider " 7851 + name + ": process is bad"); 7852 return null; 7853 } 7854 } 7855 cpr.launchingApp = proc; 7856 mLaunchingProviders.add(cpr); 7857 } finally { 7858 Binder.restoreCallingIdentity(origId); 7859 } 7860 } 7861 7862 // Make sure the provider is published (the same provider class 7863 // may be published under multiple names). 7864 if (firstClass) { 7865 mProviderMap.putProviderByClass(comp, cpr); 7866 } 7867 7868 mProviderMap.putProviderByName(name, cpr); 7869 conn = incProviderCountLocked(r, cpr, token, stable); 7870 if (conn != null) { 7871 conn.waiting = true; 7872 } 7873 } 7874 } 7875 7876 // Wait for the provider to be published... 7877 synchronized (cpr) { 7878 while (cpr.provider == null) { 7879 if (cpr.launchingApp == null) { 7880 Slog.w(TAG, "Unable to launch app " 7881 + cpi.applicationInfo.packageName + "/" 7882 + cpi.applicationInfo.uid + " for provider " 7883 + name + ": launching app became null"); 7884 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7885 UserHandle.getUserId(cpi.applicationInfo.uid), 7886 cpi.applicationInfo.packageName, 7887 cpi.applicationInfo.uid, name); 7888 return null; 7889 } 7890 try { 7891 if (DEBUG_MU) { 7892 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7893 + cpr.launchingApp); 7894 } 7895 if (conn != null) { 7896 conn.waiting = true; 7897 } 7898 cpr.wait(); 7899 } catch (InterruptedException ex) { 7900 } finally { 7901 if (conn != null) { 7902 conn.waiting = false; 7903 } 7904 } 7905 } 7906 } 7907 return cpr != null ? cpr.newHolder(conn) : null; 7908 } 7909 7910 public final ContentProviderHolder getContentProvider( 7911 IApplicationThread caller, String name, int userId, boolean stable) { 7912 enforceNotIsolatedCaller("getContentProvider"); 7913 if (caller == null) { 7914 String msg = "null IApplicationThread when getting content provider " 7915 + name; 7916 Slog.w(TAG, msg); 7917 throw new SecurityException(msg); 7918 } 7919 7920 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7921 false, true, "getContentProvider", null); 7922 return getContentProviderImpl(caller, name, null, stable, userId); 7923 } 7924 7925 public ContentProviderHolder getContentProviderExternal( 7926 String name, int userId, IBinder token) { 7927 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7928 "Do not have permission in call getContentProviderExternal()"); 7929 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7930 false, true, "getContentProvider", null); 7931 return getContentProviderExternalUnchecked(name, token, userId); 7932 } 7933 7934 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7935 IBinder token, int userId) { 7936 return getContentProviderImpl(null, name, token, true, userId); 7937 } 7938 7939 /** 7940 * Drop a content provider from a ProcessRecord's bookkeeping 7941 */ 7942 public void removeContentProvider(IBinder connection, boolean stable) { 7943 enforceNotIsolatedCaller("removeContentProvider"); 7944 long ident = Binder.clearCallingIdentity(); 7945 try { 7946 synchronized (this) { 7947 ContentProviderConnection conn; 7948 try { 7949 conn = (ContentProviderConnection)connection; 7950 } catch (ClassCastException e) { 7951 String msg ="removeContentProvider: " + connection 7952 + " not a ContentProviderConnection"; 7953 Slog.w(TAG, msg); 7954 throw new IllegalArgumentException(msg); 7955 } 7956 if (conn == null) { 7957 throw new NullPointerException("connection is null"); 7958 } 7959 if (decProviderCountLocked(conn, null, null, stable)) { 7960 updateOomAdjLocked(); 7961 } 7962 } 7963 } finally { 7964 Binder.restoreCallingIdentity(ident); 7965 } 7966 } 7967 7968 public void removeContentProviderExternal(String name, IBinder token) { 7969 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7970 "Do not have permission in call removeContentProviderExternal()"); 7971 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7972 } 7973 7974 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7975 synchronized (this) { 7976 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7977 if(cpr == null) { 7978 //remove from mProvidersByClass 7979 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7980 return; 7981 } 7982 7983 //update content provider record entry info 7984 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7985 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7986 if (localCpr.hasExternalProcessHandles()) { 7987 if (localCpr.removeExternalProcessHandleLocked(token)) { 7988 updateOomAdjLocked(); 7989 } else { 7990 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7991 + " with no external reference for token: " 7992 + token + "."); 7993 } 7994 } else { 7995 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7996 + " with no external references."); 7997 } 7998 } 7999 } 8000 8001 public final void publishContentProviders(IApplicationThread caller, 8002 List<ContentProviderHolder> providers) { 8003 if (providers == null) { 8004 return; 8005 } 8006 8007 enforceNotIsolatedCaller("publishContentProviders"); 8008 synchronized (this) { 8009 final ProcessRecord r = getRecordForAppLocked(caller); 8010 if (DEBUG_MU) 8011 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8012 if (r == null) { 8013 throw new SecurityException( 8014 "Unable to find app for caller " + caller 8015 + " (pid=" + Binder.getCallingPid() 8016 + ") when publishing content providers"); 8017 } 8018 8019 final long origId = Binder.clearCallingIdentity(); 8020 8021 final int N = providers.size(); 8022 for (int i=0; i<N; i++) { 8023 ContentProviderHolder src = providers.get(i); 8024 if (src == null || src.info == null || src.provider == null) { 8025 continue; 8026 } 8027 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8028 if (DEBUG_MU) 8029 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8030 if (dst != null) { 8031 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8032 mProviderMap.putProviderByClass(comp, dst); 8033 String names[] = dst.info.authority.split(";"); 8034 for (int j = 0; j < names.length; j++) { 8035 mProviderMap.putProviderByName(names[j], dst); 8036 } 8037 8038 int NL = mLaunchingProviders.size(); 8039 int j; 8040 for (j=0; j<NL; j++) { 8041 if (mLaunchingProviders.get(j) == dst) { 8042 mLaunchingProviders.remove(j); 8043 j--; 8044 NL--; 8045 } 8046 } 8047 synchronized (dst) { 8048 dst.provider = src.provider; 8049 dst.proc = r; 8050 dst.notifyAll(); 8051 } 8052 updateOomAdjLocked(r); 8053 } 8054 } 8055 8056 Binder.restoreCallingIdentity(origId); 8057 } 8058 } 8059 8060 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8061 ContentProviderConnection conn; 8062 try { 8063 conn = (ContentProviderConnection)connection; 8064 } catch (ClassCastException e) { 8065 String msg ="refContentProvider: " + connection 8066 + " not a ContentProviderConnection"; 8067 Slog.w(TAG, msg); 8068 throw new IllegalArgumentException(msg); 8069 } 8070 if (conn == null) { 8071 throw new NullPointerException("connection is null"); 8072 } 8073 8074 synchronized (this) { 8075 if (stable > 0) { 8076 conn.numStableIncs += stable; 8077 } 8078 stable = conn.stableCount + stable; 8079 if (stable < 0) { 8080 throw new IllegalStateException("stableCount < 0: " + stable); 8081 } 8082 8083 if (unstable > 0) { 8084 conn.numUnstableIncs += unstable; 8085 } 8086 unstable = conn.unstableCount + unstable; 8087 if (unstable < 0) { 8088 throw new IllegalStateException("unstableCount < 0: " + unstable); 8089 } 8090 8091 if ((stable+unstable) <= 0) { 8092 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8093 + stable + " unstable=" + unstable); 8094 } 8095 conn.stableCount = stable; 8096 conn.unstableCount = unstable; 8097 return !conn.dead; 8098 } 8099 } 8100 8101 public void unstableProviderDied(IBinder connection) { 8102 ContentProviderConnection conn; 8103 try { 8104 conn = (ContentProviderConnection)connection; 8105 } catch (ClassCastException e) { 8106 String msg ="refContentProvider: " + connection 8107 + " not a ContentProviderConnection"; 8108 Slog.w(TAG, msg); 8109 throw new IllegalArgumentException(msg); 8110 } 8111 if (conn == null) { 8112 throw new NullPointerException("connection is null"); 8113 } 8114 8115 // Safely retrieve the content provider associated with the connection. 8116 IContentProvider provider; 8117 synchronized (this) { 8118 provider = conn.provider.provider; 8119 } 8120 8121 if (provider == null) { 8122 // Um, yeah, we're way ahead of you. 8123 return; 8124 } 8125 8126 // Make sure the caller is being honest with us. 8127 if (provider.asBinder().pingBinder()) { 8128 // Er, no, still looks good to us. 8129 synchronized (this) { 8130 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8131 + " says " + conn + " died, but we don't agree"); 8132 return; 8133 } 8134 } 8135 8136 // Well look at that! It's dead! 8137 synchronized (this) { 8138 if (conn.provider.provider != provider) { 8139 // But something changed... good enough. 8140 return; 8141 } 8142 8143 ProcessRecord proc = conn.provider.proc; 8144 if (proc == null || proc.thread == null) { 8145 // Seems like the process is already cleaned up. 8146 return; 8147 } 8148 8149 // As far as we're concerned, this is just like receiving a 8150 // death notification... just a bit prematurely. 8151 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8152 + ") early provider death"); 8153 final long ident = Binder.clearCallingIdentity(); 8154 try { 8155 appDiedLocked(proc, proc.pid, proc.thread); 8156 } finally { 8157 Binder.restoreCallingIdentity(ident); 8158 } 8159 } 8160 } 8161 8162 @Override 8163 public void appNotRespondingViaProvider(IBinder connection) { 8164 enforceCallingPermission( 8165 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8166 8167 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8168 if (conn == null) { 8169 Slog.w(TAG, "ContentProviderConnection is null"); 8170 return; 8171 } 8172 8173 final ProcessRecord host = conn.provider.proc; 8174 if (host == null) { 8175 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8176 return; 8177 } 8178 8179 final long token = Binder.clearCallingIdentity(); 8180 try { 8181 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8182 } finally { 8183 Binder.restoreCallingIdentity(token); 8184 } 8185 } 8186 8187 public final void installSystemProviders() { 8188 List<ProviderInfo> providers; 8189 synchronized (this) { 8190 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8191 providers = generateApplicationProvidersLocked(app); 8192 if (providers != null) { 8193 for (int i=providers.size()-1; i>=0; i--) { 8194 ProviderInfo pi = (ProviderInfo)providers.get(i); 8195 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8196 Slog.w(TAG, "Not installing system proc provider " + pi.name 8197 + ": not system .apk"); 8198 providers.remove(i); 8199 } 8200 } 8201 } 8202 } 8203 if (providers != null) { 8204 mSystemThread.installSystemProviders(providers); 8205 } 8206 8207 mCoreSettingsObserver = new CoreSettingsObserver(this); 8208 8209 mUsageStatsService.monitorPackages(); 8210 } 8211 8212 /** 8213 * Allows app to retrieve the MIME type of a URI without having permission 8214 * to access its content provider. 8215 * 8216 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8217 * 8218 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8219 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8220 */ 8221 public String getProviderMimeType(Uri uri, int userId) { 8222 enforceNotIsolatedCaller("getProviderMimeType"); 8223 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8224 userId, false, true, "getProviderMimeType", null); 8225 final String name = uri.getAuthority(); 8226 final long ident = Binder.clearCallingIdentity(); 8227 ContentProviderHolder holder = null; 8228 8229 try { 8230 holder = getContentProviderExternalUnchecked(name, null, userId); 8231 if (holder != null) { 8232 return holder.provider.getType(uri); 8233 } 8234 } catch (RemoteException e) { 8235 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8236 return null; 8237 } finally { 8238 if (holder != null) { 8239 removeContentProviderExternalUnchecked(name, null, userId); 8240 } 8241 Binder.restoreCallingIdentity(ident); 8242 } 8243 8244 return null; 8245 } 8246 8247 // ========================================================= 8248 // GLOBAL MANAGEMENT 8249 // ========================================================= 8250 8251 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8252 boolean isolated) { 8253 String proc = customProcess != null ? customProcess : info.processName; 8254 BatteryStatsImpl.Uid.Proc ps = null; 8255 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8256 int uid = info.uid; 8257 if (isolated) { 8258 int userId = UserHandle.getUserId(uid); 8259 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8260 while (true) { 8261 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8262 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8263 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8264 } 8265 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8266 mNextIsolatedProcessUid++; 8267 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8268 // No process for this uid, use it. 8269 break; 8270 } 8271 stepsLeft--; 8272 if (stepsLeft <= 0) { 8273 return null; 8274 } 8275 } 8276 } 8277 return new ProcessRecord(stats, info, proc, uid); 8278 } 8279 8280 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8281 ProcessRecord app; 8282 if (!isolated) { 8283 app = getProcessRecordLocked(info.processName, info.uid, true); 8284 } else { 8285 app = null; 8286 } 8287 8288 if (app == null) { 8289 app = newProcessRecordLocked(info, null, isolated); 8290 mProcessNames.put(info.processName, app.uid, app); 8291 if (isolated) { 8292 mIsolatedProcesses.put(app.uid, app); 8293 } 8294 updateLruProcessLocked(app, false, null); 8295 updateOomAdjLocked(); 8296 } 8297 8298 // This package really, really can not be stopped. 8299 try { 8300 AppGlobals.getPackageManager().setPackageStoppedState( 8301 info.packageName, false, UserHandle.getUserId(app.uid)); 8302 } catch (RemoteException e) { 8303 } catch (IllegalArgumentException e) { 8304 Slog.w(TAG, "Failed trying to unstop package " 8305 + info.packageName + ": " + e); 8306 } 8307 8308 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8309 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8310 app.persistent = true; 8311 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8312 } 8313 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8314 mPersistentStartingProcesses.add(app); 8315 startProcessLocked(app, "added application", app.processName); 8316 } 8317 8318 return app; 8319 } 8320 8321 public void unhandledBack() { 8322 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8323 "unhandledBack()"); 8324 8325 synchronized(this) { 8326 final long origId = Binder.clearCallingIdentity(); 8327 try { 8328 getFocusedStack().unhandledBackLocked(); 8329 } finally { 8330 Binder.restoreCallingIdentity(origId); 8331 } 8332 } 8333 } 8334 8335 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8336 enforceNotIsolatedCaller("openContentUri"); 8337 final int userId = UserHandle.getCallingUserId(); 8338 String name = uri.getAuthority(); 8339 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8340 ParcelFileDescriptor pfd = null; 8341 if (cph != null) { 8342 // We record the binder invoker's uid in thread-local storage before 8343 // going to the content provider to open the file. Later, in the code 8344 // that handles all permissions checks, we look for this uid and use 8345 // that rather than the Activity Manager's own uid. The effect is that 8346 // we do the check against the caller's permissions even though it looks 8347 // to the content provider like the Activity Manager itself is making 8348 // the request. 8349 sCallerIdentity.set(new Identity( 8350 Binder.getCallingPid(), Binder.getCallingUid())); 8351 try { 8352 pfd = cph.provider.openFile(null, uri, "r", null); 8353 } catch (FileNotFoundException e) { 8354 // do nothing; pfd will be returned null 8355 } finally { 8356 // Ensure that whatever happens, we clean up the identity state 8357 sCallerIdentity.remove(); 8358 } 8359 8360 // We've got the fd now, so we're done with the provider. 8361 removeContentProviderExternalUnchecked(name, null, userId); 8362 } else { 8363 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8364 } 8365 return pfd; 8366 } 8367 8368 // Actually is sleeping or shutting down or whatever else in the future 8369 // is an inactive state. 8370 public boolean isSleepingOrShuttingDown() { 8371 return mSleeping || mShuttingDown; 8372 } 8373 8374 public void goingToSleep() { 8375 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8376 != PackageManager.PERMISSION_GRANTED) { 8377 throw new SecurityException("Requires permission " 8378 + android.Manifest.permission.DEVICE_POWER); 8379 } 8380 8381 synchronized(this) { 8382 mWentToSleep = true; 8383 updateEventDispatchingLocked(); 8384 8385 if (!mSleeping) { 8386 mSleeping = true; 8387 mStackSupervisor.goingToSleepLocked(); 8388 8389 // Initialize the wake times of all processes. 8390 checkExcessivePowerUsageLocked(false); 8391 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8392 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8393 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8394 } 8395 } 8396 } 8397 8398 @Override 8399 public boolean shutdown(int timeout) { 8400 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8401 != PackageManager.PERMISSION_GRANTED) { 8402 throw new SecurityException("Requires permission " 8403 + android.Manifest.permission.SHUTDOWN); 8404 } 8405 8406 boolean timedout = false; 8407 8408 synchronized(this) { 8409 mShuttingDown = true; 8410 updateEventDispatchingLocked(); 8411 timedout = mStackSupervisor.shutdownLocked(timeout); 8412 } 8413 8414 mAppOpsService.shutdown(); 8415 mUsageStatsService.shutdown(); 8416 mBatteryStatsService.shutdown(); 8417 synchronized (this) { 8418 mProcessStats.shutdownLocked(); 8419 } 8420 8421 return timedout; 8422 } 8423 8424 public final void activitySlept(IBinder token) { 8425 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8426 8427 final long origId = Binder.clearCallingIdentity(); 8428 8429 synchronized (this) { 8430 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8431 if (r != null) { 8432 mStackSupervisor.activitySleptLocked(r); 8433 } 8434 } 8435 8436 Binder.restoreCallingIdentity(origId); 8437 } 8438 8439 void logLockScreen(String msg) { 8440 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8441 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8442 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8443 mStackSupervisor.mDismissKeyguardOnNextActivity); 8444 } 8445 8446 private void comeOutOfSleepIfNeededLocked() { 8447 if (!mWentToSleep && !mLockScreenShown) { 8448 if (mSleeping) { 8449 mSleeping = false; 8450 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8451 } 8452 } 8453 } 8454 8455 public void wakingUp() { 8456 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8457 != PackageManager.PERMISSION_GRANTED) { 8458 throw new SecurityException("Requires permission " 8459 + android.Manifest.permission.DEVICE_POWER); 8460 } 8461 8462 synchronized(this) { 8463 mWentToSleep = false; 8464 updateEventDispatchingLocked(); 8465 comeOutOfSleepIfNeededLocked(); 8466 } 8467 } 8468 8469 private void updateEventDispatchingLocked() { 8470 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8471 } 8472 8473 public void setLockScreenShown(boolean shown) { 8474 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8475 != PackageManager.PERMISSION_GRANTED) { 8476 throw new SecurityException("Requires permission " 8477 + android.Manifest.permission.DEVICE_POWER); 8478 } 8479 8480 synchronized(this) { 8481 long ident = Binder.clearCallingIdentity(); 8482 try { 8483 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8484 mLockScreenShown = shown; 8485 comeOutOfSleepIfNeededLocked(); 8486 } finally { 8487 Binder.restoreCallingIdentity(ident); 8488 } 8489 } 8490 } 8491 8492 public void stopAppSwitches() { 8493 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8494 != PackageManager.PERMISSION_GRANTED) { 8495 throw new SecurityException("Requires permission " 8496 + android.Manifest.permission.STOP_APP_SWITCHES); 8497 } 8498 8499 synchronized(this) { 8500 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8501 + APP_SWITCH_DELAY_TIME; 8502 mDidAppSwitch = false; 8503 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8504 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8505 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8506 } 8507 } 8508 8509 public void resumeAppSwitches() { 8510 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8511 != PackageManager.PERMISSION_GRANTED) { 8512 throw new SecurityException("Requires permission " 8513 + android.Manifest.permission.STOP_APP_SWITCHES); 8514 } 8515 8516 synchronized(this) { 8517 // Note that we don't execute any pending app switches... we will 8518 // let those wait until either the timeout, or the next start 8519 // activity request. 8520 mAppSwitchesAllowedTime = 0; 8521 } 8522 } 8523 8524 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8525 String name) { 8526 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8527 return true; 8528 } 8529 8530 final int perm = checkComponentPermission( 8531 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8532 callingUid, -1, true); 8533 if (perm == PackageManager.PERMISSION_GRANTED) { 8534 return true; 8535 } 8536 8537 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8538 return false; 8539 } 8540 8541 public void setDebugApp(String packageName, boolean waitForDebugger, 8542 boolean persistent) { 8543 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8544 "setDebugApp()"); 8545 8546 long ident = Binder.clearCallingIdentity(); 8547 try { 8548 // Note that this is not really thread safe if there are multiple 8549 // callers into it at the same time, but that's not a situation we 8550 // care about. 8551 if (persistent) { 8552 final ContentResolver resolver = mContext.getContentResolver(); 8553 Settings.Global.putString( 8554 resolver, Settings.Global.DEBUG_APP, 8555 packageName); 8556 Settings.Global.putInt( 8557 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8558 waitForDebugger ? 1 : 0); 8559 } 8560 8561 synchronized (this) { 8562 if (!persistent) { 8563 mOrigDebugApp = mDebugApp; 8564 mOrigWaitForDebugger = mWaitForDebugger; 8565 } 8566 mDebugApp = packageName; 8567 mWaitForDebugger = waitForDebugger; 8568 mDebugTransient = !persistent; 8569 if (packageName != null) { 8570 forceStopPackageLocked(packageName, -1, false, false, true, true, 8571 false, UserHandle.USER_ALL, "set debug app"); 8572 } 8573 } 8574 } finally { 8575 Binder.restoreCallingIdentity(ident); 8576 } 8577 } 8578 8579 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8580 synchronized (this) { 8581 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8582 if (!isDebuggable) { 8583 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8584 throw new SecurityException("Process not debuggable: " + app.packageName); 8585 } 8586 } 8587 8588 mOpenGlTraceApp = processName; 8589 } 8590 } 8591 8592 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8593 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8594 synchronized (this) { 8595 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8596 if (!isDebuggable) { 8597 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8598 throw new SecurityException("Process not debuggable: " + app.packageName); 8599 } 8600 } 8601 mProfileApp = processName; 8602 mProfileFile = profileFile; 8603 if (mProfileFd != null) { 8604 try { 8605 mProfileFd.close(); 8606 } catch (IOException e) { 8607 } 8608 mProfileFd = null; 8609 } 8610 mProfileFd = profileFd; 8611 mProfileType = 0; 8612 mAutoStopProfiler = autoStopProfiler; 8613 } 8614 } 8615 8616 @Override 8617 public void setAlwaysFinish(boolean enabled) { 8618 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8619 "setAlwaysFinish()"); 8620 8621 Settings.Global.putInt( 8622 mContext.getContentResolver(), 8623 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8624 8625 synchronized (this) { 8626 mAlwaysFinishActivities = enabled; 8627 } 8628 } 8629 8630 @Override 8631 public void setActivityController(IActivityController controller) { 8632 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8633 "setActivityController()"); 8634 synchronized (this) { 8635 mController = controller; 8636 Watchdog.getInstance().setActivityController(controller); 8637 } 8638 } 8639 8640 @Override 8641 public void setUserIsMonkey(boolean userIsMonkey) { 8642 synchronized (this) { 8643 synchronized (mPidsSelfLocked) { 8644 final int callingPid = Binder.getCallingPid(); 8645 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8646 if (precessRecord == null) { 8647 throw new SecurityException("Unknown process: " + callingPid); 8648 } 8649 if (precessRecord.instrumentationUiAutomationConnection == null) { 8650 throw new SecurityException("Only an instrumentation process " 8651 + "with a UiAutomation can call setUserIsMonkey"); 8652 } 8653 } 8654 mUserIsMonkey = userIsMonkey; 8655 } 8656 } 8657 8658 @Override 8659 public boolean isUserAMonkey() { 8660 synchronized (this) { 8661 // If there is a controller also implies the user is a monkey. 8662 return (mUserIsMonkey || mController != null); 8663 } 8664 } 8665 8666 public void requestBugReport() { 8667 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8668 SystemProperties.set("ctl.start", "bugreport"); 8669 } 8670 8671 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8672 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8673 } 8674 8675 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8676 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8677 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8678 } 8679 return KEY_DISPATCHING_TIMEOUT; 8680 } 8681 8682 @Override 8683 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8684 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8685 != PackageManager.PERMISSION_GRANTED) { 8686 throw new SecurityException("Requires permission " 8687 + android.Manifest.permission.FILTER_EVENTS); 8688 } 8689 ProcessRecord proc; 8690 long timeout; 8691 synchronized (this) { 8692 synchronized (mPidsSelfLocked) { 8693 proc = mPidsSelfLocked.get(pid); 8694 } 8695 timeout = getInputDispatchingTimeoutLocked(proc); 8696 } 8697 8698 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8699 return -1; 8700 } 8701 8702 return timeout; 8703 } 8704 8705 /** 8706 * Handle input dispatching timeouts. 8707 * Returns whether input dispatching should be aborted or not. 8708 */ 8709 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8710 final ActivityRecord activity, final ActivityRecord parent, 8711 final boolean aboveSystem, String reason) { 8712 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8713 != PackageManager.PERMISSION_GRANTED) { 8714 throw new SecurityException("Requires permission " 8715 + android.Manifest.permission.FILTER_EVENTS); 8716 } 8717 8718 final String annotation; 8719 if (reason == null) { 8720 annotation = "Input dispatching timed out"; 8721 } else { 8722 annotation = "Input dispatching timed out (" + reason + ")"; 8723 } 8724 8725 if (proc != null) { 8726 synchronized (this) { 8727 if (proc.debugging) { 8728 return false; 8729 } 8730 8731 if (mDidDexOpt) { 8732 // Give more time since we were dexopting. 8733 mDidDexOpt = false; 8734 return false; 8735 } 8736 8737 if (proc.instrumentationClass != null) { 8738 Bundle info = new Bundle(); 8739 info.putString("shortMsg", "keyDispatchingTimedOut"); 8740 info.putString("longMsg", annotation); 8741 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8742 return true; 8743 } 8744 } 8745 mHandler.post(new Runnable() { 8746 @Override 8747 public void run() { 8748 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8749 } 8750 }); 8751 } 8752 8753 return true; 8754 } 8755 8756 public Bundle getAssistContextExtras(int requestType) { 8757 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8758 "getAssistContextExtras()"); 8759 PendingAssistExtras pae; 8760 Bundle extras = new Bundle(); 8761 synchronized (this) { 8762 ActivityRecord activity = getFocusedStack().mResumedActivity; 8763 if (activity == null) { 8764 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8765 return null; 8766 } 8767 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8768 if (activity.app == null || activity.app.thread == null) { 8769 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8770 return extras; 8771 } 8772 if (activity.app.pid == Binder.getCallingPid()) { 8773 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8774 return extras; 8775 } 8776 pae = new PendingAssistExtras(activity); 8777 try { 8778 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8779 requestType); 8780 mPendingAssistExtras.add(pae); 8781 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8782 } catch (RemoteException e) { 8783 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8784 return extras; 8785 } 8786 } 8787 synchronized (pae) { 8788 while (!pae.haveResult) { 8789 try { 8790 pae.wait(); 8791 } catch (InterruptedException e) { 8792 } 8793 } 8794 if (pae.result != null) { 8795 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8796 } 8797 } 8798 synchronized (this) { 8799 mPendingAssistExtras.remove(pae); 8800 mHandler.removeCallbacks(pae); 8801 } 8802 return extras; 8803 } 8804 8805 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8806 PendingAssistExtras pae = (PendingAssistExtras)token; 8807 synchronized (pae) { 8808 pae.result = extras; 8809 pae.haveResult = true; 8810 pae.notifyAll(); 8811 } 8812 } 8813 8814 public void registerProcessObserver(IProcessObserver observer) { 8815 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8816 "registerProcessObserver()"); 8817 synchronized (this) { 8818 mProcessObservers.register(observer); 8819 } 8820 } 8821 8822 @Override 8823 public void unregisterProcessObserver(IProcessObserver observer) { 8824 synchronized (this) { 8825 mProcessObservers.unregister(observer); 8826 } 8827 } 8828 8829 @Override 8830 public boolean convertFromTranslucent(IBinder token) { 8831 final long origId = Binder.clearCallingIdentity(); 8832 try { 8833 synchronized (this) { 8834 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8835 if (r == null) { 8836 return false; 8837 } 8838 if (r.changeWindowTranslucency(true)) { 8839 mWindowManager.setAppFullscreen(token, true); 8840 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8841 return true; 8842 } 8843 return false; 8844 } 8845 } finally { 8846 Binder.restoreCallingIdentity(origId); 8847 } 8848 } 8849 8850 @Override 8851 public boolean convertToTranslucent(IBinder token) { 8852 final long origId = Binder.clearCallingIdentity(); 8853 try { 8854 synchronized (this) { 8855 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8856 if (r == null) { 8857 return false; 8858 } 8859 if (r.changeWindowTranslucency(false)) { 8860 r.task.stack.convertToTranslucent(r); 8861 mWindowManager.setAppFullscreen(token, false); 8862 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8863 return true; 8864 } 8865 return false; 8866 } 8867 } finally { 8868 Binder.restoreCallingIdentity(origId); 8869 } 8870 } 8871 8872 @Override 8873 public void setImmersive(IBinder token, boolean immersive) { 8874 synchronized(this) { 8875 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8876 if (r == null) { 8877 throw new IllegalArgumentException(); 8878 } 8879 r.immersive = immersive; 8880 8881 // update associated state if we're frontmost 8882 if (r == mFocusedActivity) { 8883 if (DEBUG_IMMERSIVE) { 8884 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8885 } 8886 applyUpdateLockStateLocked(r); 8887 } 8888 } 8889 } 8890 8891 @Override 8892 public boolean isImmersive(IBinder token) { 8893 synchronized (this) { 8894 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8895 if (r == null) { 8896 throw new IllegalArgumentException(); 8897 } 8898 return r.immersive; 8899 } 8900 } 8901 8902 public boolean isTopActivityImmersive() { 8903 enforceNotIsolatedCaller("startActivity"); 8904 synchronized (this) { 8905 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8906 return (r != null) ? r.immersive : false; 8907 } 8908 } 8909 8910 public final void enterSafeMode() { 8911 synchronized(this) { 8912 // It only makes sense to do this before the system is ready 8913 // and started launching other packages. 8914 if (!mSystemReady) { 8915 try { 8916 AppGlobals.getPackageManager().enterSafeMode(); 8917 } catch (RemoteException e) { 8918 } 8919 } 8920 } 8921 } 8922 8923 public final void showSafeModeOverlay() { 8924 View v = LayoutInflater.from(mContext).inflate( 8925 com.android.internal.R.layout.safe_mode, null); 8926 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8927 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8928 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8929 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8930 lp.gravity = Gravity.BOTTOM | Gravity.START; 8931 lp.format = v.getBackground().getOpacity(); 8932 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8933 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8934 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8935 ((WindowManager)mContext.getSystemService( 8936 Context.WINDOW_SERVICE)).addView(v, lp); 8937 } 8938 8939 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8940 if (!(sender instanceof PendingIntentRecord)) { 8941 return; 8942 } 8943 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8944 synchronized (stats) { 8945 if (mBatteryStatsService.isOnBattery()) { 8946 mBatteryStatsService.enforceCallingPermission(); 8947 PendingIntentRecord rec = (PendingIntentRecord)sender; 8948 int MY_UID = Binder.getCallingUid(); 8949 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8950 BatteryStatsImpl.Uid.Pkg pkg = 8951 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8952 sourcePkg != null ? sourcePkg : rec.key.packageName); 8953 pkg.incWakeupsLocked(); 8954 } 8955 } 8956 } 8957 8958 public boolean killPids(int[] pids, String pReason, boolean secure) { 8959 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8960 throw new SecurityException("killPids only available to the system"); 8961 } 8962 String reason = (pReason == null) ? "Unknown" : pReason; 8963 // XXX Note: don't acquire main activity lock here, because the window 8964 // manager calls in with its locks held. 8965 8966 boolean killed = false; 8967 synchronized (mPidsSelfLocked) { 8968 int[] types = new int[pids.length]; 8969 int worstType = 0; 8970 for (int i=0; i<pids.length; i++) { 8971 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8972 if (proc != null) { 8973 int type = proc.setAdj; 8974 types[i] = type; 8975 if (type > worstType) { 8976 worstType = type; 8977 } 8978 } 8979 } 8980 8981 // If the worst oom_adj is somewhere in the cached proc LRU range, 8982 // then constrain it so we will kill all cached procs. 8983 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8984 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8985 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8986 } 8987 8988 // If this is not a secure call, don't let it kill processes that 8989 // are important. 8990 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8991 worstType = ProcessList.SERVICE_ADJ; 8992 } 8993 8994 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8995 for (int i=0; i<pids.length; i++) { 8996 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8997 if (proc == null) { 8998 continue; 8999 } 9000 int adj = proc.setAdj; 9001 if (adj >= worstType && !proc.killedByAm) { 9002 killUnneededProcessLocked(proc, reason); 9003 killed = true; 9004 } 9005 } 9006 } 9007 return killed; 9008 } 9009 9010 @Override 9011 public void killUid(int uid, String reason) { 9012 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9013 throw new SecurityException("killUid only available to the system"); 9014 } 9015 synchronized (this) { 9016 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9017 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9018 reason != null ? reason : "kill uid"); 9019 } 9020 } 9021 9022 @Override 9023 public boolean killProcessesBelowForeground(String reason) { 9024 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9025 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9026 } 9027 9028 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9029 } 9030 9031 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9032 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9033 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9034 } 9035 9036 boolean killed = false; 9037 synchronized (mPidsSelfLocked) { 9038 final int size = mPidsSelfLocked.size(); 9039 for (int i = 0; i < size; i++) { 9040 final int pid = mPidsSelfLocked.keyAt(i); 9041 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9042 if (proc == null) continue; 9043 9044 final int adj = proc.setAdj; 9045 if (adj > belowAdj && !proc.killedByAm) { 9046 killUnneededProcessLocked(proc, reason); 9047 killed = true; 9048 } 9049 } 9050 } 9051 return killed; 9052 } 9053 9054 @Override 9055 public void hang(final IBinder who, boolean allowRestart) { 9056 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9057 != PackageManager.PERMISSION_GRANTED) { 9058 throw new SecurityException("Requires permission " 9059 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9060 } 9061 9062 final IBinder.DeathRecipient death = new DeathRecipient() { 9063 @Override 9064 public void binderDied() { 9065 synchronized (this) { 9066 notifyAll(); 9067 } 9068 } 9069 }; 9070 9071 try { 9072 who.linkToDeath(death, 0); 9073 } catch (RemoteException e) { 9074 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9075 return; 9076 } 9077 9078 synchronized (this) { 9079 Watchdog.getInstance().setAllowRestart(allowRestart); 9080 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9081 synchronized (death) { 9082 while (who.isBinderAlive()) { 9083 try { 9084 death.wait(); 9085 } catch (InterruptedException e) { 9086 } 9087 } 9088 } 9089 Watchdog.getInstance().setAllowRestart(true); 9090 } 9091 } 9092 9093 @Override 9094 public void restart() { 9095 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9096 != PackageManager.PERMISSION_GRANTED) { 9097 throw new SecurityException("Requires permission " 9098 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9099 } 9100 9101 Log.i(TAG, "Sending shutdown broadcast..."); 9102 9103 BroadcastReceiver br = new BroadcastReceiver() { 9104 @Override public void onReceive(Context context, Intent intent) { 9105 // Now the broadcast is done, finish up the low-level shutdown. 9106 Log.i(TAG, "Shutting down activity manager..."); 9107 shutdown(10000); 9108 Log.i(TAG, "Shutdown complete, restarting!"); 9109 Process.killProcess(Process.myPid()); 9110 System.exit(10); 9111 } 9112 }; 9113 9114 // First send the high-level shut down broadcast. 9115 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9116 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9117 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9118 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9119 mContext.sendOrderedBroadcastAsUser(intent, 9120 UserHandle.ALL, null, br, mHandler, 0, null, null); 9121 */ 9122 br.onReceive(mContext, intent); 9123 } 9124 9125 private long getLowRamTimeSinceIdle(long now) { 9126 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9127 } 9128 9129 @Override 9130 public void performIdleMaintenance() { 9131 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9132 != PackageManager.PERMISSION_GRANTED) { 9133 throw new SecurityException("Requires permission " 9134 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9135 } 9136 9137 synchronized (this) { 9138 final long now = SystemClock.uptimeMillis(); 9139 final long timeSinceLastIdle = now - mLastIdleTime; 9140 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9141 mLastIdleTime = now; 9142 mLowRamTimeSinceLastIdle = 0; 9143 if (mLowRamStartTime != 0) { 9144 mLowRamStartTime = now; 9145 } 9146 9147 StringBuilder sb = new StringBuilder(128); 9148 sb.append("Idle maintenance over "); 9149 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9150 sb.append(" low RAM for "); 9151 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9152 Slog.i(TAG, sb.toString()); 9153 9154 // If at least 1/3 of our time since the last idle period has been spent 9155 // with RAM low, then we want to kill processes. 9156 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9157 9158 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9159 ProcessRecord proc = mLruProcesses.get(i); 9160 if (proc.notCachedSinceIdle) { 9161 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9162 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9163 if (doKilling && proc.initialIdlePss != 0 9164 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9165 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9166 + " from " + proc.initialIdlePss + ")"); 9167 } 9168 } 9169 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9170 proc.notCachedSinceIdle = true; 9171 proc.initialIdlePss = 0; 9172 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9173 mSleeping, now); 9174 } 9175 } 9176 9177 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9178 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9179 } 9180 } 9181 9182 public final void startRunning(String pkg, String cls, String action, 9183 String data) { 9184 synchronized(this) { 9185 if (mStartRunning) { 9186 return; 9187 } 9188 mStartRunning = true; 9189 mTopComponent = pkg != null && cls != null 9190 ? new ComponentName(pkg, cls) : null; 9191 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9192 mTopData = data; 9193 if (!mSystemReady) { 9194 return; 9195 } 9196 } 9197 9198 systemReady(null); 9199 } 9200 9201 private void retrieveSettings() { 9202 final ContentResolver resolver = mContext.getContentResolver(); 9203 String debugApp = Settings.Global.getString( 9204 resolver, Settings.Global.DEBUG_APP); 9205 boolean waitForDebugger = Settings.Global.getInt( 9206 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9207 boolean alwaysFinishActivities = Settings.Global.getInt( 9208 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9209 boolean forceRtl = Settings.Global.getInt( 9210 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9211 // Transfer any global setting for forcing RTL layout, into a System Property 9212 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9213 9214 Configuration configuration = new Configuration(); 9215 Settings.System.getConfiguration(resolver, configuration); 9216 if (forceRtl) { 9217 // This will take care of setting the correct layout direction flags 9218 configuration.setLayoutDirection(configuration.locale); 9219 } 9220 9221 synchronized (this) { 9222 mDebugApp = mOrigDebugApp = debugApp; 9223 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9224 mAlwaysFinishActivities = alwaysFinishActivities; 9225 // This happens before any activities are started, so we can 9226 // change mConfiguration in-place. 9227 updateConfigurationLocked(configuration, null, false, true); 9228 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9229 } 9230 } 9231 9232 public boolean testIsSystemReady() { 9233 // no need to synchronize(this) just to read & return the value 9234 return mSystemReady; 9235 } 9236 9237 private static File getCalledPreBootReceiversFile() { 9238 File dataDir = Environment.getDataDirectory(); 9239 File systemDir = new File(dataDir, "system"); 9240 File fname = new File(systemDir, "called_pre_boots.dat"); 9241 return fname; 9242 } 9243 9244 static final int LAST_DONE_VERSION = 10000; 9245 9246 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9247 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9248 File file = getCalledPreBootReceiversFile(); 9249 FileInputStream fis = null; 9250 try { 9251 fis = new FileInputStream(file); 9252 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9253 int fvers = dis.readInt(); 9254 if (fvers == LAST_DONE_VERSION) { 9255 String vers = dis.readUTF(); 9256 String codename = dis.readUTF(); 9257 String build = dis.readUTF(); 9258 if (android.os.Build.VERSION.RELEASE.equals(vers) 9259 && android.os.Build.VERSION.CODENAME.equals(codename) 9260 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9261 int num = dis.readInt(); 9262 while (num > 0) { 9263 num--; 9264 String pkg = dis.readUTF(); 9265 String cls = dis.readUTF(); 9266 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9267 } 9268 } 9269 } 9270 } catch (FileNotFoundException e) { 9271 } catch (IOException e) { 9272 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9273 } finally { 9274 if (fis != null) { 9275 try { 9276 fis.close(); 9277 } catch (IOException e) { 9278 } 9279 } 9280 } 9281 return lastDoneReceivers; 9282 } 9283 9284 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9285 File file = getCalledPreBootReceiversFile(); 9286 FileOutputStream fos = null; 9287 DataOutputStream dos = null; 9288 try { 9289 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9290 fos = new FileOutputStream(file); 9291 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9292 dos.writeInt(LAST_DONE_VERSION); 9293 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9294 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9295 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9296 dos.writeInt(list.size()); 9297 for (int i=0; i<list.size(); i++) { 9298 dos.writeUTF(list.get(i).getPackageName()); 9299 dos.writeUTF(list.get(i).getClassName()); 9300 } 9301 } catch (IOException e) { 9302 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9303 file.delete(); 9304 } finally { 9305 FileUtils.sync(fos); 9306 if (dos != null) { 9307 try { 9308 dos.close(); 9309 } catch (IOException e) { 9310 // TODO Auto-generated catch block 9311 e.printStackTrace(); 9312 } 9313 } 9314 } 9315 } 9316 9317 public void systemReady(final Runnable goingCallback) { 9318 synchronized(this) { 9319 if (mSystemReady) { 9320 if (goingCallback != null) goingCallback.run(); 9321 return; 9322 } 9323 9324 // Check to see if there are any update receivers to run. 9325 if (!mDidUpdate) { 9326 if (mWaitingUpdate) { 9327 return; 9328 } 9329 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9330 List<ResolveInfo> ris = null; 9331 try { 9332 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9333 intent, null, 0, 0); 9334 } catch (RemoteException e) { 9335 } 9336 if (ris != null) { 9337 for (int i=ris.size()-1; i>=0; i--) { 9338 if ((ris.get(i).activityInfo.applicationInfo.flags 9339 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9340 ris.remove(i); 9341 } 9342 } 9343 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9344 9345 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9346 9347 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9348 for (int i=0; i<ris.size(); i++) { 9349 ActivityInfo ai = ris.get(i).activityInfo; 9350 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9351 if (lastDoneReceivers.contains(comp)) { 9352 // We already did the pre boot receiver for this app with the current 9353 // platform version, so don't do it again... 9354 ris.remove(i); 9355 i--; 9356 // ...however, do keep it as one that has been done, so we don't 9357 // forget about it when rewriting the file of last done receivers. 9358 doneReceivers.add(comp); 9359 } 9360 } 9361 9362 final int[] users = getUsersLocked(); 9363 for (int i=0; i<ris.size(); i++) { 9364 ActivityInfo ai = ris.get(i).activityInfo; 9365 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9366 doneReceivers.add(comp); 9367 intent.setComponent(comp); 9368 for (int j=0; j<users.length; j++) { 9369 IIntentReceiver finisher = null; 9370 if (i == ris.size()-1 && j == users.length-1) { 9371 finisher = new IIntentReceiver.Stub() { 9372 public void performReceive(Intent intent, int resultCode, 9373 String data, Bundle extras, boolean ordered, 9374 boolean sticky, int sendingUser) { 9375 // The raw IIntentReceiver interface is called 9376 // with the AM lock held, so redispatch to 9377 // execute our code without the lock. 9378 mHandler.post(new Runnable() { 9379 public void run() { 9380 synchronized (ActivityManagerService.this) { 9381 mDidUpdate = true; 9382 } 9383 writeLastDonePreBootReceivers(doneReceivers); 9384 showBootMessage(mContext.getText( 9385 R.string.android_upgrading_complete), 9386 false); 9387 systemReady(goingCallback); 9388 } 9389 }); 9390 } 9391 }; 9392 } 9393 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9394 + " for user " + users[j]); 9395 broadcastIntentLocked(null, null, intent, null, finisher, 9396 0, null, null, null, AppOpsManager.OP_NONE, 9397 true, false, MY_PID, Process.SYSTEM_UID, 9398 users[j]); 9399 if (finisher != null) { 9400 mWaitingUpdate = true; 9401 } 9402 } 9403 } 9404 } 9405 if (mWaitingUpdate) { 9406 return; 9407 } 9408 mDidUpdate = true; 9409 } 9410 9411 mAppOpsService.systemReady(); 9412 mSystemReady = true; 9413 if (!mStartRunning) { 9414 return; 9415 } 9416 } 9417 9418 ArrayList<ProcessRecord> procsToKill = null; 9419 synchronized(mPidsSelfLocked) { 9420 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9421 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9422 if (!isAllowedWhileBooting(proc.info)){ 9423 if (procsToKill == null) { 9424 procsToKill = new ArrayList<ProcessRecord>(); 9425 } 9426 procsToKill.add(proc); 9427 } 9428 } 9429 } 9430 9431 synchronized(this) { 9432 if (procsToKill != null) { 9433 for (int i=procsToKill.size()-1; i>=0; i--) { 9434 ProcessRecord proc = procsToKill.get(i); 9435 Slog.i(TAG, "Removing system update proc: " + proc); 9436 removeProcessLocked(proc, true, false, "system update done"); 9437 } 9438 } 9439 9440 // Now that we have cleaned up any update processes, we 9441 // are ready to start launching real processes and know that 9442 // we won't trample on them any more. 9443 mProcessesReady = true; 9444 } 9445 9446 Slog.i(TAG, "System now ready"); 9447 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9448 SystemClock.uptimeMillis()); 9449 9450 synchronized(this) { 9451 // Make sure we have no pre-ready processes sitting around. 9452 9453 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9454 ResolveInfo ri = mContext.getPackageManager() 9455 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9456 STOCK_PM_FLAGS); 9457 CharSequence errorMsg = null; 9458 if (ri != null) { 9459 ActivityInfo ai = ri.activityInfo; 9460 ApplicationInfo app = ai.applicationInfo; 9461 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9462 mTopAction = Intent.ACTION_FACTORY_TEST; 9463 mTopData = null; 9464 mTopComponent = new ComponentName(app.packageName, 9465 ai.name); 9466 } else { 9467 errorMsg = mContext.getResources().getText( 9468 com.android.internal.R.string.factorytest_not_system); 9469 } 9470 } else { 9471 errorMsg = mContext.getResources().getText( 9472 com.android.internal.R.string.factorytest_no_action); 9473 } 9474 if (errorMsg != null) { 9475 mTopAction = null; 9476 mTopData = null; 9477 mTopComponent = null; 9478 Message msg = Message.obtain(); 9479 msg.what = SHOW_FACTORY_ERROR_MSG; 9480 msg.getData().putCharSequence("msg", errorMsg); 9481 mHandler.sendMessage(msg); 9482 } 9483 } 9484 } 9485 9486 retrieveSettings(); 9487 9488 synchronized (this) { 9489 readGrantedUriPermissionsLocked(); 9490 } 9491 9492 if (goingCallback != null) goingCallback.run(); 9493 9494 synchronized (this) { 9495 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9496 try { 9497 List apps = AppGlobals.getPackageManager(). 9498 getPersistentApplications(STOCK_PM_FLAGS); 9499 if (apps != null) { 9500 int N = apps.size(); 9501 int i; 9502 for (i=0; i<N; i++) { 9503 ApplicationInfo info 9504 = (ApplicationInfo)apps.get(i); 9505 if (info != null && 9506 !info.packageName.equals("android")) { 9507 addAppLocked(info, false); 9508 } 9509 } 9510 } 9511 } catch (RemoteException ex) { 9512 // pm is in same process, this will never happen. 9513 } 9514 } 9515 9516 // Start up initial activity. 9517 mBooting = true; 9518 9519 try { 9520 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9521 Message msg = Message.obtain(); 9522 msg.what = SHOW_UID_ERROR_MSG; 9523 mHandler.sendMessage(msg); 9524 } 9525 } catch (RemoteException e) { 9526 } 9527 9528 long ident = Binder.clearCallingIdentity(); 9529 try { 9530 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9531 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9532 | Intent.FLAG_RECEIVER_FOREGROUND); 9533 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9534 broadcastIntentLocked(null, null, intent, 9535 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9536 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9537 intent = new Intent(Intent.ACTION_USER_STARTING); 9538 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9539 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9540 broadcastIntentLocked(null, null, intent, 9541 null, new IIntentReceiver.Stub() { 9542 @Override 9543 public void performReceive(Intent intent, int resultCode, String data, 9544 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9545 throws RemoteException { 9546 } 9547 }, 0, null, null, 9548 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9549 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9550 } finally { 9551 Binder.restoreCallingIdentity(ident); 9552 } 9553 mStackSupervisor.resumeTopActivitiesLocked(); 9554 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9555 } 9556 } 9557 9558 private boolean makeAppCrashingLocked(ProcessRecord app, 9559 String shortMsg, String longMsg, String stackTrace) { 9560 app.crashing = true; 9561 app.crashingReport = generateProcessError(app, 9562 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9563 startAppProblemLocked(app); 9564 app.stopFreezingAllLocked(); 9565 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9566 } 9567 9568 private void makeAppNotRespondingLocked(ProcessRecord app, 9569 String activity, String shortMsg, String longMsg) { 9570 app.notResponding = true; 9571 app.notRespondingReport = generateProcessError(app, 9572 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9573 activity, shortMsg, longMsg, null); 9574 startAppProblemLocked(app); 9575 app.stopFreezingAllLocked(); 9576 } 9577 9578 /** 9579 * Generate a process error record, suitable for attachment to a ProcessRecord. 9580 * 9581 * @param app The ProcessRecord in which the error occurred. 9582 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9583 * ActivityManager.AppErrorStateInfo 9584 * @param activity The activity associated with the crash, if known. 9585 * @param shortMsg Short message describing the crash. 9586 * @param longMsg Long message describing the crash. 9587 * @param stackTrace Full crash stack trace, may be null. 9588 * 9589 * @return Returns a fully-formed AppErrorStateInfo record. 9590 */ 9591 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9592 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9593 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9594 9595 report.condition = condition; 9596 report.processName = app.processName; 9597 report.pid = app.pid; 9598 report.uid = app.info.uid; 9599 report.tag = activity; 9600 report.shortMsg = shortMsg; 9601 report.longMsg = longMsg; 9602 report.stackTrace = stackTrace; 9603 9604 return report; 9605 } 9606 9607 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9608 synchronized (this) { 9609 app.crashing = false; 9610 app.crashingReport = null; 9611 app.notResponding = false; 9612 app.notRespondingReport = null; 9613 if (app.anrDialog == fromDialog) { 9614 app.anrDialog = null; 9615 } 9616 if (app.waitDialog == fromDialog) { 9617 app.waitDialog = null; 9618 } 9619 if (app.pid > 0 && app.pid != MY_PID) { 9620 handleAppCrashLocked(app, null, null, null); 9621 killUnneededProcessLocked(app, "user request after error"); 9622 } 9623 } 9624 } 9625 9626 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9627 String stackTrace) { 9628 long now = SystemClock.uptimeMillis(); 9629 9630 Long crashTime; 9631 if (!app.isolated) { 9632 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9633 } else { 9634 crashTime = null; 9635 } 9636 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9637 // This process loses! 9638 Slog.w(TAG, "Process " + app.info.processName 9639 + " has crashed too many times: killing!"); 9640 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9641 app.userId, app.info.processName, app.uid); 9642 mStackSupervisor.handleAppCrashLocked(app); 9643 if (!app.persistent) { 9644 // We don't want to start this process again until the user 9645 // explicitly does so... but for persistent process, we really 9646 // need to keep it running. If a persistent process is actually 9647 // repeatedly crashing, then badness for everyone. 9648 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9649 app.info.processName); 9650 if (!app.isolated) { 9651 // XXX We don't have a way to mark isolated processes 9652 // as bad, since they don't have a peristent identity. 9653 mBadProcesses.put(app.info.processName, app.uid, 9654 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9655 mProcessCrashTimes.remove(app.info.processName, app.uid); 9656 } 9657 app.bad = true; 9658 app.removed = true; 9659 // Don't let services in this process be restarted and potentially 9660 // annoy the user repeatedly. Unless it is persistent, since those 9661 // processes run critical code. 9662 removeProcessLocked(app, false, false, "crash"); 9663 mStackSupervisor.resumeTopActivitiesLocked(); 9664 return false; 9665 } 9666 mStackSupervisor.resumeTopActivitiesLocked(); 9667 } else { 9668 mStackSupervisor.finishTopRunningActivityLocked(app); 9669 } 9670 9671 // Bump up the crash count of any services currently running in the proc. 9672 for (int i=app.services.size()-1; i>=0; i--) { 9673 // Any services running in the application need to be placed 9674 // back in the pending list. 9675 ServiceRecord sr = app.services.valueAt(i); 9676 sr.crashCount++; 9677 } 9678 9679 // If the crashing process is what we consider to be the "home process" and it has been 9680 // replaced by a third-party app, clear the package preferred activities from packages 9681 // with a home activity running in the process to prevent a repeatedly crashing app 9682 // from blocking the user to manually clear the list. 9683 final ArrayList<ActivityRecord> activities = app.activities; 9684 if (app == mHomeProcess && activities.size() > 0 9685 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9686 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9687 final ActivityRecord r = activities.get(activityNdx); 9688 if (r.isHomeActivity()) { 9689 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9690 try { 9691 ActivityThread.getPackageManager() 9692 .clearPackagePreferredActivities(r.packageName); 9693 } catch (RemoteException c) { 9694 // pm is in same process, this will never happen. 9695 } 9696 } 9697 } 9698 } 9699 9700 if (!app.isolated) { 9701 // XXX Can't keep track of crash times for isolated processes, 9702 // because they don't have a perisistent identity. 9703 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9704 } 9705 9706 return true; 9707 } 9708 9709 void startAppProblemLocked(ProcessRecord app) { 9710 if (app.userId == mCurrentUserId) { 9711 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9712 mContext, app.info.packageName, app.info.flags); 9713 } else { 9714 // If this app is not running under the current user, then we 9715 // can't give it a report button because that would require 9716 // launching the report UI under a different user. 9717 app.errorReportReceiver = null; 9718 } 9719 skipCurrentReceiverLocked(app); 9720 } 9721 9722 void skipCurrentReceiverLocked(ProcessRecord app) { 9723 for (BroadcastQueue queue : mBroadcastQueues) { 9724 queue.skipCurrentReceiverLocked(app); 9725 } 9726 } 9727 9728 /** 9729 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9730 * The application process will exit immediately after this call returns. 9731 * @param app object of the crashing app, null for the system server 9732 * @param crashInfo describing the exception 9733 */ 9734 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9735 ProcessRecord r = findAppProcess(app, "Crash"); 9736 final String processName = app == null ? "system_server" 9737 : (r == null ? "unknown" : r.processName); 9738 9739 handleApplicationCrashInner("crash", r, processName, crashInfo); 9740 } 9741 9742 /* Native crash reporting uses this inner version because it needs to be somewhat 9743 * decoupled from the AM-managed cleanup lifecycle 9744 */ 9745 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9746 ApplicationErrorReport.CrashInfo crashInfo) { 9747 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9748 UserHandle.getUserId(Binder.getCallingUid()), processName, 9749 r == null ? -1 : r.info.flags, 9750 crashInfo.exceptionClassName, 9751 crashInfo.exceptionMessage, 9752 crashInfo.throwFileName, 9753 crashInfo.throwLineNumber); 9754 9755 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9756 9757 crashApplication(r, crashInfo); 9758 } 9759 9760 public void handleApplicationStrictModeViolation( 9761 IBinder app, 9762 int violationMask, 9763 StrictMode.ViolationInfo info) { 9764 ProcessRecord r = findAppProcess(app, "StrictMode"); 9765 if (r == null) { 9766 return; 9767 } 9768 9769 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9770 Integer stackFingerprint = info.hashCode(); 9771 boolean logIt = true; 9772 synchronized (mAlreadyLoggedViolatedStacks) { 9773 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9774 logIt = false; 9775 // TODO: sub-sample into EventLog for these, with 9776 // the info.durationMillis? Then we'd get 9777 // the relative pain numbers, without logging all 9778 // the stack traces repeatedly. We'd want to do 9779 // likewise in the client code, which also does 9780 // dup suppression, before the Binder call. 9781 } else { 9782 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9783 mAlreadyLoggedViolatedStacks.clear(); 9784 } 9785 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9786 } 9787 } 9788 if (logIt) { 9789 logStrictModeViolationToDropBox(r, info); 9790 } 9791 } 9792 9793 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9794 AppErrorResult result = new AppErrorResult(); 9795 synchronized (this) { 9796 final long origId = Binder.clearCallingIdentity(); 9797 9798 Message msg = Message.obtain(); 9799 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9800 HashMap<String, Object> data = new HashMap<String, Object>(); 9801 data.put("result", result); 9802 data.put("app", r); 9803 data.put("violationMask", violationMask); 9804 data.put("info", info); 9805 msg.obj = data; 9806 mHandler.sendMessage(msg); 9807 9808 Binder.restoreCallingIdentity(origId); 9809 } 9810 int res = result.get(); 9811 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9812 } 9813 } 9814 9815 // Depending on the policy in effect, there could be a bunch of 9816 // these in quick succession so we try to batch these together to 9817 // minimize disk writes, number of dropbox entries, and maximize 9818 // compression, by having more fewer, larger records. 9819 private void logStrictModeViolationToDropBox( 9820 ProcessRecord process, 9821 StrictMode.ViolationInfo info) { 9822 if (info == null) { 9823 return; 9824 } 9825 final boolean isSystemApp = process == null || 9826 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9827 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9828 final String processName = process == null ? "unknown" : process.processName; 9829 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9830 final DropBoxManager dbox = (DropBoxManager) 9831 mContext.getSystemService(Context.DROPBOX_SERVICE); 9832 9833 // Exit early if the dropbox isn't configured to accept this report type. 9834 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9835 9836 boolean bufferWasEmpty; 9837 boolean needsFlush; 9838 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9839 synchronized (sb) { 9840 bufferWasEmpty = sb.length() == 0; 9841 appendDropBoxProcessHeaders(process, processName, sb); 9842 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9843 sb.append("System-App: ").append(isSystemApp).append("\n"); 9844 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9845 if (info.violationNumThisLoop != 0) { 9846 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9847 } 9848 if (info.numAnimationsRunning != 0) { 9849 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9850 } 9851 if (info.broadcastIntentAction != null) { 9852 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9853 } 9854 if (info.durationMillis != -1) { 9855 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9856 } 9857 if (info.numInstances != -1) { 9858 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9859 } 9860 if (info.tags != null) { 9861 for (String tag : info.tags) { 9862 sb.append("Span-Tag: ").append(tag).append("\n"); 9863 } 9864 } 9865 sb.append("\n"); 9866 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9867 sb.append(info.crashInfo.stackTrace); 9868 } 9869 sb.append("\n"); 9870 9871 // Only buffer up to ~64k. Various logging bits truncate 9872 // things at 128k. 9873 needsFlush = (sb.length() > 64 * 1024); 9874 } 9875 9876 // Flush immediately if the buffer's grown too large, or this 9877 // is a non-system app. Non-system apps are isolated with a 9878 // different tag & policy and not batched. 9879 // 9880 // Batching is useful during internal testing with 9881 // StrictMode settings turned up high. Without batching, 9882 // thousands of separate files could be created on boot. 9883 if (!isSystemApp || needsFlush) { 9884 new Thread("Error dump: " + dropboxTag) { 9885 @Override 9886 public void run() { 9887 String report; 9888 synchronized (sb) { 9889 report = sb.toString(); 9890 sb.delete(0, sb.length()); 9891 sb.trimToSize(); 9892 } 9893 if (report.length() != 0) { 9894 dbox.addText(dropboxTag, report); 9895 } 9896 } 9897 }.start(); 9898 return; 9899 } 9900 9901 // System app batching: 9902 if (!bufferWasEmpty) { 9903 // An existing dropbox-writing thread is outstanding, so 9904 // we don't need to start it up. The existing thread will 9905 // catch the buffer appends we just did. 9906 return; 9907 } 9908 9909 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9910 // (After this point, we shouldn't access AMS internal data structures.) 9911 new Thread("Error dump: " + dropboxTag) { 9912 @Override 9913 public void run() { 9914 // 5 second sleep to let stacks arrive and be batched together 9915 try { 9916 Thread.sleep(5000); // 5 seconds 9917 } catch (InterruptedException e) {} 9918 9919 String errorReport; 9920 synchronized (mStrictModeBuffer) { 9921 errorReport = mStrictModeBuffer.toString(); 9922 if (errorReport.length() == 0) { 9923 return; 9924 } 9925 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9926 mStrictModeBuffer.trimToSize(); 9927 } 9928 dbox.addText(dropboxTag, errorReport); 9929 } 9930 }.start(); 9931 } 9932 9933 /** 9934 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9935 * @param app object of the crashing app, null for the system server 9936 * @param tag reported by the caller 9937 * @param crashInfo describing the context of the error 9938 * @return true if the process should exit immediately (WTF is fatal) 9939 */ 9940 public boolean handleApplicationWtf(IBinder app, String tag, 9941 ApplicationErrorReport.CrashInfo crashInfo) { 9942 ProcessRecord r = findAppProcess(app, "WTF"); 9943 final String processName = app == null ? "system_server" 9944 : (r == null ? "unknown" : r.processName); 9945 9946 EventLog.writeEvent(EventLogTags.AM_WTF, 9947 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9948 processName, 9949 r == null ? -1 : r.info.flags, 9950 tag, crashInfo.exceptionMessage); 9951 9952 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9953 9954 if (r != null && r.pid != Process.myPid() && 9955 Settings.Global.getInt(mContext.getContentResolver(), 9956 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9957 crashApplication(r, crashInfo); 9958 return true; 9959 } else { 9960 return false; 9961 } 9962 } 9963 9964 /** 9965 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9966 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9967 */ 9968 private ProcessRecord findAppProcess(IBinder app, String reason) { 9969 if (app == null) { 9970 return null; 9971 } 9972 9973 synchronized (this) { 9974 final int NP = mProcessNames.getMap().size(); 9975 for (int ip=0; ip<NP; ip++) { 9976 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9977 final int NA = apps.size(); 9978 for (int ia=0; ia<NA; ia++) { 9979 ProcessRecord p = apps.valueAt(ia); 9980 if (p.thread != null && p.thread.asBinder() == app) { 9981 return p; 9982 } 9983 } 9984 } 9985 9986 Slog.w(TAG, "Can't find mystery application for " + reason 9987 + " from pid=" + Binder.getCallingPid() 9988 + " uid=" + Binder.getCallingUid() + ": " + app); 9989 return null; 9990 } 9991 } 9992 9993 /** 9994 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9995 * to append various headers to the dropbox log text. 9996 */ 9997 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9998 StringBuilder sb) { 9999 // Watchdog thread ends up invoking this function (with 10000 // a null ProcessRecord) to add the stack file to dropbox. 10001 // Do not acquire a lock on this (am) in such cases, as it 10002 // could cause a potential deadlock, if and when watchdog 10003 // is invoked due to unavailability of lock on am and it 10004 // would prevent watchdog from killing system_server. 10005 if (process == null) { 10006 sb.append("Process: ").append(processName).append("\n"); 10007 return; 10008 } 10009 // Note: ProcessRecord 'process' is guarded by the service 10010 // instance. (notably process.pkgList, which could otherwise change 10011 // concurrently during execution of this method) 10012 synchronized (this) { 10013 sb.append("Process: ").append(processName).append("\n"); 10014 int flags = process.info.flags; 10015 IPackageManager pm = AppGlobals.getPackageManager(); 10016 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10017 for (int ip=0; ip<process.pkgList.size(); ip++) { 10018 String pkg = process.pkgList.keyAt(ip); 10019 sb.append("Package: ").append(pkg); 10020 try { 10021 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10022 if (pi != null) { 10023 sb.append(" v").append(pi.versionCode); 10024 if (pi.versionName != null) { 10025 sb.append(" (").append(pi.versionName).append(")"); 10026 } 10027 } 10028 } catch (RemoteException e) { 10029 Slog.e(TAG, "Error getting package info: " + pkg, e); 10030 } 10031 sb.append("\n"); 10032 } 10033 } 10034 } 10035 10036 private static String processClass(ProcessRecord process) { 10037 if (process == null || process.pid == MY_PID) { 10038 return "system_server"; 10039 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10040 return "system_app"; 10041 } else { 10042 return "data_app"; 10043 } 10044 } 10045 10046 /** 10047 * Write a description of an error (crash, WTF, ANR) to the drop box. 10048 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10049 * @param process which caused the error, null means the system server 10050 * @param activity which triggered the error, null if unknown 10051 * @param parent activity related to the error, null if unknown 10052 * @param subject line related to the error, null if absent 10053 * @param report in long form describing the error, null if absent 10054 * @param logFile to include in the report, null if none 10055 * @param crashInfo giving an application stack trace, null if absent 10056 */ 10057 public void addErrorToDropBox(String eventType, 10058 ProcessRecord process, String processName, ActivityRecord activity, 10059 ActivityRecord parent, String subject, 10060 final String report, final File logFile, 10061 final ApplicationErrorReport.CrashInfo crashInfo) { 10062 // NOTE -- this must never acquire the ActivityManagerService lock, 10063 // otherwise the watchdog may be prevented from resetting the system. 10064 10065 final String dropboxTag = processClass(process) + "_" + eventType; 10066 final DropBoxManager dbox = (DropBoxManager) 10067 mContext.getSystemService(Context.DROPBOX_SERVICE); 10068 10069 // Exit early if the dropbox isn't configured to accept this report type. 10070 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10071 10072 final StringBuilder sb = new StringBuilder(1024); 10073 appendDropBoxProcessHeaders(process, processName, sb); 10074 if (activity != null) { 10075 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10076 } 10077 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10078 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10079 } 10080 if (parent != null && parent != activity) { 10081 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10082 } 10083 if (subject != null) { 10084 sb.append("Subject: ").append(subject).append("\n"); 10085 } 10086 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10087 if (Debug.isDebuggerConnected()) { 10088 sb.append("Debugger: Connected\n"); 10089 } 10090 sb.append("\n"); 10091 10092 // Do the rest in a worker thread to avoid blocking the caller on I/O 10093 // (After this point, we shouldn't access AMS internal data structures.) 10094 Thread worker = new Thread("Error dump: " + dropboxTag) { 10095 @Override 10096 public void run() { 10097 if (report != null) { 10098 sb.append(report); 10099 } 10100 if (logFile != null) { 10101 try { 10102 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10103 "\n\n[[TRUNCATED]]")); 10104 } catch (IOException e) { 10105 Slog.e(TAG, "Error reading " + logFile, e); 10106 } 10107 } 10108 if (crashInfo != null && crashInfo.stackTrace != null) { 10109 sb.append(crashInfo.stackTrace); 10110 } 10111 10112 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10113 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10114 if (lines > 0) { 10115 sb.append("\n"); 10116 10117 // Merge several logcat streams, and take the last N lines 10118 InputStreamReader input = null; 10119 try { 10120 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10121 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10122 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10123 10124 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10125 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10126 input = new InputStreamReader(logcat.getInputStream()); 10127 10128 int num; 10129 char[] buf = new char[8192]; 10130 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10131 } catch (IOException e) { 10132 Slog.e(TAG, "Error running logcat", e); 10133 } finally { 10134 if (input != null) try { input.close(); } catch (IOException e) {} 10135 } 10136 } 10137 10138 dbox.addText(dropboxTag, sb.toString()); 10139 } 10140 }; 10141 10142 if (process == null) { 10143 // If process is null, we are being called from some internal code 10144 // and may be about to die -- run this synchronously. 10145 worker.run(); 10146 } else { 10147 worker.start(); 10148 } 10149 } 10150 10151 /** 10152 * Bring up the "unexpected error" dialog box for a crashing app. 10153 * Deal with edge cases (intercepts from instrumented applications, 10154 * ActivityController, error intent receivers, that sort of thing). 10155 * @param r the application crashing 10156 * @param crashInfo describing the failure 10157 */ 10158 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10159 long timeMillis = System.currentTimeMillis(); 10160 String shortMsg = crashInfo.exceptionClassName; 10161 String longMsg = crashInfo.exceptionMessage; 10162 String stackTrace = crashInfo.stackTrace; 10163 if (shortMsg != null && longMsg != null) { 10164 longMsg = shortMsg + ": " + longMsg; 10165 } else if (shortMsg != null) { 10166 longMsg = shortMsg; 10167 } 10168 10169 AppErrorResult result = new AppErrorResult(); 10170 synchronized (this) { 10171 if (mController != null) { 10172 try { 10173 String name = r != null ? r.processName : null; 10174 int pid = r != null ? r.pid : Binder.getCallingPid(); 10175 if (!mController.appCrashed(name, pid, 10176 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10177 Slog.w(TAG, "Force-killing crashed app " + name 10178 + " at watcher's request"); 10179 Process.killProcess(pid); 10180 return; 10181 } 10182 } catch (RemoteException e) { 10183 mController = null; 10184 Watchdog.getInstance().setActivityController(null); 10185 } 10186 } 10187 10188 final long origId = Binder.clearCallingIdentity(); 10189 10190 // If this process is running instrumentation, finish it. 10191 if (r != null && r.instrumentationClass != null) { 10192 Slog.w(TAG, "Error in app " + r.processName 10193 + " running instrumentation " + r.instrumentationClass + ":"); 10194 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10195 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10196 Bundle info = new Bundle(); 10197 info.putString("shortMsg", shortMsg); 10198 info.putString("longMsg", longMsg); 10199 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10200 Binder.restoreCallingIdentity(origId); 10201 return; 10202 } 10203 10204 // If we can't identify the process or it's already exceeded its crash quota, 10205 // quit right away without showing a crash dialog. 10206 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10207 Binder.restoreCallingIdentity(origId); 10208 return; 10209 } 10210 10211 Message msg = Message.obtain(); 10212 msg.what = SHOW_ERROR_MSG; 10213 HashMap data = new HashMap(); 10214 data.put("result", result); 10215 data.put("app", r); 10216 msg.obj = data; 10217 mHandler.sendMessage(msg); 10218 10219 Binder.restoreCallingIdentity(origId); 10220 } 10221 10222 int res = result.get(); 10223 10224 Intent appErrorIntent = null; 10225 synchronized (this) { 10226 if (r != null && !r.isolated) { 10227 // XXX Can't keep track of crash time for isolated processes, 10228 // since they don't have a persistent identity. 10229 mProcessCrashTimes.put(r.info.processName, r.uid, 10230 SystemClock.uptimeMillis()); 10231 } 10232 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10233 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10234 } 10235 } 10236 10237 if (appErrorIntent != null) { 10238 try { 10239 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10240 } catch (ActivityNotFoundException e) { 10241 Slog.w(TAG, "bug report receiver dissappeared", e); 10242 } 10243 } 10244 } 10245 10246 Intent createAppErrorIntentLocked(ProcessRecord r, 10247 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10248 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10249 if (report == null) { 10250 return null; 10251 } 10252 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10253 result.setComponent(r.errorReportReceiver); 10254 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10255 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10256 return result; 10257 } 10258 10259 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10260 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10261 if (r.errorReportReceiver == null) { 10262 return null; 10263 } 10264 10265 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10266 return null; 10267 } 10268 10269 ApplicationErrorReport report = new ApplicationErrorReport(); 10270 report.packageName = r.info.packageName; 10271 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10272 report.processName = r.processName; 10273 report.time = timeMillis; 10274 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10275 10276 if (r.crashing || r.forceCrashReport) { 10277 report.type = ApplicationErrorReport.TYPE_CRASH; 10278 report.crashInfo = crashInfo; 10279 } else if (r.notResponding) { 10280 report.type = ApplicationErrorReport.TYPE_ANR; 10281 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10282 10283 report.anrInfo.activity = r.notRespondingReport.tag; 10284 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10285 report.anrInfo.info = r.notRespondingReport.longMsg; 10286 } 10287 10288 return report; 10289 } 10290 10291 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10292 enforceNotIsolatedCaller("getProcessesInErrorState"); 10293 // assume our apps are happy - lazy create the list 10294 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10295 10296 final boolean allUsers = ActivityManager.checkUidPermission( 10297 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10298 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10299 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10300 10301 synchronized (this) { 10302 10303 // iterate across all processes 10304 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10305 ProcessRecord app = mLruProcesses.get(i); 10306 if (!allUsers && app.userId != userId) { 10307 continue; 10308 } 10309 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10310 // This one's in trouble, so we'll generate a report for it 10311 // crashes are higher priority (in case there's a crash *and* an anr) 10312 ActivityManager.ProcessErrorStateInfo report = null; 10313 if (app.crashing) { 10314 report = app.crashingReport; 10315 } else if (app.notResponding) { 10316 report = app.notRespondingReport; 10317 } 10318 10319 if (report != null) { 10320 if (errList == null) { 10321 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10322 } 10323 errList.add(report); 10324 } else { 10325 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10326 " crashing = " + app.crashing + 10327 " notResponding = " + app.notResponding); 10328 } 10329 } 10330 } 10331 } 10332 10333 return errList; 10334 } 10335 10336 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10337 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10338 if (currApp != null) { 10339 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10340 } 10341 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10342 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10343 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10344 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10345 if (currApp != null) { 10346 currApp.lru = 0; 10347 } 10348 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10349 } else if (adj >= ProcessList.SERVICE_ADJ) { 10350 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10351 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10352 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10353 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10354 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10355 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10356 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10357 } else { 10358 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10359 } 10360 } 10361 10362 private void fillInProcMemInfo(ProcessRecord app, 10363 ActivityManager.RunningAppProcessInfo outInfo) { 10364 outInfo.pid = app.pid; 10365 outInfo.uid = app.info.uid; 10366 if (mHeavyWeightProcess == app) { 10367 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10368 } 10369 if (app.persistent) { 10370 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10371 } 10372 if (app.activities.size() > 0) { 10373 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10374 } 10375 outInfo.lastTrimLevel = app.trimMemoryLevel; 10376 int adj = app.curAdj; 10377 outInfo.importance = oomAdjToImportance(adj, outInfo); 10378 outInfo.importanceReasonCode = app.adjTypeCode; 10379 } 10380 10381 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10382 enforceNotIsolatedCaller("getRunningAppProcesses"); 10383 // Lazy instantiation of list 10384 List<ActivityManager.RunningAppProcessInfo> runList = null; 10385 final boolean allUsers = ActivityManager.checkUidPermission( 10386 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10387 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10388 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10389 synchronized (this) { 10390 // Iterate across all processes 10391 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10392 ProcessRecord app = mLruProcesses.get(i); 10393 if (!allUsers && app.userId != userId) { 10394 continue; 10395 } 10396 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10397 // Generate process state info for running application 10398 ActivityManager.RunningAppProcessInfo currApp = 10399 new ActivityManager.RunningAppProcessInfo(app.processName, 10400 app.pid, app.getPackageList()); 10401 fillInProcMemInfo(app, currApp); 10402 if (app.adjSource instanceof ProcessRecord) { 10403 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10404 currApp.importanceReasonImportance = oomAdjToImportance( 10405 app.adjSourceOom, null); 10406 } else if (app.adjSource instanceof ActivityRecord) { 10407 ActivityRecord r = (ActivityRecord)app.adjSource; 10408 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10409 } 10410 if (app.adjTarget instanceof ComponentName) { 10411 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10412 } 10413 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10414 // + " lru=" + currApp.lru); 10415 if (runList == null) { 10416 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10417 } 10418 runList.add(currApp); 10419 } 10420 } 10421 } 10422 return runList; 10423 } 10424 10425 public List<ApplicationInfo> getRunningExternalApplications() { 10426 enforceNotIsolatedCaller("getRunningExternalApplications"); 10427 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10428 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10429 if (runningApps != null && runningApps.size() > 0) { 10430 Set<String> extList = new HashSet<String>(); 10431 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10432 if (app.pkgList != null) { 10433 for (String pkg : app.pkgList) { 10434 extList.add(pkg); 10435 } 10436 } 10437 } 10438 IPackageManager pm = AppGlobals.getPackageManager(); 10439 for (String pkg : extList) { 10440 try { 10441 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10442 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10443 retList.add(info); 10444 } 10445 } catch (RemoteException e) { 10446 } 10447 } 10448 } 10449 return retList; 10450 } 10451 10452 @Override 10453 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10454 enforceNotIsolatedCaller("getMyMemoryState"); 10455 synchronized (this) { 10456 ProcessRecord proc; 10457 synchronized (mPidsSelfLocked) { 10458 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10459 } 10460 fillInProcMemInfo(proc, outInfo); 10461 } 10462 } 10463 10464 @Override 10465 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10466 if (checkCallingPermission(android.Manifest.permission.DUMP) 10467 != PackageManager.PERMISSION_GRANTED) { 10468 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10469 + Binder.getCallingPid() 10470 + ", uid=" + Binder.getCallingUid() 10471 + " without permission " 10472 + android.Manifest.permission.DUMP); 10473 return; 10474 } 10475 10476 boolean dumpAll = false; 10477 boolean dumpClient = false; 10478 String dumpPackage = null; 10479 10480 int opti = 0; 10481 while (opti < args.length) { 10482 String opt = args[opti]; 10483 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10484 break; 10485 } 10486 opti++; 10487 if ("-a".equals(opt)) { 10488 dumpAll = true; 10489 } else if ("-c".equals(opt)) { 10490 dumpClient = true; 10491 } else if ("-h".equals(opt)) { 10492 pw.println("Activity manager dump options:"); 10493 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10494 pw.println(" cmd may be one of:"); 10495 pw.println(" a[ctivities]: activity stack state"); 10496 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10497 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10498 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10499 pw.println(" o[om]: out of memory management"); 10500 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10501 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10502 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10503 pw.println(" service [COMP_SPEC]: service client-side state"); 10504 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10505 pw.println(" all: dump all activities"); 10506 pw.println(" top: dump the top activity"); 10507 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10508 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10509 pw.println(" a partial substring in a component name, a"); 10510 pw.println(" hex object identifier."); 10511 pw.println(" -a: include all available server state."); 10512 pw.println(" -c: include client state."); 10513 return; 10514 } else { 10515 pw.println("Unknown argument: " + opt + "; use -h for help"); 10516 } 10517 } 10518 10519 long origId = Binder.clearCallingIdentity(); 10520 boolean more = false; 10521 // Is the caller requesting to dump a particular piece of data? 10522 if (opti < args.length) { 10523 String cmd = args[opti]; 10524 opti++; 10525 if ("activities".equals(cmd) || "a".equals(cmd)) { 10526 synchronized (this) { 10527 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10528 } 10529 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10530 String[] newArgs; 10531 String name; 10532 if (opti >= args.length) { 10533 name = null; 10534 newArgs = EMPTY_STRING_ARRAY; 10535 } else { 10536 name = args[opti]; 10537 opti++; 10538 newArgs = new String[args.length - opti]; 10539 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10540 args.length - opti); 10541 } 10542 synchronized (this) { 10543 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10544 } 10545 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10546 String[] newArgs; 10547 String name; 10548 if (opti >= args.length) { 10549 name = null; 10550 newArgs = EMPTY_STRING_ARRAY; 10551 } else { 10552 name = args[opti]; 10553 opti++; 10554 newArgs = new String[args.length - opti]; 10555 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10556 args.length - opti); 10557 } 10558 synchronized (this) { 10559 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10560 } 10561 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10562 String[] newArgs; 10563 String name; 10564 if (opti >= args.length) { 10565 name = null; 10566 newArgs = EMPTY_STRING_ARRAY; 10567 } else { 10568 name = args[opti]; 10569 opti++; 10570 newArgs = new String[args.length - opti]; 10571 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10572 args.length - opti); 10573 } 10574 synchronized (this) { 10575 dumpProcessesLocked(fd, pw, args, opti, true, name); 10576 } 10577 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10578 synchronized (this) { 10579 dumpOomLocked(fd, pw, args, opti, true); 10580 } 10581 } else if ("provider".equals(cmd)) { 10582 String[] newArgs; 10583 String name; 10584 if (opti >= args.length) { 10585 name = null; 10586 newArgs = EMPTY_STRING_ARRAY; 10587 } else { 10588 name = args[opti]; 10589 opti++; 10590 newArgs = new String[args.length - opti]; 10591 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10592 } 10593 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10594 pw.println("No providers match: " + name); 10595 pw.println("Use -h for help."); 10596 } 10597 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10598 synchronized (this) { 10599 dumpProvidersLocked(fd, pw, args, opti, true, null); 10600 } 10601 } else if ("service".equals(cmd)) { 10602 String[] newArgs; 10603 String name; 10604 if (opti >= args.length) { 10605 name = null; 10606 newArgs = EMPTY_STRING_ARRAY; 10607 } else { 10608 name = args[opti]; 10609 opti++; 10610 newArgs = new String[args.length - opti]; 10611 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10612 args.length - opti); 10613 } 10614 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10615 pw.println("No services match: " + name); 10616 pw.println("Use -h for help."); 10617 } 10618 } else if ("package".equals(cmd)) { 10619 String[] newArgs; 10620 if (opti >= args.length) { 10621 pw.println("package: no package name specified"); 10622 pw.println("Use -h for help."); 10623 } else { 10624 dumpPackage = args[opti]; 10625 opti++; 10626 newArgs = new String[args.length - opti]; 10627 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10628 args.length - opti); 10629 args = newArgs; 10630 opti = 0; 10631 more = true; 10632 } 10633 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10634 synchronized (this) { 10635 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10636 } 10637 } else { 10638 // Dumping a single activity? 10639 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10640 pw.println("Bad activity command, or no activities match: " + cmd); 10641 pw.println("Use -h for help."); 10642 } 10643 } 10644 if (!more) { 10645 Binder.restoreCallingIdentity(origId); 10646 return; 10647 } 10648 } 10649 10650 // No piece of data specified, dump everything. 10651 synchronized (this) { 10652 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10653 pw.println(); 10654 if (dumpAll) { 10655 pw.println("-------------------------------------------------------------------------------"); 10656 } 10657 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10658 pw.println(); 10659 if (dumpAll) { 10660 pw.println("-------------------------------------------------------------------------------"); 10661 } 10662 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10663 pw.println(); 10664 if (dumpAll) { 10665 pw.println("-------------------------------------------------------------------------------"); 10666 } 10667 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10668 pw.println(); 10669 if (dumpAll) { 10670 pw.println("-------------------------------------------------------------------------------"); 10671 } 10672 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10673 pw.println(); 10674 if (dumpAll) { 10675 pw.println("-------------------------------------------------------------------------------"); 10676 } 10677 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10678 } 10679 Binder.restoreCallingIdentity(origId); 10680 } 10681 10682 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10683 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10684 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10685 10686 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10687 dumpPackage); 10688 boolean needSep = printedAnything; 10689 10690 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10691 dumpPackage, needSep, " mFocusedActivity: "); 10692 if (printed) { 10693 printedAnything = true; 10694 needSep = false; 10695 } 10696 10697 if (dumpPackage == null) { 10698 if (needSep) { 10699 pw.println(); 10700 } 10701 needSep = true; 10702 printedAnything = true; 10703 mStackSupervisor.dump(pw, " "); 10704 } 10705 10706 if (mRecentTasks.size() > 0) { 10707 boolean printedHeader = false; 10708 10709 final int N = mRecentTasks.size(); 10710 for (int i=0; i<N; i++) { 10711 TaskRecord tr = mRecentTasks.get(i); 10712 if (dumpPackage != null) { 10713 if (tr.realActivity == null || 10714 !dumpPackage.equals(tr.realActivity)) { 10715 continue; 10716 } 10717 } 10718 if (!printedHeader) { 10719 if (needSep) { 10720 pw.println(); 10721 } 10722 pw.println(" Recent tasks:"); 10723 printedHeader = true; 10724 printedAnything = true; 10725 } 10726 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10727 pw.println(tr); 10728 if (dumpAll) { 10729 mRecentTasks.get(i).dump(pw, " "); 10730 } 10731 } 10732 } 10733 10734 if (!printedAnything) { 10735 pw.println(" (nothing)"); 10736 } 10737 } 10738 10739 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10740 int opti, boolean dumpAll, String dumpPackage) { 10741 boolean needSep = false; 10742 boolean printedAnything = false; 10743 int numPers = 0; 10744 10745 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10746 10747 if (dumpAll) { 10748 final int NP = mProcessNames.getMap().size(); 10749 for (int ip=0; ip<NP; ip++) { 10750 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10751 final int NA = procs.size(); 10752 for (int ia=0; ia<NA; ia++) { 10753 ProcessRecord r = procs.valueAt(ia); 10754 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10755 continue; 10756 } 10757 if (!needSep) { 10758 pw.println(" All known processes:"); 10759 needSep = true; 10760 printedAnything = true; 10761 } 10762 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10763 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10764 pw.print(" "); pw.println(r); 10765 r.dump(pw, " "); 10766 if (r.persistent) { 10767 numPers++; 10768 } 10769 } 10770 } 10771 } 10772 10773 if (mIsolatedProcesses.size() > 0) { 10774 boolean printed = false; 10775 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10776 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10777 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10778 continue; 10779 } 10780 if (!printed) { 10781 if (needSep) { 10782 pw.println(); 10783 } 10784 pw.println(" Isolated process list (sorted by uid):"); 10785 printedAnything = true; 10786 printed = true; 10787 needSep = true; 10788 } 10789 pw.println(String.format("%sIsolated #%2d: %s", 10790 " ", i, r.toString())); 10791 } 10792 } 10793 10794 if (mLruProcesses.size() > 0) { 10795 if (needSep) { 10796 pw.println(); 10797 } 10798 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10799 pw.print(" total, non-act at "); 10800 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10801 pw.print(", non-svc at "); 10802 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10803 pw.println("):"); 10804 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10805 needSep = true; 10806 printedAnything = true; 10807 } 10808 10809 if (dumpAll || dumpPackage != null) { 10810 synchronized (mPidsSelfLocked) { 10811 boolean printed = false; 10812 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10813 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10814 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10815 continue; 10816 } 10817 if (!printed) { 10818 if (needSep) pw.println(); 10819 needSep = true; 10820 pw.println(" PID mappings:"); 10821 printed = true; 10822 printedAnything = true; 10823 } 10824 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10825 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10826 } 10827 } 10828 } 10829 10830 if (mForegroundProcesses.size() > 0) { 10831 synchronized (mPidsSelfLocked) { 10832 boolean printed = false; 10833 for (int i=0; i<mForegroundProcesses.size(); i++) { 10834 ProcessRecord r = mPidsSelfLocked.get( 10835 mForegroundProcesses.valueAt(i).pid); 10836 if (dumpPackage != null && (r == null 10837 || !r.pkgList.containsKey(dumpPackage))) { 10838 continue; 10839 } 10840 if (!printed) { 10841 if (needSep) pw.println(); 10842 needSep = true; 10843 pw.println(" Foreground Processes:"); 10844 printed = true; 10845 printedAnything = true; 10846 } 10847 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10848 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10849 } 10850 } 10851 } 10852 10853 if (mPersistentStartingProcesses.size() > 0) { 10854 if (needSep) pw.println(); 10855 needSep = true; 10856 printedAnything = true; 10857 pw.println(" Persisent processes that are starting:"); 10858 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10859 "Starting Norm", "Restarting PERS", dumpPackage); 10860 } 10861 10862 if (mRemovedProcesses.size() > 0) { 10863 if (needSep) pw.println(); 10864 needSep = true; 10865 printedAnything = true; 10866 pw.println(" Processes that are being removed:"); 10867 dumpProcessList(pw, this, mRemovedProcesses, " ", 10868 "Removed Norm", "Removed PERS", dumpPackage); 10869 } 10870 10871 if (mProcessesOnHold.size() > 0) { 10872 if (needSep) pw.println(); 10873 needSep = true; 10874 printedAnything = true; 10875 pw.println(" Processes that are on old until the system is ready:"); 10876 dumpProcessList(pw, this, mProcessesOnHold, " ", 10877 "OnHold Norm", "OnHold PERS", dumpPackage); 10878 } 10879 10880 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10881 10882 if (mProcessCrashTimes.getMap().size() > 0) { 10883 boolean printed = false; 10884 long now = SystemClock.uptimeMillis(); 10885 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10886 final int NP = pmap.size(); 10887 for (int ip=0; ip<NP; ip++) { 10888 String pname = pmap.keyAt(ip); 10889 SparseArray<Long> uids = pmap.valueAt(ip); 10890 final int N = uids.size(); 10891 for (int i=0; i<N; i++) { 10892 int puid = uids.keyAt(i); 10893 ProcessRecord r = mProcessNames.get(pname, puid); 10894 if (dumpPackage != null && (r == null 10895 || !r.pkgList.containsKey(dumpPackage))) { 10896 continue; 10897 } 10898 if (!printed) { 10899 if (needSep) pw.println(); 10900 needSep = true; 10901 pw.println(" Time since processes crashed:"); 10902 printed = true; 10903 printedAnything = true; 10904 } 10905 pw.print(" Process "); pw.print(pname); 10906 pw.print(" uid "); pw.print(puid); 10907 pw.print(": last crashed "); 10908 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10909 pw.println(" ago"); 10910 } 10911 } 10912 } 10913 10914 if (mBadProcesses.getMap().size() > 0) { 10915 boolean printed = false; 10916 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10917 final int NP = pmap.size(); 10918 for (int ip=0; ip<NP; ip++) { 10919 String pname = pmap.keyAt(ip); 10920 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10921 final int N = uids.size(); 10922 for (int i=0; i<N; i++) { 10923 int puid = uids.keyAt(i); 10924 ProcessRecord r = mProcessNames.get(pname, puid); 10925 if (dumpPackage != null && (r == null 10926 || !r.pkgList.containsKey(dumpPackage))) { 10927 continue; 10928 } 10929 if (!printed) { 10930 if (needSep) pw.println(); 10931 needSep = true; 10932 pw.println(" Bad processes:"); 10933 printedAnything = true; 10934 } 10935 BadProcessInfo info = uids.valueAt(i); 10936 pw.print(" Bad process "); pw.print(pname); 10937 pw.print(" uid "); pw.print(puid); 10938 pw.print(": crashed at time "); pw.println(info.time); 10939 if (info.shortMsg != null) { 10940 pw.print(" Short msg: "); pw.println(info.shortMsg); 10941 } 10942 if (info.longMsg != null) { 10943 pw.print(" Long msg: "); pw.println(info.longMsg); 10944 } 10945 if (info.stack != null) { 10946 pw.println(" Stack:"); 10947 int lastPos = 0; 10948 for (int pos=0; pos<info.stack.length(); pos++) { 10949 if (info.stack.charAt(pos) == '\n') { 10950 pw.print(" "); 10951 pw.write(info.stack, lastPos, pos-lastPos); 10952 pw.println(); 10953 lastPos = pos+1; 10954 } 10955 } 10956 if (lastPos < info.stack.length()) { 10957 pw.print(" "); 10958 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10959 pw.println(); 10960 } 10961 } 10962 } 10963 } 10964 } 10965 10966 if (dumpPackage == null) { 10967 pw.println(); 10968 needSep = false; 10969 pw.println(" mStartedUsers:"); 10970 for (int i=0; i<mStartedUsers.size(); i++) { 10971 UserStartedState uss = mStartedUsers.valueAt(i); 10972 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10973 pw.print(": "); uss.dump("", pw); 10974 } 10975 pw.print(" mStartedUserArray: ["); 10976 for (int i=0; i<mStartedUserArray.length; i++) { 10977 if (i > 0) pw.print(", "); 10978 pw.print(mStartedUserArray[i]); 10979 } 10980 pw.println("]"); 10981 pw.print(" mUserLru: ["); 10982 for (int i=0; i<mUserLru.size(); i++) { 10983 if (i > 0) pw.print(", "); 10984 pw.print(mUserLru.get(i)); 10985 } 10986 pw.println("]"); 10987 if (dumpAll) { 10988 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10989 } 10990 } 10991 if (mHomeProcess != null && (dumpPackage == null 10992 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10993 if (needSep) { 10994 pw.println(); 10995 needSep = false; 10996 } 10997 pw.println(" mHomeProcess: " + mHomeProcess); 10998 } 10999 if (mPreviousProcess != null && (dumpPackage == null 11000 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11001 if (needSep) { 11002 pw.println(); 11003 needSep = false; 11004 } 11005 pw.println(" mPreviousProcess: " + mPreviousProcess); 11006 } 11007 if (dumpAll) { 11008 StringBuilder sb = new StringBuilder(128); 11009 sb.append(" mPreviousProcessVisibleTime: "); 11010 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11011 pw.println(sb); 11012 } 11013 if (mHeavyWeightProcess != null && (dumpPackage == null 11014 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11015 if (needSep) { 11016 pw.println(); 11017 needSep = false; 11018 } 11019 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11020 } 11021 if (dumpPackage == null) { 11022 pw.println(" mConfiguration: " + mConfiguration); 11023 } 11024 if (dumpAll) { 11025 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11026 if (mCompatModePackages.getPackages().size() > 0) { 11027 boolean printed = false; 11028 for (Map.Entry<String, Integer> entry 11029 : mCompatModePackages.getPackages().entrySet()) { 11030 String pkg = entry.getKey(); 11031 int mode = entry.getValue(); 11032 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11033 continue; 11034 } 11035 if (!printed) { 11036 pw.println(" mScreenCompatPackages:"); 11037 printed = true; 11038 } 11039 pw.print(" "); pw.print(pkg); pw.print(": "); 11040 pw.print(mode); pw.println(); 11041 } 11042 } 11043 } 11044 if (dumpPackage == null) { 11045 if (mSleeping || mWentToSleep || mLockScreenShown) { 11046 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11047 + " mLockScreenShown " + mLockScreenShown); 11048 } 11049 if (mShuttingDown) { 11050 pw.println(" mShuttingDown=" + mShuttingDown); 11051 } 11052 } 11053 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11054 || mOrigWaitForDebugger) { 11055 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11056 || dumpPackage.equals(mOrigDebugApp)) { 11057 if (needSep) { 11058 pw.println(); 11059 needSep = false; 11060 } 11061 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11062 + " mDebugTransient=" + mDebugTransient 11063 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11064 } 11065 } 11066 if (mOpenGlTraceApp != null) { 11067 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11068 if (needSep) { 11069 pw.println(); 11070 needSep = false; 11071 } 11072 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11073 } 11074 } 11075 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11076 || mProfileFd != null) { 11077 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11078 if (needSep) { 11079 pw.println(); 11080 needSep = false; 11081 } 11082 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11083 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11084 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11085 + mAutoStopProfiler); 11086 } 11087 } 11088 if (dumpPackage == null) { 11089 if (mAlwaysFinishActivities || mController != null) { 11090 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11091 + " mController=" + mController); 11092 } 11093 if (dumpAll) { 11094 pw.println(" Total persistent processes: " + numPers); 11095 pw.println(" mStartRunning=" + mStartRunning 11096 + " mProcessesReady=" + mProcessesReady 11097 + " mSystemReady=" + mSystemReady); 11098 pw.println(" mBooting=" + mBooting 11099 + " mBooted=" + mBooted 11100 + " mFactoryTest=" + mFactoryTest); 11101 pw.print(" mLastPowerCheckRealtime="); 11102 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11103 pw.println(""); 11104 pw.print(" mLastPowerCheckUptime="); 11105 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11106 pw.println(""); 11107 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11108 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11109 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11110 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11111 + " (" + mLruProcesses.size() + " total)" 11112 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11113 + " mNumServiceProcs=" + mNumServiceProcs 11114 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11115 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11116 + " mLastMemoryLevel" + mLastMemoryLevel 11117 + " mLastNumProcesses" + mLastNumProcesses); 11118 long now = SystemClock.uptimeMillis(); 11119 pw.print(" mLastIdleTime="); 11120 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11121 pw.print(" mLowRamSinceLastIdle="); 11122 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11123 pw.println(); 11124 } 11125 } 11126 11127 if (!printedAnything) { 11128 pw.println(" (nothing)"); 11129 } 11130 } 11131 11132 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11133 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11134 if (mProcessesToGc.size() > 0) { 11135 boolean printed = false; 11136 long now = SystemClock.uptimeMillis(); 11137 for (int i=0; i<mProcessesToGc.size(); i++) { 11138 ProcessRecord proc = mProcessesToGc.get(i); 11139 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11140 continue; 11141 } 11142 if (!printed) { 11143 if (needSep) pw.println(); 11144 needSep = true; 11145 pw.println(" Processes that are waiting to GC:"); 11146 printed = true; 11147 } 11148 pw.print(" Process "); pw.println(proc); 11149 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11150 pw.print(", last gced="); 11151 pw.print(now-proc.lastRequestedGc); 11152 pw.print(" ms ago, last lowMem="); 11153 pw.print(now-proc.lastLowMemory); 11154 pw.println(" ms ago"); 11155 11156 } 11157 } 11158 return needSep; 11159 } 11160 11161 void printOomLevel(PrintWriter pw, String name, int adj) { 11162 pw.print(" "); 11163 if (adj >= 0) { 11164 pw.print(' '); 11165 if (adj < 10) pw.print(' '); 11166 } else { 11167 if (adj > -10) pw.print(' '); 11168 } 11169 pw.print(adj); 11170 pw.print(": "); 11171 pw.print(name); 11172 pw.print(" ("); 11173 pw.print(mProcessList.getMemLevel(adj)/1024); 11174 pw.println(" kB)"); 11175 } 11176 11177 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11178 int opti, boolean dumpAll) { 11179 boolean needSep = false; 11180 11181 if (mLruProcesses.size() > 0) { 11182 if (needSep) pw.println(); 11183 needSep = true; 11184 pw.println(" OOM levels:"); 11185 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11186 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11187 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11188 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11189 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11190 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11191 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11192 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11193 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11194 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11195 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11196 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11197 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11198 11199 if (needSep) pw.println(); 11200 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11201 pw.print(" total, non-act at "); 11202 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11203 pw.print(", non-svc at "); 11204 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11205 pw.println("):"); 11206 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11207 needSep = true; 11208 } 11209 11210 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11211 11212 pw.println(); 11213 pw.println(" mHomeProcess: " + mHomeProcess); 11214 pw.println(" mPreviousProcess: " + mPreviousProcess); 11215 if (mHeavyWeightProcess != null) { 11216 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11217 } 11218 11219 return true; 11220 } 11221 11222 /** 11223 * There are three ways to call this: 11224 * - no provider specified: dump all the providers 11225 * - a flattened component name that matched an existing provider was specified as the 11226 * first arg: dump that one provider 11227 * - the first arg isn't the flattened component name of an existing provider: 11228 * dump all providers whose component contains the first arg as a substring 11229 */ 11230 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11231 int opti, boolean dumpAll) { 11232 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11233 } 11234 11235 static class ItemMatcher { 11236 ArrayList<ComponentName> components; 11237 ArrayList<String> strings; 11238 ArrayList<Integer> objects; 11239 boolean all; 11240 11241 ItemMatcher() { 11242 all = true; 11243 } 11244 11245 void build(String name) { 11246 ComponentName componentName = ComponentName.unflattenFromString(name); 11247 if (componentName != null) { 11248 if (components == null) { 11249 components = new ArrayList<ComponentName>(); 11250 } 11251 components.add(componentName); 11252 all = false; 11253 } else { 11254 int objectId = 0; 11255 // Not a '/' separated full component name; maybe an object ID? 11256 try { 11257 objectId = Integer.parseInt(name, 16); 11258 if (objects == null) { 11259 objects = new ArrayList<Integer>(); 11260 } 11261 objects.add(objectId); 11262 all = false; 11263 } catch (RuntimeException e) { 11264 // Not an integer; just do string match. 11265 if (strings == null) { 11266 strings = new ArrayList<String>(); 11267 } 11268 strings.add(name); 11269 all = false; 11270 } 11271 } 11272 } 11273 11274 int build(String[] args, int opti) { 11275 for (; opti<args.length; opti++) { 11276 String name = args[opti]; 11277 if ("--".equals(name)) { 11278 return opti+1; 11279 } 11280 build(name); 11281 } 11282 return opti; 11283 } 11284 11285 boolean match(Object object, ComponentName comp) { 11286 if (all) { 11287 return true; 11288 } 11289 if (components != null) { 11290 for (int i=0; i<components.size(); i++) { 11291 if (components.get(i).equals(comp)) { 11292 return true; 11293 } 11294 } 11295 } 11296 if (objects != null) { 11297 for (int i=0; i<objects.size(); i++) { 11298 if (System.identityHashCode(object) == objects.get(i)) { 11299 return true; 11300 } 11301 } 11302 } 11303 if (strings != null) { 11304 String flat = comp.flattenToString(); 11305 for (int i=0; i<strings.size(); i++) { 11306 if (flat.contains(strings.get(i))) { 11307 return true; 11308 } 11309 } 11310 } 11311 return false; 11312 } 11313 } 11314 11315 /** 11316 * There are three things that cmd can be: 11317 * - a flattened component name that matches an existing activity 11318 * - the cmd arg isn't the flattened component name of an existing activity: 11319 * dump all activity whose component contains the cmd as a substring 11320 * - A hex number of the ActivityRecord object instance. 11321 */ 11322 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11323 int opti, boolean dumpAll) { 11324 ArrayList<ActivityRecord> activities; 11325 11326 synchronized (this) { 11327 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11328 } 11329 11330 if (activities.size() <= 0) { 11331 return false; 11332 } 11333 11334 String[] newArgs = new String[args.length - opti]; 11335 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11336 11337 TaskRecord lastTask = null; 11338 boolean needSep = false; 11339 for (int i=activities.size()-1; i>=0; i--) { 11340 ActivityRecord r = activities.get(i); 11341 if (needSep) { 11342 pw.println(); 11343 } 11344 needSep = true; 11345 synchronized (this) { 11346 if (lastTask != r.task) { 11347 lastTask = r.task; 11348 pw.print("TASK "); pw.print(lastTask.affinity); 11349 pw.print(" id="); pw.println(lastTask.taskId); 11350 if (dumpAll) { 11351 lastTask.dump(pw, " "); 11352 } 11353 } 11354 } 11355 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11356 } 11357 return true; 11358 } 11359 11360 /** 11361 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11362 * there is a thread associated with the activity. 11363 */ 11364 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11365 final ActivityRecord r, String[] args, boolean dumpAll) { 11366 String innerPrefix = prefix + " "; 11367 synchronized (this) { 11368 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11369 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11370 pw.print(" pid="); 11371 if (r.app != null) pw.println(r.app.pid); 11372 else pw.println("(not running)"); 11373 if (dumpAll) { 11374 r.dump(pw, innerPrefix); 11375 } 11376 } 11377 if (r.app != null && r.app.thread != null) { 11378 // flush anything that is already in the PrintWriter since the thread is going 11379 // to write to the file descriptor directly 11380 pw.flush(); 11381 try { 11382 TransferPipe tp = new TransferPipe(); 11383 try { 11384 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11385 r.appToken, innerPrefix, args); 11386 tp.go(fd); 11387 } finally { 11388 tp.kill(); 11389 } 11390 } catch (IOException e) { 11391 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11392 } catch (RemoteException e) { 11393 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11394 } 11395 } 11396 } 11397 11398 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11399 int opti, boolean dumpAll, String dumpPackage) { 11400 boolean needSep = false; 11401 boolean onlyHistory = false; 11402 boolean printedAnything = false; 11403 11404 if ("history".equals(dumpPackage)) { 11405 if (opti < args.length && "-s".equals(args[opti])) { 11406 dumpAll = false; 11407 } 11408 onlyHistory = true; 11409 dumpPackage = null; 11410 } 11411 11412 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11413 if (!onlyHistory && dumpAll) { 11414 if (mRegisteredReceivers.size() > 0) { 11415 boolean printed = false; 11416 Iterator it = mRegisteredReceivers.values().iterator(); 11417 while (it.hasNext()) { 11418 ReceiverList r = (ReceiverList)it.next(); 11419 if (dumpPackage != null && (r.app == null || 11420 !dumpPackage.equals(r.app.info.packageName))) { 11421 continue; 11422 } 11423 if (!printed) { 11424 pw.println(" Registered Receivers:"); 11425 needSep = true; 11426 printed = true; 11427 printedAnything = true; 11428 } 11429 pw.print(" * "); pw.println(r); 11430 r.dump(pw, " "); 11431 } 11432 } 11433 11434 if (mReceiverResolver.dump(pw, needSep ? 11435 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11436 " ", dumpPackage, false)) { 11437 needSep = true; 11438 printedAnything = true; 11439 } 11440 } 11441 11442 for (BroadcastQueue q : mBroadcastQueues) { 11443 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11444 printedAnything |= needSep; 11445 } 11446 11447 needSep = true; 11448 11449 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11450 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11451 if (needSep) { 11452 pw.println(); 11453 } 11454 needSep = true; 11455 printedAnything = true; 11456 pw.print(" Sticky broadcasts for user "); 11457 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11458 StringBuilder sb = new StringBuilder(128); 11459 for (Map.Entry<String, ArrayList<Intent>> ent 11460 : mStickyBroadcasts.valueAt(user).entrySet()) { 11461 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11462 if (dumpAll) { 11463 pw.println(":"); 11464 ArrayList<Intent> intents = ent.getValue(); 11465 final int N = intents.size(); 11466 for (int i=0; i<N; i++) { 11467 sb.setLength(0); 11468 sb.append(" Intent: "); 11469 intents.get(i).toShortString(sb, false, true, false, false); 11470 pw.println(sb.toString()); 11471 Bundle bundle = intents.get(i).getExtras(); 11472 if (bundle != null) { 11473 pw.print(" "); 11474 pw.println(bundle.toString()); 11475 } 11476 } 11477 } else { 11478 pw.println(""); 11479 } 11480 } 11481 } 11482 } 11483 11484 if (!onlyHistory && dumpAll) { 11485 pw.println(); 11486 for (BroadcastQueue queue : mBroadcastQueues) { 11487 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11488 + queue.mBroadcastsScheduled); 11489 } 11490 pw.println(" mHandler:"); 11491 mHandler.dump(new PrintWriterPrinter(pw), " "); 11492 needSep = true; 11493 printedAnything = true; 11494 } 11495 11496 if (!printedAnything) { 11497 pw.println(" (nothing)"); 11498 } 11499 } 11500 11501 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11502 int opti, boolean dumpAll, String dumpPackage) { 11503 boolean needSep; 11504 boolean printedAnything = false; 11505 11506 ItemMatcher matcher = new ItemMatcher(); 11507 matcher.build(args, opti); 11508 11509 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11510 11511 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11512 printedAnything |= needSep; 11513 11514 if (mLaunchingProviders.size() > 0) { 11515 boolean printed = false; 11516 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11517 ContentProviderRecord r = mLaunchingProviders.get(i); 11518 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11519 continue; 11520 } 11521 if (!printed) { 11522 if (needSep) pw.println(); 11523 needSep = true; 11524 pw.println(" Launching content providers:"); 11525 printed = true; 11526 printedAnything = true; 11527 } 11528 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11529 pw.println(r); 11530 } 11531 } 11532 11533 if (mGrantedUriPermissions.size() > 0) { 11534 boolean printed = false; 11535 int dumpUid = -2; 11536 if (dumpPackage != null) { 11537 try { 11538 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11539 } catch (NameNotFoundException e) { 11540 dumpUid = -1; 11541 } 11542 } 11543 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11544 int uid = mGrantedUriPermissions.keyAt(i); 11545 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11546 continue; 11547 } 11548 ArrayMap<Uri, UriPermission> perms 11549 = mGrantedUriPermissions.valueAt(i); 11550 if (!printed) { 11551 if (needSep) pw.println(); 11552 needSep = true; 11553 pw.println(" Granted Uri Permissions:"); 11554 printed = true; 11555 printedAnything = true; 11556 } 11557 pw.print(" * UID "); pw.print(uid); 11558 pw.println(" holds:"); 11559 for (UriPermission perm : perms.values()) { 11560 pw.print(" "); pw.println(perm); 11561 if (dumpAll) { 11562 perm.dump(pw, " "); 11563 } 11564 } 11565 } 11566 } 11567 11568 if (!printedAnything) { 11569 pw.println(" (nothing)"); 11570 } 11571 } 11572 11573 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11574 int opti, boolean dumpAll, String dumpPackage) { 11575 boolean printed = false; 11576 11577 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11578 11579 if (mIntentSenderRecords.size() > 0) { 11580 Iterator<WeakReference<PendingIntentRecord>> it 11581 = mIntentSenderRecords.values().iterator(); 11582 while (it.hasNext()) { 11583 WeakReference<PendingIntentRecord> ref = it.next(); 11584 PendingIntentRecord rec = ref != null ? ref.get(): null; 11585 if (dumpPackage != null && (rec == null 11586 || !dumpPackage.equals(rec.key.packageName))) { 11587 continue; 11588 } 11589 printed = true; 11590 if (rec != null) { 11591 pw.print(" * "); pw.println(rec); 11592 if (dumpAll) { 11593 rec.dump(pw, " "); 11594 } 11595 } else { 11596 pw.print(" * "); pw.println(ref); 11597 } 11598 } 11599 } 11600 11601 if (!printed) { 11602 pw.println(" (nothing)"); 11603 } 11604 } 11605 11606 private static final int dumpProcessList(PrintWriter pw, 11607 ActivityManagerService service, List list, 11608 String prefix, String normalLabel, String persistentLabel, 11609 String dumpPackage) { 11610 int numPers = 0; 11611 final int N = list.size()-1; 11612 for (int i=N; i>=0; i--) { 11613 ProcessRecord r = (ProcessRecord)list.get(i); 11614 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11615 continue; 11616 } 11617 pw.println(String.format("%s%s #%2d: %s", 11618 prefix, (r.persistent ? persistentLabel : normalLabel), 11619 i, r.toString())); 11620 if (r.persistent) { 11621 numPers++; 11622 } 11623 } 11624 return numPers; 11625 } 11626 11627 private static final boolean dumpProcessOomList(PrintWriter pw, 11628 ActivityManagerService service, List<ProcessRecord> origList, 11629 String prefix, String normalLabel, String persistentLabel, 11630 boolean inclDetails, String dumpPackage) { 11631 11632 ArrayList<Pair<ProcessRecord, Integer>> list 11633 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11634 for (int i=0; i<origList.size(); i++) { 11635 ProcessRecord r = origList.get(i); 11636 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11637 continue; 11638 } 11639 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11640 } 11641 11642 if (list.size() <= 0) { 11643 return false; 11644 } 11645 11646 Comparator<Pair<ProcessRecord, Integer>> comparator 11647 = new Comparator<Pair<ProcessRecord, Integer>>() { 11648 @Override 11649 public int compare(Pair<ProcessRecord, Integer> object1, 11650 Pair<ProcessRecord, Integer> object2) { 11651 if (object1.first.setAdj != object2.first.setAdj) { 11652 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11653 } 11654 if (object1.second.intValue() != object2.second.intValue()) { 11655 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11656 } 11657 return 0; 11658 } 11659 }; 11660 11661 Collections.sort(list, comparator); 11662 11663 final long curRealtime = SystemClock.elapsedRealtime(); 11664 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11665 final long curUptime = SystemClock.uptimeMillis(); 11666 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11667 11668 for (int i=list.size()-1; i>=0; i--) { 11669 ProcessRecord r = list.get(i).first; 11670 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11671 char schedGroup; 11672 switch (r.setSchedGroup) { 11673 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11674 schedGroup = 'B'; 11675 break; 11676 case Process.THREAD_GROUP_DEFAULT: 11677 schedGroup = 'F'; 11678 break; 11679 default: 11680 schedGroup = '?'; 11681 break; 11682 } 11683 char foreground; 11684 if (r.foregroundActivities) { 11685 foreground = 'A'; 11686 } else if (r.foregroundServices) { 11687 foreground = 'S'; 11688 } else { 11689 foreground = ' '; 11690 } 11691 String procState = ProcessList.makeProcStateString(r.curProcState); 11692 pw.print(prefix); 11693 pw.print(r.persistent ? persistentLabel : normalLabel); 11694 pw.print(" #"); 11695 int num = (origList.size()-1)-list.get(i).second; 11696 if (num < 10) pw.print(' '); 11697 pw.print(num); 11698 pw.print(": "); 11699 pw.print(oomAdj); 11700 pw.print(' '); 11701 pw.print(schedGroup); 11702 pw.print('/'); 11703 pw.print(foreground); 11704 pw.print('/'); 11705 pw.print(procState); 11706 pw.print(" trm:"); 11707 if (r.trimMemoryLevel < 10) pw.print(' '); 11708 pw.print(r.trimMemoryLevel); 11709 pw.print(' '); 11710 pw.print(r.toShortString()); 11711 pw.print(" ("); 11712 pw.print(r.adjType); 11713 pw.println(')'); 11714 if (r.adjSource != null || r.adjTarget != null) { 11715 pw.print(prefix); 11716 pw.print(" "); 11717 if (r.adjTarget instanceof ComponentName) { 11718 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11719 } else if (r.adjTarget != null) { 11720 pw.print(r.adjTarget.toString()); 11721 } else { 11722 pw.print("{null}"); 11723 } 11724 pw.print("<="); 11725 if (r.adjSource instanceof ProcessRecord) { 11726 pw.print("Proc{"); 11727 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11728 pw.println("}"); 11729 } else if (r.adjSource != null) { 11730 pw.println(r.adjSource.toString()); 11731 } else { 11732 pw.println("{null}"); 11733 } 11734 } 11735 if (inclDetails) { 11736 pw.print(prefix); 11737 pw.print(" "); 11738 pw.print("oom: max="); pw.print(r.maxAdj); 11739 pw.print(" curRaw="); pw.print(r.curRawAdj); 11740 pw.print(" setRaw="); pw.print(r.setRawAdj); 11741 pw.print(" cur="); pw.print(r.curAdj); 11742 pw.print(" set="); pw.println(r.setAdj); 11743 pw.print(prefix); 11744 pw.print(" "); 11745 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11746 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11747 pw.print(" lastPss="); pw.print(r.lastPss); 11748 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11749 pw.print(prefix); 11750 pw.print(" "); 11751 pw.print("keeping="); pw.print(r.keeping); 11752 pw.print(" cached="); pw.print(r.cached); 11753 pw.print(" empty="); pw.print(r.empty); 11754 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11755 11756 if (!r.keeping) { 11757 if (r.lastWakeTime != 0) { 11758 long wtime; 11759 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11760 synchronized (stats) { 11761 wtime = stats.getProcessWakeTime(r.info.uid, 11762 r.pid, curRealtime); 11763 } 11764 long timeUsed = wtime - r.lastWakeTime; 11765 pw.print(prefix); 11766 pw.print(" "); 11767 pw.print("keep awake over "); 11768 TimeUtils.formatDuration(realtimeSince, pw); 11769 pw.print(" used "); 11770 TimeUtils.formatDuration(timeUsed, pw); 11771 pw.print(" ("); 11772 pw.print((timeUsed*100)/realtimeSince); 11773 pw.println("%)"); 11774 } 11775 if (r.lastCpuTime != 0) { 11776 long timeUsed = r.curCpuTime - r.lastCpuTime; 11777 pw.print(prefix); 11778 pw.print(" "); 11779 pw.print("run cpu over "); 11780 TimeUtils.formatDuration(uptimeSince, pw); 11781 pw.print(" used "); 11782 TimeUtils.formatDuration(timeUsed, pw); 11783 pw.print(" ("); 11784 pw.print((timeUsed*100)/uptimeSince); 11785 pw.println("%)"); 11786 } 11787 } 11788 } 11789 } 11790 return true; 11791 } 11792 11793 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11794 ArrayList<ProcessRecord> procs; 11795 synchronized (this) { 11796 if (args != null && args.length > start 11797 && args[start].charAt(0) != '-') { 11798 procs = new ArrayList<ProcessRecord>(); 11799 int pid = -1; 11800 try { 11801 pid = Integer.parseInt(args[start]); 11802 } catch (NumberFormatException e) { 11803 } 11804 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11805 ProcessRecord proc = mLruProcesses.get(i); 11806 if (proc.pid == pid) { 11807 procs.add(proc); 11808 } else if (proc.processName.equals(args[start])) { 11809 procs.add(proc); 11810 } 11811 } 11812 if (procs.size() <= 0) { 11813 return null; 11814 } 11815 } else { 11816 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11817 } 11818 } 11819 return procs; 11820 } 11821 11822 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11823 PrintWriter pw, String[] args) { 11824 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11825 if (procs == null) { 11826 pw.println("No process found for: " + args[0]); 11827 return; 11828 } 11829 11830 long uptime = SystemClock.uptimeMillis(); 11831 long realtime = SystemClock.elapsedRealtime(); 11832 pw.println("Applications Graphics Acceleration Info:"); 11833 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11834 11835 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11836 ProcessRecord r = procs.get(i); 11837 if (r.thread != null) { 11838 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11839 pw.flush(); 11840 try { 11841 TransferPipe tp = new TransferPipe(); 11842 try { 11843 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11844 tp.go(fd); 11845 } finally { 11846 tp.kill(); 11847 } 11848 } catch (IOException e) { 11849 pw.println("Failure while dumping the app: " + r); 11850 pw.flush(); 11851 } catch (RemoteException e) { 11852 pw.println("Got a RemoteException while dumping the app " + r); 11853 pw.flush(); 11854 } 11855 } 11856 } 11857 } 11858 11859 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11860 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11861 if (procs == null) { 11862 pw.println("No process found for: " + args[0]); 11863 return; 11864 } 11865 11866 pw.println("Applications Database Info:"); 11867 11868 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11869 ProcessRecord r = procs.get(i); 11870 if (r.thread != null) { 11871 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11872 pw.flush(); 11873 try { 11874 TransferPipe tp = new TransferPipe(); 11875 try { 11876 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11877 tp.go(fd); 11878 } finally { 11879 tp.kill(); 11880 } 11881 } catch (IOException e) { 11882 pw.println("Failure while dumping the app: " + r); 11883 pw.flush(); 11884 } catch (RemoteException e) { 11885 pw.println("Got a RemoteException while dumping the app " + r); 11886 pw.flush(); 11887 } 11888 } 11889 } 11890 } 11891 11892 final static class MemItem { 11893 final boolean isProc; 11894 final String label; 11895 final String shortLabel; 11896 final long pss; 11897 final int id; 11898 final boolean hasActivities; 11899 ArrayList<MemItem> subitems; 11900 11901 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11902 boolean _hasActivities) { 11903 isProc = true; 11904 label = _label; 11905 shortLabel = _shortLabel; 11906 pss = _pss; 11907 id = _id; 11908 hasActivities = _hasActivities; 11909 } 11910 11911 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11912 isProc = false; 11913 label = _label; 11914 shortLabel = _shortLabel; 11915 pss = _pss; 11916 id = _id; 11917 hasActivities = false; 11918 } 11919 } 11920 11921 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11922 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11923 if (sort && !isCompact) { 11924 Collections.sort(items, new Comparator<MemItem>() { 11925 @Override 11926 public int compare(MemItem lhs, MemItem rhs) { 11927 if (lhs.pss < rhs.pss) { 11928 return 1; 11929 } else if (lhs.pss > rhs.pss) { 11930 return -1; 11931 } 11932 return 0; 11933 } 11934 }); 11935 } 11936 11937 for (int i=0; i<items.size(); i++) { 11938 MemItem mi = items.get(i); 11939 if (!isCompact) { 11940 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11941 } else if (mi.isProc) { 11942 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11943 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11944 pw.println(mi.hasActivities ? ",a" : ",e"); 11945 } else { 11946 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11947 pw.println(mi.pss); 11948 } 11949 if (mi.subitems != null) { 11950 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11951 true, isCompact); 11952 } 11953 } 11954 } 11955 11956 // These are in KB. 11957 static final long[] DUMP_MEM_BUCKETS = new long[] { 11958 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11959 120*1024, 160*1024, 200*1024, 11960 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11961 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11962 }; 11963 11964 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11965 boolean stackLike) { 11966 int start = label.lastIndexOf('.'); 11967 if (start >= 0) start++; 11968 else start = 0; 11969 int end = label.length(); 11970 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11971 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11972 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11973 out.append(bucket); 11974 out.append(stackLike ? "MB." : "MB "); 11975 out.append(label, start, end); 11976 return; 11977 } 11978 } 11979 out.append(memKB/1024); 11980 out.append(stackLike ? "MB." : "MB "); 11981 out.append(label, start, end); 11982 } 11983 11984 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11985 ProcessList.NATIVE_ADJ, 11986 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11987 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11988 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11989 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11990 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11991 }; 11992 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11993 "Native", 11994 "System", "Persistent", "Foreground", 11995 "Visible", "Perceptible", 11996 "Heavy Weight", "Backup", 11997 "A Services", "Home", 11998 "Previous", "B Services", "Cached" 11999 }; 12000 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12001 "native", 12002 "sys", "pers", "fore", 12003 "vis", "percept", 12004 "heavy", "backup", 12005 "servicea", "home", 12006 "prev", "serviceb", "cached" 12007 }; 12008 12009 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12010 long realtime, boolean isCheckinRequest, boolean isCompact) { 12011 if (isCheckinRequest || isCompact) { 12012 // short checkin version 12013 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12014 } else { 12015 pw.println("Applications Memory Usage (kB):"); 12016 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12017 } 12018 } 12019 12020 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12021 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12022 boolean dumpDetails = false; 12023 boolean dumpFullDetails = false; 12024 boolean dumpDalvik = false; 12025 boolean oomOnly = false; 12026 boolean isCompact = false; 12027 boolean localOnly = false; 12028 12029 int opti = 0; 12030 while (opti < args.length) { 12031 String opt = args[opti]; 12032 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12033 break; 12034 } 12035 opti++; 12036 if ("-a".equals(opt)) { 12037 dumpDetails = true; 12038 dumpFullDetails = true; 12039 dumpDalvik = true; 12040 } else if ("-d".equals(opt)) { 12041 dumpDalvik = true; 12042 } else if ("-c".equals(opt)) { 12043 isCompact = true; 12044 } else if ("--oom".equals(opt)) { 12045 oomOnly = true; 12046 } else if ("--local".equals(opt)) { 12047 localOnly = true; 12048 } else if ("-h".equals(opt)) { 12049 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12050 pw.println(" -a: include all available information for each process."); 12051 pw.println(" -d: include dalvik details when dumping process details."); 12052 pw.println(" -c: dump in a compact machine-parseable representation."); 12053 pw.println(" --oom: only show processes organized by oom adj."); 12054 pw.println(" --local: only collect details locally, don't call process."); 12055 pw.println("If [process] is specified it can be the name or "); 12056 pw.println("pid of a specific process to dump."); 12057 return; 12058 } else { 12059 pw.println("Unknown argument: " + opt + "; use -h for help"); 12060 } 12061 } 12062 12063 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12064 long uptime = SystemClock.uptimeMillis(); 12065 long realtime = SystemClock.elapsedRealtime(); 12066 final long[] tmpLong = new long[1]; 12067 12068 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12069 if (procs == null) { 12070 // No Java processes. Maybe they want to print a native process. 12071 if (args != null && args.length > opti 12072 && args[opti].charAt(0) != '-') { 12073 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12074 = new ArrayList<ProcessCpuTracker.Stats>(); 12075 updateCpuStatsNow(); 12076 int findPid = -1; 12077 try { 12078 findPid = Integer.parseInt(args[opti]); 12079 } catch (NumberFormatException e) { 12080 } 12081 synchronized (mProcessCpuThread) { 12082 final int N = mProcessCpuTracker.countStats(); 12083 for (int i=0; i<N; i++) { 12084 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12085 if (st.pid == findPid || (st.baseName != null 12086 && st.baseName.equals(args[opti]))) { 12087 nativeProcs.add(st); 12088 } 12089 } 12090 } 12091 if (nativeProcs.size() > 0) { 12092 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12093 isCompact); 12094 Debug.MemoryInfo mi = null; 12095 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12096 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12097 final int pid = r.pid; 12098 if (!isCheckinRequest && dumpDetails) { 12099 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12100 } 12101 if (mi == null) { 12102 mi = new Debug.MemoryInfo(); 12103 } 12104 if (dumpDetails || (!brief && !oomOnly)) { 12105 Debug.getMemoryInfo(pid, mi); 12106 } else { 12107 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12108 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12109 } 12110 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12111 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12112 if (isCheckinRequest) { 12113 pw.println(); 12114 } 12115 } 12116 return; 12117 } 12118 } 12119 pw.println("No process found for: " + args[opti]); 12120 return; 12121 } 12122 12123 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12124 dumpDetails = true; 12125 } 12126 12127 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12128 12129 String[] innerArgs = new String[args.length-opti]; 12130 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12131 12132 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12133 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12134 long nativePss=0, dalvikPss=0, otherPss=0; 12135 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12136 12137 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12138 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12139 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12140 12141 long totalPss = 0; 12142 long cachedPss = 0; 12143 12144 Debug.MemoryInfo mi = null; 12145 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12146 final ProcessRecord r = procs.get(i); 12147 final IApplicationThread thread; 12148 final int pid; 12149 final int oomAdj; 12150 final boolean hasActivities; 12151 synchronized (this) { 12152 thread = r.thread; 12153 pid = r.pid; 12154 oomAdj = r.getSetAdjWithServices(); 12155 hasActivities = r.activities.size() > 0; 12156 } 12157 if (thread != null) { 12158 if (!isCheckinRequest && dumpDetails) { 12159 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12160 } 12161 if (mi == null) { 12162 mi = new Debug.MemoryInfo(); 12163 } 12164 if (dumpDetails || (!brief && !oomOnly)) { 12165 Debug.getMemoryInfo(pid, mi); 12166 } else { 12167 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12168 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12169 } 12170 if (dumpDetails) { 12171 if (localOnly) { 12172 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12173 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12174 if (isCheckinRequest) { 12175 pw.println(); 12176 } 12177 } else { 12178 try { 12179 pw.flush(); 12180 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12181 dumpDalvik, innerArgs); 12182 } catch (RemoteException e) { 12183 if (!isCheckinRequest) { 12184 pw.println("Got RemoteException!"); 12185 pw.flush(); 12186 } 12187 } 12188 } 12189 } 12190 12191 final long myTotalPss = mi.getTotalPss(); 12192 final long myTotalUss = mi.getTotalUss(); 12193 12194 synchronized (this) { 12195 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12196 // Record this for posterity if the process has been stable. 12197 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12198 } 12199 } 12200 12201 if (!isCheckinRequest && mi != null) { 12202 totalPss += myTotalPss; 12203 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12204 (hasActivities ? " / activities)" : ")"), 12205 r.processName, myTotalPss, pid, hasActivities); 12206 procMems.add(pssItem); 12207 procMemsMap.put(pid, pssItem); 12208 12209 nativePss += mi.nativePss; 12210 dalvikPss += mi.dalvikPss; 12211 otherPss += mi.otherPss; 12212 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12213 long mem = mi.getOtherPss(j); 12214 miscPss[j] += mem; 12215 otherPss -= mem; 12216 } 12217 12218 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12219 cachedPss += myTotalPss; 12220 } 12221 12222 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12223 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12224 || oomIndex == (oomPss.length-1)) { 12225 oomPss[oomIndex] += myTotalPss; 12226 if (oomProcs[oomIndex] == null) { 12227 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12228 } 12229 oomProcs[oomIndex].add(pssItem); 12230 break; 12231 } 12232 } 12233 } 12234 } 12235 } 12236 12237 if (!isCheckinRequest && procs.size() > 1) { 12238 // If we are showing aggregations, also look for native processes to 12239 // include so that our aggregations are more accurate. 12240 updateCpuStatsNow(); 12241 synchronized (mProcessCpuThread) { 12242 final int N = mProcessCpuTracker.countStats(); 12243 for (int i=0; i<N; i++) { 12244 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12245 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12246 if (mi == null) { 12247 mi = new Debug.MemoryInfo(); 12248 } 12249 if (!brief && !oomOnly) { 12250 Debug.getMemoryInfo(st.pid, mi); 12251 } else { 12252 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12253 mi.nativePrivateDirty = (int)tmpLong[0]; 12254 } 12255 12256 final long myTotalPss = mi.getTotalPss(); 12257 totalPss += myTotalPss; 12258 12259 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12260 st.name, myTotalPss, st.pid, false); 12261 procMems.add(pssItem); 12262 12263 nativePss += mi.nativePss; 12264 dalvikPss += mi.dalvikPss; 12265 otherPss += mi.otherPss; 12266 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12267 long mem = mi.getOtherPss(j); 12268 miscPss[j] += mem; 12269 otherPss -= mem; 12270 } 12271 oomPss[0] += myTotalPss; 12272 if (oomProcs[0] == null) { 12273 oomProcs[0] = new ArrayList<MemItem>(); 12274 } 12275 oomProcs[0].add(pssItem); 12276 } 12277 } 12278 } 12279 12280 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12281 12282 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12283 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12284 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12285 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12286 String label = Debug.MemoryInfo.getOtherLabel(j); 12287 catMems.add(new MemItem(label, label, miscPss[j], j)); 12288 } 12289 12290 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12291 for (int j=0; j<oomPss.length; j++) { 12292 if (oomPss[j] != 0) { 12293 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12294 : DUMP_MEM_OOM_LABEL[j]; 12295 MemItem item = new MemItem(label, label, oomPss[j], 12296 DUMP_MEM_OOM_ADJ[j]); 12297 item.subitems = oomProcs[j]; 12298 oomMems.add(item); 12299 } 12300 } 12301 12302 if (!brief && !oomOnly && !isCompact) { 12303 pw.println(); 12304 pw.println("Total PSS by process:"); 12305 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12306 pw.println(); 12307 } 12308 if (!isCompact) { 12309 pw.println("Total PSS by OOM adjustment:"); 12310 } 12311 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12312 if (!brief && !oomOnly) { 12313 PrintWriter out = categoryPw != null ? categoryPw : pw; 12314 if (!isCompact) { 12315 out.println(); 12316 out.println("Total PSS by category:"); 12317 } 12318 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12319 } 12320 if (!isCompact) { 12321 pw.println(); 12322 } 12323 MemInfoReader memInfo = new MemInfoReader(); 12324 memInfo.readMemInfo(); 12325 if (!brief) { 12326 if (!isCompact) { 12327 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12328 pw.print(" kB (status "); 12329 switch (mLastMemoryLevel) { 12330 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12331 pw.println("normal)"); 12332 break; 12333 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12334 pw.println("moderate)"); 12335 break; 12336 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12337 pw.println("low)"); 12338 break; 12339 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12340 pw.println("critical)"); 12341 break; 12342 default: 12343 pw.print(mLastMemoryLevel); 12344 pw.println(")"); 12345 break; 12346 } 12347 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12348 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12349 pw.print(cachedPss); pw.print(" cached pss + "); 12350 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12351 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12352 } else { 12353 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12354 pw.print(cachedPss + memInfo.getCachedSizeKb() 12355 + memInfo.getFreeSizeKb()); pw.print(","); 12356 pw.println(totalPss - cachedPss); 12357 } 12358 } 12359 if (!isCompact) { 12360 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12361 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12362 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12363 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12364 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12365 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12366 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12367 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12368 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12369 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12370 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12371 } 12372 if (!brief) { 12373 if (memInfo.getZramTotalSizeKb() != 0) { 12374 if (!isCompact) { 12375 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12376 pw.print(" kB physical used for "); 12377 pw.print(memInfo.getSwapTotalSizeKb() 12378 - memInfo.getSwapFreeSizeKb()); 12379 pw.print(" kB in swap ("); 12380 pw.print(memInfo.getSwapTotalSizeKb()); 12381 pw.println(" kB total swap)"); 12382 } else { 12383 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12384 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12385 pw.println(memInfo.getSwapFreeSizeKb()); 12386 } 12387 } 12388 final int[] SINGLE_LONG_FORMAT = new int[] { 12389 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12390 }; 12391 long[] longOut = new long[1]; 12392 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12393 SINGLE_LONG_FORMAT, null, longOut, null); 12394 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12395 longOut[0] = 0; 12396 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12397 SINGLE_LONG_FORMAT, null, longOut, null); 12398 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12399 longOut[0] = 0; 12400 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12401 SINGLE_LONG_FORMAT, null, longOut, null); 12402 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12403 longOut[0] = 0; 12404 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12405 SINGLE_LONG_FORMAT, null, longOut, null); 12406 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12407 if (!isCompact) { 12408 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12409 pw.print(" KSM: "); pw.print(sharing); 12410 pw.print(" kB saved from shared "); 12411 pw.print(shared); pw.println(" kB"); 12412 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12413 pw.print(voltile); pw.println(" kB volatile"); 12414 } 12415 pw.print(" Tuning: "); 12416 pw.print(ActivityManager.staticGetMemoryClass()); 12417 pw.print(" (large "); 12418 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12419 pw.print("), oom "); 12420 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12421 pw.print(" kB"); 12422 pw.print(", restore limit "); 12423 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12424 pw.print(" kB"); 12425 if (ActivityManager.isLowRamDeviceStatic()) { 12426 pw.print(" (low-ram)"); 12427 } 12428 if (ActivityManager.isHighEndGfx()) { 12429 pw.print(" (high-end-gfx)"); 12430 } 12431 pw.println(); 12432 } else { 12433 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12434 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12435 pw.println(voltile); 12436 pw.print("tuning,"); 12437 pw.print(ActivityManager.staticGetMemoryClass()); 12438 pw.print(','); 12439 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12440 pw.print(','); 12441 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12442 if (ActivityManager.isLowRamDeviceStatic()) { 12443 pw.print(",low-ram"); 12444 } 12445 if (ActivityManager.isHighEndGfx()) { 12446 pw.print(",high-end-gfx"); 12447 } 12448 pw.println(); 12449 } 12450 } 12451 } 12452 } 12453 12454 /** 12455 * Searches array of arguments for the specified string 12456 * @param args array of argument strings 12457 * @param value value to search for 12458 * @return true if the value is contained in the array 12459 */ 12460 private static boolean scanArgs(String[] args, String value) { 12461 if (args != null) { 12462 for (String arg : args) { 12463 if (value.equals(arg)) { 12464 return true; 12465 } 12466 } 12467 } 12468 return false; 12469 } 12470 12471 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12472 ContentProviderRecord cpr, boolean always) { 12473 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12474 12475 if (!inLaunching || always) { 12476 synchronized (cpr) { 12477 cpr.launchingApp = null; 12478 cpr.notifyAll(); 12479 } 12480 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12481 String names[] = cpr.info.authority.split(";"); 12482 for (int j = 0; j < names.length; j++) { 12483 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12484 } 12485 } 12486 12487 for (int i=0; i<cpr.connections.size(); i++) { 12488 ContentProviderConnection conn = cpr.connections.get(i); 12489 if (conn.waiting) { 12490 // If this connection is waiting for the provider, then we don't 12491 // need to mess with its process unless we are always removing 12492 // or for some reason the provider is not currently launching. 12493 if (inLaunching && !always) { 12494 continue; 12495 } 12496 } 12497 ProcessRecord capp = conn.client; 12498 conn.dead = true; 12499 if (conn.stableCount > 0) { 12500 if (!capp.persistent && capp.thread != null 12501 && capp.pid != 0 12502 && capp.pid != MY_PID) { 12503 killUnneededProcessLocked(capp, "depends on provider " 12504 + cpr.name.flattenToShortString() 12505 + " in dying proc " + (proc != null ? proc.processName : "??")); 12506 } 12507 } else if (capp.thread != null && conn.provider.provider != null) { 12508 try { 12509 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12510 } catch (RemoteException e) { 12511 } 12512 // In the protocol here, we don't expect the client to correctly 12513 // clean up this connection, we'll just remove it. 12514 cpr.connections.remove(i); 12515 conn.client.conProviders.remove(conn); 12516 } 12517 } 12518 12519 if (inLaunching && always) { 12520 mLaunchingProviders.remove(cpr); 12521 } 12522 return inLaunching; 12523 } 12524 12525 /** 12526 * Main code for cleaning up a process when it has gone away. This is 12527 * called both as a result of the process dying, or directly when stopping 12528 * a process when running in single process mode. 12529 */ 12530 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12531 boolean restarting, boolean allowRestart, int index) { 12532 if (index >= 0) { 12533 removeLruProcessLocked(app); 12534 ProcessList.remove(app.pid); 12535 } 12536 12537 mProcessesToGc.remove(app); 12538 mPendingPssProcesses.remove(app); 12539 12540 // Dismiss any open dialogs. 12541 if (app.crashDialog != null && !app.forceCrashReport) { 12542 app.crashDialog.dismiss(); 12543 app.crashDialog = null; 12544 } 12545 if (app.anrDialog != null) { 12546 app.anrDialog.dismiss(); 12547 app.anrDialog = null; 12548 } 12549 if (app.waitDialog != null) { 12550 app.waitDialog.dismiss(); 12551 app.waitDialog = null; 12552 } 12553 12554 app.crashing = false; 12555 app.notResponding = false; 12556 12557 app.resetPackageList(mProcessStats); 12558 app.unlinkDeathRecipient(); 12559 app.makeInactive(mProcessStats); 12560 app.forcingToForeground = null; 12561 updateProcessForegroundLocked(app, false, false); 12562 app.foregroundActivities = false; 12563 app.hasShownUi = false; 12564 app.hasAboveClient = false; 12565 12566 mServices.killServicesLocked(app, allowRestart); 12567 12568 boolean restart = false; 12569 12570 // Remove published content providers. 12571 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12572 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12573 final boolean always = app.bad || !allowRestart; 12574 if (removeDyingProviderLocked(app, cpr, always) || always) { 12575 // We left the provider in the launching list, need to 12576 // restart it. 12577 restart = true; 12578 } 12579 12580 cpr.provider = null; 12581 cpr.proc = null; 12582 } 12583 app.pubProviders.clear(); 12584 12585 // Take care of any launching providers waiting for this process. 12586 if (checkAppInLaunchingProvidersLocked(app, false)) { 12587 restart = true; 12588 } 12589 12590 // Unregister from connected content providers. 12591 if (!app.conProviders.isEmpty()) { 12592 for (int i=0; i<app.conProviders.size(); i++) { 12593 ContentProviderConnection conn = app.conProviders.get(i); 12594 conn.provider.connections.remove(conn); 12595 } 12596 app.conProviders.clear(); 12597 } 12598 12599 // At this point there may be remaining entries in mLaunchingProviders 12600 // where we were the only one waiting, so they are no longer of use. 12601 // Look for these and clean up if found. 12602 // XXX Commented out for now. Trying to figure out a way to reproduce 12603 // the actual situation to identify what is actually going on. 12604 if (false) { 12605 for (int i=0; i<mLaunchingProviders.size(); i++) { 12606 ContentProviderRecord cpr = (ContentProviderRecord) 12607 mLaunchingProviders.get(i); 12608 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12609 synchronized (cpr) { 12610 cpr.launchingApp = null; 12611 cpr.notifyAll(); 12612 } 12613 } 12614 } 12615 } 12616 12617 skipCurrentReceiverLocked(app); 12618 12619 // Unregister any receivers. 12620 for (int i=app.receivers.size()-1; i>=0; i--) { 12621 removeReceiverLocked(app.receivers.valueAt(i)); 12622 } 12623 app.receivers.clear(); 12624 12625 // If the app is undergoing backup, tell the backup manager about it 12626 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12627 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12628 + mBackupTarget.appInfo + " died during backup"); 12629 try { 12630 IBackupManager bm = IBackupManager.Stub.asInterface( 12631 ServiceManager.getService(Context.BACKUP_SERVICE)); 12632 bm.agentDisconnected(app.info.packageName); 12633 } catch (RemoteException e) { 12634 // can't happen; backup manager is local 12635 } 12636 } 12637 12638 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12639 ProcessChangeItem item = mPendingProcessChanges.get(i); 12640 if (item.pid == app.pid) { 12641 mPendingProcessChanges.remove(i); 12642 mAvailProcessChanges.add(item); 12643 } 12644 } 12645 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12646 12647 // If the caller is restarting this app, then leave it in its 12648 // current lists and let the caller take care of it. 12649 if (restarting) { 12650 return; 12651 } 12652 12653 if (!app.persistent || app.isolated) { 12654 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12655 "Removing non-persistent process during cleanup: " + app); 12656 mProcessNames.remove(app.processName, app.uid); 12657 mIsolatedProcesses.remove(app.uid); 12658 if (mHeavyWeightProcess == app) { 12659 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12660 mHeavyWeightProcess.userId, 0)); 12661 mHeavyWeightProcess = null; 12662 } 12663 } else if (!app.removed) { 12664 // This app is persistent, so we need to keep its record around. 12665 // If it is not already on the pending app list, add it there 12666 // and start a new process for it. 12667 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12668 mPersistentStartingProcesses.add(app); 12669 restart = true; 12670 } 12671 } 12672 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12673 "Clean-up removing on hold: " + app); 12674 mProcessesOnHold.remove(app); 12675 12676 if (app == mHomeProcess) { 12677 mHomeProcess = null; 12678 } 12679 if (app == mPreviousProcess) { 12680 mPreviousProcess = null; 12681 } 12682 12683 if (restart && !app.isolated) { 12684 // We have components that still need to be running in the 12685 // process, so re-launch it. 12686 mProcessNames.put(app.processName, app.uid, app); 12687 startProcessLocked(app, "restart", app.processName); 12688 } else if (app.pid > 0 && app.pid != MY_PID) { 12689 // Goodbye! 12690 boolean removed; 12691 synchronized (mPidsSelfLocked) { 12692 mPidsSelfLocked.remove(app.pid); 12693 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12694 } 12695 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12696 app.processName, app.info.uid); 12697 if (app.isolated) { 12698 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12699 } 12700 app.setPid(0); 12701 } 12702 } 12703 12704 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12705 // Look through the content providers we are waiting to have launched, 12706 // and if any run in this process then either schedule a restart of 12707 // the process or kill the client waiting for it if this process has 12708 // gone bad. 12709 int NL = mLaunchingProviders.size(); 12710 boolean restart = false; 12711 for (int i=0; i<NL; i++) { 12712 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12713 if (cpr.launchingApp == app) { 12714 if (!alwaysBad && !app.bad) { 12715 restart = true; 12716 } else { 12717 removeDyingProviderLocked(app, cpr, true); 12718 // cpr should have been removed from mLaunchingProviders 12719 NL = mLaunchingProviders.size(); 12720 i--; 12721 } 12722 } 12723 } 12724 return restart; 12725 } 12726 12727 // ========================================================= 12728 // SERVICES 12729 // ========================================================= 12730 12731 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12732 int flags) { 12733 enforceNotIsolatedCaller("getServices"); 12734 synchronized (this) { 12735 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12736 } 12737 } 12738 12739 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12740 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12741 synchronized (this) { 12742 return mServices.getRunningServiceControlPanelLocked(name); 12743 } 12744 } 12745 12746 public ComponentName startService(IApplicationThread caller, Intent service, 12747 String resolvedType, int userId) { 12748 enforceNotIsolatedCaller("startService"); 12749 // Refuse possible leaked file descriptors 12750 if (service != null && service.hasFileDescriptors() == true) { 12751 throw new IllegalArgumentException("File descriptors passed in Intent"); 12752 } 12753 12754 if (DEBUG_SERVICE) 12755 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12756 synchronized(this) { 12757 final int callingPid = Binder.getCallingPid(); 12758 final int callingUid = Binder.getCallingUid(); 12759 final long origId = Binder.clearCallingIdentity(); 12760 ComponentName res = mServices.startServiceLocked(caller, service, 12761 resolvedType, callingPid, callingUid, userId); 12762 Binder.restoreCallingIdentity(origId); 12763 return res; 12764 } 12765 } 12766 12767 ComponentName startServiceInPackage(int uid, 12768 Intent service, String resolvedType, int userId) { 12769 synchronized(this) { 12770 if (DEBUG_SERVICE) 12771 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12772 final long origId = Binder.clearCallingIdentity(); 12773 ComponentName res = mServices.startServiceLocked(null, service, 12774 resolvedType, -1, uid, userId); 12775 Binder.restoreCallingIdentity(origId); 12776 return res; 12777 } 12778 } 12779 12780 public int stopService(IApplicationThread caller, Intent service, 12781 String resolvedType, int userId) { 12782 enforceNotIsolatedCaller("stopService"); 12783 // Refuse possible leaked file descriptors 12784 if (service != null && service.hasFileDescriptors() == true) { 12785 throw new IllegalArgumentException("File descriptors passed in Intent"); 12786 } 12787 12788 synchronized(this) { 12789 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12790 } 12791 } 12792 12793 public IBinder peekService(Intent service, String resolvedType) { 12794 enforceNotIsolatedCaller("peekService"); 12795 // Refuse possible leaked file descriptors 12796 if (service != null && service.hasFileDescriptors() == true) { 12797 throw new IllegalArgumentException("File descriptors passed in Intent"); 12798 } 12799 synchronized(this) { 12800 return mServices.peekServiceLocked(service, resolvedType); 12801 } 12802 } 12803 12804 public boolean stopServiceToken(ComponentName className, IBinder token, 12805 int startId) { 12806 synchronized(this) { 12807 return mServices.stopServiceTokenLocked(className, token, startId); 12808 } 12809 } 12810 12811 public void setServiceForeground(ComponentName className, IBinder token, 12812 int id, Notification notification, boolean removeNotification) { 12813 synchronized(this) { 12814 mServices.setServiceForegroundLocked(className, token, id, notification, 12815 removeNotification); 12816 } 12817 } 12818 12819 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12820 boolean requireFull, String name, String callerPackage) { 12821 final int callingUserId = UserHandle.getUserId(callingUid); 12822 if (callingUserId != userId) { 12823 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12824 if ((requireFull || checkComponentPermission( 12825 android.Manifest.permission.INTERACT_ACROSS_USERS, 12826 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12827 && checkComponentPermission( 12828 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12829 callingPid, callingUid, -1, true) 12830 != PackageManager.PERMISSION_GRANTED) { 12831 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12832 // In this case, they would like to just execute as their 12833 // owner user instead of failing. 12834 userId = callingUserId; 12835 } else { 12836 StringBuilder builder = new StringBuilder(128); 12837 builder.append("Permission Denial: "); 12838 builder.append(name); 12839 if (callerPackage != null) { 12840 builder.append(" from "); 12841 builder.append(callerPackage); 12842 } 12843 builder.append(" asks to run as user "); 12844 builder.append(userId); 12845 builder.append(" but is calling from user "); 12846 builder.append(UserHandle.getUserId(callingUid)); 12847 builder.append("; this requires "); 12848 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12849 if (!requireFull) { 12850 builder.append(" or "); 12851 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12852 } 12853 String msg = builder.toString(); 12854 Slog.w(TAG, msg); 12855 throw new SecurityException(msg); 12856 } 12857 } 12858 } 12859 if (userId == UserHandle.USER_CURRENT 12860 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12861 // Note that we may be accessing this outside of a lock... 12862 // shouldn't be a big deal, if this is being called outside 12863 // of a locked context there is intrinsically a race with 12864 // the value the caller will receive and someone else changing it. 12865 userId = mCurrentUserId; 12866 } 12867 if (!allowAll && userId < 0) { 12868 throw new IllegalArgumentException( 12869 "Call does not support special user #" + userId); 12870 } 12871 } 12872 return userId; 12873 } 12874 12875 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12876 String className, int flags) { 12877 boolean result = false; 12878 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12879 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12880 if (ActivityManager.checkUidPermission( 12881 android.Manifest.permission.INTERACT_ACROSS_USERS, 12882 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12883 ComponentName comp = new ComponentName(aInfo.packageName, className); 12884 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12885 + " requests FLAG_SINGLE_USER, but app does not hold " 12886 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12887 Slog.w(TAG, msg); 12888 throw new SecurityException(msg); 12889 } 12890 result = true; 12891 } 12892 } else if (componentProcessName == aInfo.packageName) { 12893 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12894 } else if ("system".equals(componentProcessName)) { 12895 result = true; 12896 } 12897 if (DEBUG_MU) { 12898 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12899 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12900 } 12901 return result; 12902 } 12903 12904 public int bindService(IApplicationThread caller, IBinder token, 12905 Intent service, String resolvedType, 12906 IServiceConnection connection, int flags, int userId) { 12907 enforceNotIsolatedCaller("bindService"); 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 synchronized(this) { 12914 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12915 connection, flags, userId); 12916 } 12917 } 12918 12919 public boolean unbindService(IServiceConnection connection) { 12920 synchronized (this) { 12921 return mServices.unbindServiceLocked(connection); 12922 } 12923 } 12924 12925 public void publishService(IBinder token, Intent intent, IBinder service) { 12926 // Refuse possible leaked file descriptors 12927 if (intent != null && intent.hasFileDescriptors() == true) { 12928 throw new IllegalArgumentException("File descriptors passed in Intent"); 12929 } 12930 12931 synchronized(this) { 12932 if (!(token instanceof ServiceRecord)) { 12933 throw new IllegalArgumentException("Invalid service token"); 12934 } 12935 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12936 } 12937 } 12938 12939 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12940 // Refuse possible leaked file descriptors 12941 if (intent != null && intent.hasFileDescriptors() == true) { 12942 throw new IllegalArgumentException("File descriptors passed in Intent"); 12943 } 12944 12945 synchronized(this) { 12946 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12947 } 12948 } 12949 12950 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12951 synchronized(this) { 12952 if (!(token instanceof ServiceRecord)) { 12953 throw new IllegalArgumentException("Invalid service token"); 12954 } 12955 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12956 } 12957 } 12958 12959 // ========================================================= 12960 // BACKUP AND RESTORE 12961 // ========================================================= 12962 12963 // Cause the target app to be launched if necessary and its backup agent 12964 // instantiated. The backup agent will invoke backupAgentCreated() on the 12965 // activity manager to announce its creation. 12966 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12967 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12968 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12969 12970 synchronized(this) { 12971 // !!! TODO: currently no check here that we're already bound 12972 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12973 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12974 synchronized (stats) { 12975 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12976 } 12977 12978 // Backup agent is now in use, its package can't be stopped. 12979 try { 12980 AppGlobals.getPackageManager().setPackageStoppedState( 12981 app.packageName, false, UserHandle.getUserId(app.uid)); 12982 } catch (RemoteException e) { 12983 } catch (IllegalArgumentException e) { 12984 Slog.w(TAG, "Failed trying to unstop package " 12985 + app.packageName + ": " + e); 12986 } 12987 12988 BackupRecord r = new BackupRecord(ss, app, backupMode); 12989 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12990 ? new ComponentName(app.packageName, app.backupAgentName) 12991 : new ComponentName("android", "FullBackupAgent"); 12992 // startProcessLocked() returns existing proc's record if it's already running 12993 ProcessRecord proc = startProcessLocked(app.processName, app, 12994 false, 0, "backup", hostingName, false, false, false); 12995 if (proc == null) { 12996 Slog.e(TAG, "Unable to start backup agent process " + r); 12997 return false; 12998 } 12999 13000 r.app = proc; 13001 mBackupTarget = r; 13002 mBackupAppName = app.packageName; 13003 13004 // Try not to kill the process during backup 13005 updateOomAdjLocked(proc); 13006 13007 // If the process is already attached, schedule the creation of the backup agent now. 13008 // If it is not yet live, this will be done when it attaches to the framework. 13009 if (proc.thread != null) { 13010 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13011 try { 13012 proc.thread.scheduleCreateBackupAgent(app, 13013 compatibilityInfoForPackageLocked(app), backupMode); 13014 } catch (RemoteException e) { 13015 // Will time out on the backup manager side 13016 } 13017 } else { 13018 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13019 } 13020 // Invariants: at this point, the target app process exists and the application 13021 // is either already running or in the process of coming up. mBackupTarget and 13022 // mBackupAppName describe the app, so that when it binds back to the AM we 13023 // know that it's scheduled for a backup-agent operation. 13024 } 13025 13026 return true; 13027 } 13028 13029 @Override 13030 public void clearPendingBackup() { 13031 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13032 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13033 13034 synchronized (this) { 13035 mBackupTarget = null; 13036 mBackupAppName = null; 13037 } 13038 } 13039 13040 // A backup agent has just come up 13041 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13042 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13043 + " = " + agent); 13044 13045 synchronized(this) { 13046 if (!agentPackageName.equals(mBackupAppName)) { 13047 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13048 return; 13049 } 13050 } 13051 13052 long oldIdent = Binder.clearCallingIdentity(); 13053 try { 13054 IBackupManager bm = IBackupManager.Stub.asInterface( 13055 ServiceManager.getService(Context.BACKUP_SERVICE)); 13056 bm.agentConnected(agentPackageName, agent); 13057 } catch (RemoteException e) { 13058 // can't happen; the backup manager service is local 13059 } catch (Exception e) { 13060 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13061 e.printStackTrace(); 13062 } finally { 13063 Binder.restoreCallingIdentity(oldIdent); 13064 } 13065 } 13066 13067 // done with this agent 13068 public void unbindBackupAgent(ApplicationInfo appInfo) { 13069 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13070 if (appInfo == null) { 13071 Slog.w(TAG, "unbind backup agent for null app"); 13072 return; 13073 } 13074 13075 synchronized(this) { 13076 try { 13077 if (mBackupAppName == null) { 13078 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13079 return; 13080 } 13081 13082 if (!mBackupAppName.equals(appInfo.packageName)) { 13083 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13084 return; 13085 } 13086 13087 // Not backing this app up any more; reset its OOM adjustment 13088 final ProcessRecord proc = mBackupTarget.app; 13089 updateOomAdjLocked(proc); 13090 13091 // If the app crashed during backup, 'thread' will be null here 13092 if (proc.thread != null) { 13093 try { 13094 proc.thread.scheduleDestroyBackupAgent(appInfo, 13095 compatibilityInfoForPackageLocked(appInfo)); 13096 } catch (Exception e) { 13097 Slog.e(TAG, "Exception when unbinding backup agent:"); 13098 e.printStackTrace(); 13099 } 13100 } 13101 } finally { 13102 mBackupTarget = null; 13103 mBackupAppName = null; 13104 } 13105 } 13106 } 13107 // ========================================================= 13108 // BROADCASTS 13109 // ========================================================= 13110 13111 private final List getStickiesLocked(String action, IntentFilter filter, 13112 List cur, int userId) { 13113 final ContentResolver resolver = mContext.getContentResolver(); 13114 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13115 if (stickies == null) { 13116 return cur; 13117 } 13118 final ArrayList<Intent> list = stickies.get(action); 13119 if (list == null) { 13120 return cur; 13121 } 13122 int N = list.size(); 13123 for (int i=0; i<N; i++) { 13124 Intent intent = list.get(i); 13125 if (filter.match(resolver, intent, true, TAG) >= 0) { 13126 if (cur == null) { 13127 cur = new ArrayList<Intent>(); 13128 } 13129 cur.add(intent); 13130 } 13131 } 13132 return cur; 13133 } 13134 13135 boolean isPendingBroadcastProcessLocked(int pid) { 13136 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13137 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13138 } 13139 13140 void skipPendingBroadcastLocked(int pid) { 13141 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13142 for (BroadcastQueue queue : mBroadcastQueues) { 13143 queue.skipPendingBroadcastLocked(pid); 13144 } 13145 } 13146 13147 // The app just attached; send any pending broadcasts that it should receive 13148 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13149 boolean didSomething = false; 13150 for (BroadcastQueue queue : mBroadcastQueues) { 13151 didSomething |= queue.sendPendingBroadcastsLocked(app); 13152 } 13153 return didSomething; 13154 } 13155 13156 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13157 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13158 enforceNotIsolatedCaller("registerReceiver"); 13159 int callingUid; 13160 int callingPid; 13161 synchronized(this) { 13162 ProcessRecord callerApp = null; 13163 if (caller != null) { 13164 callerApp = getRecordForAppLocked(caller); 13165 if (callerApp == null) { 13166 throw new SecurityException( 13167 "Unable to find app for caller " + caller 13168 + " (pid=" + Binder.getCallingPid() 13169 + ") when registering receiver " + receiver); 13170 } 13171 if (callerApp.info.uid != Process.SYSTEM_UID && 13172 !callerApp.pkgList.containsKey(callerPackage) && 13173 !"android".equals(callerPackage)) { 13174 throw new SecurityException("Given caller package " + callerPackage 13175 + " is not running in process " + callerApp); 13176 } 13177 callingUid = callerApp.info.uid; 13178 callingPid = callerApp.pid; 13179 } else { 13180 callerPackage = null; 13181 callingUid = Binder.getCallingUid(); 13182 callingPid = Binder.getCallingPid(); 13183 } 13184 13185 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13186 true, true, "registerReceiver", callerPackage); 13187 13188 List allSticky = null; 13189 13190 // Look for any matching sticky broadcasts... 13191 Iterator actions = filter.actionsIterator(); 13192 if (actions != null) { 13193 while (actions.hasNext()) { 13194 String action = (String)actions.next(); 13195 allSticky = getStickiesLocked(action, filter, allSticky, 13196 UserHandle.USER_ALL); 13197 allSticky = getStickiesLocked(action, filter, allSticky, 13198 UserHandle.getUserId(callingUid)); 13199 } 13200 } else { 13201 allSticky = getStickiesLocked(null, filter, allSticky, 13202 UserHandle.USER_ALL); 13203 allSticky = getStickiesLocked(null, filter, allSticky, 13204 UserHandle.getUserId(callingUid)); 13205 } 13206 13207 // The first sticky in the list is returned directly back to 13208 // the client. 13209 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13210 13211 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13212 + ": " + sticky); 13213 13214 if (receiver == null) { 13215 return sticky; 13216 } 13217 13218 ReceiverList rl 13219 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13220 if (rl == null) { 13221 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13222 userId, receiver); 13223 if (rl.app != null) { 13224 rl.app.receivers.add(rl); 13225 } else { 13226 try { 13227 receiver.asBinder().linkToDeath(rl, 0); 13228 } catch (RemoteException e) { 13229 return sticky; 13230 } 13231 rl.linkedToDeath = true; 13232 } 13233 mRegisteredReceivers.put(receiver.asBinder(), rl); 13234 } else if (rl.uid != callingUid) { 13235 throw new IllegalArgumentException( 13236 "Receiver requested to register for uid " + callingUid 13237 + " was previously registered for uid " + rl.uid); 13238 } else if (rl.pid != callingPid) { 13239 throw new IllegalArgumentException( 13240 "Receiver requested to register for pid " + callingPid 13241 + " was previously registered for pid " + rl.pid); 13242 } else if (rl.userId != userId) { 13243 throw new IllegalArgumentException( 13244 "Receiver requested to register for user " + userId 13245 + " was previously registered for user " + rl.userId); 13246 } 13247 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13248 permission, callingUid, userId); 13249 rl.add(bf); 13250 if (!bf.debugCheck()) { 13251 Slog.w(TAG, "==> For Dynamic broadast"); 13252 } 13253 mReceiverResolver.addFilter(bf); 13254 13255 // Enqueue broadcasts for all existing stickies that match 13256 // this filter. 13257 if (allSticky != null) { 13258 ArrayList receivers = new ArrayList(); 13259 receivers.add(bf); 13260 13261 int N = allSticky.size(); 13262 for (int i=0; i<N; i++) { 13263 Intent intent = (Intent)allSticky.get(i); 13264 BroadcastQueue queue = broadcastQueueForIntent(intent); 13265 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13266 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13267 null, null, false, true, true, -1); 13268 queue.enqueueParallelBroadcastLocked(r); 13269 queue.scheduleBroadcastsLocked(); 13270 } 13271 } 13272 13273 return sticky; 13274 } 13275 } 13276 13277 public void unregisterReceiver(IIntentReceiver receiver) { 13278 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13279 13280 final long origId = Binder.clearCallingIdentity(); 13281 try { 13282 boolean doTrim = false; 13283 13284 synchronized(this) { 13285 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13286 if (rl != null) { 13287 if (rl.curBroadcast != null) { 13288 BroadcastRecord r = rl.curBroadcast; 13289 final boolean doNext = finishReceiverLocked( 13290 receiver.asBinder(), r.resultCode, r.resultData, 13291 r.resultExtras, r.resultAbort); 13292 if (doNext) { 13293 doTrim = true; 13294 r.queue.processNextBroadcast(false); 13295 } 13296 } 13297 13298 if (rl.app != null) { 13299 rl.app.receivers.remove(rl); 13300 } 13301 removeReceiverLocked(rl); 13302 if (rl.linkedToDeath) { 13303 rl.linkedToDeath = false; 13304 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13305 } 13306 } 13307 } 13308 13309 // If we actually concluded any broadcasts, we might now be able 13310 // to trim the recipients' apps from our working set 13311 if (doTrim) { 13312 trimApplications(); 13313 return; 13314 } 13315 13316 } finally { 13317 Binder.restoreCallingIdentity(origId); 13318 } 13319 } 13320 13321 void removeReceiverLocked(ReceiverList rl) { 13322 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13323 int N = rl.size(); 13324 for (int i=0; i<N; i++) { 13325 mReceiverResolver.removeFilter(rl.get(i)); 13326 } 13327 } 13328 13329 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13330 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13331 ProcessRecord r = mLruProcesses.get(i); 13332 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13333 try { 13334 r.thread.dispatchPackageBroadcast(cmd, packages); 13335 } catch (RemoteException ex) { 13336 } 13337 } 13338 } 13339 } 13340 13341 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13342 int[] users) { 13343 List<ResolveInfo> receivers = null; 13344 try { 13345 HashSet<ComponentName> singleUserReceivers = null; 13346 boolean scannedFirstReceivers = false; 13347 for (int user : users) { 13348 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13349 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13350 if (user != 0 && newReceivers != null) { 13351 // If this is not the primary user, we need to check for 13352 // any receivers that should be filtered out. 13353 for (int i=0; i<newReceivers.size(); i++) { 13354 ResolveInfo ri = newReceivers.get(i); 13355 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13356 newReceivers.remove(i); 13357 i--; 13358 } 13359 } 13360 } 13361 if (newReceivers != null && newReceivers.size() == 0) { 13362 newReceivers = null; 13363 } 13364 if (receivers == null) { 13365 receivers = newReceivers; 13366 } else if (newReceivers != null) { 13367 // We need to concatenate the additional receivers 13368 // found with what we have do far. This would be easy, 13369 // but we also need to de-dup any receivers that are 13370 // singleUser. 13371 if (!scannedFirstReceivers) { 13372 // Collect any single user receivers we had already retrieved. 13373 scannedFirstReceivers = true; 13374 for (int i=0; i<receivers.size(); i++) { 13375 ResolveInfo ri = receivers.get(i); 13376 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13377 ComponentName cn = new ComponentName( 13378 ri.activityInfo.packageName, ri.activityInfo.name); 13379 if (singleUserReceivers == null) { 13380 singleUserReceivers = new HashSet<ComponentName>(); 13381 } 13382 singleUserReceivers.add(cn); 13383 } 13384 } 13385 } 13386 // Add the new results to the existing results, tracking 13387 // and de-dupping single user receivers. 13388 for (int i=0; i<newReceivers.size(); i++) { 13389 ResolveInfo ri = newReceivers.get(i); 13390 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13391 ComponentName cn = new ComponentName( 13392 ri.activityInfo.packageName, ri.activityInfo.name); 13393 if (singleUserReceivers == null) { 13394 singleUserReceivers = new HashSet<ComponentName>(); 13395 } 13396 if (!singleUserReceivers.contains(cn)) { 13397 singleUserReceivers.add(cn); 13398 receivers.add(ri); 13399 } 13400 } else { 13401 receivers.add(ri); 13402 } 13403 } 13404 } 13405 } 13406 } catch (RemoteException ex) { 13407 // pm is in same process, this will never happen. 13408 } 13409 return receivers; 13410 } 13411 13412 private final int broadcastIntentLocked(ProcessRecord callerApp, 13413 String callerPackage, Intent intent, String resolvedType, 13414 IIntentReceiver resultTo, int resultCode, String resultData, 13415 Bundle map, String requiredPermission, int appOp, 13416 boolean ordered, boolean sticky, int callingPid, int callingUid, 13417 int userId) { 13418 intent = new Intent(intent); 13419 13420 // By default broadcasts do not go to stopped apps. 13421 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13422 13423 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13424 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13425 + " ordered=" + ordered + " userid=" + userId); 13426 if ((resultTo != null) && !ordered) { 13427 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13428 } 13429 13430 userId = handleIncomingUser(callingPid, callingUid, userId, 13431 true, false, "broadcast", callerPackage); 13432 13433 // Make sure that the user who is receiving this broadcast is started. 13434 // If not, we will just skip it. 13435 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13436 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13437 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13438 Slog.w(TAG, "Skipping broadcast of " + intent 13439 + ": user " + userId + " is stopped"); 13440 return ActivityManager.BROADCAST_SUCCESS; 13441 } 13442 } 13443 13444 /* 13445 * Prevent non-system code (defined here to be non-persistent 13446 * processes) from sending protected broadcasts. 13447 */ 13448 int callingAppId = UserHandle.getAppId(callingUid); 13449 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13450 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13451 callingUid == 0) { 13452 // Always okay. 13453 } else if (callerApp == null || !callerApp.persistent) { 13454 try { 13455 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13456 intent.getAction())) { 13457 String msg = "Permission Denial: not allowed to send broadcast " 13458 + intent.getAction() + " from pid=" 13459 + callingPid + ", uid=" + callingUid; 13460 Slog.w(TAG, msg); 13461 throw new SecurityException(msg); 13462 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13463 // Special case for compatibility: we don't want apps to send this, 13464 // but historically it has not been protected and apps may be using it 13465 // to poke their own app widget. So, instead of making it protected, 13466 // just limit it to the caller. 13467 if (callerApp == null) { 13468 String msg = "Permission Denial: not allowed to send broadcast " 13469 + intent.getAction() + " from unknown caller."; 13470 Slog.w(TAG, msg); 13471 throw new SecurityException(msg); 13472 } else if (intent.getComponent() != null) { 13473 // They are good enough to send to an explicit component... verify 13474 // it is being sent to the calling app. 13475 if (!intent.getComponent().getPackageName().equals( 13476 callerApp.info.packageName)) { 13477 String msg = "Permission Denial: not allowed to send broadcast " 13478 + intent.getAction() + " to " 13479 + intent.getComponent().getPackageName() + " from " 13480 + callerApp.info.packageName; 13481 Slog.w(TAG, msg); 13482 throw new SecurityException(msg); 13483 } 13484 } else { 13485 // Limit broadcast to their own package. 13486 intent.setPackage(callerApp.info.packageName); 13487 } 13488 } 13489 } catch (RemoteException e) { 13490 Slog.w(TAG, "Remote exception", e); 13491 return ActivityManager.BROADCAST_SUCCESS; 13492 } 13493 } 13494 13495 // Handle special intents: if this broadcast is from the package 13496 // manager about a package being removed, we need to remove all of 13497 // its activities from the history stack. 13498 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13499 intent.getAction()); 13500 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13501 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13502 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13503 || uidRemoved) { 13504 if (checkComponentPermission( 13505 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13506 callingPid, callingUid, -1, true) 13507 == PackageManager.PERMISSION_GRANTED) { 13508 if (uidRemoved) { 13509 final Bundle intentExtras = intent.getExtras(); 13510 final int uid = intentExtras != null 13511 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13512 if (uid >= 0) { 13513 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13514 synchronized (bs) { 13515 bs.removeUidStatsLocked(uid); 13516 } 13517 mAppOpsService.uidRemoved(uid); 13518 } 13519 } else { 13520 // If resources are unavailable just force stop all 13521 // those packages and flush the attribute cache as well. 13522 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13523 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13524 if (list != null && (list.length > 0)) { 13525 for (String pkg : list) { 13526 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13527 "storage unmount"); 13528 } 13529 sendPackageBroadcastLocked( 13530 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13531 } 13532 } else { 13533 Uri data = intent.getData(); 13534 String ssp; 13535 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13536 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13537 intent.getAction()); 13538 boolean fullUninstall = removed && 13539 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13540 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13541 forceStopPackageLocked(ssp, UserHandle.getAppId( 13542 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13543 false, fullUninstall, userId, 13544 removed ? "pkg removed" : "pkg changed"); 13545 } 13546 if (removed) { 13547 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13548 new String[] {ssp}, userId); 13549 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13550 mAppOpsService.packageRemoved( 13551 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13552 13553 // Remove all permissions granted from/to this package 13554 removeUriPermissionsForPackageLocked(ssp, userId, true); 13555 } 13556 } 13557 } 13558 } 13559 } 13560 } else { 13561 String msg = "Permission Denial: " + intent.getAction() 13562 + " broadcast from " + callerPackage + " (pid=" + callingPid 13563 + ", uid=" + callingUid + ")" 13564 + " requires " 13565 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13566 Slog.w(TAG, msg); 13567 throw new SecurityException(msg); 13568 } 13569 13570 // Special case for adding a package: by default turn on compatibility 13571 // mode. 13572 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13573 Uri data = intent.getData(); 13574 String ssp; 13575 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13576 mCompatModePackages.handlePackageAddedLocked(ssp, 13577 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13578 } 13579 } 13580 13581 /* 13582 * If this is the time zone changed action, queue up a message that will reset the timezone 13583 * of all currently running processes. This message will get queued up before the broadcast 13584 * happens. 13585 */ 13586 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13587 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13588 } 13589 13590 /* 13591 * If the user set the time, let all running processes know. 13592 */ 13593 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13594 final int is24Hour = intent.getBooleanExtra( 13595 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13596 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13597 } 13598 13599 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13600 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13601 } 13602 13603 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13604 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13605 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13606 } 13607 13608 // Add to the sticky list if requested. 13609 if (sticky) { 13610 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13611 callingPid, callingUid) 13612 != PackageManager.PERMISSION_GRANTED) { 13613 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13614 + callingPid + ", uid=" + callingUid 13615 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13616 Slog.w(TAG, msg); 13617 throw new SecurityException(msg); 13618 } 13619 if (requiredPermission != null) { 13620 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13621 + " and enforce permission " + requiredPermission); 13622 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13623 } 13624 if (intent.getComponent() != null) { 13625 throw new SecurityException( 13626 "Sticky broadcasts can't target a specific component"); 13627 } 13628 // We use userId directly here, since the "all" target is maintained 13629 // as a separate set of sticky broadcasts. 13630 if (userId != UserHandle.USER_ALL) { 13631 // But first, if this is not a broadcast to all users, then 13632 // make sure it doesn't conflict with an existing broadcast to 13633 // all users. 13634 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13635 UserHandle.USER_ALL); 13636 if (stickies != null) { 13637 ArrayList<Intent> list = stickies.get(intent.getAction()); 13638 if (list != null) { 13639 int N = list.size(); 13640 int i; 13641 for (i=0; i<N; i++) { 13642 if (intent.filterEquals(list.get(i))) { 13643 throw new IllegalArgumentException( 13644 "Sticky broadcast " + intent + " for user " 13645 + userId + " conflicts with existing global broadcast"); 13646 } 13647 } 13648 } 13649 } 13650 } 13651 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13652 if (stickies == null) { 13653 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13654 mStickyBroadcasts.put(userId, stickies); 13655 } 13656 ArrayList<Intent> list = stickies.get(intent.getAction()); 13657 if (list == null) { 13658 list = new ArrayList<Intent>(); 13659 stickies.put(intent.getAction(), list); 13660 } 13661 int N = list.size(); 13662 int i; 13663 for (i=0; i<N; i++) { 13664 if (intent.filterEquals(list.get(i))) { 13665 // This sticky already exists, replace it. 13666 list.set(i, new Intent(intent)); 13667 break; 13668 } 13669 } 13670 if (i >= N) { 13671 list.add(new Intent(intent)); 13672 } 13673 } 13674 13675 int[] users; 13676 if (userId == UserHandle.USER_ALL) { 13677 // Caller wants broadcast to go to all started users. 13678 users = mStartedUserArray; 13679 } else { 13680 // Caller wants broadcast to go to one specific user. 13681 users = new int[] {userId}; 13682 } 13683 13684 // Figure out who all will receive this broadcast. 13685 List receivers = null; 13686 List<BroadcastFilter> registeredReceivers = null; 13687 // Need to resolve the intent to interested receivers... 13688 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13689 == 0) { 13690 receivers = collectReceiverComponents(intent, resolvedType, users); 13691 } 13692 if (intent.getComponent() == null) { 13693 registeredReceivers = mReceiverResolver.queryIntent(intent, 13694 resolvedType, false, userId); 13695 } 13696 13697 final boolean replacePending = 13698 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13699 13700 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13701 + " replacePending=" + replacePending); 13702 13703 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13704 if (!ordered && NR > 0) { 13705 // If we are not serializing this broadcast, then send the 13706 // registered receivers separately so they don't wait for the 13707 // components to be launched. 13708 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13709 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13710 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13711 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13712 ordered, sticky, false, userId); 13713 if (DEBUG_BROADCAST) Slog.v( 13714 TAG, "Enqueueing parallel broadcast " + r); 13715 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13716 if (!replaced) { 13717 queue.enqueueParallelBroadcastLocked(r); 13718 queue.scheduleBroadcastsLocked(); 13719 } 13720 registeredReceivers = null; 13721 NR = 0; 13722 } 13723 13724 // Merge into one list. 13725 int ir = 0; 13726 if (receivers != null) { 13727 // A special case for PACKAGE_ADDED: do not allow the package 13728 // being added to see this broadcast. This prevents them from 13729 // using this as a back door to get run as soon as they are 13730 // installed. Maybe in the future we want to have a special install 13731 // broadcast or such for apps, but we'd like to deliberately make 13732 // this decision. 13733 String skipPackages[] = null; 13734 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13735 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13736 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13737 Uri data = intent.getData(); 13738 if (data != null) { 13739 String pkgName = data.getSchemeSpecificPart(); 13740 if (pkgName != null) { 13741 skipPackages = new String[] { pkgName }; 13742 } 13743 } 13744 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13745 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13746 } 13747 if (skipPackages != null && (skipPackages.length > 0)) { 13748 for (String skipPackage : skipPackages) { 13749 if (skipPackage != null) { 13750 int NT = receivers.size(); 13751 for (int it=0; it<NT; it++) { 13752 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13753 if (curt.activityInfo.packageName.equals(skipPackage)) { 13754 receivers.remove(it); 13755 it--; 13756 NT--; 13757 } 13758 } 13759 } 13760 } 13761 } 13762 13763 int NT = receivers != null ? receivers.size() : 0; 13764 int it = 0; 13765 ResolveInfo curt = null; 13766 BroadcastFilter curr = null; 13767 while (it < NT && ir < NR) { 13768 if (curt == null) { 13769 curt = (ResolveInfo)receivers.get(it); 13770 } 13771 if (curr == null) { 13772 curr = registeredReceivers.get(ir); 13773 } 13774 if (curr.getPriority() >= curt.priority) { 13775 // Insert this broadcast record into the final list. 13776 receivers.add(it, curr); 13777 ir++; 13778 curr = null; 13779 it++; 13780 NT++; 13781 } else { 13782 // Skip to the next ResolveInfo in the final list. 13783 it++; 13784 curt = null; 13785 } 13786 } 13787 } 13788 while (ir < NR) { 13789 if (receivers == null) { 13790 receivers = new ArrayList(); 13791 } 13792 receivers.add(registeredReceivers.get(ir)); 13793 ir++; 13794 } 13795 13796 if ((receivers != null && receivers.size() > 0) 13797 || resultTo != null) { 13798 BroadcastQueue queue = broadcastQueueForIntent(intent); 13799 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13800 callerPackage, callingPid, callingUid, resolvedType, 13801 requiredPermission, appOp, receivers, resultTo, resultCode, 13802 resultData, map, ordered, sticky, false, userId); 13803 if (DEBUG_BROADCAST) Slog.v( 13804 TAG, "Enqueueing ordered broadcast " + r 13805 + ": prev had " + queue.mOrderedBroadcasts.size()); 13806 if (DEBUG_BROADCAST) { 13807 int seq = r.intent.getIntExtra("seq", -1); 13808 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13809 } 13810 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13811 if (!replaced) { 13812 queue.enqueueOrderedBroadcastLocked(r); 13813 queue.scheduleBroadcastsLocked(); 13814 } 13815 } 13816 13817 return ActivityManager.BROADCAST_SUCCESS; 13818 } 13819 13820 final Intent verifyBroadcastLocked(Intent intent) { 13821 // Refuse possible leaked file descriptors 13822 if (intent != null && intent.hasFileDescriptors() == true) { 13823 throw new IllegalArgumentException("File descriptors passed in Intent"); 13824 } 13825 13826 int flags = intent.getFlags(); 13827 13828 if (!mProcessesReady) { 13829 // if the caller really truly claims to know what they're doing, go 13830 // ahead and allow the broadcast without launching any receivers 13831 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13832 intent = new Intent(intent); 13833 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13834 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13835 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13836 + " before boot completion"); 13837 throw new IllegalStateException("Cannot broadcast before boot completed"); 13838 } 13839 } 13840 13841 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13842 throw new IllegalArgumentException( 13843 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13844 } 13845 13846 return intent; 13847 } 13848 13849 public final int broadcastIntent(IApplicationThread caller, 13850 Intent intent, String resolvedType, IIntentReceiver resultTo, 13851 int resultCode, String resultData, Bundle map, 13852 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13853 enforceNotIsolatedCaller("broadcastIntent"); 13854 synchronized(this) { 13855 intent = verifyBroadcastLocked(intent); 13856 13857 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13858 final int callingPid = Binder.getCallingPid(); 13859 final int callingUid = Binder.getCallingUid(); 13860 final long origId = Binder.clearCallingIdentity(); 13861 int res = broadcastIntentLocked(callerApp, 13862 callerApp != null ? callerApp.info.packageName : null, 13863 intent, resolvedType, resultTo, 13864 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13865 callingPid, callingUid, userId); 13866 Binder.restoreCallingIdentity(origId); 13867 return res; 13868 } 13869 } 13870 13871 int broadcastIntentInPackage(String packageName, int uid, 13872 Intent intent, String resolvedType, IIntentReceiver resultTo, 13873 int resultCode, String resultData, Bundle map, 13874 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13875 synchronized(this) { 13876 intent = verifyBroadcastLocked(intent); 13877 13878 final long origId = Binder.clearCallingIdentity(); 13879 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13880 resultTo, resultCode, resultData, map, requiredPermission, 13881 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13882 Binder.restoreCallingIdentity(origId); 13883 return res; 13884 } 13885 } 13886 13887 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13888 // Refuse possible leaked file descriptors 13889 if (intent != null && intent.hasFileDescriptors() == true) { 13890 throw new IllegalArgumentException("File descriptors passed in Intent"); 13891 } 13892 13893 userId = handleIncomingUser(Binder.getCallingPid(), 13894 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13895 13896 synchronized(this) { 13897 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13898 != PackageManager.PERMISSION_GRANTED) { 13899 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13900 + Binder.getCallingPid() 13901 + ", uid=" + Binder.getCallingUid() 13902 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13903 Slog.w(TAG, msg); 13904 throw new SecurityException(msg); 13905 } 13906 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13907 if (stickies != null) { 13908 ArrayList<Intent> list = stickies.get(intent.getAction()); 13909 if (list != null) { 13910 int N = list.size(); 13911 int i; 13912 for (i=0; i<N; i++) { 13913 if (intent.filterEquals(list.get(i))) { 13914 list.remove(i); 13915 break; 13916 } 13917 } 13918 if (list.size() <= 0) { 13919 stickies.remove(intent.getAction()); 13920 } 13921 } 13922 if (stickies.size() <= 0) { 13923 mStickyBroadcasts.remove(userId); 13924 } 13925 } 13926 } 13927 } 13928 13929 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13930 String resultData, Bundle resultExtras, boolean resultAbort) { 13931 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13932 if (r == null) { 13933 Slog.w(TAG, "finishReceiver called but not found on queue"); 13934 return false; 13935 } 13936 13937 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13938 } 13939 13940 void backgroundServicesFinishedLocked(int userId) { 13941 for (BroadcastQueue queue : mBroadcastQueues) { 13942 queue.backgroundServicesFinishedLocked(userId); 13943 } 13944 } 13945 13946 public void finishReceiver(IBinder who, int resultCode, String resultData, 13947 Bundle resultExtras, boolean resultAbort) { 13948 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13949 13950 // Refuse possible leaked file descriptors 13951 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13952 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13953 } 13954 13955 final long origId = Binder.clearCallingIdentity(); 13956 try { 13957 boolean doNext = false; 13958 BroadcastRecord r; 13959 13960 synchronized(this) { 13961 r = broadcastRecordForReceiverLocked(who); 13962 if (r != null) { 13963 doNext = r.queue.finishReceiverLocked(r, resultCode, 13964 resultData, resultExtras, resultAbort, true); 13965 } 13966 } 13967 13968 if (doNext) { 13969 r.queue.processNextBroadcast(false); 13970 } 13971 trimApplications(); 13972 } finally { 13973 Binder.restoreCallingIdentity(origId); 13974 } 13975 } 13976 13977 // ========================================================= 13978 // INSTRUMENTATION 13979 // ========================================================= 13980 13981 public boolean startInstrumentation(ComponentName className, 13982 String profileFile, int flags, Bundle arguments, 13983 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13984 int userId) { 13985 enforceNotIsolatedCaller("startInstrumentation"); 13986 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13987 userId, false, true, "startInstrumentation", null); 13988 // Refuse possible leaked file descriptors 13989 if (arguments != null && arguments.hasFileDescriptors()) { 13990 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13991 } 13992 13993 synchronized(this) { 13994 InstrumentationInfo ii = null; 13995 ApplicationInfo ai = null; 13996 try { 13997 ii = mContext.getPackageManager().getInstrumentationInfo( 13998 className, STOCK_PM_FLAGS); 13999 ai = AppGlobals.getPackageManager().getApplicationInfo( 14000 ii.targetPackage, STOCK_PM_FLAGS, userId); 14001 } catch (PackageManager.NameNotFoundException e) { 14002 } catch (RemoteException e) { 14003 } 14004 if (ii == null) { 14005 reportStartInstrumentationFailure(watcher, className, 14006 "Unable to find instrumentation info for: " + className); 14007 return false; 14008 } 14009 if (ai == null) { 14010 reportStartInstrumentationFailure(watcher, className, 14011 "Unable to find instrumentation target package: " + ii.targetPackage); 14012 return false; 14013 } 14014 14015 int match = mContext.getPackageManager().checkSignatures( 14016 ii.targetPackage, ii.packageName); 14017 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14018 String msg = "Permission Denial: starting instrumentation " 14019 + className + " from pid=" 14020 + Binder.getCallingPid() 14021 + ", uid=" + Binder.getCallingPid() 14022 + " not allowed because package " + ii.packageName 14023 + " does not have a signature matching the target " 14024 + ii.targetPackage; 14025 reportStartInstrumentationFailure(watcher, className, msg); 14026 throw new SecurityException(msg); 14027 } 14028 14029 final long origId = Binder.clearCallingIdentity(); 14030 // Instrumentation can kill and relaunch even persistent processes 14031 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14032 "start instr"); 14033 ProcessRecord app = addAppLocked(ai, false); 14034 app.instrumentationClass = className; 14035 app.instrumentationInfo = ai; 14036 app.instrumentationProfileFile = profileFile; 14037 app.instrumentationArguments = arguments; 14038 app.instrumentationWatcher = watcher; 14039 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14040 app.instrumentationResultClass = className; 14041 Binder.restoreCallingIdentity(origId); 14042 } 14043 14044 return true; 14045 } 14046 14047 /** 14048 * Report errors that occur while attempting to start Instrumentation. Always writes the 14049 * error to the logs, but if somebody is watching, send the report there too. This enables 14050 * the "am" command to report errors with more information. 14051 * 14052 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14053 * @param cn The component name of the instrumentation. 14054 * @param report The error report. 14055 */ 14056 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14057 ComponentName cn, String report) { 14058 Slog.w(TAG, report); 14059 try { 14060 if (watcher != null) { 14061 Bundle results = new Bundle(); 14062 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14063 results.putString("Error", report); 14064 watcher.instrumentationStatus(cn, -1, results); 14065 } 14066 } catch (RemoteException e) { 14067 Slog.w(TAG, e); 14068 } 14069 } 14070 14071 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14072 if (app.instrumentationWatcher != null) { 14073 try { 14074 // NOTE: IInstrumentationWatcher *must* be oneway here 14075 app.instrumentationWatcher.instrumentationFinished( 14076 app.instrumentationClass, 14077 resultCode, 14078 results); 14079 } catch (RemoteException e) { 14080 } 14081 } 14082 if (app.instrumentationUiAutomationConnection != null) { 14083 try { 14084 app.instrumentationUiAutomationConnection.shutdown(); 14085 } catch (RemoteException re) { 14086 /* ignore */ 14087 } 14088 // Only a UiAutomation can set this flag and now that 14089 // it is finished we make sure it is reset to its default. 14090 mUserIsMonkey = false; 14091 } 14092 app.instrumentationWatcher = null; 14093 app.instrumentationUiAutomationConnection = null; 14094 app.instrumentationClass = null; 14095 app.instrumentationInfo = null; 14096 app.instrumentationProfileFile = null; 14097 app.instrumentationArguments = null; 14098 14099 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14100 "finished inst"); 14101 } 14102 14103 public void finishInstrumentation(IApplicationThread target, 14104 int resultCode, Bundle results) { 14105 int userId = UserHandle.getCallingUserId(); 14106 // Refuse possible leaked file descriptors 14107 if (results != null && results.hasFileDescriptors()) { 14108 throw new IllegalArgumentException("File descriptors passed in Intent"); 14109 } 14110 14111 synchronized(this) { 14112 ProcessRecord app = getRecordForAppLocked(target); 14113 if (app == null) { 14114 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14115 return; 14116 } 14117 final long origId = Binder.clearCallingIdentity(); 14118 finishInstrumentationLocked(app, resultCode, results); 14119 Binder.restoreCallingIdentity(origId); 14120 } 14121 } 14122 14123 // ========================================================= 14124 // CONFIGURATION 14125 // ========================================================= 14126 14127 public ConfigurationInfo getDeviceConfigurationInfo() { 14128 ConfigurationInfo config = new ConfigurationInfo(); 14129 synchronized (this) { 14130 config.reqTouchScreen = mConfiguration.touchscreen; 14131 config.reqKeyboardType = mConfiguration.keyboard; 14132 config.reqNavigation = mConfiguration.navigation; 14133 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14134 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14135 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14136 } 14137 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14138 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14139 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14140 } 14141 config.reqGlEsVersion = GL_ES_VERSION; 14142 } 14143 return config; 14144 } 14145 14146 ActivityStack getFocusedStack() { 14147 return mStackSupervisor.getFocusedStack(); 14148 } 14149 14150 public Configuration getConfiguration() { 14151 Configuration ci; 14152 synchronized(this) { 14153 ci = new Configuration(mConfiguration); 14154 } 14155 return ci; 14156 } 14157 14158 public void updatePersistentConfiguration(Configuration values) { 14159 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14160 "updateConfiguration()"); 14161 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14162 "updateConfiguration()"); 14163 if (values == null) { 14164 throw new NullPointerException("Configuration must not be null"); 14165 } 14166 14167 synchronized(this) { 14168 final long origId = Binder.clearCallingIdentity(); 14169 updateConfigurationLocked(values, null, true, false); 14170 Binder.restoreCallingIdentity(origId); 14171 } 14172 } 14173 14174 public void updateConfiguration(Configuration values) { 14175 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14176 "updateConfiguration()"); 14177 14178 synchronized(this) { 14179 if (values == null && mWindowManager != null) { 14180 // sentinel: fetch the current configuration from the window manager 14181 values = mWindowManager.computeNewConfiguration(); 14182 } 14183 14184 if (mWindowManager != null) { 14185 mProcessList.applyDisplaySize(mWindowManager); 14186 } 14187 14188 final long origId = Binder.clearCallingIdentity(); 14189 if (values != null) { 14190 Settings.System.clearConfiguration(values); 14191 } 14192 updateConfigurationLocked(values, null, false, false); 14193 Binder.restoreCallingIdentity(origId); 14194 } 14195 } 14196 14197 /** 14198 * Do either or both things: (1) change the current configuration, and (2) 14199 * make sure the given activity is running with the (now) current 14200 * configuration. Returns true if the activity has been left running, or 14201 * false if <var>starting</var> is being destroyed to match the new 14202 * configuration. 14203 * @param persistent TODO 14204 */ 14205 boolean updateConfigurationLocked(Configuration values, 14206 ActivityRecord starting, boolean persistent, boolean initLocale) { 14207 int changes = 0; 14208 14209 if (values != null) { 14210 Configuration newConfig = new Configuration(mConfiguration); 14211 changes = newConfig.updateFrom(values); 14212 if (changes != 0) { 14213 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14214 Slog.i(TAG, "Updating configuration to: " + values); 14215 } 14216 14217 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14218 14219 if (values.locale != null && !initLocale) { 14220 saveLocaleLocked(values.locale, 14221 !values.locale.equals(mConfiguration.locale), 14222 values.userSetLocale); 14223 } 14224 14225 mConfigurationSeq++; 14226 if (mConfigurationSeq <= 0) { 14227 mConfigurationSeq = 1; 14228 } 14229 newConfig.seq = mConfigurationSeq; 14230 mConfiguration = newConfig; 14231 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14232 14233 final Configuration configCopy = new Configuration(mConfiguration); 14234 14235 // TODO: If our config changes, should we auto dismiss any currently 14236 // showing dialogs? 14237 mShowDialogs = shouldShowDialogs(newConfig); 14238 14239 AttributeCache ac = AttributeCache.instance(); 14240 if (ac != null) { 14241 ac.updateConfiguration(configCopy); 14242 } 14243 14244 // Make sure all resources in our process are updated 14245 // right now, so that anyone who is going to retrieve 14246 // resource values after we return will be sure to get 14247 // the new ones. This is especially important during 14248 // boot, where the first config change needs to guarantee 14249 // all resources have that config before following boot 14250 // code is executed. 14251 mSystemThread.applyConfigurationToResources(configCopy); 14252 14253 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14254 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14255 msg.obj = new Configuration(configCopy); 14256 mHandler.sendMessage(msg); 14257 } 14258 14259 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14260 ProcessRecord app = mLruProcesses.get(i); 14261 try { 14262 if (app.thread != null) { 14263 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14264 + app.processName + " new config " + mConfiguration); 14265 app.thread.scheduleConfigurationChanged(configCopy); 14266 } 14267 } catch (Exception e) { 14268 } 14269 } 14270 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14271 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14272 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14273 | Intent.FLAG_RECEIVER_FOREGROUND); 14274 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14275 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14276 Process.SYSTEM_UID, UserHandle.USER_ALL); 14277 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14278 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14279 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14280 broadcastIntentLocked(null, null, intent, 14281 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14282 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14283 } 14284 } 14285 } 14286 14287 boolean kept = true; 14288 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14289 // mainStack is null during startup. 14290 if (mainStack != null) { 14291 if (changes != 0 && starting == null) { 14292 // If the configuration changed, and the caller is not already 14293 // in the process of starting an activity, then find the top 14294 // activity to check if its configuration needs to change. 14295 starting = mainStack.topRunningActivityLocked(null); 14296 } 14297 14298 if (starting != null) { 14299 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14300 // And we need to make sure at this point that all other activities 14301 // are made visible with the correct configuration. 14302 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14303 } 14304 } 14305 14306 if (values != null && mWindowManager != null) { 14307 mWindowManager.setNewConfiguration(mConfiguration); 14308 } 14309 14310 return kept; 14311 } 14312 14313 /** 14314 * Decide based on the configuration whether we should shouw the ANR, 14315 * crash, etc dialogs. The idea is that if there is no affordnace to 14316 * press the on-screen buttons, we shouldn't show the dialog. 14317 * 14318 * A thought: SystemUI might also want to get told about this, the Power 14319 * dialog / global actions also might want different behaviors. 14320 */ 14321 private static final boolean shouldShowDialogs(Configuration config) { 14322 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14323 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14324 } 14325 14326 /** 14327 * Save the locale. You must be inside a synchronized (this) block. 14328 */ 14329 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14330 if(isDiff) { 14331 SystemProperties.set("user.language", l.getLanguage()); 14332 SystemProperties.set("user.region", l.getCountry()); 14333 } 14334 14335 if(isPersist) { 14336 SystemProperties.set("persist.sys.language", l.getLanguage()); 14337 SystemProperties.set("persist.sys.country", l.getCountry()); 14338 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14339 } 14340 } 14341 14342 @Override 14343 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14344 ActivityRecord srec = ActivityRecord.forToken(token); 14345 return srec != null && srec.task.affinity != null && 14346 srec.task.affinity.equals(destAffinity); 14347 } 14348 14349 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14350 Intent resultData) { 14351 14352 synchronized (this) { 14353 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14354 if (stack != null) { 14355 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14356 } 14357 return false; 14358 } 14359 } 14360 14361 public int getLaunchedFromUid(IBinder activityToken) { 14362 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14363 if (srec == null) { 14364 return -1; 14365 } 14366 return srec.launchedFromUid; 14367 } 14368 14369 public String getLaunchedFromPackage(IBinder activityToken) { 14370 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14371 if (srec == null) { 14372 return null; 14373 } 14374 return srec.launchedFromPackage; 14375 } 14376 14377 // ========================================================= 14378 // LIFETIME MANAGEMENT 14379 // ========================================================= 14380 14381 // Returns which broadcast queue the app is the current [or imminent] receiver 14382 // on, or 'null' if the app is not an active broadcast recipient. 14383 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14384 BroadcastRecord r = app.curReceiver; 14385 if (r != null) { 14386 return r.queue; 14387 } 14388 14389 // It's not the current receiver, but it might be starting up to become one 14390 synchronized (this) { 14391 for (BroadcastQueue queue : mBroadcastQueues) { 14392 r = queue.mPendingBroadcast; 14393 if (r != null && r.curApp == app) { 14394 // found it; report which queue it's in 14395 return queue; 14396 } 14397 } 14398 } 14399 14400 return null; 14401 } 14402 14403 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14404 boolean doingAll, long now) { 14405 if (mAdjSeq == app.adjSeq) { 14406 // This adjustment has already been computed. 14407 return app.curRawAdj; 14408 } 14409 14410 if (app.thread == null) { 14411 app.adjSeq = mAdjSeq; 14412 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14413 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14414 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14415 } 14416 14417 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14418 app.adjSource = null; 14419 app.adjTarget = null; 14420 app.empty = false; 14421 app.cached = false; 14422 14423 final int activitiesSize = app.activities.size(); 14424 14425 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14426 // The max adjustment doesn't allow this app to be anything 14427 // below foreground, so it is not worth doing work for it. 14428 app.adjType = "fixed"; 14429 app.adjSeq = mAdjSeq; 14430 app.curRawAdj = app.maxAdj; 14431 app.foregroundActivities = false; 14432 app.keeping = true; 14433 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14434 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14435 // System process can do UI, and when they do we want to have 14436 // them trim their memory after the user leaves the UI. To 14437 // facilitate this, here we need to determine whether or not it 14438 // is currently showing UI. 14439 app.systemNoUi = true; 14440 if (app == TOP_APP) { 14441 app.systemNoUi = false; 14442 } else if (activitiesSize > 0) { 14443 for (int j = 0; j < activitiesSize; j++) { 14444 final ActivityRecord r = app.activities.get(j); 14445 if (r.visible) { 14446 app.systemNoUi = false; 14447 } 14448 } 14449 } 14450 if (!app.systemNoUi) { 14451 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14452 } 14453 return (app.curAdj=app.maxAdj); 14454 } 14455 14456 app.keeping = false; 14457 app.systemNoUi = false; 14458 14459 // Determine the importance of the process, starting with most 14460 // important to least, and assign an appropriate OOM adjustment. 14461 int adj; 14462 int schedGroup; 14463 int procState; 14464 boolean foregroundActivities = false; 14465 boolean interesting = false; 14466 BroadcastQueue queue; 14467 if (app == TOP_APP) { 14468 // The last app on the list is the foreground app. 14469 adj = ProcessList.FOREGROUND_APP_ADJ; 14470 schedGroup = Process.THREAD_GROUP_DEFAULT; 14471 app.adjType = "top-activity"; 14472 foregroundActivities = true; 14473 interesting = true; 14474 procState = ActivityManager.PROCESS_STATE_TOP; 14475 } else if (app.instrumentationClass != null) { 14476 // Don't want to kill running instrumentation. 14477 adj = ProcessList.FOREGROUND_APP_ADJ; 14478 schedGroup = Process.THREAD_GROUP_DEFAULT; 14479 app.adjType = "instrumentation"; 14480 interesting = true; 14481 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14482 } else if ((queue = isReceivingBroadcast(app)) != null) { 14483 // An app that is currently receiving a broadcast also 14484 // counts as being in the foreground for OOM killer purposes. 14485 // It's placed in a sched group based on the nature of the 14486 // broadcast as reflected by which queue it's active in. 14487 adj = ProcessList.FOREGROUND_APP_ADJ; 14488 schedGroup = (queue == mFgBroadcastQueue) 14489 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14490 app.adjType = "broadcast"; 14491 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14492 } else if (app.executingServices.size() > 0) { 14493 // An app that is currently executing a service callback also 14494 // counts as being in the foreground. 14495 adj = ProcessList.FOREGROUND_APP_ADJ; 14496 schedGroup = app.execServicesFg ? 14497 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14498 app.adjType = "exec-service"; 14499 procState = ActivityManager.PROCESS_STATE_SERVICE; 14500 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14501 } else { 14502 // As far as we know the process is empty. We may change our mind later. 14503 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14504 // At this point we don't actually know the adjustment. Use the cached adj 14505 // value that the caller wants us to. 14506 adj = cachedAdj; 14507 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14508 app.cached = true; 14509 app.empty = true; 14510 app.adjType = "cch-empty"; 14511 } 14512 14513 // Examine all activities if not already foreground. 14514 if (!foregroundActivities && activitiesSize > 0) { 14515 for (int j = 0; j < activitiesSize; j++) { 14516 final ActivityRecord r = app.activities.get(j); 14517 if (r.app != app) { 14518 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14519 + app + "?!?"); 14520 continue; 14521 } 14522 if (r.visible) { 14523 // App has a visible activity; only upgrade adjustment. 14524 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14525 adj = ProcessList.VISIBLE_APP_ADJ; 14526 app.adjType = "visible"; 14527 } 14528 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14529 procState = ActivityManager.PROCESS_STATE_TOP; 14530 } 14531 schedGroup = Process.THREAD_GROUP_DEFAULT; 14532 app.cached = false; 14533 app.empty = false; 14534 foregroundActivities = true; 14535 break; 14536 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14537 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14538 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14539 app.adjType = "pausing"; 14540 } 14541 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14542 procState = ActivityManager.PROCESS_STATE_TOP; 14543 } 14544 schedGroup = Process.THREAD_GROUP_DEFAULT; 14545 app.cached = false; 14546 app.empty = false; 14547 foregroundActivities = true; 14548 } else if (r.state == ActivityState.STOPPING) { 14549 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14550 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14551 app.adjType = "stopping"; 14552 } 14553 // For the process state, we will at this point consider the 14554 // process to be cached. It will be cached either as an activity 14555 // or empty depending on whether the activity is finishing. We do 14556 // this so that we can treat the process as cached for purposes of 14557 // memory trimming (determing current memory level, trim command to 14558 // send to process) since there can be an arbitrary number of stopping 14559 // processes and they should soon all go into the cached state. 14560 if (!r.finishing) { 14561 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14562 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14563 } 14564 } 14565 app.cached = false; 14566 app.empty = false; 14567 foregroundActivities = true; 14568 } else { 14569 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14570 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14571 app.adjType = "cch-act"; 14572 } 14573 } 14574 } 14575 } 14576 14577 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14578 if (app.foregroundServices) { 14579 // The user is aware of this app, so make it visible. 14580 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14581 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14582 app.cached = false; 14583 app.adjType = "fg-service"; 14584 schedGroup = Process.THREAD_GROUP_DEFAULT; 14585 } else if (app.forcingToForeground != null) { 14586 // The user is aware of this app, so make it visible. 14587 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14588 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14589 app.cached = false; 14590 app.adjType = "force-fg"; 14591 app.adjSource = app.forcingToForeground; 14592 schedGroup = Process.THREAD_GROUP_DEFAULT; 14593 } 14594 } 14595 14596 if (app.foregroundServices) { 14597 interesting = true; 14598 } 14599 14600 if (app == mHeavyWeightProcess) { 14601 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14602 // We don't want to kill the current heavy-weight process. 14603 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14604 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14605 app.cached = false; 14606 app.adjType = "heavy"; 14607 } 14608 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14609 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14610 } 14611 } 14612 14613 if (app == mHomeProcess) { 14614 if (adj > ProcessList.HOME_APP_ADJ) { 14615 // This process is hosting what we currently consider to be the 14616 // home app, so we don't want to let it go into the background. 14617 adj = ProcessList.HOME_APP_ADJ; 14618 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14619 app.cached = false; 14620 app.adjType = "home"; 14621 } 14622 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14623 procState = ActivityManager.PROCESS_STATE_HOME; 14624 } 14625 } 14626 14627 if (app == mPreviousProcess && app.activities.size() > 0) { 14628 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14629 // This was the previous process that showed UI to the user. 14630 // We want to try to keep it around more aggressively, to give 14631 // a good experience around switching between two apps. 14632 adj = ProcessList.PREVIOUS_APP_ADJ; 14633 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14634 app.cached = false; 14635 app.adjType = "previous"; 14636 } 14637 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14638 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14639 } 14640 } 14641 14642 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14643 + " reason=" + app.adjType); 14644 14645 // By default, we use the computed adjustment. It may be changed if 14646 // there are applications dependent on our services or providers, but 14647 // this gives us a baseline and makes sure we don't get into an 14648 // infinite recursion. 14649 app.adjSeq = mAdjSeq; 14650 app.curRawAdj = adj; 14651 app.hasStartedServices = false; 14652 14653 if (mBackupTarget != null && app == mBackupTarget.app) { 14654 // If possible we want to avoid killing apps while they're being backed up 14655 if (adj > ProcessList.BACKUP_APP_ADJ) { 14656 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14657 adj = ProcessList.BACKUP_APP_ADJ; 14658 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14659 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14660 } 14661 app.adjType = "backup"; 14662 app.cached = false; 14663 } 14664 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14665 procState = ActivityManager.PROCESS_STATE_BACKUP; 14666 } 14667 } 14668 14669 boolean mayBeTop = false; 14670 14671 for (int is = app.services.size()-1; 14672 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14673 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14674 || procState > ActivityManager.PROCESS_STATE_TOP); 14675 is--) { 14676 ServiceRecord s = app.services.valueAt(is); 14677 if (s.startRequested) { 14678 app.hasStartedServices = true; 14679 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14680 procState = ActivityManager.PROCESS_STATE_SERVICE; 14681 } 14682 if (app.hasShownUi && app != mHomeProcess) { 14683 // If this process has shown some UI, let it immediately 14684 // go to the LRU list because it may be pretty heavy with 14685 // UI stuff. We'll tag it with a label just to help 14686 // debug and understand what is going on. 14687 if (adj > ProcessList.SERVICE_ADJ) { 14688 app.adjType = "cch-started-ui-services"; 14689 } 14690 } else { 14691 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14692 // This service has seen some activity within 14693 // recent memory, so we will keep its process ahead 14694 // of the background processes. 14695 if (adj > ProcessList.SERVICE_ADJ) { 14696 adj = ProcessList.SERVICE_ADJ; 14697 app.adjType = "started-services"; 14698 app.cached = false; 14699 } 14700 } 14701 // If we have let the service slide into the background 14702 // state, still have some text describing what it is doing 14703 // even though the service no longer has an impact. 14704 if (adj > ProcessList.SERVICE_ADJ) { 14705 app.adjType = "cch-started-services"; 14706 } 14707 } 14708 // Don't kill this process because it is doing work; it 14709 // has said it is doing work. 14710 app.keeping = true; 14711 } 14712 for (int conni = s.connections.size()-1; 14713 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14714 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14715 || procState > ActivityManager.PROCESS_STATE_TOP); 14716 conni--) { 14717 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14718 for (int i = 0; 14719 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14720 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14721 || procState > ActivityManager.PROCESS_STATE_TOP); 14722 i++) { 14723 // XXX should compute this based on the max of 14724 // all connected clients. 14725 ConnectionRecord cr = clist.get(i); 14726 if (cr.binding.client == app) { 14727 // Binding to ourself is not interesting. 14728 continue; 14729 } 14730 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14731 ProcessRecord client = cr.binding.client; 14732 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14733 TOP_APP, doingAll, now); 14734 int clientProcState = client.curProcState; 14735 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14736 // If the other app is cached for any reason, for purposes here 14737 // we are going to consider it empty. The specific cached state 14738 // doesn't propagate except under certain conditions. 14739 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14740 } 14741 String adjType = null; 14742 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14743 // Not doing bind OOM management, so treat 14744 // this guy more like a started service. 14745 if (app.hasShownUi && app != mHomeProcess) { 14746 // If this process has shown some UI, let it immediately 14747 // go to the LRU list because it may be pretty heavy with 14748 // UI stuff. We'll tag it with a label just to help 14749 // debug and understand what is going on. 14750 if (adj > clientAdj) { 14751 adjType = "cch-bound-ui-services"; 14752 } 14753 app.cached = false; 14754 clientAdj = adj; 14755 clientProcState = procState; 14756 } else { 14757 if (now >= (s.lastActivity 14758 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14759 // This service has not seen activity within 14760 // recent memory, so allow it to drop to the 14761 // LRU list if there is no other reason to keep 14762 // it around. We'll also tag it with a label just 14763 // to help debug and undertand what is going on. 14764 if (adj > clientAdj) { 14765 adjType = "cch-bound-services"; 14766 } 14767 clientAdj = adj; 14768 } 14769 } 14770 } 14771 if (adj > clientAdj) { 14772 // If this process has recently shown UI, and 14773 // the process that is binding to it is less 14774 // important than being visible, then we don't 14775 // care about the binding as much as we care 14776 // about letting this process get into the LRU 14777 // list to be killed and restarted if needed for 14778 // memory. 14779 if (app.hasShownUi && app != mHomeProcess 14780 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14781 adjType = "cch-bound-ui-services"; 14782 } else { 14783 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14784 |Context.BIND_IMPORTANT)) != 0) { 14785 adj = clientAdj; 14786 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14787 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14788 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14789 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14790 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14791 adj = clientAdj; 14792 } else { 14793 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14794 adj = ProcessList.VISIBLE_APP_ADJ; 14795 } 14796 } 14797 if (!client.cached) { 14798 app.cached = false; 14799 } 14800 if (client.keeping) { 14801 app.keeping = true; 14802 } 14803 adjType = "service"; 14804 } 14805 } 14806 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14807 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14808 schedGroup = Process.THREAD_GROUP_DEFAULT; 14809 } 14810 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14811 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14812 // Special handling of clients who are in the top state. 14813 // We *may* want to consider this process to be in the 14814 // top state as well, but only if there is not another 14815 // reason for it to be running. Being on the top is a 14816 // special state, meaning you are specifically running 14817 // for the current top app. If the process is already 14818 // running in the background for some other reason, it 14819 // is more important to continue considering it to be 14820 // in the background state. 14821 mayBeTop = true; 14822 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14823 } else { 14824 // Special handling for above-top states (persistent 14825 // processes). These should not bring the current process 14826 // into the top state, since they are not on top. Instead 14827 // give them the best state after that. 14828 clientProcState = 14829 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14830 } 14831 } 14832 } else { 14833 if (clientProcState < 14834 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14835 clientProcState = 14836 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14837 } 14838 } 14839 if (procState > clientProcState) { 14840 procState = clientProcState; 14841 } 14842 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14843 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14844 app.pendingUiClean = true; 14845 } 14846 if (adjType != null) { 14847 app.adjType = adjType; 14848 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14849 .REASON_SERVICE_IN_USE; 14850 app.adjSource = cr.binding.client; 14851 app.adjSourceOom = clientAdj; 14852 app.adjTarget = s.name; 14853 } 14854 } 14855 final ActivityRecord a = cr.activity; 14856 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14857 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14858 (a.visible || a.state == ActivityState.RESUMED 14859 || a.state == ActivityState.PAUSING)) { 14860 adj = ProcessList.FOREGROUND_APP_ADJ; 14861 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14862 schedGroup = Process.THREAD_GROUP_DEFAULT; 14863 } 14864 app.cached = false; 14865 app.adjType = "service"; 14866 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14867 .REASON_SERVICE_IN_USE; 14868 app.adjSource = a; 14869 app.adjSourceOom = adj; 14870 app.adjTarget = s.name; 14871 } 14872 } 14873 } 14874 } 14875 } 14876 14877 for (int provi = app.pubProviders.size()-1; 14878 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14879 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14880 || procState > ActivityManager.PROCESS_STATE_TOP); 14881 provi--) { 14882 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14883 for (int i = cpr.connections.size()-1; 14884 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14885 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14886 || procState > ActivityManager.PROCESS_STATE_TOP); 14887 i--) { 14888 ContentProviderConnection conn = cpr.connections.get(i); 14889 ProcessRecord client = conn.client; 14890 if (client == app) { 14891 // Being our own client is not interesting. 14892 continue; 14893 } 14894 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14895 int clientProcState = client.curProcState; 14896 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14897 // If the other app is cached for any reason, for purposes here 14898 // we are going to consider it empty. 14899 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14900 } 14901 if (adj > clientAdj) { 14902 if (app.hasShownUi && app != mHomeProcess 14903 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14904 app.adjType = "cch-ui-provider"; 14905 } else { 14906 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14907 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14908 app.adjType = "provider"; 14909 } 14910 app.cached &= client.cached; 14911 app.keeping |= client.keeping; 14912 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14913 .REASON_PROVIDER_IN_USE; 14914 app.adjSource = client; 14915 app.adjSourceOom = clientAdj; 14916 app.adjTarget = cpr.name; 14917 } 14918 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14919 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14920 // Special handling of clients who are in the top state. 14921 // We *may* want to consider this process to be in the 14922 // top state as well, but only if there is not another 14923 // reason for it to be running. Being on the top is a 14924 // special state, meaning you are specifically running 14925 // for the current top app. If the process is already 14926 // running in the background for some other reason, it 14927 // is more important to continue considering it to be 14928 // in the background state. 14929 mayBeTop = true; 14930 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14931 } else { 14932 // Special handling for above-top states (persistent 14933 // processes). These should not bring the current process 14934 // into the top state, since they are not on top. Instead 14935 // give them the best state after that. 14936 clientProcState = 14937 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14938 } 14939 } 14940 if (procState > clientProcState) { 14941 procState = clientProcState; 14942 } 14943 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14944 schedGroup = Process.THREAD_GROUP_DEFAULT; 14945 } 14946 } 14947 // If the provider has external (non-framework) process 14948 // dependencies, ensure that its adjustment is at least 14949 // FOREGROUND_APP_ADJ. 14950 if (cpr.hasExternalProcessHandles()) { 14951 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14952 adj = ProcessList.FOREGROUND_APP_ADJ; 14953 schedGroup = Process.THREAD_GROUP_DEFAULT; 14954 app.cached = false; 14955 app.keeping = true; 14956 app.adjType = "provider"; 14957 app.adjTarget = cpr.name; 14958 } 14959 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14960 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14961 } 14962 } 14963 } 14964 14965 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14966 // A client of one of our services or providers is in the top state. We 14967 // *may* want to be in the top state, but not if we are already running in 14968 // the background for some other reason. For the decision here, we are going 14969 // to pick out a few specific states that we want to remain in when a client 14970 // is top (states that tend to be longer-term) and otherwise allow it to go 14971 // to the top state. 14972 switch (procState) { 14973 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14974 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14975 case ActivityManager.PROCESS_STATE_SERVICE: 14976 // These all are longer-term states, so pull them up to the top 14977 // of the background states, but not all the way to the top state. 14978 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14979 break; 14980 default: 14981 // Otherwise, top is a better choice, so take it. 14982 procState = ActivityManager.PROCESS_STATE_TOP; 14983 break; 14984 } 14985 } 14986 14987 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14988 // This is a cached process, but with client activities. Mark it so. 14989 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14990 app.adjType = "cch-client-act"; 14991 } 14992 14993 if (adj == ProcessList.SERVICE_ADJ) { 14994 if (doingAll) { 14995 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14996 mNewNumServiceProcs++; 14997 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14998 if (!app.serviceb) { 14999 // This service isn't far enough down on the LRU list to 15000 // normally be a B service, but if we are low on RAM and it 15001 // is large we want to force it down since we would prefer to 15002 // keep launcher over it. 15003 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15004 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15005 app.serviceHighRam = true; 15006 app.serviceb = true; 15007 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15008 } else { 15009 mNewNumAServiceProcs++; 15010 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15011 } 15012 } else { 15013 app.serviceHighRam = false; 15014 } 15015 } 15016 if (app.serviceb) { 15017 adj = ProcessList.SERVICE_B_ADJ; 15018 } 15019 } 15020 15021 app.curRawAdj = adj; 15022 15023 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15024 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15025 if (adj > app.maxAdj) { 15026 adj = app.maxAdj; 15027 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15028 schedGroup = Process.THREAD_GROUP_DEFAULT; 15029 } 15030 } 15031 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15032 app.keeping = true; 15033 } 15034 15035 // Do final modification to adj. Everything we do between here and applying 15036 // the final setAdj must be done in this function, because we will also use 15037 // it when computing the final cached adj later. Note that we don't need to 15038 // worry about this for max adj above, since max adj will always be used to 15039 // keep it out of the cached vaues. 15040 adj = app.modifyRawOomAdj(adj); 15041 15042 app.curProcState = procState; 15043 15044 int importance = app.memImportance; 15045 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15046 app.curAdj = adj; 15047 app.curSchedGroup = schedGroup; 15048 if (!interesting) { 15049 // For this reporting, if there is not something explicitly 15050 // interesting in this process then we will push it to the 15051 // background importance. 15052 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15053 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15054 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15055 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15056 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15057 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15058 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15059 } else if (adj >= ProcessList.SERVICE_ADJ) { 15060 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15061 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15062 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15063 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15064 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15065 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15066 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15067 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15068 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15069 } else { 15070 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15071 } 15072 } 15073 15074 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15075 if (foregroundActivities != app.foregroundActivities) { 15076 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15077 } 15078 if (changes != 0) { 15079 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15080 app.memImportance = importance; 15081 app.foregroundActivities = foregroundActivities; 15082 int i = mPendingProcessChanges.size()-1; 15083 ProcessChangeItem item = null; 15084 while (i >= 0) { 15085 item = mPendingProcessChanges.get(i); 15086 if (item.pid == app.pid) { 15087 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15088 break; 15089 } 15090 i--; 15091 } 15092 if (i < 0) { 15093 // No existing item in pending changes; need a new one. 15094 final int NA = mAvailProcessChanges.size(); 15095 if (NA > 0) { 15096 item = mAvailProcessChanges.remove(NA-1); 15097 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15098 } else { 15099 item = new ProcessChangeItem(); 15100 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15101 } 15102 item.changes = 0; 15103 item.pid = app.pid; 15104 item.uid = app.info.uid; 15105 if (mPendingProcessChanges.size() == 0) { 15106 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15107 "*** Enqueueing dispatch processes changed!"); 15108 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15109 } 15110 mPendingProcessChanges.add(item); 15111 } 15112 item.changes |= changes; 15113 item.importance = importance; 15114 item.foregroundActivities = foregroundActivities; 15115 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15116 + Integer.toHexString(System.identityHashCode(item)) 15117 + " " + app.toShortString() + ": changes=" + item.changes 15118 + " importance=" + item.importance 15119 + " foreground=" + item.foregroundActivities 15120 + " type=" + app.adjType + " source=" + app.adjSource 15121 + " target=" + app.adjTarget); 15122 } 15123 15124 return app.curRawAdj; 15125 } 15126 15127 /** 15128 * Schedule PSS collection of a process. 15129 */ 15130 void requestPssLocked(ProcessRecord proc, int procState) { 15131 if (mPendingPssProcesses.contains(proc)) { 15132 return; 15133 } 15134 if (mPendingPssProcesses.size() == 0) { 15135 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15136 } 15137 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15138 proc.pssProcState = procState; 15139 mPendingPssProcesses.add(proc); 15140 } 15141 15142 /** 15143 * Schedule PSS collection of all processes. 15144 */ 15145 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15146 if (!always) { 15147 if (now < (mLastFullPssTime + 15148 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15149 return; 15150 } 15151 } 15152 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15153 mLastFullPssTime = now; 15154 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15155 mPendingPssProcesses.clear(); 15156 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15157 ProcessRecord app = mLruProcesses.get(i); 15158 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15159 app.pssProcState = app.setProcState; 15160 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15161 mSleeping, now); 15162 mPendingPssProcesses.add(app); 15163 } 15164 } 15165 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15166 } 15167 15168 /** 15169 * Ask a given process to GC right now. 15170 */ 15171 final void performAppGcLocked(ProcessRecord app) { 15172 try { 15173 app.lastRequestedGc = SystemClock.uptimeMillis(); 15174 if (app.thread != null) { 15175 if (app.reportLowMemory) { 15176 app.reportLowMemory = false; 15177 app.thread.scheduleLowMemory(); 15178 } else { 15179 app.thread.processInBackground(); 15180 } 15181 } 15182 } catch (Exception e) { 15183 // whatever. 15184 } 15185 } 15186 15187 /** 15188 * Returns true if things are idle enough to perform GCs. 15189 */ 15190 private final boolean canGcNowLocked() { 15191 boolean processingBroadcasts = false; 15192 for (BroadcastQueue q : mBroadcastQueues) { 15193 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15194 processingBroadcasts = true; 15195 } 15196 } 15197 return !processingBroadcasts 15198 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15199 } 15200 15201 /** 15202 * Perform GCs on all processes that are waiting for it, but only 15203 * if things are idle. 15204 */ 15205 final void performAppGcsLocked() { 15206 final int N = mProcessesToGc.size(); 15207 if (N <= 0) { 15208 return; 15209 } 15210 if (canGcNowLocked()) { 15211 while (mProcessesToGc.size() > 0) { 15212 ProcessRecord proc = mProcessesToGc.remove(0); 15213 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15214 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15215 <= SystemClock.uptimeMillis()) { 15216 // To avoid spamming the system, we will GC processes one 15217 // at a time, waiting a few seconds between each. 15218 performAppGcLocked(proc); 15219 scheduleAppGcsLocked(); 15220 return; 15221 } else { 15222 // It hasn't been long enough since we last GCed this 15223 // process... put it in the list to wait for its time. 15224 addProcessToGcListLocked(proc); 15225 break; 15226 } 15227 } 15228 } 15229 15230 scheduleAppGcsLocked(); 15231 } 15232 } 15233 15234 /** 15235 * If all looks good, perform GCs on all processes waiting for them. 15236 */ 15237 final void performAppGcsIfAppropriateLocked() { 15238 if (canGcNowLocked()) { 15239 performAppGcsLocked(); 15240 return; 15241 } 15242 // Still not idle, wait some more. 15243 scheduleAppGcsLocked(); 15244 } 15245 15246 /** 15247 * Schedule the execution of all pending app GCs. 15248 */ 15249 final void scheduleAppGcsLocked() { 15250 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15251 15252 if (mProcessesToGc.size() > 0) { 15253 // Schedule a GC for the time to the next process. 15254 ProcessRecord proc = mProcessesToGc.get(0); 15255 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15256 15257 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15258 long now = SystemClock.uptimeMillis(); 15259 if (when < (now+GC_TIMEOUT)) { 15260 when = now + GC_TIMEOUT; 15261 } 15262 mHandler.sendMessageAtTime(msg, when); 15263 } 15264 } 15265 15266 /** 15267 * Add a process to the array of processes waiting to be GCed. Keeps the 15268 * list in sorted order by the last GC time. The process can't already be 15269 * on the list. 15270 */ 15271 final void addProcessToGcListLocked(ProcessRecord proc) { 15272 boolean added = false; 15273 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15274 if (mProcessesToGc.get(i).lastRequestedGc < 15275 proc.lastRequestedGc) { 15276 added = true; 15277 mProcessesToGc.add(i+1, proc); 15278 break; 15279 } 15280 } 15281 if (!added) { 15282 mProcessesToGc.add(0, proc); 15283 } 15284 } 15285 15286 /** 15287 * Set up to ask a process to GC itself. This will either do it 15288 * immediately, or put it on the list of processes to gc the next 15289 * time things are idle. 15290 */ 15291 final void scheduleAppGcLocked(ProcessRecord app) { 15292 long now = SystemClock.uptimeMillis(); 15293 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15294 return; 15295 } 15296 if (!mProcessesToGc.contains(app)) { 15297 addProcessToGcListLocked(app); 15298 scheduleAppGcsLocked(); 15299 } 15300 } 15301 15302 final void checkExcessivePowerUsageLocked(boolean doKills) { 15303 updateCpuStatsNow(); 15304 15305 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15306 boolean doWakeKills = doKills; 15307 boolean doCpuKills = doKills; 15308 if (mLastPowerCheckRealtime == 0) { 15309 doWakeKills = false; 15310 } 15311 if (mLastPowerCheckUptime == 0) { 15312 doCpuKills = false; 15313 } 15314 if (stats.isScreenOn()) { 15315 doWakeKills = false; 15316 } 15317 final long curRealtime = SystemClock.elapsedRealtime(); 15318 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15319 final long curUptime = SystemClock.uptimeMillis(); 15320 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15321 mLastPowerCheckRealtime = curRealtime; 15322 mLastPowerCheckUptime = curUptime; 15323 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15324 doWakeKills = false; 15325 } 15326 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15327 doCpuKills = false; 15328 } 15329 int i = mLruProcesses.size(); 15330 while (i > 0) { 15331 i--; 15332 ProcessRecord app = mLruProcesses.get(i); 15333 if (!app.keeping) { 15334 long wtime; 15335 synchronized (stats) { 15336 wtime = stats.getProcessWakeTime(app.info.uid, 15337 app.pid, curRealtime); 15338 } 15339 long wtimeUsed = wtime - app.lastWakeTime; 15340 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15341 if (DEBUG_POWER) { 15342 StringBuilder sb = new StringBuilder(128); 15343 sb.append("Wake for "); 15344 app.toShortString(sb); 15345 sb.append(": over "); 15346 TimeUtils.formatDuration(realtimeSince, sb); 15347 sb.append(" used "); 15348 TimeUtils.formatDuration(wtimeUsed, sb); 15349 sb.append(" ("); 15350 sb.append((wtimeUsed*100)/realtimeSince); 15351 sb.append("%)"); 15352 Slog.i(TAG, sb.toString()); 15353 sb.setLength(0); 15354 sb.append("CPU for "); 15355 app.toShortString(sb); 15356 sb.append(": over "); 15357 TimeUtils.formatDuration(uptimeSince, sb); 15358 sb.append(" used "); 15359 TimeUtils.formatDuration(cputimeUsed, sb); 15360 sb.append(" ("); 15361 sb.append((cputimeUsed*100)/uptimeSince); 15362 sb.append("%)"); 15363 Slog.i(TAG, sb.toString()); 15364 } 15365 // If a process has held a wake lock for more 15366 // than 50% of the time during this period, 15367 // that sounds bad. Kill! 15368 if (doWakeKills && realtimeSince > 0 15369 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15370 synchronized (stats) { 15371 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15372 realtimeSince, wtimeUsed); 15373 } 15374 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15375 + " during " + realtimeSince); 15376 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15377 } else if (doCpuKills && uptimeSince > 0 15378 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15379 synchronized (stats) { 15380 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15381 uptimeSince, cputimeUsed); 15382 } 15383 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15384 + " during " + uptimeSince); 15385 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15386 } else { 15387 app.lastWakeTime = wtime; 15388 app.lastCpuTime = app.curCpuTime; 15389 } 15390 } 15391 } 15392 } 15393 15394 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15395 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15396 boolean success = true; 15397 15398 if (app.curRawAdj != app.setRawAdj) { 15399 if (wasKeeping && !app.keeping) { 15400 // This app is no longer something we want to keep. Note 15401 // its current wake lock time to later know to kill it if 15402 // it is not behaving well. 15403 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15404 synchronized (stats) { 15405 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15406 app.pid, SystemClock.elapsedRealtime()); 15407 } 15408 app.lastCpuTime = app.curCpuTime; 15409 } 15410 15411 app.setRawAdj = app.curRawAdj; 15412 } 15413 15414 if (app.curAdj != app.setAdj) { 15415 ProcessList.setOomAdj(app.pid, app.curAdj); 15416 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15417 TAG, "Set " + app.pid + " " + app.processName + 15418 " adj " + app.curAdj + ": " + app.adjType); 15419 app.setAdj = app.curAdj; 15420 } 15421 15422 if (app.setSchedGroup != app.curSchedGroup) { 15423 app.setSchedGroup = app.curSchedGroup; 15424 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15425 "Setting process group of " + app.processName 15426 + " to " + app.curSchedGroup); 15427 if (app.waitingToKill != null && 15428 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15429 killUnneededProcessLocked(app, app.waitingToKill); 15430 success = false; 15431 } else { 15432 if (true) { 15433 long oldId = Binder.clearCallingIdentity(); 15434 try { 15435 Process.setProcessGroup(app.pid, app.curSchedGroup); 15436 } catch (Exception e) { 15437 Slog.w(TAG, "Failed setting process group of " + app.pid 15438 + " to " + app.curSchedGroup); 15439 e.printStackTrace(); 15440 } finally { 15441 Binder.restoreCallingIdentity(oldId); 15442 } 15443 } else { 15444 if (app.thread != null) { 15445 try { 15446 app.thread.setSchedulingGroup(app.curSchedGroup); 15447 } catch (RemoteException e) { 15448 } 15449 } 15450 } 15451 Process.setSwappiness(app.pid, 15452 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15453 } 15454 } 15455 if (app.repProcState != app.curProcState) { 15456 app.repProcState = app.curProcState; 15457 if (!reportingProcessState && app.thread != null) { 15458 try { 15459 if (false) { 15460 //RuntimeException h = new RuntimeException("here"); 15461 Slog.i(TAG, "Sending new process state " + app.repProcState 15462 + " to " + app /*, h*/); 15463 } 15464 app.thread.setProcessState(app.repProcState); 15465 } catch (RemoteException e) { 15466 } 15467 } 15468 } 15469 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15470 app.setProcState)) { 15471 app.lastStateTime = now; 15472 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15473 mSleeping, now); 15474 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15475 + ProcessList.makeProcStateString(app.setProcState) + " to " 15476 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15477 + (app.nextPssTime-now) + ": " + app); 15478 } else { 15479 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15480 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15481 requestPssLocked(app, app.setProcState); 15482 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15483 mSleeping, now); 15484 } else if (false && DEBUG_PSS) { 15485 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15486 } 15487 } 15488 if (app.setProcState != app.curProcState) { 15489 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15490 "Proc state change of " + app.processName 15491 + " to " + app.curProcState); 15492 app.setProcState = app.curProcState; 15493 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15494 app.notCachedSinceIdle = false; 15495 } 15496 if (!doingAll) { 15497 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15498 } else { 15499 app.procStateChanged = true; 15500 } 15501 } 15502 return success; 15503 } 15504 15505 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15506 if (proc.thread != null && proc.baseProcessTracker != null) { 15507 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15508 } 15509 } 15510 15511 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15512 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15513 if (app.thread == null) { 15514 return false; 15515 } 15516 15517 final boolean wasKeeping = app.keeping; 15518 15519 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15520 15521 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15522 reportingProcessState, now); 15523 } 15524 15525 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15526 boolean oomAdj) { 15527 if (isForeground != proc.foregroundServices) { 15528 proc.foregroundServices = isForeground; 15529 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15530 proc.info.uid); 15531 if (isForeground) { 15532 if (curProcs == null) { 15533 curProcs = new ArrayList<ProcessRecord>(); 15534 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15535 } 15536 if (!curProcs.contains(proc)) { 15537 curProcs.add(proc); 15538 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15539 proc.info.packageName, proc.info.uid); 15540 } 15541 } else { 15542 if (curProcs != null) { 15543 if (curProcs.remove(proc)) { 15544 mBatteryStatsService.noteEvent( 15545 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15546 proc.info.packageName, proc.info.uid); 15547 if (curProcs.size() <= 0) { 15548 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15549 } 15550 } 15551 } 15552 } 15553 if (oomAdj) { 15554 updateOomAdjLocked(); 15555 } 15556 } 15557 } 15558 15559 private final ActivityRecord resumedAppLocked() { 15560 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15561 String pkg; 15562 int uid; 15563 if (act != null) { 15564 pkg = act.packageName; 15565 uid = act.info.applicationInfo.uid; 15566 } else { 15567 pkg = null; 15568 uid = -1; 15569 } 15570 // Has the UID or resumed package name changed? 15571 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15572 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15573 if (mCurResumedPackage != null) { 15574 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15575 mCurResumedPackage, mCurResumedUid); 15576 } 15577 mCurResumedPackage = pkg; 15578 mCurResumedUid = uid; 15579 if (mCurResumedPackage != null) { 15580 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15581 mCurResumedPackage, mCurResumedUid); 15582 } 15583 } 15584 return act; 15585 } 15586 15587 final boolean updateOomAdjLocked(ProcessRecord app) { 15588 return updateOomAdjLocked(app, false); 15589 } 15590 15591 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15592 final ActivityRecord TOP_ACT = resumedAppLocked(); 15593 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15594 final boolean wasCached = app.cached; 15595 15596 mAdjSeq++; 15597 15598 // This is the desired cached adjusment we want to tell it to use. 15599 // If our app is currently cached, we know it, and that is it. Otherwise, 15600 // we don't know it yet, and it needs to now be cached we will then 15601 // need to do a complete oom adj. 15602 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15603 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15604 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15605 SystemClock.uptimeMillis()); 15606 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15607 // Changed to/from cached state, so apps after it in the LRU 15608 // list may also be changed. 15609 updateOomAdjLocked(); 15610 } 15611 return success; 15612 } 15613 15614 final void updateOomAdjLocked() { 15615 final ActivityRecord TOP_ACT = resumedAppLocked(); 15616 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15617 final long now = SystemClock.uptimeMillis(); 15618 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15619 final int N = mLruProcesses.size(); 15620 15621 if (false) { 15622 RuntimeException e = new RuntimeException(); 15623 e.fillInStackTrace(); 15624 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15625 } 15626 15627 mAdjSeq++; 15628 mNewNumServiceProcs = 0; 15629 mNewNumAServiceProcs = 0; 15630 15631 final int emptyProcessLimit; 15632 final int cachedProcessLimit; 15633 if (mProcessLimit <= 0) { 15634 emptyProcessLimit = cachedProcessLimit = 0; 15635 } else if (mProcessLimit == 1) { 15636 emptyProcessLimit = 1; 15637 cachedProcessLimit = 0; 15638 } else { 15639 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15640 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15641 } 15642 15643 // Let's determine how many processes we have running vs. 15644 // how many slots we have for background processes; we may want 15645 // to put multiple processes in a slot of there are enough of 15646 // them. 15647 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15648 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15649 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15650 if (numEmptyProcs > cachedProcessLimit) { 15651 // If there are more empty processes than our limit on cached 15652 // processes, then use the cached process limit for the factor. 15653 // This ensures that the really old empty processes get pushed 15654 // down to the bottom, so if we are running low on memory we will 15655 // have a better chance at keeping around more cached processes 15656 // instead of a gazillion empty processes. 15657 numEmptyProcs = cachedProcessLimit; 15658 } 15659 int emptyFactor = numEmptyProcs/numSlots; 15660 if (emptyFactor < 1) emptyFactor = 1; 15661 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15662 if (cachedFactor < 1) cachedFactor = 1; 15663 int stepCached = 0; 15664 int stepEmpty = 0; 15665 int numCached = 0; 15666 int numEmpty = 0; 15667 int numTrimming = 0; 15668 15669 mNumNonCachedProcs = 0; 15670 mNumCachedHiddenProcs = 0; 15671 15672 // First update the OOM adjustment for each of the 15673 // application processes based on their current state. 15674 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15675 int nextCachedAdj = curCachedAdj+1; 15676 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15677 int nextEmptyAdj = curEmptyAdj+2; 15678 for (int i=N-1; i>=0; i--) { 15679 ProcessRecord app = mLruProcesses.get(i); 15680 if (!app.killedByAm && app.thread != null) { 15681 app.procStateChanged = false; 15682 final boolean wasKeeping = app.keeping; 15683 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15684 15685 // If we haven't yet assigned the final cached adj 15686 // to the process, do that now. 15687 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15688 switch (app.curProcState) { 15689 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15690 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15691 // This process is a cached process holding activities... 15692 // assign it the next cached value for that type, and then 15693 // step that cached level. 15694 app.curRawAdj = curCachedAdj; 15695 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15696 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15697 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15698 + ")"); 15699 if (curCachedAdj != nextCachedAdj) { 15700 stepCached++; 15701 if (stepCached >= cachedFactor) { 15702 stepCached = 0; 15703 curCachedAdj = nextCachedAdj; 15704 nextCachedAdj += 2; 15705 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15706 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15707 } 15708 } 15709 } 15710 break; 15711 default: 15712 // For everything else, assign next empty cached process 15713 // level and bump that up. Note that this means that 15714 // long-running services that have dropped down to the 15715 // cached level will be treated as empty (since their process 15716 // state is still as a service), which is what we want. 15717 app.curRawAdj = curEmptyAdj; 15718 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15719 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15720 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15721 + ")"); 15722 if (curEmptyAdj != nextEmptyAdj) { 15723 stepEmpty++; 15724 if (stepEmpty >= emptyFactor) { 15725 stepEmpty = 0; 15726 curEmptyAdj = nextEmptyAdj; 15727 nextEmptyAdj += 2; 15728 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15729 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15730 } 15731 } 15732 } 15733 break; 15734 } 15735 } 15736 15737 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15738 15739 // Count the number of process types. 15740 switch (app.curProcState) { 15741 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15742 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15743 mNumCachedHiddenProcs++; 15744 numCached++; 15745 if (numCached > cachedProcessLimit) { 15746 killUnneededProcessLocked(app, "cached #" + numCached); 15747 } 15748 break; 15749 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15750 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15751 && app.lastActivityTime < oldTime) { 15752 killUnneededProcessLocked(app, "empty for " 15753 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15754 / 1000) + "s"); 15755 } else { 15756 numEmpty++; 15757 if (numEmpty > emptyProcessLimit) { 15758 killUnneededProcessLocked(app, "empty #" + numEmpty); 15759 } 15760 } 15761 break; 15762 default: 15763 mNumNonCachedProcs++; 15764 break; 15765 } 15766 15767 if (app.isolated && app.services.size() <= 0) { 15768 // If this is an isolated process, and there are no 15769 // services running in it, then the process is no longer 15770 // needed. We agressively kill these because we can by 15771 // definition not re-use the same process again, and it is 15772 // good to avoid having whatever code was running in them 15773 // left sitting around after no longer needed. 15774 killUnneededProcessLocked(app, "isolated not needed"); 15775 } 15776 15777 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15778 && !app.killedByAm) { 15779 numTrimming++; 15780 } 15781 } 15782 } 15783 15784 mNumServiceProcs = mNewNumServiceProcs; 15785 15786 // Now determine the memory trimming level of background processes. 15787 // Unfortunately we need to start at the back of the list to do this 15788 // properly. We only do this if the number of background apps we 15789 // are managing to keep around is less than half the maximum we desire; 15790 // if we are keeping a good number around, we'll let them use whatever 15791 // memory they want. 15792 final int numCachedAndEmpty = numCached + numEmpty; 15793 int memFactor; 15794 if (numCached <= ProcessList.TRIM_CACHED_APPS 15795 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15796 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15797 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15798 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15799 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15800 } else { 15801 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15802 } 15803 } else { 15804 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15805 } 15806 // We always allow the memory level to go up (better). We only allow it to go 15807 // down if we are in a state where that is allowed, *and* the total number of processes 15808 // has gone down since last time. 15809 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15810 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15811 + " last=" + mLastNumProcesses); 15812 if (memFactor > mLastMemoryLevel) { 15813 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15814 memFactor = mLastMemoryLevel; 15815 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15816 } 15817 } 15818 mLastMemoryLevel = memFactor; 15819 mLastNumProcesses = mLruProcesses.size(); 15820 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15821 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15822 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15823 if (mLowRamStartTime == 0) { 15824 mLowRamStartTime = now; 15825 } 15826 int step = 0; 15827 int fgTrimLevel; 15828 switch (memFactor) { 15829 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15830 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15831 break; 15832 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15833 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15834 break; 15835 default: 15836 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15837 break; 15838 } 15839 int factor = numTrimming/3; 15840 int minFactor = 2; 15841 if (mHomeProcess != null) minFactor++; 15842 if (mPreviousProcess != null) minFactor++; 15843 if (factor < minFactor) factor = minFactor; 15844 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15845 for (int i=N-1; i>=0; i--) { 15846 ProcessRecord app = mLruProcesses.get(i); 15847 if (allChanged || app.procStateChanged) { 15848 setProcessTrackerState(app, trackerMemFactor, now); 15849 app.procStateChanged = false; 15850 } 15851 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15852 && !app.killedByAm) { 15853 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15854 try { 15855 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15856 "Trimming memory of " + app.processName 15857 + " to " + curLevel); 15858 app.thread.scheduleTrimMemory(curLevel); 15859 } catch (RemoteException e) { 15860 } 15861 if (false) { 15862 // For now we won't do this; our memory trimming seems 15863 // to be good enough at this point that destroying 15864 // activities causes more harm than good. 15865 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15866 && app != mHomeProcess && app != mPreviousProcess) { 15867 // Need to do this on its own message because the stack may not 15868 // be in a consistent state at this point. 15869 // For these apps we will also finish their activities 15870 // to help them free memory. 15871 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15872 } 15873 } 15874 } 15875 app.trimMemoryLevel = curLevel; 15876 step++; 15877 if (step >= factor) { 15878 step = 0; 15879 switch (curLevel) { 15880 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15881 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15882 break; 15883 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15884 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15885 break; 15886 } 15887 } 15888 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15889 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15890 && app.thread != null) { 15891 try { 15892 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15893 "Trimming memory of heavy-weight " + app.processName 15894 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15895 app.thread.scheduleTrimMemory( 15896 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15897 } catch (RemoteException e) { 15898 } 15899 } 15900 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15901 } else { 15902 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15903 || app.systemNoUi) && app.pendingUiClean) { 15904 // If this application is now in the background and it 15905 // had done UI, then give it the special trim level to 15906 // have it free UI resources. 15907 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15908 if (app.trimMemoryLevel < level && app.thread != null) { 15909 try { 15910 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15911 "Trimming memory of bg-ui " + app.processName 15912 + " to " + level); 15913 app.thread.scheduleTrimMemory(level); 15914 } catch (RemoteException e) { 15915 } 15916 } 15917 app.pendingUiClean = false; 15918 } 15919 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15920 try { 15921 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15922 "Trimming memory of fg " + app.processName 15923 + " to " + fgTrimLevel); 15924 app.thread.scheduleTrimMemory(fgTrimLevel); 15925 } catch (RemoteException e) { 15926 } 15927 } 15928 app.trimMemoryLevel = fgTrimLevel; 15929 } 15930 } 15931 } else { 15932 if (mLowRamStartTime != 0) { 15933 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15934 mLowRamStartTime = 0; 15935 } 15936 for (int i=N-1; i>=0; i--) { 15937 ProcessRecord app = mLruProcesses.get(i); 15938 if (allChanged || app.procStateChanged) { 15939 setProcessTrackerState(app, trackerMemFactor, now); 15940 app.procStateChanged = false; 15941 } 15942 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15943 || app.systemNoUi) && app.pendingUiClean) { 15944 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15945 && app.thread != null) { 15946 try { 15947 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15948 "Trimming memory of ui hidden " + app.processName 15949 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15950 app.thread.scheduleTrimMemory( 15951 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15952 } catch (RemoteException e) { 15953 } 15954 } 15955 app.pendingUiClean = false; 15956 } 15957 app.trimMemoryLevel = 0; 15958 } 15959 } 15960 15961 if (mAlwaysFinishActivities) { 15962 // Need to do this on its own message because the stack may not 15963 // be in a consistent state at this point. 15964 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15965 } 15966 15967 if (allChanged) { 15968 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15969 } 15970 15971 if (mProcessStats.shouldWriteNowLocked(now)) { 15972 mHandler.post(new Runnable() { 15973 @Override public void run() { 15974 synchronized (ActivityManagerService.this) { 15975 mProcessStats.writeStateAsyncLocked(); 15976 } 15977 } 15978 }); 15979 } 15980 15981 if (DEBUG_OOM_ADJ) { 15982 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15983 } 15984 } 15985 15986 final void trimApplications() { 15987 synchronized (this) { 15988 int i; 15989 15990 // First remove any unused application processes whose package 15991 // has been removed. 15992 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15993 final ProcessRecord app = mRemovedProcesses.get(i); 15994 if (app.activities.size() == 0 15995 && app.curReceiver == null && app.services.size() == 0) { 15996 Slog.i( 15997 TAG, "Exiting empty application process " 15998 + app.processName + " (" 15999 + (app.thread != null ? app.thread.asBinder() : null) 16000 + ")\n"); 16001 if (app.pid > 0 && app.pid != MY_PID) { 16002 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16003 app.processName, app.setAdj, "empty"); 16004 app.killedByAm = true; 16005 Process.killProcessQuiet(app.pid); 16006 } else { 16007 try { 16008 app.thread.scheduleExit(); 16009 } catch (Exception e) { 16010 // Ignore exceptions. 16011 } 16012 } 16013 cleanUpApplicationRecordLocked(app, false, true, -1); 16014 mRemovedProcesses.remove(i); 16015 16016 if (app.persistent) { 16017 if (app.persistent) { 16018 addAppLocked(app.info, false); 16019 } 16020 } 16021 } 16022 } 16023 16024 // Now update the oom adj for all processes. 16025 updateOomAdjLocked(); 16026 } 16027 } 16028 16029 /** This method sends the specified signal to each of the persistent apps */ 16030 public void signalPersistentProcesses(int sig) throws RemoteException { 16031 if (sig != Process.SIGNAL_USR1) { 16032 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16033 } 16034 16035 synchronized (this) { 16036 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16037 != PackageManager.PERMISSION_GRANTED) { 16038 throw new SecurityException("Requires permission " 16039 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16040 } 16041 16042 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16043 ProcessRecord r = mLruProcesses.get(i); 16044 if (r.thread != null && r.persistent) { 16045 Process.sendSignal(r.pid, sig); 16046 } 16047 } 16048 } 16049 } 16050 16051 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16052 if (proc == null || proc == mProfileProc) { 16053 proc = mProfileProc; 16054 path = mProfileFile; 16055 profileType = mProfileType; 16056 clearProfilerLocked(); 16057 } 16058 if (proc == null) { 16059 return; 16060 } 16061 try { 16062 proc.thread.profilerControl(false, path, null, profileType); 16063 } catch (RemoteException e) { 16064 throw new IllegalStateException("Process disappeared"); 16065 } 16066 } 16067 16068 private void clearProfilerLocked() { 16069 if (mProfileFd != null) { 16070 try { 16071 mProfileFd.close(); 16072 } catch (IOException e) { 16073 } 16074 } 16075 mProfileApp = null; 16076 mProfileProc = null; 16077 mProfileFile = null; 16078 mProfileType = 0; 16079 mAutoStopProfiler = false; 16080 } 16081 16082 public boolean profileControl(String process, int userId, boolean start, 16083 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16084 16085 try { 16086 synchronized (this) { 16087 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16088 // its own permission. 16089 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16090 != PackageManager.PERMISSION_GRANTED) { 16091 throw new SecurityException("Requires permission " 16092 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16093 } 16094 16095 if (start && fd == null) { 16096 throw new IllegalArgumentException("null fd"); 16097 } 16098 16099 ProcessRecord proc = null; 16100 if (process != null) { 16101 proc = findProcessLocked(process, userId, "profileControl"); 16102 } 16103 16104 if (start && (proc == null || proc.thread == null)) { 16105 throw new IllegalArgumentException("Unknown process: " + process); 16106 } 16107 16108 if (start) { 16109 stopProfilerLocked(null, null, 0); 16110 setProfileApp(proc.info, proc.processName, path, fd, false); 16111 mProfileProc = proc; 16112 mProfileType = profileType; 16113 try { 16114 fd = fd.dup(); 16115 } catch (IOException e) { 16116 fd = null; 16117 } 16118 proc.thread.profilerControl(start, path, fd, profileType); 16119 fd = null; 16120 mProfileFd = null; 16121 } else { 16122 stopProfilerLocked(proc, path, profileType); 16123 if (fd != null) { 16124 try { 16125 fd.close(); 16126 } catch (IOException e) { 16127 } 16128 } 16129 } 16130 16131 return true; 16132 } 16133 } catch (RemoteException e) { 16134 throw new IllegalStateException("Process disappeared"); 16135 } finally { 16136 if (fd != null) { 16137 try { 16138 fd.close(); 16139 } catch (IOException e) { 16140 } 16141 } 16142 } 16143 } 16144 16145 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16146 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16147 userId, true, true, callName, null); 16148 ProcessRecord proc = null; 16149 try { 16150 int pid = Integer.parseInt(process); 16151 synchronized (mPidsSelfLocked) { 16152 proc = mPidsSelfLocked.get(pid); 16153 } 16154 } catch (NumberFormatException e) { 16155 } 16156 16157 if (proc == null) { 16158 ArrayMap<String, SparseArray<ProcessRecord>> all 16159 = mProcessNames.getMap(); 16160 SparseArray<ProcessRecord> procs = all.get(process); 16161 if (procs != null && procs.size() > 0) { 16162 proc = procs.valueAt(0); 16163 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16164 for (int i=1; i<procs.size(); i++) { 16165 ProcessRecord thisProc = procs.valueAt(i); 16166 if (thisProc.userId == userId) { 16167 proc = thisProc; 16168 break; 16169 } 16170 } 16171 } 16172 } 16173 } 16174 16175 return proc; 16176 } 16177 16178 public boolean dumpHeap(String process, int userId, boolean managed, 16179 String path, ParcelFileDescriptor fd) throws RemoteException { 16180 16181 try { 16182 synchronized (this) { 16183 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16184 // its own permission (same as profileControl). 16185 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16186 != PackageManager.PERMISSION_GRANTED) { 16187 throw new SecurityException("Requires permission " 16188 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16189 } 16190 16191 if (fd == null) { 16192 throw new IllegalArgumentException("null fd"); 16193 } 16194 16195 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16196 if (proc == null || proc.thread == null) { 16197 throw new IllegalArgumentException("Unknown process: " + process); 16198 } 16199 16200 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16201 if (!isDebuggable) { 16202 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16203 throw new SecurityException("Process not debuggable: " + proc); 16204 } 16205 } 16206 16207 proc.thread.dumpHeap(managed, path, fd); 16208 fd = null; 16209 return true; 16210 } 16211 } catch (RemoteException e) { 16212 throw new IllegalStateException("Process disappeared"); 16213 } finally { 16214 if (fd != null) { 16215 try { 16216 fd.close(); 16217 } catch (IOException e) { 16218 } 16219 } 16220 } 16221 } 16222 16223 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16224 public void monitor() { 16225 synchronized (this) { } 16226 } 16227 16228 void onCoreSettingsChange(Bundle settings) { 16229 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16230 ProcessRecord processRecord = mLruProcesses.get(i); 16231 try { 16232 if (processRecord.thread != null) { 16233 processRecord.thread.setCoreSettings(settings); 16234 } 16235 } catch (RemoteException re) { 16236 /* ignore */ 16237 } 16238 } 16239 } 16240 16241 // Multi-user methods 16242 16243 /** 16244 * Start user, if its not already running, but don't bring it to foreground. 16245 */ 16246 @Override 16247 public boolean startUserInBackground(final int userId) { 16248 return startUser(userId, /* foreground */ false); 16249 } 16250 16251 /** 16252 * Refreshes the list of users related to the current user when either a 16253 * user switch happens or when a new related user is started in the 16254 * background. 16255 */ 16256 private void updateRelatedUserIdsLocked() { 16257 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16258 int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null 16259 for (int i = 0; i < relatedUserIds.length; i++) { 16260 relatedUserIds[i] = relatedUsers.get(i).id; 16261 } 16262 mRelatedUserIds = relatedUserIds; 16263 } 16264 16265 @Override 16266 public boolean switchUser(final int userId) { 16267 return startUser(userId, /* foregound */ true); 16268 } 16269 16270 private boolean startUser(final int userId, boolean foreground) { 16271 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16272 != PackageManager.PERMISSION_GRANTED) { 16273 String msg = "Permission Denial: switchUser() from pid=" 16274 + Binder.getCallingPid() 16275 + ", uid=" + Binder.getCallingUid() 16276 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16277 Slog.w(TAG, msg); 16278 throw new SecurityException(msg); 16279 } 16280 16281 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16282 16283 final long ident = Binder.clearCallingIdentity(); 16284 try { 16285 synchronized (this) { 16286 final int oldUserId = mCurrentUserId; 16287 if (oldUserId == userId) { 16288 return true; 16289 } 16290 16291 mStackSupervisor.setLockTaskModeLocked(null); 16292 16293 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16294 if (userInfo == null) { 16295 Slog.w(TAG, "No user info for user #" + userId); 16296 return false; 16297 } 16298 16299 if (foreground) { 16300 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16301 R.anim.screen_user_enter); 16302 } 16303 16304 boolean needStart = false; 16305 16306 // If the user we are switching to is not currently started, then 16307 // we need to start it now. 16308 if (mStartedUsers.get(userId) == null) { 16309 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16310 updateStartedUserArrayLocked(); 16311 needStart = true; 16312 } 16313 16314 final Integer userIdInt = Integer.valueOf(userId); 16315 mUserLru.remove(userIdInt); 16316 mUserLru.add(userIdInt); 16317 16318 if (foreground) { 16319 mCurrentUserId = userId; 16320 updateRelatedUserIdsLocked(); 16321 mWindowManager.setCurrentUser(userId, mRelatedUserIds); 16322 // Once the internal notion of the active user has switched, we lock the device 16323 // with the option to show the user switcher on the keyguard. 16324 mWindowManager.lockNow(null); 16325 } else { 16326 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16327 updateRelatedUserIdsLocked(); 16328 mWindowManager.updateRelatedUserIds(mRelatedUserIds); 16329 mUserLru.remove(currentUserIdInt); 16330 mUserLru.add(currentUserIdInt); 16331 } 16332 16333 final UserStartedState uss = mStartedUsers.get(userId); 16334 16335 // Make sure user is in the started state. If it is currently 16336 // stopping, we need to knock that off. 16337 if (uss.mState == UserStartedState.STATE_STOPPING) { 16338 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16339 // so we can just fairly silently bring the user back from 16340 // the almost-dead. 16341 uss.mState = UserStartedState.STATE_RUNNING; 16342 updateStartedUserArrayLocked(); 16343 needStart = true; 16344 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16345 // This means ACTION_SHUTDOWN has been sent, so we will 16346 // need to treat this as a new boot of the user. 16347 uss.mState = UserStartedState.STATE_BOOTING; 16348 updateStartedUserArrayLocked(); 16349 needStart = true; 16350 } 16351 16352 if (foreground) { 16353 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16354 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16355 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16356 oldUserId, userId, uss)); 16357 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16358 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16359 } 16360 16361 if (needStart) { 16362 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16363 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16364 | Intent.FLAG_RECEIVER_FOREGROUND); 16365 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16366 broadcastIntentLocked(null, null, intent, 16367 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16368 false, false, MY_PID, Process.SYSTEM_UID, userId); 16369 } 16370 16371 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16372 if (userId != 0) { 16373 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16374 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16375 broadcastIntentLocked(null, null, intent, null, 16376 new IIntentReceiver.Stub() { 16377 public void performReceive(Intent intent, int resultCode, 16378 String data, Bundle extras, boolean ordered, 16379 boolean sticky, int sendingUser) { 16380 userInitialized(uss, userId); 16381 } 16382 }, 0, null, null, null, AppOpsManager.OP_NONE, 16383 true, false, MY_PID, Process.SYSTEM_UID, 16384 userId); 16385 uss.initializing = true; 16386 } else { 16387 getUserManagerLocked().makeInitialized(userInfo.id); 16388 } 16389 } 16390 16391 if (foreground) { 16392 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16393 if (homeInFront) { 16394 startHomeActivityLocked(userId); 16395 } else { 16396 mStackSupervisor.resumeTopActivitiesLocked(); 16397 } 16398 EventLogTags.writeAmSwitchUser(userId); 16399 getUserManagerLocked().userForeground(userId); 16400 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16401 } 16402 16403 if (needStart) { 16404 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16405 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16406 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16407 broadcastIntentLocked(null, null, intent, 16408 null, new IIntentReceiver.Stub() { 16409 @Override 16410 public void performReceive(Intent intent, int resultCode, String data, 16411 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16412 throws RemoteException { 16413 } 16414 }, 0, null, null, 16415 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16416 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16417 } 16418 } 16419 } finally { 16420 Binder.restoreCallingIdentity(ident); 16421 } 16422 16423 return true; 16424 } 16425 16426 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16427 long ident = Binder.clearCallingIdentity(); 16428 try { 16429 Intent intent; 16430 if (oldUserId >= 0) { 16431 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16432 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16433 | Intent.FLAG_RECEIVER_FOREGROUND); 16434 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16435 broadcastIntentLocked(null, null, intent, 16436 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16437 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16438 } 16439 if (newUserId >= 0) { 16440 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16441 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16442 | Intent.FLAG_RECEIVER_FOREGROUND); 16443 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16444 broadcastIntentLocked(null, null, intent, 16445 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16446 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16447 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16448 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16449 | Intent.FLAG_RECEIVER_FOREGROUND); 16450 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16451 broadcastIntentLocked(null, null, intent, 16452 null, null, 0, null, null, 16453 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16454 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16455 } 16456 } finally { 16457 Binder.restoreCallingIdentity(ident); 16458 } 16459 } 16460 16461 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16462 final int newUserId) { 16463 final int N = mUserSwitchObservers.beginBroadcast(); 16464 if (N > 0) { 16465 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16466 int mCount = 0; 16467 @Override 16468 public void sendResult(Bundle data) throws RemoteException { 16469 synchronized (ActivityManagerService.this) { 16470 if (mCurUserSwitchCallback == this) { 16471 mCount++; 16472 if (mCount == N) { 16473 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16474 } 16475 } 16476 } 16477 } 16478 }; 16479 synchronized (this) { 16480 uss.switching = true; 16481 mCurUserSwitchCallback = callback; 16482 } 16483 for (int i=0; i<N; i++) { 16484 try { 16485 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16486 newUserId, callback); 16487 } catch (RemoteException e) { 16488 } 16489 } 16490 } else { 16491 synchronized (this) { 16492 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16493 } 16494 } 16495 mUserSwitchObservers.finishBroadcast(); 16496 } 16497 16498 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16499 synchronized (this) { 16500 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16501 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16502 } 16503 } 16504 16505 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16506 mCurUserSwitchCallback = null; 16507 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16508 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16509 oldUserId, newUserId, uss)); 16510 } 16511 16512 void userInitialized(UserStartedState uss, int newUserId) { 16513 completeSwitchAndInitalize(uss, newUserId, true, false); 16514 } 16515 16516 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16517 completeSwitchAndInitalize(uss, newUserId, false, true); 16518 } 16519 16520 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16521 boolean clearInitializing, boolean clearSwitching) { 16522 boolean unfrozen = false; 16523 synchronized (this) { 16524 if (clearInitializing) { 16525 uss.initializing = false; 16526 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16527 } 16528 if (clearSwitching) { 16529 uss.switching = false; 16530 } 16531 if (!uss.switching && !uss.initializing) { 16532 mWindowManager.stopFreezingScreen(); 16533 unfrozen = true; 16534 } 16535 } 16536 if (unfrozen) { 16537 final int N = mUserSwitchObservers.beginBroadcast(); 16538 for (int i=0; i<N; i++) { 16539 try { 16540 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16541 } catch (RemoteException e) { 16542 } 16543 } 16544 mUserSwitchObservers.finishBroadcast(); 16545 } 16546 } 16547 16548 void scheduleStartRelatedUsersLocked() { 16549 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16550 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16551 DateUtils.SECOND_IN_MILLIS); 16552 } 16553 } 16554 16555 void startRelatedUsersLocked() { 16556 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16557 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16558 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16559 for (UserInfo relatedUser : relatedUsers) { 16560 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16561 toStart.add(relatedUser); 16562 } 16563 } 16564 final int n = toStart.size(); 16565 int i = 0; 16566 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16567 startUserInBackground(toStart.get(i).id); 16568 } 16569 if (i < n) { 16570 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16571 } 16572 } 16573 16574 void finishUserSwitch(UserStartedState uss) { 16575 synchronized (this) { 16576 if (uss.mState == UserStartedState.STATE_BOOTING 16577 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16578 uss.mState = UserStartedState.STATE_RUNNING; 16579 final int userId = uss.mHandle.getIdentifier(); 16580 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16581 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16582 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16583 broadcastIntentLocked(null, null, intent, 16584 null, null, 0, null, null, 16585 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16586 true, false, MY_PID, Process.SYSTEM_UID, userId); 16587 } 16588 16589 startRelatedUsersLocked(); 16590 16591 int num = mUserLru.size(); 16592 int i = 0; 16593 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16594 Integer oldUserId = mUserLru.get(i); 16595 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16596 if (oldUss == null) { 16597 // Shouldn't happen, but be sane if it does. 16598 mUserLru.remove(i); 16599 num--; 16600 continue; 16601 } 16602 if (oldUss.mState == UserStartedState.STATE_STOPPING 16603 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16604 // This user is already stopping, doesn't count. 16605 num--; 16606 i++; 16607 continue; 16608 } 16609 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16610 // Owner and current can't be stopped, but count as running. 16611 i++; 16612 continue; 16613 } 16614 // This is a user to be stopped. 16615 stopUserLocked(oldUserId, null); 16616 num--; 16617 i++; 16618 } 16619 } 16620 } 16621 16622 @Override 16623 public int stopUser(final int userId, final IStopUserCallback callback) { 16624 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16625 != PackageManager.PERMISSION_GRANTED) { 16626 String msg = "Permission Denial: switchUser() from pid=" 16627 + Binder.getCallingPid() 16628 + ", uid=" + Binder.getCallingUid() 16629 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16630 Slog.w(TAG, msg); 16631 throw new SecurityException(msg); 16632 } 16633 if (userId <= 0) { 16634 throw new IllegalArgumentException("Can't stop primary user " + userId); 16635 } 16636 synchronized (this) { 16637 return stopUserLocked(userId, callback); 16638 } 16639 } 16640 16641 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16642 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16643 if (mCurrentUserId == userId) { 16644 return ActivityManager.USER_OP_IS_CURRENT; 16645 } 16646 16647 final UserStartedState uss = mStartedUsers.get(userId); 16648 if (uss == null) { 16649 // User is not started, nothing to do... but we do need to 16650 // callback if requested. 16651 if (callback != null) { 16652 mHandler.post(new Runnable() { 16653 @Override 16654 public void run() { 16655 try { 16656 callback.userStopped(userId); 16657 } catch (RemoteException e) { 16658 } 16659 } 16660 }); 16661 } 16662 return ActivityManager.USER_OP_SUCCESS; 16663 } 16664 16665 if (callback != null) { 16666 uss.mStopCallbacks.add(callback); 16667 } 16668 16669 if (uss.mState != UserStartedState.STATE_STOPPING 16670 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16671 uss.mState = UserStartedState.STATE_STOPPING; 16672 updateStartedUserArrayLocked(); 16673 16674 long ident = Binder.clearCallingIdentity(); 16675 try { 16676 // We are going to broadcast ACTION_USER_STOPPING and then 16677 // once that is done send a final ACTION_SHUTDOWN and then 16678 // stop the user. 16679 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16680 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16681 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16682 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16683 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16684 // This is the result receiver for the final shutdown broadcast. 16685 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16686 @Override 16687 public void performReceive(Intent intent, int resultCode, String data, 16688 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16689 finishUserStop(uss); 16690 } 16691 }; 16692 // This is the result receiver for the initial stopping broadcast. 16693 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16694 @Override 16695 public void performReceive(Intent intent, int resultCode, String data, 16696 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16697 // On to the next. 16698 synchronized (ActivityManagerService.this) { 16699 if (uss.mState != UserStartedState.STATE_STOPPING) { 16700 // Whoops, we are being started back up. Abort, abort! 16701 return; 16702 } 16703 uss.mState = UserStartedState.STATE_SHUTDOWN; 16704 } 16705 broadcastIntentLocked(null, null, shutdownIntent, 16706 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16707 true, false, MY_PID, Process.SYSTEM_UID, userId); 16708 } 16709 }; 16710 // Kick things off. 16711 broadcastIntentLocked(null, null, stoppingIntent, 16712 null, stoppingReceiver, 0, null, null, 16713 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16714 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16715 } finally { 16716 Binder.restoreCallingIdentity(ident); 16717 } 16718 } 16719 16720 return ActivityManager.USER_OP_SUCCESS; 16721 } 16722 16723 void finishUserStop(UserStartedState uss) { 16724 final int userId = uss.mHandle.getIdentifier(); 16725 boolean stopped; 16726 ArrayList<IStopUserCallback> callbacks; 16727 synchronized (this) { 16728 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16729 if (mStartedUsers.get(userId) != uss) { 16730 stopped = false; 16731 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16732 stopped = false; 16733 } else { 16734 stopped = true; 16735 // User can no longer run. 16736 mStartedUsers.remove(userId); 16737 mUserLru.remove(Integer.valueOf(userId)); 16738 updateStartedUserArrayLocked(); 16739 16740 // Clean up all state and processes associated with the user. 16741 // Kill all the processes for the user. 16742 forceStopUserLocked(userId, "finish user"); 16743 } 16744 } 16745 16746 for (int i=0; i<callbacks.size(); i++) { 16747 try { 16748 if (stopped) callbacks.get(i).userStopped(userId); 16749 else callbacks.get(i).userStopAborted(userId); 16750 } catch (RemoteException e) { 16751 } 16752 } 16753 16754 mStackSupervisor.removeUserLocked(userId); 16755 } 16756 16757 @Override 16758 public UserInfo getCurrentUser() { 16759 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16760 != PackageManager.PERMISSION_GRANTED) && ( 16761 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16762 != PackageManager.PERMISSION_GRANTED)) { 16763 String msg = "Permission Denial: getCurrentUser() from pid=" 16764 + Binder.getCallingPid() 16765 + ", uid=" + Binder.getCallingUid() 16766 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16767 Slog.w(TAG, msg); 16768 throw new SecurityException(msg); 16769 } 16770 synchronized (this) { 16771 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16772 } 16773 } 16774 16775 int getCurrentUserIdLocked() { 16776 return mCurrentUserId; 16777 } 16778 16779 @Override 16780 public boolean isUserRunning(int userId, boolean orStopped) { 16781 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16782 != PackageManager.PERMISSION_GRANTED) { 16783 String msg = "Permission Denial: isUserRunning() from pid=" 16784 + Binder.getCallingPid() 16785 + ", uid=" + Binder.getCallingUid() 16786 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16787 Slog.w(TAG, msg); 16788 throw new SecurityException(msg); 16789 } 16790 synchronized (this) { 16791 return isUserRunningLocked(userId, orStopped); 16792 } 16793 } 16794 16795 boolean isUserRunningLocked(int userId, boolean orStopped) { 16796 UserStartedState state = mStartedUsers.get(userId); 16797 if (state == null) { 16798 return false; 16799 } 16800 if (orStopped) { 16801 return true; 16802 } 16803 return state.mState != UserStartedState.STATE_STOPPING 16804 && state.mState != UserStartedState.STATE_SHUTDOWN; 16805 } 16806 16807 @Override 16808 public int[] getRunningUserIds() { 16809 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16810 != PackageManager.PERMISSION_GRANTED) { 16811 String msg = "Permission Denial: isUserRunning() from pid=" 16812 + Binder.getCallingPid() 16813 + ", uid=" + Binder.getCallingUid() 16814 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16815 Slog.w(TAG, msg); 16816 throw new SecurityException(msg); 16817 } 16818 synchronized (this) { 16819 return mStartedUserArray; 16820 } 16821 } 16822 16823 private void updateStartedUserArrayLocked() { 16824 int num = 0; 16825 for (int i=0; i<mStartedUsers.size(); i++) { 16826 UserStartedState uss = mStartedUsers.valueAt(i); 16827 // This list does not include stopping users. 16828 if (uss.mState != UserStartedState.STATE_STOPPING 16829 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16830 num++; 16831 } 16832 } 16833 mStartedUserArray = new int[num]; 16834 num = 0; 16835 for (int i=0; i<mStartedUsers.size(); i++) { 16836 UserStartedState uss = mStartedUsers.valueAt(i); 16837 if (uss.mState != UserStartedState.STATE_STOPPING 16838 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16839 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16840 num++; 16841 } 16842 } 16843 } 16844 16845 @Override 16846 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16847 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16848 != PackageManager.PERMISSION_GRANTED) { 16849 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16850 + Binder.getCallingPid() 16851 + ", uid=" + Binder.getCallingUid() 16852 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16853 Slog.w(TAG, msg); 16854 throw new SecurityException(msg); 16855 } 16856 16857 mUserSwitchObservers.register(observer); 16858 } 16859 16860 @Override 16861 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16862 mUserSwitchObservers.unregister(observer); 16863 } 16864 16865 private boolean userExists(int userId) { 16866 if (userId == 0) { 16867 return true; 16868 } 16869 UserManagerService ums = getUserManagerLocked(); 16870 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16871 } 16872 16873 int[] getUsersLocked() { 16874 UserManagerService ums = getUserManagerLocked(); 16875 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16876 } 16877 16878 UserManagerService getUserManagerLocked() { 16879 if (mUserManager == null) { 16880 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16881 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16882 } 16883 return mUserManager; 16884 } 16885 16886 private int applyUserId(int uid, int userId) { 16887 return UserHandle.getUid(userId, uid); 16888 } 16889 16890 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16891 if (info == null) return null; 16892 ApplicationInfo newInfo = new ApplicationInfo(info); 16893 newInfo.uid = applyUserId(info.uid, userId); 16894 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16895 + info.packageName; 16896 return newInfo; 16897 } 16898 16899 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16900 if (aInfo == null 16901 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16902 return aInfo; 16903 } 16904 16905 ActivityInfo info = new ActivityInfo(aInfo); 16906 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16907 return info; 16908 } 16909} 16910