ActivityManagerService.java revision f0f94d129b6eb3c48624e915898d86d4f2de59ff
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 || app.treatLikeActivity; 2319 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2320 if (!activityChange && hasActivity) { 2321 // The process has activities, so we are only allowing activity-based adjustments 2322 // to move it. It should be kept in the front of the list with other 2323 // processes that have activities, and we don't want those to change their 2324 // order except due to activity operations. 2325 return; 2326 } 2327 2328 mLruSeq++; 2329 final long now = SystemClock.uptimeMillis(); 2330 app.lastActivityTime = now; 2331 2332 // First a quick reject: if the app is already at the position we will 2333 // put it, then there is nothing to do. 2334 if (hasActivity) { 2335 final int N = mLruProcesses.size(); 2336 if (N > 0 && mLruProcesses.get(N-1) == app) { 2337 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2338 return; 2339 } 2340 } else { 2341 if (mLruProcessServiceStart > 0 2342 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2343 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2344 return; 2345 } 2346 } 2347 2348 int lrui = mLruProcesses.lastIndexOf(app); 2349 2350 if (app.persistent && lrui >= 0) { 2351 // We don't care about the position of persistent processes, as long as 2352 // they are in the list. 2353 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2354 return; 2355 } 2356 2357 /* In progress: compute new position first, so we can avoid doing work 2358 if the process is not actually going to move. Not yet working. 2359 int addIndex; 2360 int nextIndex; 2361 boolean inActivity = false, inService = false; 2362 if (hasActivity) { 2363 // Process has activities, put it at the very tipsy-top. 2364 addIndex = mLruProcesses.size(); 2365 nextIndex = mLruProcessServiceStart; 2366 inActivity = true; 2367 } else if (hasService) { 2368 // Process has services, put it at the top of the service list. 2369 addIndex = mLruProcessActivityStart; 2370 nextIndex = mLruProcessServiceStart; 2371 inActivity = true; 2372 inService = true; 2373 } else { 2374 // Process not otherwise of interest, it goes to the top of the non-service area. 2375 addIndex = mLruProcessServiceStart; 2376 if (client != null) { 2377 int clientIndex = mLruProcesses.lastIndexOf(client); 2378 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2379 + app); 2380 if (clientIndex >= 0 && addIndex > clientIndex) { 2381 addIndex = clientIndex; 2382 } 2383 } 2384 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2385 } 2386 2387 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2388 + mLruProcessActivityStart + "): " + app); 2389 */ 2390 2391 if (lrui >= 0) { 2392 if (lrui < mLruProcessActivityStart) { 2393 mLruProcessActivityStart--; 2394 } 2395 if (lrui < mLruProcessServiceStart) { 2396 mLruProcessServiceStart--; 2397 } 2398 /* 2399 if (addIndex > lrui) { 2400 addIndex--; 2401 } 2402 if (nextIndex > lrui) { 2403 nextIndex--; 2404 } 2405 */ 2406 mLruProcesses.remove(lrui); 2407 } 2408 2409 /* 2410 mLruProcesses.add(addIndex, app); 2411 if (inActivity) { 2412 mLruProcessActivityStart++; 2413 } 2414 if (inService) { 2415 mLruProcessActivityStart++; 2416 } 2417 */ 2418 2419 int nextIndex; 2420 if (hasActivity) { 2421 final int N = mLruProcesses.size(); 2422 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2423 // Process doesn't have activities, but has clients with 2424 // activities... move it up, but one below the top (the top 2425 // should always have a real activity). 2426 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2427 mLruProcesses.add(N-1, app); 2428 // To keep it from spamming the LRU list (by making a bunch of clients), 2429 // we will push down any other entries owned by the app. 2430 final int uid = app.info.uid; 2431 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2432 ProcessRecord subProc = mLruProcesses.get(i); 2433 if (subProc.info.uid == uid) { 2434 // We want to push this one down the list. If the process after 2435 // it is for the same uid, however, don't do so, because we don't 2436 // want them internally to be re-ordered. 2437 if (mLruProcesses.get(i-1).info.uid != uid) { 2438 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2439 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2440 ProcessRecord tmp = mLruProcesses.get(i); 2441 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2442 mLruProcesses.set(i-1, tmp); 2443 i--; 2444 } 2445 } else { 2446 // A gap, we can stop here. 2447 break; 2448 } 2449 } 2450 } else { 2451 // Process has activities, put it at the very tipsy-top. 2452 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2453 mLruProcesses.add(app); 2454 } 2455 nextIndex = mLruProcessServiceStart; 2456 } else if (hasService) { 2457 // Process has services, put it at the top of the service list. 2458 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2459 mLruProcesses.add(mLruProcessActivityStart, app); 2460 nextIndex = mLruProcessServiceStart; 2461 mLruProcessActivityStart++; 2462 } else { 2463 // Process not otherwise of interest, it goes to the top of the non-service area. 2464 int index = mLruProcessServiceStart; 2465 if (client != null) { 2466 // If there is a client, don't allow the process to be moved up higher 2467 // in the list than that client. 2468 int clientIndex = mLruProcesses.lastIndexOf(client); 2469 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2470 + " when updating " + app); 2471 if (clientIndex <= lrui) { 2472 // Don't allow the client index restriction to push it down farther in the 2473 // list than it already is. 2474 clientIndex = lrui; 2475 } 2476 if (clientIndex >= 0 && index > clientIndex) { 2477 index = clientIndex; 2478 } 2479 } 2480 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2481 mLruProcesses.add(index, app); 2482 nextIndex = index-1; 2483 mLruProcessActivityStart++; 2484 mLruProcessServiceStart++; 2485 } 2486 2487 // If the app is currently using a content provider or service, 2488 // bump those processes as well. 2489 for (int j=app.connections.size()-1; j>=0; j--) { 2490 ConnectionRecord cr = app.connections.valueAt(j); 2491 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2492 && cr.binding.service.app != null 2493 && cr.binding.service.app.lruSeq != mLruSeq 2494 && !cr.binding.service.app.persistent) { 2495 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2496 "service connection", cr, app); 2497 } 2498 } 2499 for (int j=app.conProviders.size()-1; j>=0; j--) { 2500 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2501 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2502 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2503 "provider reference", cpr, app); 2504 } 2505 } 2506 } 2507 2508 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2509 if (uid == Process.SYSTEM_UID) { 2510 // The system gets to run in any process. If there are multiple 2511 // processes with the same uid, just pick the first (this 2512 // should never happen). 2513 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2514 if (procs == null) return null; 2515 final int N = procs.size(); 2516 for (int i = 0; i < N; i++) { 2517 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2518 } 2519 } 2520 ProcessRecord proc = mProcessNames.get(processName, uid); 2521 if (false && proc != null && !keepIfLarge 2522 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2523 && proc.lastCachedPss >= 4000) { 2524 // Turn this condition on to cause killing to happen regularly, for testing. 2525 if (proc.baseProcessTracker != null) { 2526 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2527 } 2528 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2529 + "k from cached"); 2530 } else if (proc != null && !keepIfLarge 2531 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2532 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2533 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2534 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2535 if (proc.baseProcessTracker != null) { 2536 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2537 } 2538 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2539 + "k from cached"); 2540 } 2541 } 2542 return proc; 2543 } 2544 2545 void ensurePackageDexOpt(String packageName) { 2546 IPackageManager pm = AppGlobals.getPackageManager(); 2547 try { 2548 if (pm.performDexOpt(packageName)) { 2549 mDidDexOpt = true; 2550 } 2551 } catch (RemoteException e) { 2552 } 2553 } 2554 2555 boolean isNextTransitionForward() { 2556 int transit = mWindowManager.getPendingAppTransition(); 2557 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2558 || transit == AppTransition.TRANSIT_TASK_OPEN 2559 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2560 } 2561 2562 final ProcessRecord startProcessLocked(String processName, 2563 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2564 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2565 boolean isolated, boolean keepIfLarge) { 2566 ProcessRecord app; 2567 if (!isolated) { 2568 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2569 } else { 2570 // If this is an isolated process, it can't re-use an existing process. 2571 app = null; 2572 } 2573 // We don't have to do anything more if: 2574 // (1) There is an existing application record; and 2575 // (2) The caller doesn't think it is dead, OR there is no thread 2576 // object attached to it so we know it couldn't have crashed; and 2577 // (3) There is a pid assigned to it, so it is either starting or 2578 // already running. 2579 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2580 + " app=" + app + " knownToBeDead=" + knownToBeDead 2581 + " thread=" + (app != null ? app.thread : null) 2582 + " pid=" + (app != null ? app.pid : -1)); 2583 if (app != null && app.pid > 0) { 2584 if (!knownToBeDead || app.thread == null) { 2585 // We already have the app running, or are waiting for it to 2586 // come up (we have a pid but not yet its thread), so keep it. 2587 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2588 // If this is a new package in the process, add the package to the list 2589 app.addPackage(info.packageName, mProcessStats); 2590 return app; 2591 } 2592 2593 // An application record is attached to a previous process, 2594 // clean it up now. 2595 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2596 handleAppDiedLocked(app, true, true); 2597 } 2598 2599 String hostingNameStr = hostingName != null 2600 ? hostingName.flattenToShortString() : null; 2601 2602 if (!isolated) { 2603 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2604 // If we are in the background, then check to see if this process 2605 // is bad. If so, we will just silently fail. 2606 if (mBadProcesses.get(info.processName, info.uid) != null) { 2607 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2608 + "/" + info.processName); 2609 return null; 2610 } 2611 } else { 2612 // When the user is explicitly starting a process, then clear its 2613 // crash count so that we won't make it bad until they see at 2614 // least one crash dialog again, and make the process good again 2615 // if it had been bad. 2616 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2617 + "/" + info.processName); 2618 mProcessCrashTimes.remove(info.processName, info.uid); 2619 if (mBadProcesses.get(info.processName, info.uid) != null) { 2620 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2621 UserHandle.getUserId(info.uid), info.uid, 2622 info.processName); 2623 mBadProcesses.remove(info.processName, info.uid); 2624 if (app != null) { 2625 app.bad = false; 2626 } 2627 } 2628 } 2629 } 2630 2631 if (app == null) { 2632 app = newProcessRecordLocked(info, processName, isolated); 2633 if (app == null) { 2634 Slog.w(TAG, "Failed making new process record for " 2635 + processName + "/" + info.uid + " isolated=" + isolated); 2636 return null; 2637 } 2638 mProcessNames.put(processName, app.uid, app); 2639 if (isolated) { 2640 mIsolatedProcesses.put(app.uid, app); 2641 } 2642 } else { 2643 // If this is a new package in the process, add the package to the list 2644 app.addPackage(info.packageName, mProcessStats); 2645 } 2646 2647 // If the system is not ready yet, then hold off on starting this 2648 // process until it is. 2649 if (!mProcessesReady 2650 && !isAllowedWhileBooting(info) 2651 && !allowWhileBooting) { 2652 if (!mProcessesOnHold.contains(app)) { 2653 mProcessesOnHold.add(app); 2654 } 2655 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2656 return app; 2657 } 2658 2659 startProcessLocked(app, hostingType, hostingNameStr); 2660 return (app.pid != 0) ? app : null; 2661 } 2662 2663 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2664 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2665 } 2666 2667 private final void startProcessLocked(ProcessRecord app, 2668 String hostingType, String hostingNameStr) { 2669 if (app.pid > 0 && app.pid != MY_PID) { 2670 synchronized (mPidsSelfLocked) { 2671 mPidsSelfLocked.remove(app.pid); 2672 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2673 } 2674 app.setPid(0); 2675 } 2676 2677 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2678 "startProcessLocked removing on hold: " + app); 2679 mProcessesOnHold.remove(app); 2680 2681 updateCpuStats(); 2682 2683 try { 2684 int uid = app.uid; 2685 2686 int[] gids = null; 2687 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2688 if (!app.isolated) { 2689 int[] permGids = null; 2690 try { 2691 final PackageManager pm = mContext.getPackageManager(); 2692 permGids = pm.getPackageGids(app.info.packageName); 2693 2694 if (Environment.isExternalStorageEmulated()) { 2695 if (pm.checkPermission( 2696 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2697 app.info.packageName) == PERMISSION_GRANTED) { 2698 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2699 } else { 2700 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2701 } 2702 } 2703 } catch (PackageManager.NameNotFoundException e) { 2704 Slog.w(TAG, "Unable to retrieve gids", e); 2705 } 2706 2707 /* 2708 * Add shared application GID so applications can share some 2709 * resources like shared libraries 2710 */ 2711 if (permGids == null) { 2712 gids = new int[1]; 2713 } else { 2714 gids = new int[permGids.length + 1]; 2715 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2716 } 2717 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2718 } 2719 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2720 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2721 && mTopComponent != null 2722 && app.processName.equals(mTopComponent.getPackageName())) { 2723 uid = 0; 2724 } 2725 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2726 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2727 uid = 0; 2728 } 2729 } 2730 int debugFlags = 0; 2731 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2732 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2733 // Also turn on CheckJNI for debuggable apps. It's quite 2734 // awkward to turn on otherwise. 2735 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2736 } 2737 // Run the app in safe mode if its manifest requests so or the 2738 // system is booted in safe mode. 2739 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2740 Zygote.systemInSafeMode == true) { 2741 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2742 } 2743 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2744 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2745 } 2746 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2747 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2748 } 2749 if ("1".equals(SystemProperties.get("debug.assert"))) { 2750 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2751 } 2752 2753 // Start the process. It will either succeed and return a result containing 2754 // the PID of the new process, or else throw a RuntimeException. 2755 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2756 app.processName, uid, uid, gids, debugFlags, mountExternal, 2757 app.info.targetSdkVersion, app.info.seinfo, null); 2758 2759 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2760 synchronized (bs) { 2761 if (bs.isOnBattery()) { 2762 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2763 } 2764 } 2765 2766 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2767 UserHandle.getUserId(uid), startResult.pid, uid, 2768 app.processName, hostingType, 2769 hostingNameStr != null ? hostingNameStr : ""); 2770 2771 if (app.persistent) { 2772 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2773 } 2774 2775 StringBuilder buf = mStringBuilder; 2776 buf.setLength(0); 2777 buf.append("Start proc "); 2778 buf.append(app.processName); 2779 buf.append(" for "); 2780 buf.append(hostingType); 2781 if (hostingNameStr != null) { 2782 buf.append(" "); 2783 buf.append(hostingNameStr); 2784 } 2785 buf.append(": pid="); 2786 buf.append(startResult.pid); 2787 buf.append(" uid="); 2788 buf.append(uid); 2789 buf.append(" gids={"); 2790 if (gids != null) { 2791 for (int gi=0; gi<gids.length; gi++) { 2792 if (gi != 0) buf.append(", "); 2793 buf.append(gids[gi]); 2794 2795 } 2796 } 2797 buf.append("}"); 2798 Slog.i(TAG, buf.toString()); 2799 app.setPid(startResult.pid); 2800 app.usingWrapper = startResult.usingWrapper; 2801 app.removed = false; 2802 synchronized (mPidsSelfLocked) { 2803 this.mPidsSelfLocked.put(startResult.pid, app); 2804 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2805 msg.obj = app; 2806 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2807 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2808 } 2809 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2810 app.processName, app.info.uid); 2811 if (app.isolated) { 2812 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2813 } 2814 } catch (RuntimeException e) { 2815 // XXX do better error recovery. 2816 app.setPid(0); 2817 Slog.e(TAG, "Failure starting process " + app.processName, e); 2818 } 2819 } 2820 2821 void updateUsageStats(ActivityRecord component, boolean resumed) { 2822 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2823 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2824 if (resumed) { 2825 mUsageStatsService.noteResumeComponent(component.realActivity); 2826 synchronized (stats) { 2827 stats.noteActivityResumedLocked(component.app.uid); 2828 } 2829 } else { 2830 mUsageStatsService.notePauseComponent(component.realActivity); 2831 synchronized (stats) { 2832 stats.noteActivityPausedLocked(component.app.uid); 2833 } 2834 } 2835 } 2836 2837 Intent getHomeIntent() { 2838 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2839 intent.setComponent(mTopComponent); 2840 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2841 intent.addCategory(Intent.CATEGORY_HOME); 2842 } 2843 return intent; 2844 } 2845 2846 boolean startHomeActivityLocked(int userId) { 2847 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2848 && mTopAction == null) { 2849 // We are running in factory test mode, but unable to find 2850 // the factory test app, so just sit around displaying the 2851 // error message and don't try to start anything. 2852 return false; 2853 } 2854 Intent intent = getHomeIntent(); 2855 ActivityInfo aInfo = 2856 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2857 if (aInfo != null) { 2858 intent.setComponent(new ComponentName( 2859 aInfo.applicationInfo.packageName, aInfo.name)); 2860 // Don't do this if the home app is currently being 2861 // instrumented. 2862 aInfo = new ActivityInfo(aInfo); 2863 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2864 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2865 aInfo.applicationInfo.uid, true); 2866 if (app == null || app.instrumentationClass == null) { 2867 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2868 mStackSupervisor.startHomeActivity(intent, aInfo); 2869 } 2870 } 2871 2872 return true; 2873 } 2874 2875 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2876 ActivityInfo ai = null; 2877 ComponentName comp = intent.getComponent(); 2878 try { 2879 if (comp != null) { 2880 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2881 } else { 2882 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2883 intent, 2884 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2885 flags, userId); 2886 2887 if (info != null) { 2888 ai = info.activityInfo; 2889 } 2890 } 2891 } catch (RemoteException e) { 2892 // ignore 2893 } 2894 2895 return ai; 2896 } 2897 2898 /** 2899 * Starts the "new version setup screen" if appropriate. 2900 */ 2901 void startSetupActivityLocked() { 2902 // Only do this once per boot. 2903 if (mCheckedForSetup) { 2904 return; 2905 } 2906 2907 // We will show this screen if the current one is a different 2908 // version than the last one shown, and we are not running in 2909 // low-level factory test mode. 2910 final ContentResolver resolver = mContext.getContentResolver(); 2911 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2912 Settings.Global.getInt(resolver, 2913 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2914 mCheckedForSetup = true; 2915 2916 // See if we should be showing the platform update setup UI. 2917 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2918 List<ResolveInfo> ris = mContext.getPackageManager() 2919 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2920 2921 // We don't allow third party apps to replace this. 2922 ResolveInfo ri = null; 2923 for (int i=0; ris != null && i<ris.size(); i++) { 2924 if ((ris.get(i).activityInfo.applicationInfo.flags 2925 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2926 ri = ris.get(i); 2927 break; 2928 } 2929 } 2930 2931 if (ri != null) { 2932 String vers = ri.activityInfo.metaData != null 2933 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2934 : null; 2935 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2936 vers = ri.activityInfo.applicationInfo.metaData.getString( 2937 Intent.METADATA_SETUP_VERSION); 2938 } 2939 String lastVers = Settings.Secure.getString( 2940 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2941 if (vers != null && !vers.equals(lastVers)) { 2942 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2943 intent.setComponent(new ComponentName( 2944 ri.activityInfo.packageName, ri.activityInfo.name)); 2945 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2946 null, null, 0, 0, 0, null, 0, null, false, null, null); 2947 } 2948 } 2949 } 2950 } 2951 2952 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2953 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2954 } 2955 2956 void enforceNotIsolatedCaller(String caller) { 2957 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2958 throw new SecurityException("Isolated process not allowed to call " + caller); 2959 } 2960 } 2961 2962 @Override 2963 public int getFrontActivityScreenCompatMode() { 2964 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2965 synchronized (this) { 2966 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2967 } 2968 } 2969 2970 @Override 2971 public void setFrontActivityScreenCompatMode(int mode) { 2972 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2973 "setFrontActivityScreenCompatMode"); 2974 synchronized (this) { 2975 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2976 } 2977 } 2978 2979 @Override 2980 public int getPackageScreenCompatMode(String packageName) { 2981 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2982 synchronized (this) { 2983 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2984 } 2985 } 2986 2987 @Override 2988 public void setPackageScreenCompatMode(String packageName, int mode) { 2989 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2990 "setPackageScreenCompatMode"); 2991 synchronized (this) { 2992 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2993 } 2994 } 2995 2996 @Override 2997 public boolean getPackageAskScreenCompat(String packageName) { 2998 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2999 synchronized (this) { 3000 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3001 } 3002 } 3003 3004 @Override 3005 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3006 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3007 "setPackageAskScreenCompat"); 3008 synchronized (this) { 3009 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3010 } 3011 } 3012 3013 private void dispatchProcessesChanged() { 3014 int N; 3015 synchronized (this) { 3016 N = mPendingProcessChanges.size(); 3017 if (mActiveProcessChanges.length < N) { 3018 mActiveProcessChanges = new ProcessChangeItem[N]; 3019 } 3020 mPendingProcessChanges.toArray(mActiveProcessChanges); 3021 mAvailProcessChanges.addAll(mPendingProcessChanges); 3022 mPendingProcessChanges.clear(); 3023 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3024 } 3025 3026 int i = mProcessObservers.beginBroadcast(); 3027 while (i > 0) { 3028 i--; 3029 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3030 if (observer != null) { 3031 try { 3032 for (int j=0; j<N; j++) { 3033 ProcessChangeItem item = mActiveProcessChanges[j]; 3034 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3035 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3036 + item.pid + " uid=" + item.uid + ": " 3037 + item.foregroundActivities); 3038 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3039 item.foregroundActivities); 3040 } 3041 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3042 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3043 + item.pid + " uid=" + item.uid + ": " + item.importance); 3044 observer.onImportanceChanged(item.pid, item.uid, 3045 item.importance); 3046 } 3047 } 3048 } catch (RemoteException e) { 3049 } 3050 } 3051 } 3052 mProcessObservers.finishBroadcast(); 3053 } 3054 3055 private void dispatchProcessDied(int pid, int uid) { 3056 int i = mProcessObservers.beginBroadcast(); 3057 while (i > 0) { 3058 i--; 3059 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3060 if (observer != null) { 3061 try { 3062 observer.onProcessDied(pid, uid); 3063 } catch (RemoteException e) { 3064 } 3065 } 3066 } 3067 mProcessObservers.finishBroadcast(); 3068 } 3069 3070 final void doPendingActivityLaunchesLocked(boolean doResume) { 3071 final int N = mPendingActivityLaunches.size(); 3072 if (N <= 0) { 3073 return; 3074 } 3075 for (int i=0; i<N; i++) { 3076 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3077 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3078 doResume && i == (N-1), null); 3079 } 3080 mPendingActivityLaunches.clear(); 3081 } 3082 3083 @Override 3084 public final int startActivity(IApplicationThread caller, String callingPackage, 3085 Intent intent, String resolvedType, IBinder resultTo, 3086 String resultWho, int requestCode, int startFlags, 3087 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3088 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3089 resultWho, requestCode, 3090 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3091 } 3092 3093 @Override 3094 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3095 Intent intent, String resolvedType, IBinder resultTo, 3096 String resultWho, int requestCode, int startFlags, 3097 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3098 enforceNotIsolatedCaller("startActivity"); 3099 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3100 false, true, "startActivity", null); 3101 // TODO: Switch to user app stacks here. 3102 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3103 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3104 null, null, options, userId, null); 3105 } 3106 3107 @Override 3108 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3109 Intent intent, String resolvedType, IBinder resultTo, 3110 String resultWho, int requestCode, int startFlags, String profileFile, 3111 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3112 enforceNotIsolatedCaller("startActivityAndWait"); 3113 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3114 false, true, "startActivityAndWait", null); 3115 WaitResult res = new WaitResult(); 3116 // TODO: Switch to user app stacks here. 3117 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3118 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3119 res, null, options, UserHandle.getCallingUserId(), null); 3120 return res; 3121 } 3122 3123 @Override 3124 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3125 Intent intent, String resolvedType, IBinder resultTo, 3126 String resultWho, int requestCode, int startFlags, Configuration config, 3127 Bundle options, int userId) { 3128 enforceNotIsolatedCaller("startActivityWithConfig"); 3129 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3130 false, true, "startActivityWithConfig", null); 3131 // TODO: Switch to user app stacks here. 3132 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3133 resolvedType, resultTo, resultWho, requestCode, startFlags, 3134 null, null, null, config, options, userId, null); 3135 return ret; 3136 } 3137 3138 @Override 3139 public int startActivityIntentSender(IApplicationThread caller, 3140 IntentSender intent, Intent fillInIntent, String resolvedType, 3141 IBinder resultTo, String resultWho, int requestCode, 3142 int flagsMask, int flagsValues, Bundle options) { 3143 enforceNotIsolatedCaller("startActivityIntentSender"); 3144 // Refuse possible leaked file descriptors 3145 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3146 throw new IllegalArgumentException("File descriptors passed in Intent"); 3147 } 3148 3149 IIntentSender sender = intent.getTarget(); 3150 if (!(sender instanceof PendingIntentRecord)) { 3151 throw new IllegalArgumentException("Bad PendingIntent object"); 3152 } 3153 3154 PendingIntentRecord pir = (PendingIntentRecord)sender; 3155 3156 synchronized (this) { 3157 // If this is coming from the currently resumed activity, it is 3158 // effectively saying that app switches are allowed at this point. 3159 final ActivityStack stack = getFocusedStack(); 3160 if (stack.mResumedActivity != null && 3161 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3162 mAppSwitchesAllowedTime = 0; 3163 } 3164 } 3165 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3166 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3167 return ret; 3168 } 3169 3170 @Override 3171 public boolean startNextMatchingActivity(IBinder callingActivity, 3172 Intent intent, Bundle options) { 3173 // Refuse possible leaked file descriptors 3174 if (intent != null && intent.hasFileDescriptors() == true) { 3175 throw new IllegalArgumentException("File descriptors passed in Intent"); 3176 } 3177 3178 synchronized (this) { 3179 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3180 if (r == null) { 3181 ActivityOptions.abort(options); 3182 return false; 3183 } 3184 if (r.app == null || r.app.thread == null) { 3185 // The caller is not running... d'oh! 3186 ActivityOptions.abort(options); 3187 return false; 3188 } 3189 intent = new Intent(intent); 3190 // The caller is not allowed to change the data. 3191 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3192 // And we are resetting to find the next component... 3193 intent.setComponent(null); 3194 3195 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3196 3197 ActivityInfo aInfo = null; 3198 try { 3199 List<ResolveInfo> resolves = 3200 AppGlobals.getPackageManager().queryIntentActivities( 3201 intent, r.resolvedType, 3202 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3203 UserHandle.getCallingUserId()); 3204 3205 // Look for the original activity in the list... 3206 final int N = resolves != null ? resolves.size() : 0; 3207 for (int i=0; i<N; i++) { 3208 ResolveInfo rInfo = resolves.get(i); 3209 if (rInfo.activityInfo.packageName.equals(r.packageName) 3210 && rInfo.activityInfo.name.equals(r.info.name)) { 3211 // We found the current one... the next matching is 3212 // after it. 3213 i++; 3214 if (i<N) { 3215 aInfo = resolves.get(i).activityInfo; 3216 } 3217 if (debug) { 3218 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3219 + "/" + r.info.name); 3220 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3221 + "/" + aInfo.name); 3222 } 3223 break; 3224 } 3225 } 3226 } catch (RemoteException e) { 3227 } 3228 3229 if (aInfo == null) { 3230 // Nobody who is next! 3231 ActivityOptions.abort(options); 3232 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3233 return false; 3234 } 3235 3236 intent.setComponent(new ComponentName( 3237 aInfo.applicationInfo.packageName, aInfo.name)); 3238 intent.setFlags(intent.getFlags()&~( 3239 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3240 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3241 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3242 Intent.FLAG_ACTIVITY_NEW_TASK)); 3243 3244 // Okay now we need to start the new activity, replacing the 3245 // currently running activity. This is a little tricky because 3246 // we want to start the new one as if the current one is finished, 3247 // but not finish the current one first so that there is no flicker. 3248 // And thus... 3249 final boolean wasFinishing = r.finishing; 3250 r.finishing = true; 3251 3252 // Propagate reply information over to the new activity. 3253 final ActivityRecord resultTo = r.resultTo; 3254 final String resultWho = r.resultWho; 3255 final int requestCode = r.requestCode; 3256 r.resultTo = null; 3257 if (resultTo != null) { 3258 resultTo.removeResultsLocked(r, resultWho, requestCode); 3259 } 3260 3261 final long origId = Binder.clearCallingIdentity(); 3262 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3263 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3264 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3265 options, false, null, null); 3266 Binder.restoreCallingIdentity(origId); 3267 3268 r.finishing = wasFinishing; 3269 if (res != ActivityManager.START_SUCCESS) { 3270 return false; 3271 } 3272 return true; 3273 } 3274 } 3275 3276 final int startActivityInPackage(int uid, String callingPackage, 3277 Intent intent, String resolvedType, IBinder resultTo, 3278 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3279 IActivityContainer container) { 3280 3281 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3282 false, true, "startActivityInPackage", null); 3283 3284 // TODO: Switch to user app stacks here. 3285 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3286 resultTo, resultWho, requestCode, startFlags, 3287 null, null, null, null, options, userId, container); 3288 return ret; 3289 } 3290 3291 @Override 3292 public final int startActivities(IApplicationThread caller, String callingPackage, 3293 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3294 int userId) { 3295 enforceNotIsolatedCaller("startActivities"); 3296 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3297 false, true, "startActivity", null); 3298 // TODO: Switch to user app stacks here. 3299 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3300 resolvedTypes, resultTo, options, userId); 3301 return ret; 3302 } 3303 3304 final int startActivitiesInPackage(int uid, String callingPackage, 3305 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3306 Bundle options, int userId) { 3307 3308 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3309 false, true, "startActivityInPackage", null); 3310 // TODO: Switch to user app stacks here. 3311 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3312 resultTo, options, userId); 3313 return ret; 3314 } 3315 3316 final void addRecentTaskLocked(TaskRecord task) { 3317 int N = mRecentTasks.size(); 3318 // Quick case: check if the top-most recent task is the same. 3319 if (N > 0 && mRecentTasks.get(0) == task) { 3320 return; 3321 } 3322 // Remove any existing entries that are the same kind of task. 3323 final Intent intent = task.intent; 3324 final boolean document = intent != null && intent.isDocument(); 3325 for (int i=0; i<N; i++) { 3326 TaskRecord tr = mRecentTasks.get(i); 3327 if (task != tr) { 3328 if (task.userId != tr.userId) { 3329 continue; 3330 } 3331 final Intent trIntent = tr.intent; 3332 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3333 (intent == null || !intent.filterEquals(trIntent))) { 3334 continue; 3335 } 3336 if (document || trIntent != null && trIntent.isDocument()) { 3337 // Document tasks do not match other tasks. 3338 continue; 3339 } 3340 } 3341 3342 // Either task and tr are the same or, their affinities match or their intents match 3343 // and neither of them is a document. 3344 tr.disposeThumbnail(); 3345 mRecentTasks.remove(i); 3346 i--; 3347 N--; 3348 if (task.intent == null) { 3349 // If the new recent task we are adding is not fully 3350 // specified, then replace it with the existing recent task. 3351 task = tr; 3352 } 3353 } 3354 if (N >= MAX_RECENT_TASKS) { 3355 mRecentTasks.remove(N-1).disposeThumbnail(); 3356 } 3357 mRecentTasks.add(0, task); 3358 } 3359 3360 @Override 3361 public void reportActivityFullyDrawn(IBinder token) { 3362 synchronized (this) { 3363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3364 if (r == null) { 3365 return; 3366 } 3367 r.reportFullyDrawnLocked(); 3368 } 3369 } 3370 3371 @Override 3372 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3373 synchronized (this) { 3374 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3375 if (r == null) { 3376 return; 3377 } 3378 final long origId = Binder.clearCallingIdentity(); 3379 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3380 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3381 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3382 if (config != null) { 3383 r.frozenBeforeDestroy = true; 3384 if (!updateConfigurationLocked(config, r, false, false)) { 3385 mStackSupervisor.resumeTopActivitiesLocked(); 3386 } 3387 } 3388 Binder.restoreCallingIdentity(origId); 3389 } 3390 } 3391 3392 @Override 3393 public int getRequestedOrientation(IBinder token) { 3394 synchronized (this) { 3395 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3396 if (r == null) { 3397 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3398 } 3399 return mWindowManager.getAppOrientation(r.appToken); 3400 } 3401 } 3402 3403 /** 3404 * This is the internal entry point for handling Activity.finish(). 3405 * 3406 * @param token The Binder token referencing the Activity we want to finish. 3407 * @param resultCode Result code, if any, from this Activity. 3408 * @param resultData Result data (Intent), if any, from this Activity. 3409 * 3410 * @return Returns true if the activity successfully finished, or false if it is still running. 3411 */ 3412 @Override 3413 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3414 // Refuse possible leaked file descriptors 3415 if (resultData != null && resultData.hasFileDescriptors() == true) { 3416 throw new IllegalArgumentException("File descriptors passed in Intent"); 3417 } 3418 3419 synchronized(this) { 3420 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3421 if (r == null) { 3422 return true; 3423 } 3424 if (mController != null) { 3425 // Find the first activity that is not finishing. 3426 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3427 if (next != null) { 3428 // ask watcher if this is allowed 3429 boolean resumeOK = true; 3430 try { 3431 resumeOK = mController.activityResuming(next.packageName); 3432 } catch (RemoteException e) { 3433 mController = null; 3434 Watchdog.getInstance().setActivityController(null); 3435 } 3436 3437 if (!resumeOK) { 3438 return false; 3439 } 3440 } 3441 } 3442 final long origId = Binder.clearCallingIdentity(); 3443 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3444 resultData, "app-request", true); 3445 Binder.restoreCallingIdentity(origId); 3446 return res; 3447 } 3448 } 3449 3450 @Override 3451 public final void finishHeavyWeightApp() { 3452 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3453 != PackageManager.PERMISSION_GRANTED) { 3454 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3455 + Binder.getCallingPid() 3456 + ", uid=" + Binder.getCallingUid() 3457 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3458 Slog.w(TAG, msg); 3459 throw new SecurityException(msg); 3460 } 3461 3462 synchronized(this) { 3463 if (mHeavyWeightProcess == null) { 3464 return; 3465 } 3466 3467 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3468 mHeavyWeightProcess.activities); 3469 for (int i=0; i<activities.size(); i++) { 3470 ActivityRecord r = activities.get(i); 3471 if (!r.finishing) { 3472 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3473 null, "finish-heavy", true); 3474 } 3475 } 3476 3477 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3478 mHeavyWeightProcess.userId, 0)); 3479 mHeavyWeightProcess = null; 3480 } 3481 } 3482 3483 @Override 3484 public void crashApplication(int uid, int initialPid, String packageName, 3485 String message) { 3486 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3487 != PackageManager.PERMISSION_GRANTED) { 3488 String msg = "Permission Denial: crashApplication() from pid=" 3489 + Binder.getCallingPid() 3490 + ", uid=" + Binder.getCallingUid() 3491 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3492 Slog.w(TAG, msg); 3493 throw new SecurityException(msg); 3494 } 3495 3496 synchronized(this) { 3497 ProcessRecord proc = null; 3498 3499 // Figure out which process to kill. We don't trust that initialPid 3500 // still has any relation to current pids, so must scan through the 3501 // list. 3502 synchronized (mPidsSelfLocked) { 3503 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3504 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3505 if (p.uid != uid) { 3506 continue; 3507 } 3508 if (p.pid == initialPid) { 3509 proc = p; 3510 break; 3511 } 3512 if (p.pkgList.containsKey(packageName)) { 3513 proc = p; 3514 } 3515 } 3516 } 3517 3518 if (proc == null) { 3519 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3520 + " initialPid=" + initialPid 3521 + " packageName=" + packageName); 3522 return; 3523 } 3524 3525 if (proc.thread != null) { 3526 if (proc.pid == Process.myPid()) { 3527 Log.w(TAG, "crashApplication: trying to crash self!"); 3528 return; 3529 } 3530 long ident = Binder.clearCallingIdentity(); 3531 try { 3532 proc.thread.scheduleCrash(message); 3533 } catch (RemoteException e) { 3534 } 3535 Binder.restoreCallingIdentity(ident); 3536 } 3537 } 3538 } 3539 3540 @Override 3541 public final void finishSubActivity(IBinder token, String resultWho, 3542 int requestCode) { 3543 synchronized(this) { 3544 final long origId = Binder.clearCallingIdentity(); 3545 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3546 if (r != null) { 3547 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3548 } 3549 Binder.restoreCallingIdentity(origId); 3550 } 3551 } 3552 3553 @Override 3554 public boolean finishActivityAffinity(IBinder token) { 3555 synchronized(this) { 3556 final long origId = Binder.clearCallingIdentity(); 3557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3558 boolean res = false; 3559 if (r != null) { 3560 res = r.task.stack.finishActivityAffinityLocked(r); 3561 } 3562 Binder.restoreCallingIdentity(origId); 3563 return res; 3564 } 3565 } 3566 3567 @Override 3568 public boolean willActivityBeVisible(IBinder token) { 3569 synchronized(this) { 3570 ActivityStack stack = ActivityRecord.getStackLocked(token); 3571 if (stack != null) { 3572 return stack.willActivityBeVisibleLocked(token); 3573 } 3574 return false; 3575 } 3576 } 3577 3578 @Override 3579 public void overridePendingTransition(IBinder token, String packageName, 3580 int enterAnim, int exitAnim) { 3581 synchronized(this) { 3582 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3583 if (self == null) { 3584 return; 3585 } 3586 3587 final long origId = Binder.clearCallingIdentity(); 3588 3589 if (self.state == ActivityState.RESUMED 3590 || self.state == ActivityState.PAUSING) { 3591 mWindowManager.overridePendingAppTransition(packageName, 3592 enterAnim, exitAnim, null); 3593 } 3594 3595 Binder.restoreCallingIdentity(origId); 3596 } 3597 } 3598 3599 /** 3600 * Main function for removing an existing process from the activity manager 3601 * as a result of that process going away. Clears out all connections 3602 * to the process. 3603 */ 3604 private final void handleAppDiedLocked(ProcessRecord app, 3605 boolean restarting, boolean allowRestart) { 3606 int pid = app.pid; 3607 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3608 if (!restarting) { 3609 removeLruProcessLocked(app); 3610 if (pid > 0) { 3611 ProcessList.remove(pid); 3612 } 3613 } 3614 3615 if (mProfileProc == app) { 3616 clearProfilerLocked(); 3617 } 3618 3619 // Remove this application's activities from active lists. 3620 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3621 3622 app.activities.clear(); 3623 3624 if (app.instrumentationClass != null) { 3625 Slog.w(TAG, "Crash of app " + app.processName 3626 + " running instrumentation " + app.instrumentationClass); 3627 Bundle info = new Bundle(); 3628 info.putString("shortMsg", "Process crashed."); 3629 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3630 } 3631 3632 if (!restarting) { 3633 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3634 // If there was nothing to resume, and we are not already 3635 // restarting this process, but there is a visible activity that 3636 // is hosted by the process... then make sure all visible 3637 // activities are running, taking care of restarting this 3638 // process. 3639 if (hasVisibleActivities) { 3640 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3641 } 3642 } 3643 } 3644 } 3645 3646 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3647 IBinder threadBinder = thread.asBinder(); 3648 // Find the application record. 3649 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3650 ProcessRecord rec = mLruProcesses.get(i); 3651 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3652 return i; 3653 } 3654 } 3655 return -1; 3656 } 3657 3658 final ProcessRecord getRecordForAppLocked( 3659 IApplicationThread thread) { 3660 if (thread == null) { 3661 return null; 3662 } 3663 3664 int appIndex = getLRURecordIndexForAppLocked(thread); 3665 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3666 } 3667 3668 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3669 // If there are no longer any background processes running, 3670 // and the app that died was not running instrumentation, 3671 // then tell everyone we are now low on memory. 3672 boolean haveBg = false; 3673 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3674 ProcessRecord rec = mLruProcesses.get(i); 3675 if (rec.thread != null 3676 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3677 haveBg = true; 3678 break; 3679 } 3680 } 3681 3682 if (!haveBg) { 3683 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3684 if (doReport) { 3685 long now = SystemClock.uptimeMillis(); 3686 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3687 doReport = false; 3688 } else { 3689 mLastMemUsageReportTime = now; 3690 } 3691 } 3692 final ArrayList<ProcessMemInfo> memInfos 3693 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3694 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3695 long now = SystemClock.uptimeMillis(); 3696 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3697 ProcessRecord rec = mLruProcesses.get(i); 3698 if (rec == dyingProc || rec.thread == null) { 3699 continue; 3700 } 3701 if (doReport) { 3702 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3703 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3704 } 3705 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3706 // The low memory report is overriding any current 3707 // state for a GC request. Make sure to do 3708 // heavy/important/visible/foreground processes first. 3709 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3710 rec.lastRequestedGc = 0; 3711 } else { 3712 rec.lastRequestedGc = rec.lastLowMemory; 3713 } 3714 rec.reportLowMemory = true; 3715 rec.lastLowMemory = now; 3716 mProcessesToGc.remove(rec); 3717 addProcessToGcListLocked(rec); 3718 } 3719 } 3720 if (doReport) { 3721 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3722 mHandler.sendMessage(msg); 3723 } 3724 scheduleAppGcsLocked(); 3725 } 3726 } 3727 3728 final void appDiedLocked(ProcessRecord app, int pid, 3729 IApplicationThread thread) { 3730 3731 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3732 synchronized (stats) { 3733 stats.noteProcessDiedLocked(app.info.uid, pid); 3734 } 3735 3736 // Clean up already done if the process has been re-started. 3737 if (app.pid == pid && app.thread != null && 3738 app.thread.asBinder() == thread.asBinder()) { 3739 boolean doLowMem = app.instrumentationClass == null; 3740 boolean doOomAdj = doLowMem; 3741 if (!app.killedByAm) { 3742 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3743 + ") has died."); 3744 mAllowLowerMemLevel = true; 3745 } else { 3746 // Note that we always want to do oom adj to update our state with the 3747 // new number of procs. 3748 mAllowLowerMemLevel = false; 3749 doLowMem = false; 3750 } 3751 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3752 if (DEBUG_CLEANUP) Slog.v( 3753 TAG, "Dying app: " + app + ", pid: " + pid 3754 + ", thread: " + thread.asBinder()); 3755 handleAppDiedLocked(app, false, true); 3756 3757 if (doOomAdj) { 3758 updateOomAdjLocked(); 3759 } 3760 if (doLowMem) { 3761 doLowMemReportIfNeededLocked(app); 3762 } 3763 } else if (app.pid != pid) { 3764 // A new process has already been started. 3765 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3766 + ") has died and restarted (pid " + app.pid + ")."); 3767 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3768 } else if (DEBUG_PROCESSES) { 3769 Slog.d(TAG, "Received spurious death notification for thread " 3770 + thread.asBinder()); 3771 } 3772 } 3773 3774 /** 3775 * If a stack trace dump file is configured, dump process stack traces. 3776 * @param clearTraces causes the dump file to be erased prior to the new 3777 * traces being written, if true; when false, the new traces will be 3778 * appended to any existing file content. 3779 * @param firstPids of dalvik VM processes to dump stack traces for first 3780 * @param lastPids of dalvik VM processes to dump stack traces for last 3781 * @param nativeProcs optional list of native process names to dump stack crawls 3782 * @return file containing stack traces, or null if no dump file is configured 3783 */ 3784 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3785 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3786 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3787 if (tracesPath == null || tracesPath.length() == 0) { 3788 return null; 3789 } 3790 3791 File tracesFile = new File(tracesPath); 3792 try { 3793 File tracesDir = tracesFile.getParentFile(); 3794 if (!tracesDir.exists()) { 3795 tracesFile.mkdirs(); 3796 if (!SELinux.restorecon(tracesDir)) { 3797 return null; 3798 } 3799 } 3800 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3801 3802 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3803 tracesFile.createNewFile(); 3804 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3805 } catch (IOException e) { 3806 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3807 return null; 3808 } 3809 3810 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3811 return tracesFile; 3812 } 3813 3814 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3815 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3816 // Use a FileObserver to detect when traces finish writing. 3817 // The order of traces is considered important to maintain for legibility. 3818 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3819 @Override 3820 public synchronized void onEvent(int event, String path) { notify(); } 3821 }; 3822 3823 try { 3824 observer.startWatching(); 3825 3826 // First collect all of the stacks of the most important pids. 3827 if (firstPids != null) { 3828 try { 3829 int num = firstPids.size(); 3830 for (int i = 0; i < num; i++) { 3831 synchronized (observer) { 3832 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3833 observer.wait(200); // Wait for write-close, give up after 200msec 3834 } 3835 } 3836 } catch (InterruptedException e) { 3837 Log.wtf(TAG, e); 3838 } 3839 } 3840 3841 // Next collect the stacks of the native pids 3842 if (nativeProcs != null) { 3843 int[] pids = Process.getPidsForCommands(nativeProcs); 3844 if (pids != null) { 3845 for (int pid : pids) { 3846 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3847 } 3848 } 3849 } 3850 3851 // Lastly, measure CPU usage. 3852 if (processCpuTracker != null) { 3853 processCpuTracker.init(); 3854 System.gc(); 3855 processCpuTracker.update(); 3856 try { 3857 synchronized (processCpuTracker) { 3858 processCpuTracker.wait(500); // measure over 1/2 second. 3859 } 3860 } catch (InterruptedException e) { 3861 } 3862 processCpuTracker.update(); 3863 3864 // We'll take the stack crawls of just the top apps using CPU. 3865 final int N = processCpuTracker.countWorkingStats(); 3866 int numProcs = 0; 3867 for (int i=0; i<N && numProcs<5; i++) { 3868 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3869 if (lastPids.indexOfKey(stats.pid) >= 0) { 3870 numProcs++; 3871 try { 3872 synchronized (observer) { 3873 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3874 observer.wait(200); // Wait for write-close, give up after 200msec 3875 } 3876 } catch (InterruptedException e) { 3877 Log.wtf(TAG, e); 3878 } 3879 3880 } 3881 } 3882 } 3883 } finally { 3884 observer.stopWatching(); 3885 } 3886 } 3887 3888 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3889 if (true || IS_USER_BUILD) { 3890 return; 3891 } 3892 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3893 if (tracesPath == null || tracesPath.length() == 0) { 3894 return; 3895 } 3896 3897 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3898 StrictMode.allowThreadDiskWrites(); 3899 try { 3900 final File tracesFile = new File(tracesPath); 3901 final File tracesDir = tracesFile.getParentFile(); 3902 final File tracesTmp = new File(tracesDir, "__tmp__"); 3903 try { 3904 if (!tracesDir.exists()) { 3905 tracesFile.mkdirs(); 3906 if (!SELinux.restorecon(tracesDir.getPath())) { 3907 return; 3908 } 3909 } 3910 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3911 3912 if (tracesFile.exists()) { 3913 tracesTmp.delete(); 3914 tracesFile.renameTo(tracesTmp); 3915 } 3916 StringBuilder sb = new StringBuilder(); 3917 Time tobj = new Time(); 3918 tobj.set(System.currentTimeMillis()); 3919 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3920 sb.append(": "); 3921 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3922 sb.append(" since "); 3923 sb.append(msg); 3924 FileOutputStream fos = new FileOutputStream(tracesFile); 3925 fos.write(sb.toString().getBytes()); 3926 if (app == null) { 3927 fos.write("\n*** No application process!".getBytes()); 3928 } 3929 fos.close(); 3930 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3931 } catch (IOException e) { 3932 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3933 return; 3934 } 3935 3936 if (app != null) { 3937 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3938 firstPids.add(app.pid); 3939 dumpStackTraces(tracesPath, firstPids, null, null, null); 3940 } 3941 3942 File lastTracesFile = null; 3943 File curTracesFile = null; 3944 for (int i=9; i>=0; i--) { 3945 String name = String.format(Locale.US, "slow%02d.txt", i); 3946 curTracesFile = new File(tracesDir, name); 3947 if (curTracesFile.exists()) { 3948 if (lastTracesFile != null) { 3949 curTracesFile.renameTo(lastTracesFile); 3950 } else { 3951 curTracesFile.delete(); 3952 } 3953 } 3954 lastTracesFile = curTracesFile; 3955 } 3956 tracesFile.renameTo(curTracesFile); 3957 if (tracesTmp.exists()) { 3958 tracesTmp.renameTo(tracesFile); 3959 } 3960 } finally { 3961 StrictMode.setThreadPolicy(oldPolicy); 3962 } 3963 } 3964 3965 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3966 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3967 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3968 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3969 3970 if (mController != null) { 3971 try { 3972 // 0 == continue, -1 = kill process immediately 3973 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3974 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3975 } catch (RemoteException e) { 3976 mController = null; 3977 Watchdog.getInstance().setActivityController(null); 3978 } 3979 } 3980 3981 long anrTime = SystemClock.uptimeMillis(); 3982 if (MONITOR_CPU_USAGE) { 3983 updateCpuStatsNow(); 3984 } 3985 3986 synchronized (this) { 3987 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3988 if (mShuttingDown) { 3989 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3990 return; 3991 } else if (app.notResponding) { 3992 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3993 return; 3994 } else if (app.crashing) { 3995 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3996 return; 3997 } 3998 3999 // In case we come through here for the same app before completing 4000 // this one, mark as anring now so we will bail out. 4001 app.notResponding = true; 4002 4003 // Log the ANR to the event log. 4004 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4005 app.processName, app.info.flags, annotation); 4006 4007 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4008 firstPids.add(app.pid); 4009 4010 int parentPid = app.pid; 4011 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4012 if (parentPid != app.pid) firstPids.add(parentPid); 4013 4014 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4015 4016 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4017 ProcessRecord r = mLruProcesses.get(i); 4018 if (r != null && r.thread != null) { 4019 int pid = r.pid; 4020 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4021 if (r.persistent) { 4022 firstPids.add(pid); 4023 } else { 4024 lastPids.put(pid, Boolean.TRUE); 4025 } 4026 } 4027 } 4028 } 4029 } 4030 4031 // Log the ANR to the main log. 4032 StringBuilder info = new StringBuilder(); 4033 info.setLength(0); 4034 info.append("ANR in ").append(app.processName); 4035 if (activity != null && activity.shortComponentName != null) { 4036 info.append(" (").append(activity.shortComponentName).append(")"); 4037 } 4038 info.append("\n"); 4039 info.append("PID: ").append(app.pid).append("\n"); 4040 if (annotation != null) { 4041 info.append("Reason: ").append(annotation).append("\n"); 4042 } 4043 if (parent != null && parent != activity) { 4044 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4045 } 4046 4047 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4048 4049 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4050 NATIVE_STACKS_OF_INTEREST); 4051 4052 String cpuInfo = null; 4053 if (MONITOR_CPU_USAGE) { 4054 updateCpuStatsNow(); 4055 synchronized (mProcessCpuThread) { 4056 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4057 } 4058 info.append(processCpuTracker.printCurrentLoad()); 4059 info.append(cpuInfo); 4060 } 4061 4062 info.append(processCpuTracker.printCurrentState(anrTime)); 4063 4064 Slog.e(TAG, info.toString()); 4065 if (tracesFile == null) { 4066 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4067 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4068 } 4069 4070 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4071 cpuInfo, tracesFile, null); 4072 4073 if (mController != null) { 4074 try { 4075 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4076 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4077 if (res != 0) { 4078 if (res < 0 && app.pid != MY_PID) { 4079 Process.killProcess(app.pid); 4080 } else { 4081 synchronized (this) { 4082 mServices.scheduleServiceTimeoutLocked(app); 4083 } 4084 } 4085 return; 4086 } 4087 } catch (RemoteException e) { 4088 mController = null; 4089 Watchdog.getInstance().setActivityController(null); 4090 } 4091 } 4092 4093 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4094 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4095 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4096 4097 synchronized (this) { 4098 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4099 killUnneededProcessLocked(app, "background ANR"); 4100 return; 4101 } 4102 4103 // Set the app's notResponding state, and look up the errorReportReceiver 4104 makeAppNotRespondingLocked(app, 4105 activity != null ? activity.shortComponentName : null, 4106 annotation != null ? "ANR " + annotation : "ANR", 4107 info.toString()); 4108 4109 // Bring up the infamous App Not Responding dialog 4110 Message msg = Message.obtain(); 4111 HashMap<String, Object> map = new HashMap<String, Object>(); 4112 msg.what = SHOW_NOT_RESPONDING_MSG; 4113 msg.obj = map; 4114 msg.arg1 = aboveSystem ? 1 : 0; 4115 map.put("app", app); 4116 if (activity != null) { 4117 map.put("activity", activity); 4118 } 4119 4120 mHandler.sendMessage(msg); 4121 } 4122 } 4123 4124 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4125 if (!mLaunchWarningShown) { 4126 mLaunchWarningShown = true; 4127 mHandler.post(new Runnable() { 4128 @Override 4129 public void run() { 4130 synchronized (ActivityManagerService.this) { 4131 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4132 d.show(); 4133 mHandler.postDelayed(new Runnable() { 4134 @Override 4135 public void run() { 4136 synchronized (ActivityManagerService.this) { 4137 d.dismiss(); 4138 mLaunchWarningShown = false; 4139 } 4140 } 4141 }, 4000); 4142 } 4143 } 4144 }); 4145 } 4146 } 4147 4148 @Override 4149 public boolean clearApplicationUserData(final String packageName, 4150 final IPackageDataObserver observer, int userId) { 4151 enforceNotIsolatedCaller("clearApplicationUserData"); 4152 int uid = Binder.getCallingUid(); 4153 int pid = Binder.getCallingPid(); 4154 userId = handleIncomingUser(pid, uid, 4155 userId, false, true, "clearApplicationUserData", null); 4156 long callingId = Binder.clearCallingIdentity(); 4157 try { 4158 IPackageManager pm = AppGlobals.getPackageManager(); 4159 int pkgUid = -1; 4160 synchronized(this) { 4161 try { 4162 pkgUid = pm.getPackageUid(packageName, userId); 4163 } catch (RemoteException e) { 4164 } 4165 if (pkgUid == -1) { 4166 Slog.w(TAG, "Invalid packageName: " + packageName); 4167 if (observer != null) { 4168 try { 4169 observer.onRemoveCompleted(packageName, false); 4170 } catch (RemoteException e) { 4171 Slog.i(TAG, "Observer no longer exists."); 4172 } 4173 } 4174 return false; 4175 } 4176 if (uid == pkgUid || checkComponentPermission( 4177 android.Manifest.permission.CLEAR_APP_USER_DATA, 4178 pid, uid, -1, true) 4179 == PackageManager.PERMISSION_GRANTED) { 4180 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4181 } else { 4182 throw new SecurityException("PID " + pid + " does not have permission " 4183 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4184 + " of package " + packageName); 4185 } 4186 } 4187 4188 try { 4189 // Clear application user data 4190 pm.clearApplicationUserData(packageName, observer, userId); 4191 4192 // Remove all permissions granted from/to this package 4193 removeUriPermissionsForPackageLocked(packageName, userId, true); 4194 4195 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4196 Uri.fromParts("package", packageName, null)); 4197 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4198 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4199 null, null, 0, null, null, null, false, false, userId); 4200 } catch (RemoteException e) { 4201 } 4202 } finally { 4203 Binder.restoreCallingIdentity(callingId); 4204 } 4205 return true; 4206 } 4207 4208 @Override 4209 public void killBackgroundProcesses(final String packageName, int userId) { 4210 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4211 != PackageManager.PERMISSION_GRANTED && 4212 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4213 != PackageManager.PERMISSION_GRANTED) { 4214 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4215 + Binder.getCallingPid() 4216 + ", uid=" + Binder.getCallingUid() 4217 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4218 Slog.w(TAG, msg); 4219 throw new SecurityException(msg); 4220 } 4221 4222 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4223 userId, true, true, "killBackgroundProcesses", null); 4224 long callingId = Binder.clearCallingIdentity(); 4225 try { 4226 IPackageManager pm = AppGlobals.getPackageManager(); 4227 synchronized(this) { 4228 int appId = -1; 4229 try { 4230 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4231 } catch (RemoteException e) { 4232 } 4233 if (appId == -1) { 4234 Slog.w(TAG, "Invalid packageName: " + packageName); 4235 return; 4236 } 4237 killPackageProcessesLocked(packageName, appId, userId, 4238 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4239 } 4240 } finally { 4241 Binder.restoreCallingIdentity(callingId); 4242 } 4243 } 4244 4245 @Override 4246 public void killAllBackgroundProcesses() { 4247 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4248 != PackageManager.PERMISSION_GRANTED) { 4249 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4250 + Binder.getCallingPid() 4251 + ", uid=" + Binder.getCallingUid() 4252 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4253 Slog.w(TAG, msg); 4254 throw new SecurityException(msg); 4255 } 4256 4257 long callingId = Binder.clearCallingIdentity(); 4258 try { 4259 synchronized(this) { 4260 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4261 final int NP = mProcessNames.getMap().size(); 4262 for (int ip=0; ip<NP; ip++) { 4263 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4264 final int NA = apps.size(); 4265 for (int ia=0; ia<NA; ia++) { 4266 ProcessRecord app = apps.valueAt(ia); 4267 if (app.persistent) { 4268 // we don't kill persistent processes 4269 continue; 4270 } 4271 if (app.removed) { 4272 procs.add(app); 4273 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4274 app.removed = true; 4275 procs.add(app); 4276 } 4277 } 4278 } 4279 4280 int N = procs.size(); 4281 for (int i=0; i<N; i++) { 4282 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4283 } 4284 mAllowLowerMemLevel = true; 4285 updateOomAdjLocked(); 4286 doLowMemReportIfNeededLocked(null); 4287 } 4288 } finally { 4289 Binder.restoreCallingIdentity(callingId); 4290 } 4291 } 4292 4293 @Override 4294 public void forceStopPackage(final String packageName, int userId) { 4295 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4296 != PackageManager.PERMISSION_GRANTED) { 4297 String msg = "Permission Denial: forceStopPackage() from pid=" 4298 + Binder.getCallingPid() 4299 + ", uid=" + Binder.getCallingUid() 4300 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4301 Slog.w(TAG, msg); 4302 throw new SecurityException(msg); 4303 } 4304 final int callingPid = Binder.getCallingPid(); 4305 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4306 userId, true, true, "forceStopPackage", null); 4307 long callingId = Binder.clearCallingIdentity(); 4308 try { 4309 IPackageManager pm = AppGlobals.getPackageManager(); 4310 synchronized(this) { 4311 int[] users = userId == UserHandle.USER_ALL 4312 ? getUsersLocked() : new int[] { userId }; 4313 for (int user : users) { 4314 int pkgUid = -1; 4315 try { 4316 pkgUid = pm.getPackageUid(packageName, user); 4317 } catch (RemoteException e) { 4318 } 4319 if (pkgUid == -1) { 4320 Slog.w(TAG, "Invalid packageName: " + packageName); 4321 continue; 4322 } 4323 try { 4324 pm.setPackageStoppedState(packageName, true, user); 4325 } catch (RemoteException e) { 4326 } catch (IllegalArgumentException e) { 4327 Slog.w(TAG, "Failed trying to unstop package " 4328 + packageName + ": " + e); 4329 } 4330 if (isUserRunningLocked(user, false)) { 4331 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4332 } 4333 } 4334 } 4335 } finally { 4336 Binder.restoreCallingIdentity(callingId); 4337 } 4338 } 4339 4340 /* 4341 * The pkg name and app id have to be specified. 4342 */ 4343 @Override 4344 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4345 if (pkg == null) { 4346 return; 4347 } 4348 // Make sure the uid is valid. 4349 if (appid < 0) { 4350 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4351 return; 4352 } 4353 int callerUid = Binder.getCallingUid(); 4354 // Only the system server can kill an application 4355 if (callerUid == Process.SYSTEM_UID) { 4356 // Post an aysnc message to kill the application 4357 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4358 msg.arg1 = appid; 4359 msg.arg2 = 0; 4360 Bundle bundle = new Bundle(); 4361 bundle.putString("pkg", pkg); 4362 bundle.putString("reason", reason); 4363 msg.obj = bundle; 4364 mHandler.sendMessage(msg); 4365 } else { 4366 throw new SecurityException(callerUid + " cannot kill pkg: " + 4367 pkg); 4368 } 4369 } 4370 4371 @Override 4372 public void closeSystemDialogs(String reason) { 4373 enforceNotIsolatedCaller("closeSystemDialogs"); 4374 4375 final int pid = Binder.getCallingPid(); 4376 final int uid = Binder.getCallingUid(); 4377 final long origId = Binder.clearCallingIdentity(); 4378 try { 4379 synchronized (this) { 4380 // Only allow this from foreground processes, so that background 4381 // applications can't abuse it to prevent system UI from being shown. 4382 if (uid >= Process.FIRST_APPLICATION_UID) { 4383 ProcessRecord proc; 4384 synchronized (mPidsSelfLocked) { 4385 proc = mPidsSelfLocked.get(pid); 4386 } 4387 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4388 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4389 + " from background process " + proc); 4390 return; 4391 } 4392 } 4393 closeSystemDialogsLocked(reason); 4394 } 4395 } finally { 4396 Binder.restoreCallingIdentity(origId); 4397 } 4398 } 4399 4400 void closeSystemDialogsLocked(String reason) { 4401 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4402 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4403 | Intent.FLAG_RECEIVER_FOREGROUND); 4404 if (reason != null) { 4405 intent.putExtra("reason", reason); 4406 } 4407 mWindowManager.closeSystemDialogs(reason); 4408 4409 mStackSupervisor.closeSystemDialogsLocked(); 4410 4411 broadcastIntentLocked(null, null, intent, null, 4412 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4413 Process.SYSTEM_UID, UserHandle.USER_ALL); 4414 } 4415 4416 @Override 4417 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4418 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4419 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4420 for (int i=pids.length-1; i>=0; i--) { 4421 ProcessRecord proc; 4422 int oomAdj; 4423 synchronized (this) { 4424 synchronized (mPidsSelfLocked) { 4425 proc = mPidsSelfLocked.get(pids[i]); 4426 oomAdj = proc != null ? proc.setAdj : 0; 4427 } 4428 } 4429 infos[i] = new Debug.MemoryInfo(); 4430 Debug.getMemoryInfo(pids[i], infos[i]); 4431 if (proc != null) { 4432 synchronized (this) { 4433 if (proc.thread != null && proc.setAdj == oomAdj) { 4434 // Record this for posterity if the process has been stable. 4435 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4436 infos[i].getTotalUss(), false, proc.pkgList); 4437 } 4438 } 4439 } 4440 } 4441 return infos; 4442 } 4443 4444 @Override 4445 public long[] getProcessPss(int[] pids) { 4446 enforceNotIsolatedCaller("getProcessPss"); 4447 long[] pss = new long[pids.length]; 4448 for (int i=pids.length-1; i>=0; i--) { 4449 ProcessRecord proc; 4450 int oomAdj; 4451 synchronized (this) { 4452 synchronized (mPidsSelfLocked) { 4453 proc = mPidsSelfLocked.get(pids[i]); 4454 oomAdj = proc != null ? proc.setAdj : 0; 4455 } 4456 } 4457 long[] tmpUss = new long[1]; 4458 pss[i] = Debug.getPss(pids[i], tmpUss); 4459 if (proc != null) { 4460 synchronized (this) { 4461 if (proc.thread != null && proc.setAdj == oomAdj) { 4462 // Record this for posterity if the process has been stable. 4463 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4464 } 4465 } 4466 } 4467 } 4468 return pss; 4469 } 4470 4471 @Override 4472 public void killApplicationProcess(String processName, int uid) { 4473 if (processName == null) { 4474 return; 4475 } 4476 4477 int callerUid = Binder.getCallingUid(); 4478 // Only the system server can kill an application 4479 if (callerUid == Process.SYSTEM_UID) { 4480 synchronized (this) { 4481 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4482 if (app != null && app.thread != null) { 4483 try { 4484 app.thread.scheduleSuicide(); 4485 } catch (RemoteException e) { 4486 // If the other end already died, then our work here is done. 4487 } 4488 } else { 4489 Slog.w(TAG, "Process/uid not found attempting kill of " 4490 + processName + " / " + uid); 4491 } 4492 } 4493 } else { 4494 throw new SecurityException(callerUid + " cannot kill app process: " + 4495 processName); 4496 } 4497 } 4498 4499 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4500 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4501 false, true, false, false, UserHandle.getUserId(uid), reason); 4502 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4503 Uri.fromParts("package", packageName, null)); 4504 if (!mProcessesReady) { 4505 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4506 | Intent.FLAG_RECEIVER_FOREGROUND); 4507 } 4508 intent.putExtra(Intent.EXTRA_UID, uid); 4509 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4510 broadcastIntentLocked(null, null, intent, 4511 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4512 false, false, 4513 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4514 } 4515 4516 private void forceStopUserLocked(int userId, String reason) { 4517 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4518 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4519 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4520 | Intent.FLAG_RECEIVER_FOREGROUND); 4521 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4522 broadcastIntentLocked(null, null, intent, 4523 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4524 false, false, 4525 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4526 } 4527 4528 private final boolean killPackageProcessesLocked(String packageName, int appId, 4529 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4530 boolean doit, boolean evenPersistent, String reason) { 4531 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4532 4533 // Remove all processes this package may have touched: all with the 4534 // same UID (except for the system or root user), and all whose name 4535 // matches the package name. 4536 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4537 final int NP = mProcessNames.getMap().size(); 4538 for (int ip=0; ip<NP; ip++) { 4539 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4540 final int NA = apps.size(); 4541 for (int ia=0; ia<NA; ia++) { 4542 ProcessRecord app = apps.valueAt(ia); 4543 if (app.persistent && !evenPersistent) { 4544 // we don't kill persistent processes 4545 continue; 4546 } 4547 if (app.removed) { 4548 if (doit) { 4549 procs.add(app); 4550 } 4551 continue; 4552 } 4553 4554 // Skip process if it doesn't meet our oom adj requirement. 4555 if (app.setAdj < minOomAdj) { 4556 continue; 4557 } 4558 4559 // If no package is specified, we call all processes under the 4560 // give user id. 4561 if (packageName == null) { 4562 if (app.userId != userId) { 4563 continue; 4564 } 4565 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4566 continue; 4567 } 4568 // Package has been specified, we want to hit all processes 4569 // that match it. We need to qualify this by the processes 4570 // that are running under the specified app and user ID. 4571 } else { 4572 if (UserHandle.getAppId(app.uid) != appId) { 4573 continue; 4574 } 4575 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4576 continue; 4577 } 4578 if (!app.pkgList.containsKey(packageName)) { 4579 continue; 4580 } 4581 } 4582 4583 // Process has passed all conditions, kill it! 4584 if (!doit) { 4585 return true; 4586 } 4587 app.removed = true; 4588 procs.add(app); 4589 } 4590 } 4591 4592 int N = procs.size(); 4593 for (int i=0; i<N; i++) { 4594 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4595 } 4596 updateOomAdjLocked(); 4597 return N > 0; 4598 } 4599 4600 private final boolean forceStopPackageLocked(String name, int appId, 4601 boolean callerWillRestart, boolean purgeCache, boolean doit, 4602 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4603 int i; 4604 int N; 4605 4606 if (userId == UserHandle.USER_ALL && name == null) { 4607 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4608 } 4609 4610 if (appId < 0 && name != null) { 4611 try { 4612 appId = UserHandle.getAppId( 4613 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4614 } catch (RemoteException e) { 4615 } 4616 } 4617 4618 if (doit) { 4619 if (name != null) { 4620 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4621 + " user=" + userId + ": " + reason); 4622 } else { 4623 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4624 } 4625 4626 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4627 for (int ip=pmap.size()-1; ip>=0; ip--) { 4628 SparseArray<Long> ba = pmap.valueAt(ip); 4629 for (i=ba.size()-1; i>=0; i--) { 4630 boolean remove = false; 4631 final int entUid = ba.keyAt(i); 4632 if (name != null) { 4633 if (userId == UserHandle.USER_ALL) { 4634 if (UserHandle.getAppId(entUid) == appId) { 4635 remove = true; 4636 } 4637 } else { 4638 if (entUid == UserHandle.getUid(userId, appId)) { 4639 remove = true; 4640 } 4641 } 4642 } else if (UserHandle.getUserId(entUid) == userId) { 4643 remove = true; 4644 } 4645 if (remove) { 4646 ba.removeAt(i); 4647 } 4648 } 4649 if (ba.size() == 0) { 4650 pmap.removeAt(ip); 4651 } 4652 } 4653 } 4654 4655 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4656 -100, callerWillRestart, true, doit, evenPersistent, 4657 name == null ? ("stop user " + userId) : ("stop " + name)); 4658 4659 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4660 if (!doit) { 4661 return true; 4662 } 4663 didSomething = true; 4664 } 4665 4666 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4667 if (!doit) { 4668 return true; 4669 } 4670 didSomething = true; 4671 } 4672 4673 if (name == null) { 4674 // Remove all sticky broadcasts from this user. 4675 mStickyBroadcasts.remove(userId); 4676 } 4677 4678 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4679 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4680 userId, providers)) { 4681 if (!doit) { 4682 return true; 4683 } 4684 didSomething = true; 4685 } 4686 N = providers.size(); 4687 for (i=0; i<N; i++) { 4688 removeDyingProviderLocked(null, providers.get(i), true); 4689 } 4690 4691 // Remove transient permissions granted from/to this package/user 4692 removeUriPermissionsForPackageLocked(name, userId, false); 4693 4694 if (name == null || uninstalling) { 4695 // Remove pending intents. For now we only do this when force 4696 // stopping users, because we have some problems when doing this 4697 // for packages -- app widgets are not currently cleaned up for 4698 // such packages, so they can be left with bad pending intents. 4699 if (mIntentSenderRecords.size() > 0) { 4700 Iterator<WeakReference<PendingIntentRecord>> it 4701 = mIntentSenderRecords.values().iterator(); 4702 while (it.hasNext()) { 4703 WeakReference<PendingIntentRecord> wpir = it.next(); 4704 if (wpir == null) { 4705 it.remove(); 4706 continue; 4707 } 4708 PendingIntentRecord pir = wpir.get(); 4709 if (pir == null) { 4710 it.remove(); 4711 continue; 4712 } 4713 if (name == null) { 4714 // Stopping user, remove all objects for the user. 4715 if (pir.key.userId != userId) { 4716 // Not the same user, skip it. 4717 continue; 4718 } 4719 } else { 4720 if (UserHandle.getAppId(pir.uid) != appId) { 4721 // Different app id, skip it. 4722 continue; 4723 } 4724 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4725 // Different user, skip it. 4726 continue; 4727 } 4728 if (!pir.key.packageName.equals(name)) { 4729 // Different package, skip it. 4730 continue; 4731 } 4732 } 4733 if (!doit) { 4734 return true; 4735 } 4736 didSomething = true; 4737 it.remove(); 4738 pir.canceled = true; 4739 if (pir.key.activity != null) { 4740 pir.key.activity.pendingResults.remove(pir.ref); 4741 } 4742 } 4743 } 4744 } 4745 4746 if (doit) { 4747 if (purgeCache && name != null) { 4748 AttributeCache ac = AttributeCache.instance(); 4749 if (ac != null) { 4750 ac.removePackage(name); 4751 } 4752 } 4753 if (mBooted) { 4754 mStackSupervisor.resumeTopActivitiesLocked(); 4755 mStackSupervisor.scheduleIdleLocked(); 4756 } 4757 } 4758 4759 return didSomething; 4760 } 4761 4762 private final boolean removeProcessLocked(ProcessRecord app, 4763 boolean callerWillRestart, boolean allowRestart, String reason) { 4764 final String name = app.processName; 4765 final int uid = app.uid; 4766 if (DEBUG_PROCESSES) Slog.d( 4767 TAG, "Force removing proc " + app.toShortString() + " (" + name 4768 + "/" + uid + ")"); 4769 4770 mProcessNames.remove(name, uid); 4771 mIsolatedProcesses.remove(app.uid); 4772 if (mHeavyWeightProcess == app) { 4773 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4774 mHeavyWeightProcess.userId, 0)); 4775 mHeavyWeightProcess = null; 4776 } 4777 boolean needRestart = false; 4778 if (app.pid > 0 && app.pid != MY_PID) { 4779 int pid = app.pid; 4780 synchronized (mPidsSelfLocked) { 4781 mPidsSelfLocked.remove(pid); 4782 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4783 } 4784 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4785 app.processName, app.info.uid); 4786 if (app.isolated) { 4787 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4788 } 4789 killUnneededProcessLocked(app, reason); 4790 handleAppDiedLocked(app, true, allowRestart); 4791 removeLruProcessLocked(app); 4792 4793 if (app.persistent && !app.isolated) { 4794 if (!callerWillRestart) { 4795 addAppLocked(app.info, false); 4796 } else { 4797 needRestart = true; 4798 } 4799 } 4800 } else { 4801 mRemovedProcesses.add(app); 4802 } 4803 4804 return needRestart; 4805 } 4806 4807 private final void processStartTimedOutLocked(ProcessRecord app) { 4808 final int pid = app.pid; 4809 boolean gone = false; 4810 synchronized (mPidsSelfLocked) { 4811 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4812 if (knownApp != null && knownApp.thread == null) { 4813 mPidsSelfLocked.remove(pid); 4814 gone = true; 4815 } 4816 } 4817 4818 if (gone) { 4819 Slog.w(TAG, "Process " + app + " failed to attach"); 4820 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4821 pid, app.uid, app.processName); 4822 mProcessNames.remove(app.processName, app.uid); 4823 mIsolatedProcesses.remove(app.uid); 4824 if (mHeavyWeightProcess == app) { 4825 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4826 mHeavyWeightProcess.userId, 0)); 4827 mHeavyWeightProcess = null; 4828 } 4829 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4830 app.processName, app.info.uid); 4831 if (app.isolated) { 4832 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4833 } 4834 // Take care of any launching providers waiting for this process. 4835 checkAppInLaunchingProvidersLocked(app, true); 4836 // Take care of any services that are waiting for the process. 4837 mServices.processStartTimedOutLocked(app); 4838 killUnneededProcessLocked(app, "start timeout"); 4839 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4840 Slog.w(TAG, "Unattached app died before backup, skipping"); 4841 try { 4842 IBackupManager bm = IBackupManager.Stub.asInterface( 4843 ServiceManager.getService(Context.BACKUP_SERVICE)); 4844 bm.agentDisconnected(app.info.packageName); 4845 } catch (RemoteException e) { 4846 // Can't happen; the backup manager is local 4847 } 4848 } 4849 if (isPendingBroadcastProcessLocked(pid)) { 4850 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4851 skipPendingBroadcastLocked(pid); 4852 } 4853 } else { 4854 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4855 } 4856 } 4857 4858 private final boolean attachApplicationLocked(IApplicationThread thread, 4859 int pid) { 4860 4861 // Find the application record that is being attached... either via 4862 // the pid if we are running in multiple processes, or just pull the 4863 // next app record if we are emulating process with anonymous threads. 4864 ProcessRecord app; 4865 if (pid != MY_PID && pid >= 0) { 4866 synchronized (mPidsSelfLocked) { 4867 app = mPidsSelfLocked.get(pid); 4868 } 4869 } else { 4870 app = null; 4871 } 4872 4873 if (app == null) { 4874 Slog.w(TAG, "No pending application record for pid " + pid 4875 + " (IApplicationThread " + thread + "); dropping process"); 4876 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4877 if (pid > 0 && pid != MY_PID) { 4878 Process.killProcessQuiet(pid); 4879 } else { 4880 try { 4881 thread.scheduleExit(); 4882 } catch (Exception e) { 4883 // Ignore exceptions. 4884 } 4885 } 4886 return false; 4887 } 4888 4889 // If this application record is still attached to a previous 4890 // process, clean it up now. 4891 if (app.thread != null) { 4892 handleAppDiedLocked(app, true, true); 4893 } 4894 4895 // Tell the process all about itself. 4896 4897 if (localLOGV) Slog.v( 4898 TAG, "Binding process pid " + pid + " to record " + app); 4899 4900 final String processName = app.processName; 4901 try { 4902 AppDeathRecipient adr = new AppDeathRecipient( 4903 app, pid, thread); 4904 thread.asBinder().linkToDeath(adr, 0); 4905 app.deathRecipient = adr; 4906 } catch (RemoteException e) { 4907 app.resetPackageList(mProcessStats); 4908 startProcessLocked(app, "link fail", processName); 4909 return false; 4910 } 4911 4912 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4913 4914 app.makeActive(thread, mProcessStats); 4915 app.curAdj = app.setAdj = -100; 4916 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4917 app.forcingToForeground = null; 4918 updateProcessForegroundLocked(app, false, false); 4919 app.hasShownUi = false; 4920 app.debugging = false; 4921 app.cached = false; 4922 4923 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4924 4925 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4926 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4927 4928 if (!normalMode) { 4929 Slog.i(TAG, "Launching preboot mode app: " + app); 4930 } 4931 4932 if (localLOGV) Slog.v( 4933 TAG, "New app record " + app 4934 + " thread=" + thread.asBinder() + " pid=" + pid); 4935 try { 4936 int testMode = IApplicationThread.DEBUG_OFF; 4937 if (mDebugApp != null && mDebugApp.equals(processName)) { 4938 testMode = mWaitForDebugger 4939 ? IApplicationThread.DEBUG_WAIT 4940 : IApplicationThread.DEBUG_ON; 4941 app.debugging = true; 4942 if (mDebugTransient) { 4943 mDebugApp = mOrigDebugApp; 4944 mWaitForDebugger = mOrigWaitForDebugger; 4945 } 4946 } 4947 String profileFile = app.instrumentationProfileFile; 4948 ParcelFileDescriptor profileFd = null; 4949 boolean profileAutoStop = false; 4950 if (mProfileApp != null && mProfileApp.equals(processName)) { 4951 mProfileProc = app; 4952 profileFile = mProfileFile; 4953 profileFd = mProfileFd; 4954 profileAutoStop = mAutoStopProfiler; 4955 } 4956 boolean enableOpenGlTrace = false; 4957 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4958 enableOpenGlTrace = true; 4959 mOpenGlTraceApp = null; 4960 } 4961 4962 // If the app is being launched for restore or full backup, set it up specially 4963 boolean isRestrictedBackupMode = false; 4964 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4965 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4966 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4967 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4968 } 4969 4970 ensurePackageDexOpt(app.instrumentationInfo != null 4971 ? app.instrumentationInfo.packageName 4972 : app.info.packageName); 4973 if (app.instrumentationClass != null) { 4974 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4975 } 4976 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4977 + processName + " with config " + mConfiguration); 4978 ApplicationInfo appInfo = app.instrumentationInfo != null 4979 ? app.instrumentationInfo : app.info; 4980 app.compat = compatibilityInfoForPackageLocked(appInfo); 4981 if (profileFd != null) { 4982 profileFd = profileFd.dup(); 4983 } 4984 thread.bindApplication(processName, appInfo, providers, 4985 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4986 app.instrumentationArguments, app.instrumentationWatcher, 4987 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4988 isRestrictedBackupMode || !normalMode, app.persistent, 4989 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4990 mCoreSettingsObserver.getCoreSettingsLocked()); 4991 updateLruProcessLocked(app, false, null); 4992 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4993 } catch (Exception e) { 4994 // todo: Yikes! What should we do? For now we will try to 4995 // start another process, but that could easily get us in 4996 // an infinite loop of restarting processes... 4997 Slog.w(TAG, "Exception thrown during bind!", e); 4998 4999 app.resetPackageList(mProcessStats); 5000 app.unlinkDeathRecipient(); 5001 startProcessLocked(app, "bind fail", processName); 5002 return false; 5003 } 5004 5005 // Remove this record from the list of starting applications. 5006 mPersistentStartingProcesses.remove(app); 5007 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5008 "Attach application locked removing on hold: " + app); 5009 mProcessesOnHold.remove(app); 5010 5011 boolean badApp = false; 5012 boolean didSomething = false; 5013 5014 // See if the top visible activity is waiting to run in this process... 5015 if (normalMode) { 5016 try { 5017 if (mStackSupervisor.attachApplicationLocked(app)) { 5018 didSomething = true; 5019 } 5020 } catch (Exception e) { 5021 badApp = true; 5022 } 5023 } 5024 5025 // Find any services that should be running in this process... 5026 if (!badApp) { 5027 try { 5028 didSomething |= mServices.attachApplicationLocked(app, processName); 5029 } catch (Exception e) { 5030 badApp = true; 5031 } 5032 } 5033 5034 // Check if a next-broadcast receiver is in this process... 5035 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5036 try { 5037 didSomething |= sendPendingBroadcastsLocked(app); 5038 } catch (Exception e) { 5039 // If the app died trying to launch the receiver we declare it 'bad' 5040 badApp = true; 5041 } 5042 } 5043 5044 // Check whether the next backup agent is in this process... 5045 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5046 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5047 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5048 try { 5049 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5050 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5051 mBackupTarget.backupMode); 5052 } catch (Exception e) { 5053 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5054 e.printStackTrace(); 5055 } 5056 } 5057 5058 if (badApp) { 5059 // todo: Also need to kill application to deal with all 5060 // kinds of exceptions. 5061 handleAppDiedLocked(app, false, true); 5062 return false; 5063 } 5064 5065 if (!didSomething) { 5066 updateOomAdjLocked(); 5067 } 5068 5069 return true; 5070 } 5071 5072 @Override 5073 public final void attachApplication(IApplicationThread thread) { 5074 synchronized (this) { 5075 int callingPid = Binder.getCallingPid(); 5076 final long origId = Binder.clearCallingIdentity(); 5077 attachApplicationLocked(thread, callingPid); 5078 Binder.restoreCallingIdentity(origId); 5079 } 5080 } 5081 5082 @Override 5083 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5084 final long origId = Binder.clearCallingIdentity(); 5085 synchronized (this) { 5086 ActivityStack stack = ActivityRecord.getStackLocked(token); 5087 if (stack != null) { 5088 ActivityRecord r = 5089 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5090 if (stopProfiling) { 5091 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5092 try { 5093 mProfileFd.close(); 5094 } catch (IOException e) { 5095 } 5096 clearProfilerLocked(); 5097 } 5098 } 5099 } 5100 } 5101 Binder.restoreCallingIdentity(origId); 5102 } 5103 5104 void enableScreenAfterBoot() { 5105 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5106 SystemClock.uptimeMillis()); 5107 mWindowManager.enableScreenAfterBoot(); 5108 5109 synchronized (this) { 5110 updateEventDispatchingLocked(); 5111 } 5112 } 5113 5114 @Override 5115 public void showBootMessage(final CharSequence msg, final boolean always) { 5116 enforceNotIsolatedCaller("showBootMessage"); 5117 mWindowManager.showBootMessage(msg, always); 5118 } 5119 5120 @Override 5121 public void dismissKeyguardOnNextActivity() { 5122 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5123 final long token = Binder.clearCallingIdentity(); 5124 try { 5125 synchronized (this) { 5126 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5127 if (mLockScreenShown) { 5128 mLockScreenShown = false; 5129 comeOutOfSleepIfNeededLocked(); 5130 } 5131 mStackSupervisor.setDismissKeyguard(true); 5132 } 5133 } finally { 5134 Binder.restoreCallingIdentity(token); 5135 } 5136 } 5137 5138 final void finishBooting() { 5139 IntentFilter pkgFilter = new IntentFilter(); 5140 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5141 pkgFilter.addDataScheme("package"); 5142 mContext.registerReceiver(new BroadcastReceiver() { 5143 @Override 5144 public void onReceive(Context context, Intent intent) { 5145 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5146 if (pkgs != null) { 5147 for (String pkg : pkgs) { 5148 synchronized (ActivityManagerService.this) { 5149 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5150 "finished booting")) { 5151 setResultCode(Activity.RESULT_OK); 5152 return; 5153 } 5154 } 5155 } 5156 } 5157 } 5158 }, pkgFilter); 5159 5160 synchronized (this) { 5161 // Ensure that any processes we had put on hold are now started 5162 // up. 5163 final int NP = mProcessesOnHold.size(); 5164 if (NP > 0) { 5165 ArrayList<ProcessRecord> procs = 5166 new ArrayList<ProcessRecord>(mProcessesOnHold); 5167 for (int ip=0; ip<NP; ip++) { 5168 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5169 + procs.get(ip)); 5170 startProcessLocked(procs.get(ip), "on-hold", null); 5171 } 5172 } 5173 5174 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5175 // Start looking for apps that are abusing wake locks. 5176 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5177 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5178 // Tell anyone interested that we are done booting! 5179 SystemProperties.set("sys.boot_completed", "1"); 5180 SystemProperties.set("dev.bootcomplete", "1"); 5181 for (int i=0; i<mStartedUsers.size(); i++) { 5182 UserStartedState uss = mStartedUsers.valueAt(i); 5183 if (uss.mState == UserStartedState.STATE_BOOTING) { 5184 uss.mState = UserStartedState.STATE_RUNNING; 5185 final int userId = mStartedUsers.keyAt(i); 5186 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5187 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5188 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5189 broadcastIntentLocked(null, null, intent, null, 5190 new IIntentReceiver.Stub() { 5191 @Override 5192 public void performReceive(Intent intent, int resultCode, 5193 String data, Bundle extras, boolean ordered, 5194 boolean sticky, int sendingUser) { 5195 synchronized (ActivityManagerService.this) { 5196 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5197 true, false); 5198 } 5199 } 5200 }, 5201 0, null, null, 5202 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5203 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5204 userId); 5205 } 5206 } 5207 scheduleStartRelatedUsersLocked(); 5208 } 5209 } 5210 } 5211 5212 final void ensureBootCompleted() { 5213 boolean booting; 5214 boolean enableScreen; 5215 synchronized (this) { 5216 booting = mBooting; 5217 mBooting = false; 5218 enableScreen = !mBooted; 5219 mBooted = true; 5220 } 5221 5222 if (booting) { 5223 finishBooting(); 5224 } 5225 5226 if (enableScreen) { 5227 enableScreenAfterBoot(); 5228 } 5229 } 5230 5231 @Override 5232 public final void activityResumed(IBinder token) { 5233 final long origId = Binder.clearCallingIdentity(); 5234 synchronized(this) { 5235 ActivityStack stack = ActivityRecord.getStackLocked(token); 5236 if (stack != null) { 5237 ActivityRecord.activityResumedLocked(token); 5238 } 5239 } 5240 Binder.restoreCallingIdentity(origId); 5241 } 5242 5243 @Override 5244 public final void activityPaused(IBinder token) { 5245 final long origId = Binder.clearCallingIdentity(); 5246 synchronized(this) { 5247 ActivityStack stack = ActivityRecord.getStackLocked(token); 5248 if (stack != null) { 5249 stack.activityPausedLocked(token, false); 5250 } 5251 } 5252 Binder.restoreCallingIdentity(origId); 5253 } 5254 5255 @Override 5256 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5257 CharSequence description) { 5258 if (localLOGV) Slog.v( 5259 TAG, "Activity stopped: token=" + token); 5260 5261 // Refuse possible leaked file descriptors 5262 if (icicle != null && icicle.hasFileDescriptors()) { 5263 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5264 } 5265 5266 ActivityRecord r = null; 5267 5268 final long origId = Binder.clearCallingIdentity(); 5269 5270 synchronized (this) { 5271 r = ActivityRecord.isInStackLocked(token); 5272 if (r != null) { 5273 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5274 } 5275 } 5276 5277 if (r != null) { 5278 sendPendingThumbnail(r, null, null, null, false); 5279 } 5280 5281 trimApplications(); 5282 5283 Binder.restoreCallingIdentity(origId); 5284 } 5285 5286 @Override 5287 public final void activityDestroyed(IBinder token) { 5288 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5289 synchronized (this) { 5290 ActivityStack stack = ActivityRecord.getStackLocked(token); 5291 if (stack != null) { 5292 stack.activityDestroyedLocked(token); 5293 } 5294 } 5295 } 5296 5297 @Override 5298 public String getCallingPackage(IBinder token) { 5299 synchronized (this) { 5300 ActivityRecord r = getCallingRecordLocked(token); 5301 return r != null ? r.info.packageName : null; 5302 } 5303 } 5304 5305 @Override 5306 public ComponentName getCallingActivity(IBinder token) { 5307 synchronized (this) { 5308 ActivityRecord r = getCallingRecordLocked(token); 5309 return r != null ? r.intent.getComponent() : null; 5310 } 5311 } 5312 5313 private ActivityRecord getCallingRecordLocked(IBinder token) { 5314 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5315 if (r == null) { 5316 return null; 5317 } 5318 return r.resultTo; 5319 } 5320 5321 @Override 5322 public ComponentName getActivityClassForToken(IBinder token) { 5323 synchronized(this) { 5324 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5325 if (r == null) { 5326 return null; 5327 } 5328 return r.intent.getComponent(); 5329 } 5330 } 5331 5332 @Override 5333 public String getPackageForToken(IBinder token) { 5334 synchronized(this) { 5335 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5336 if (r == null) { 5337 return null; 5338 } 5339 return r.packageName; 5340 } 5341 } 5342 5343 @Override 5344 public IIntentSender getIntentSender(int type, 5345 String packageName, IBinder token, String resultWho, 5346 int requestCode, Intent[] intents, String[] resolvedTypes, 5347 int flags, Bundle options, int userId) { 5348 enforceNotIsolatedCaller("getIntentSender"); 5349 // Refuse possible leaked file descriptors 5350 if (intents != null) { 5351 if (intents.length < 1) { 5352 throw new IllegalArgumentException("Intents array length must be >= 1"); 5353 } 5354 for (int i=0; i<intents.length; i++) { 5355 Intent intent = intents[i]; 5356 if (intent != null) { 5357 if (intent.hasFileDescriptors()) { 5358 throw new IllegalArgumentException("File descriptors passed in Intent"); 5359 } 5360 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5361 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5362 throw new IllegalArgumentException( 5363 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5364 } 5365 intents[i] = new Intent(intent); 5366 } 5367 } 5368 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5369 throw new IllegalArgumentException( 5370 "Intent array length does not match resolvedTypes length"); 5371 } 5372 } 5373 if (options != null) { 5374 if (options.hasFileDescriptors()) { 5375 throw new IllegalArgumentException("File descriptors passed in options"); 5376 } 5377 } 5378 5379 synchronized(this) { 5380 int callingUid = Binder.getCallingUid(); 5381 int origUserId = userId; 5382 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5383 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5384 "getIntentSender", null); 5385 if (origUserId == UserHandle.USER_CURRENT) { 5386 // We don't want to evaluate this until the pending intent is 5387 // actually executed. However, we do want to always do the 5388 // security checking for it above. 5389 userId = UserHandle.USER_CURRENT; 5390 } 5391 try { 5392 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5393 int uid = AppGlobals.getPackageManager() 5394 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5395 if (!UserHandle.isSameApp(callingUid, uid)) { 5396 String msg = "Permission Denial: getIntentSender() from pid=" 5397 + Binder.getCallingPid() 5398 + ", uid=" + Binder.getCallingUid() 5399 + ", (need uid=" + uid + ")" 5400 + " is not allowed to send as package " + packageName; 5401 Slog.w(TAG, msg); 5402 throw new SecurityException(msg); 5403 } 5404 } 5405 5406 return getIntentSenderLocked(type, packageName, callingUid, userId, 5407 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5408 5409 } catch (RemoteException e) { 5410 throw new SecurityException(e); 5411 } 5412 } 5413 } 5414 5415 IIntentSender getIntentSenderLocked(int type, String packageName, 5416 int callingUid, int userId, IBinder token, String resultWho, 5417 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5418 Bundle options) { 5419 if (DEBUG_MU) 5420 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5421 ActivityRecord activity = null; 5422 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5423 activity = ActivityRecord.isInStackLocked(token); 5424 if (activity == null) { 5425 return null; 5426 } 5427 if (activity.finishing) { 5428 return null; 5429 } 5430 } 5431 5432 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5433 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5434 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5435 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5436 |PendingIntent.FLAG_UPDATE_CURRENT); 5437 5438 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5439 type, packageName, activity, resultWho, 5440 requestCode, intents, resolvedTypes, flags, options, userId); 5441 WeakReference<PendingIntentRecord> ref; 5442 ref = mIntentSenderRecords.get(key); 5443 PendingIntentRecord rec = ref != null ? ref.get() : null; 5444 if (rec != null) { 5445 if (!cancelCurrent) { 5446 if (updateCurrent) { 5447 if (rec.key.requestIntent != null) { 5448 rec.key.requestIntent.replaceExtras(intents != null ? 5449 intents[intents.length - 1] : null); 5450 } 5451 if (intents != null) { 5452 intents[intents.length-1] = rec.key.requestIntent; 5453 rec.key.allIntents = intents; 5454 rec.key.allResolvedTypes = resolvedTypes; 5455 } else { 5456 rec.key.allIntents = null; 5457 rec.key.allResolvedTypes = null; 5458 } 5459 } 5460 return rec; 5461 } 5462 rec.canceled = true; 5463 mIntentSenderRecords.remove(key); 5464 } 5465 if (noCreate) { 5466 return rec; 5467 } 5468 rec = new PendingIntentRecord(this, key, callingUid); 5469 mIntentSenderRecords.put(key, rec.ref); 5470 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5471 if (activity.pendingResults == null) { 5472 activity.pendingResults 5473 = new HashSet<WeakReference<PendingIntentRecord>>(); 5474 } 5475 activity.pendingResults.add(rec.ref); 5476 } 5477 return rec; 5478 } 5479 5480 @Override 5481 public void cancelIntentSender(IIntentSender sender) { 5482 if (!(sender instanceof PendingIntentRecord)) { 5483 return; 5484 } 5485 synchronized(this) { 5486 PendingIntentRecord rec = (PendingIntentRecord)sender; 5487 try { 5488 int uid = AppGlobals.getPackageManager() 5489 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5490 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5491 String msg = "Permission Denial: cancelIntentSender() from pid=" 5492 + Binder.getCallingPid() 5493 + ", uid=" + Binder.getCallingUid() 5494 + " is not allowed to cancel packges " 5495 + rec.key.packageName; 5496 Slog.w(TAG, msg); 5497 throw new SecurityException(msg); 5498 } 5499 } catch (RemoteException e) { 5500 throw new SecurityException(e); 5501 } 5502 cancelIntentSenderLocked(rec, true); 5503 } 5504 } 5505 5506 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5507 rec.canceled = true; 5508 mIntentSenderRecords.remove(rec.key); 5509 if (cleanActivity && rec.key.activity != null) { 5510 rec.key.activity.pendingResults.remove(rec.ref); 5511 } 5512 } 5513 5514 @Override 5515 public String getPackageForIntentSender(IIntentSender pendingResult) { 5516 if (!(pendingResult instanceof PendingIntentRecord)) { 5517 return null; 5518 } 5519 try { 5520 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5521 return res.key.packageName; 5522 } catch (ClassCastException e) { 5523 } 5524 return null; 5525 } 5526 5527 @Override 5528 public int getUidForIntentSender(IIntentSender sender) { 5529 if (sender instanceof PendingIntentRecord) { 5530 try { 5531 PendingIntentRecord res = (PendingIntentRecord)sender; 5532 return res.uid; 5533 } catch (ClassCastException e) { 5534 } 5535 } 5536 return -1; 5537 } 5538 5539 @Override 5540 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5541 if (!(pendingResult instanceof PendingIntentRecord)) { 5542 return false; 5543 } 5544 try { 5545 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5546 if (res.key.allIntents == null) { 5547 return false; 5548 } 5549 for (int i=0; i<res.key.allIntents.length; i++) { 5550 Intent intent = res.key.allIntents[i]; 5551 if (intent.getPackage() != null && intent.getComponent() != null) { 5552 return false; 5553 } 5554 } 5555 return true; 5556 } catch (ClassCastException e) { 5557 } 5558 return false; 5559 } 5560 5561 @Override 5562 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5563 if (!(pendingResult instanceof PendingIntentRecord)) { 5564 return false; 5565 } 5566 try { 5567 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5568 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5569 return true; 5570 } 5571 return false; 5572 } catch (ClassCastException e) { 5573 } 5574 return false; 5575 } 5576 5577 @Override 5578 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5579 if (!(pendingResult instanceof PendingIntentRecord)) { 5580 return null; 5581 } 5582 try { 5583 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5584 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5585 } catch (ClassCastException e) { 5586 } 5587 return null; 5588 } 5589 5590 @Override 5591 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5592 if (!(pendingResult instanceof PendingIntentRecord)) { 5593 return null; 5594 } 5595 try { 5596 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5597 Intent intent = res.key.requestIntent; 5598 if (intent != null) { 5599 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5600 || res.lastTagPrefix.equals(prefix))) { 5601 return res.lastTag; 5602 } 5603 res.lastTagPrefix = prefix; 5604 StringBuilder sb = new StringBuilder(128); 5605 if (prefix != null) { 5606 sb.append(prefix); 5607 } 5608 if (intent.getAction() != null) { 5609 sb.append(intent.getAction()); 5610 } else if (intent.getComponent() != null) { 5611 intent.getComponent().appendShortString(sb); 5612 } else { 5613 sb.append("?"); 5614 } 5615 return res.lastTag = sb.toString(); 5616 } 5617 } catch (ClassCastException e) { 5618 } 5619 return null; 5620 } 5621 5622 @Override 5623 public void setProcessLimit(int max) { 5624 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5625 "setProcessLimit()"); 5626 synchronized (this) { 5627 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5628 mProcessLimitOverride = max; 5629 } 5630 trimApplications(); 5631 } 5632 5633 @Override 5634 public int getProcessLimit() { 5635 synchronized (this) { 5636 return mProcessLimitOverride; 5637 } 5638 } 5639 5640 void foregroundTokenDied(ForegroundToken token) { 5641 synchronized (ActivityManagerService.this) { 5642 synchronized (mPidsSelfLocked) { 5643 ForegroundToken cur 5644 = mForegroundProcesses.get(token.pid); 5645 if (cur != token) { 5646 return; 5647 } 5648 mForegroundProcesses.remove(token.pid); 5649 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5650 if (pr == null) { 5651 return; 5652 } 5653 pr.forcingToForeground = null; 5654 updateProcessForegroundLocked(pr, false, false); 5655 } 5656 updateOomAdjLocked(); 5657 } 5658 } 5659 5660 @Override 5661 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5662 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5663 "setProcessForeground()"); 5664 synchronized(this) { 5665 boolean changed = false; 5666 5667 synchronized (mPidsSelfLocked) { 5668 ProcessRecord pr = mPidsSelfLocked.get(pid); 5669 if (pr == null && isForeground) { 5670 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5671 return; 5672 } 5673 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5674 if (oldToken != null) { 5675 oldToken.token.unlinkToDeath(oldToken, 0); 5676 mForegroundProcesses.remove(pid); 5677 if (pr != null) { 5678 pr.forcingToForeground = null; 5679 } 5680 changed = true; 5681 } 5682 if (isForeground && token != null) { 5683 ForegroundToken newToken = new ForegroundToken() { 5684 @Override 5685 public void binderDied() { 5686 foregroundTokenDied(this); 5687 } 5688 }; 5689 newToken.pid = pid; 5690 newToken.token = token; 5691 try { 5692 token.linkToDeath(newToken, 0); 5693 mForegroundProcesses.put(pid, newToken); 5694 pr.forcingToForeground = token; 5695 changed = true; 5696 } catch (RemoteException e) { 5697 // If the process died while doing this, we will later 5698 // do the cleanup with the process death link. 5699 } 5700 } 5701 } 5702 5703 if (changed) { 5704 updateOomAdjLocked(); 5705 } 5706 } 5707 } 5708 5709 // ========================================================= 5710 // PERMISSIONS 5711 // ========================================================= 5712 5713 static class PermissionController extends IPermissionController.Stub { 5714 ActivityManagerService mActivityManagerService; 5715 PermissionController(ActivityManagerService activityManagerService) { 5716 mActivityManagerService = activityManagerService; 5717 } 5718 5719 @Override 5720 public boolean checkPermission(String permission, int pid, int uid) { 5721 return mActivityManagerService.checkPermission(permission, pid, 5722 uid) == PackageManager.PERMISSION_GRANTED; 5723 } 5724 } 5725 5726 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5727 @Override 5728 public int checkComponentPermission(String permission, int pid, int uid, 5729 int owningUid, boolean exported) { 5730 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5731 owningUid, exported); 5732 } 5733 5734 @Override 5735 public Object getAMSLock() { 5736 return ActivityManagerService.this; 5737 } 5738 } 5739 5740 /** 5741 * This can be called with or without the global lock held. 5742 */ 5743 int checkComponentPermission(String permission, int pid, int uid, 5744 int owningUid, boolean exported) { 5745 // We might be performing an operation on behalf of an indirect binder 5746 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5747 // client identity accordingly before proceeding. 5748 Identity tlsIdentity = sCallerIdentity.get(); 5749 if (tlsIdentity != null) { 5750 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5751 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5752 uid = tlsIdentity.uid; 5753 pid = tlsIdentity.pid; 5754 } 5755 5756 if (pid == MY_PID) { 5757 return PackageManager.PERMISSION_GRANTED; 5758 } 5759 5760 return ActivityManager.checkComponentPermission(permission, uid, 5761 owningUid, exported); 5762 } 5763 5764 /** 5765 * As the only public entry point for permissions checking, this method 5766 * can enforce the semantic that requesting a check on a null global 5767 * permission is automatically denied. (Internally a null permission 5768 * string is used when calling {@link #checkComponentPermission} in cases 5769 * when only uid-based security is needed.) 5770 * 5771 * This can be called with or without the global lock held. 5772 */ 5773 @Override 5774 public int checkPermission(String permission, int pid, int uid) { 5775 if (permission == null) { 5776 return PackageManager.PERMISSION_DENIED; 5777 } 5778 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5779 } 5780 5781 /** 5782 * Binder IPC calls go through the public entry point. 5783 * This can be called with or without the global lock held. 5784 */ 5785 int checkCallingPermission(String permission) { 5786 return checkPermission(permission, 5787 Binder.getCallingPid(), 5788 UserHandle.getAppId(Binder.getCallingUid())); 5789 } 5790 5791 /** 5792 * This can be called with or without the global lock held. 5793 */ 5794 void enforceCallingPermission(String permission, String func) { 5795 if (checkCallingPermission(permission) 5796 == PackageManager.PERMISSION_GRANTED) { 5797 return; 5798 } 5799 5800 String msg = "Permission Denial: " + func + " from pid=" 5801 + Binder.getCallingPid() 5802 + ", uid=" + Binder.getCallingUid() 5803 + " requires " + permission; 5804 Slog.w(TAG, msg); 5805 throw new SecurityException(msg); 5806 } 5807 5808 /** 5809 * Determine if UID is holding permissions required to access {@link Uri} in 5810 * the given {@link ProviderInfo}. Final permission checking is always done 5811 * in {@link ContentProvider}. 5812 */ 5813 private final boolean checkHoldingPermissionsLocked( 5814 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5815 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5816 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5817 5818 if (pi.applicationInfo.uid == uid) { 5819 return true; 5820 } else if (!pi.exported) { 5821 return false; 5822 } 5823 5824 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5825 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5826 try { 5827 // check if target holds top-level <provider> permissions 5828 if (!readMet && pi.readPermission != null 5829 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5830 readMet = true; 5831 } 5832 if (!writeMet && pi.writePermission != null 5833 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5834 writeMet = true; 5835 } 5836 5837 // track if unprotected read/write is allowed; any denied 5838 // <path-permission> below removes this ability 5839 boolean allowDefaultRead = pi.readPermission == null; 5840 boolean allowDefaultWrite = pi.writePermission == null; 5841 5842 // check if target holds any <path-permission> that match uri 5843 final PathPermission[] pps = pi.pathPermissions; 5844 if (pps != null) { 5845 final String path = uri.getPath(); 5846 int i = pps.length; 5847 while (i > 0 && (!readMet || !writeMet)) { 5848 i--; 5849 PathPermission pp = pps[i]; 5850 if (pp.match(path)) { 5851 if (!readMet) { 5852 final String pprperm = pp.getReadPermission(); 5853 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5854 + pprperm + " for " + pp.getPath() 5855 + ": match=" + pp.match(path) 5856 + " check=" + pm.checkUidPermission(pprperm, uid)); 5857 if (pprperm != null) { 5858 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5859 readMet = true; 5860 } else { 5861 allowDefaultRead = false; 5862 } 5863 } 5864 } 5865 if (!writeMet) { 5866 final String ppwperm = pp.getWritePermission(); 5867 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5868 + ppwperm + " for " + pp.getPath() 5869 + ": match=" + pp.match(path) 5870 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5871 if (ppwperm != null) { 5872 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5873 writeMet = true; 5874 } else { 5875 allowDefaultWrite = false; 5876 } 5877 } 5878 } 5879 } 5880 } 5881 } 5882 5883 // grant unprotected <provider> read/write, if not blocked by 5884 // <path-permission> above 5885 if (allowDefaultRead) readMet = true; 5886 if (allowDefaultWrite) writeMet = true; 5887 5888 } catch (RemoteException e) { 5889 return false; 5890 } 5891 5892 return readMet && writeMet; 5893 } 5894 5895 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5896 ProviderInfo pi = null; 5897 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5898 if (cpr != null) { 5899 pi = cpr.info; 5900 } else { 5901 try { 5902 pi = AppGlobals.getPackageManager().resolveContentProvider( 5903 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5904 } catch (RemoteException ex) { 5905 } 5906 } 5907 return pi; 5908 } 5909 5910 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5911 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5912 if (targetUris != null) { 5913 return targetUris.get(uri); 5914 } else { 5915 return null; 5916 } 5917 } 5918 5919 private UriPermission findOrCreateUriPermissionLocked( 5920 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5921 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5922 if (targetUris == null) { 5923 targetUris = Maps.newArrayMap(); 5924 mGrantedUriPermissions.put(targetUid, targetUris); 5925 } 5926 5927 UriPermission perm = targetUris.get(uri); 5928 if (perm == null) { 5929 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5930 targetUris.put(uri, perm); 5931 } 5932 5933 return perm; 5934 } 5935 5936 private final boolean checkUriPermissionLocked( 5937 Uri uri, int uid, int modeFlags, int minStrength) { 5938 // Root gets to do everything. 5939 if (uid == 0) { 5940 return true; 5941 } 5942 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5943 if (perms == null) return false; 5944 UriPermission perm = perms.get(uri); 5945 if (perm == null) return false; 5946 return perm.getStrength(modeFlags) >= minStrength; 5947 } 5948 5949 @Override 5950 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5951 enforceNotIsolatedCaller("checkUriPermission"); 5952 5953 // Another redirected-binder-call permissions check as in 5954 // {@link checkComponentPermission}. 5955 Identity tlsIdentity = sCallerIdentity.get(); 5956 if (tlsIdentity != null) { 5957 uid = tlsIdentity.uid; 5958 pid = tlsIdentity.pid; 5959 } 5960 5961 // Our own process gets to do everything. 5962 if (pid == MY_PID) { 5963 return PackageManager.PERMISSION_GRANTED; 5964 } 5965 synchronized(this) { 5966 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5967 ? PackageManager.PERMISSION_GRANTED 5968 : PackageManager.PERMISSION_DENIED; 5969 } 5970 } 5971 5972 /** 5973 * Check if the targetPkg can be granted permission to access uri by 5974 * the callingUid using the given modeFlags. Throws a security exception 5975 * if callingUid is not allowed to do this. Returns the uid of the target 5976 * if the URI permission grant should be performed; returns -1 if it is not 5977 * needed (for example targetPkg already has permission to access the URI). 5978 * If you already know the uid of the target, you can supply it in 5979 * lastTargetUid else set that to -1. 5980 */ 5981 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5982 Uri uri, int modeFlags, int lastTargetUid) { 5983 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5984 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5985 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5986 if (modeFlags == 0) { 5987 return -1; 5988 } 5989 5990 if (targetPkg != null) { 5991 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5992 "Checking grant " + targetPkg + " permission to " + uri); 5993 } 5994 5995 final IPackageManager pm = AppGlobals.getPackageManager(); 5996 5997 // If this is not a content: uri, we can't do anything with it. 5998 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5999 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6000 "Can't grant URI permission for non-content URI: " + uri); 6001 return -1; 6002 } 6003 6004 final String authority = uri.getAuthority(); 6005 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6006 if (pi == null) { 6007 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6008 return -1; 6009 } 6010 6011 int targetUid = lastTargetUid; 6012 if (targetUid < 0 && targetPkg != null) { 6013 try { 6014 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6015 if (targetUid < 0) { 6016 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6017 "Can't grant URI permission no uid for: " + targetPkg); 6018 return -1; 6019 } 6020 } catch (RemoteException ex) { 6021 return -1; 6022 } 6023 } 6024 6025 if (targetUid >= 0) { 6026 // First... does the target actually need this permission? 6027 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6028 // No need to grant the target this permission. 6029 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6030 "Target " + targetPkg + " already has full permission to " + uri); 6031 return -1; 6032 } 6033 } else { 6034 // First... there is no target package, so can anyone access it? 6035 boolean allowed = pi.exported; 6036 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6037 if (pi.readPermission != null) { 6038 allowed = false; 6039 } 6040 } 6041 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6042 if (pi.writePermission != null) { 6043 allowed = false; 6044 } 6045 } 6046 if (allowed) { 6047 return -1; 6048 } 6049 } 6050 6051 // Second... is the provider allowing granting of URI permissions? 6052 if (!pi.grantUriPermissions) { 6053 throw new SecurityException("Provider " + pi.packageName 6054 + "/" + pi.name 6055 + " does not allow granting of Uri permissions (uri " 6056 + uri + ")"); 6057 } 6058 if (pi.uriPermissionPatterns != null) { 6059 final int N = pi.uriPermissionPatterns.length; 6060 boolean allowed = false; 6061 for (int i=0; i<N; i++) { 6062 if (pi.uriPermissionPatterns[i] != null 6063 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6064 allowed = true; 6065 break; 6066 } 6067 } 6068 if (!allowed) { 6069 throw new SecurityException("Provider " + pi.packageName 6070 + "/" + pi.name 6071 + " does not allow granting of permission to path of Uri " 6072 + uri); 6073 } 6074 } 6075 6076 // Third... does the caller itself have permission to access 6077 // this uri? 6078 if (callingUid != Process.myUid()) { 6079 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6080 // Require they hold a strong enough Uri permission 6081 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6082 : UriPermission.STRENGTH_OWNED; 6083 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6084 throw new SecurityException("Uid " + callingUid 6085 + " does not have permission to uri " + uri); 6086 } 6087 } 6088 } 6089 6090 return targetUid; 6091 } 6092 6093 @Override 6094 public int checkGrantUriPermission(int callingUid, String targetPkg, 6095 Uri uri, int modeFlags) { 6096 enforceNotIsolatedCaller("checkGrantUriPermission"); 6097 synchronized(this) { 6098 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6099 } 6100 } 6101 6102 void grantUriPermissionUncheckedLocked( 6103 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6104 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6105 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6106 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6107 if (modeFlags == 0) { 6108 return; 6109 } 6110 6111 // So here we are: the caller has the assumed permission 6112 // to the uri, and the target doesn't. Let's now give this to 6113 // the target. 6114 6115 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6116 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6117 6118 final String authority = uri.getAuthority(); 6119 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6120 if (pi == null) { 6121 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6122 return; 6123 } 6124 6125 final UriPermission perm = findOrCreateUriPermissionLocked( 6126 pi.packageName, targetPkg, targetUid, uri); 6127 perm.grantModes(modeFlags, persistable, owner); 6128 } 6129 6130 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6131 int modeFlags, UriPermissionOwner owner) { 6132 if (targetPkg == null) { 6133 throw new NullPointerException("targetPkg"); 6134 } 6135 6136 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6137 if (targetUid < 0) { 6138 return; 6139 } 6140 6141 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6142 } 6143 6144 static class NeededUriGrants extends ArrayList<Uri> { 6145 final String targetPkg; 6146 final int targetUid; 6147 final int flags; 6148 6149 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6150 this.targetPkg = targetPkg; 6151 this.targetUid = targetUid; 6152 this.flags = flags; 6153 } 6154 } 6155 6156 /** 6157 * Like checkGrantUriPermissionLocked, but takes an Intent. 6158 */ 6159 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6160 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6161 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6162 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6163 + " clip=" + (intent != null ? intent.getClipData() : null) 6164 + " from " + intent + "; flags=0x" 6165 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6166 6167 if (targetPkg == null) { 6168 throw new NullPointerException("targetPkg"); 6169 } 6170 6171 if (intent == null) { 6172 return null; 6173 } 6174 Uri data = intent.getData(); 6175 ClipData clip = intent.getClipData(); 6176 if (data == null && clip == null) { 6177 return null; 6178 } 6179 6180 if (data != null) { 6181 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6182 mode, needed != null ? needed.targetUid : -1); 6183 if (targetUid > 0) { 6184 if (needed == null) { 6185 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6186 } 6187 needed.add(data); 6188 } 6189 } 6190 if (clip != null) { 6191 for (int i=0; i<clip.getItemCount(); i++) { 6192 Uri uri = clip.getItemAt(i).getUri(); 6193 if (uri != null) { 6194 int targetUid = -1; 6195 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6196 mode, needed != null ? needed.targetUid : -1); 6197 if (targetUid > 0) { 6198 if (needed == null) { 6199 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6200 } 6201 needed.add(uri); 6202 } 6203 } else { 6204 Intent clipIntent = clip.getItemAt(i).getIntent(); 6205 if (clipIntent != null) { 6206 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6207 callingUid, targetPkg, clipIntent, mode, needed); 6208 if (newNeeded != null) { 6209 needed = newNeeded; 6210 } 6211 } 6212 } 6213 } 6214 } 6215 6216 return needed; 6217 } 6218 6219 /** 6220 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6221 */ 6222 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6223 UriPermissionOwner owner) { 6224 if (needed != null) { 6225 for (int i=0; i<needed.size(); i++) { 6226 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6227 needed.get(i), needed.flags, owner); 6228 } 6229 } 6230 } 6231 6232 void grantUriPermissionFromIntentLocked(int callingUid, 6233 String targetPkg, Intent intent, UriPermissionOwner owner) { 6234 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6235 intent, intent != null ? intent.getFlags() : 0, null); 6236 if (needed == null) { 6237 return; 6238 } 6239 6240 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6241 } 6242 6243 @Override 6244 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6245 Uri uri, int modeFlags) { 6246 enforceNotIsolatedCaller("grantUriPermission"); 6247 synchronized(this) { 6248 final ProcessRecord r = getRecordForAppLocked(caller); 6249 if (r == null) { 6250 throw new SecurityException("Unable to find app for caller " 6251 + caller 6252 + " when granting permission to uri " + uri); 6253 } 6254 if (targetPkg == null) { 6255 throw new IllegalArgumentException("null target"); 6256 } 6257 if (uri == null) { 6258 throw new IllegalArgumentException("null uri"); 6259 } 6260 6261 // Persistable only supported through Intents 6262 Preconditions.checkFlagsArgument(modeFlags, 6263 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6264 6265 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6266 null); 6267 } 6268 } 6269 6270 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6271 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6272 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6273 ArrayMap<Uri, UriPermission> perms 6274 = mGrantedUriPermissions.get(perm.targetUid); 6275 if (perms != null) { 6276 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6277 "Removing " + perm.targetUid + " permission to " + perm.uri); 6278 perms.remove(perm.uri); 6279 if (perms.size() == 0) { 6280 mGrantedUriPermissions.remove(perm.targetUid); 6281 } 6282 } 6283 } 6284 } 6285 6286 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6287 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6288 6289 final IPackageManager pm = AppGlobals.getPackageManager(); 6290 final String authority = uri.getAuthority(); 6291 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6292 if (pi == null) { 6293 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6294 return; 6295 } 6296 6297 // Does the caller have this permission on the URI? 6298 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6299 // Right now, if you are not the original owner of the permission, 6300 // you are not allowed to revoke it. 6301 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6302 throw new SecurityException("Uid " + callingUid 6303 + " does not have permission to uri " + uri); 6304 //} 6305 } 6306 6307 boolean persistChanged = false; 6308 6309 // Go through all of the permissions and remove any that match. 6310 final List<String> SEGMENTS = uri.getPathSegments(); 6311 if (SEGMENTS != null) { 6312 final int NS = SEGMENTS.size(); 6313 int N = mGrantedUriPermissions.size(); 6314 for (int i=0; i<N; i++) { 6315 ArrayMap<Uri, UriPermission> perms 6316 = mGrantedUriPermissions.valueAt(i); 6317 Iterator<UriPermission> it = perms.values().iterator(); 6318 toploop: 6319 while (it.hasNext()) { 6320 UriPermission perm = it.next(); 6321 Uri targetUri = perm.uri; 6322 if (!authority.equals(targetUri.getAuthority())) { 6323 continue; 6324 } 6325 List<String> targetSegments = targetUri.getPathSegments(); 6326 if (targetSegments == null) { 6327 continue; 6328 } 6329 if (targetSegments.size() < NS) { 6330 continue; 6331 } 6332 for (int j=0; j<NS; j++) { 6333 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6334 continue toploop; 6335 } 6336 } 6337 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6338 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6339 persistChanged |= perm.clearModes(modeFlags, true); 6340 if (perm.modeFlags == 0) { 6341 it.remove(); 6342 } 6343 } 6344 if (perms.size() == 0) { 6345 mGrantedUriPermissions.remove( 6346 mGrantedUriPermissions.keyAt(i)); 6347 N--; 6348 i--; 6349 } 6350 } 6351 } 6352 6353 if (persistChanged) { 6354 schedulePersistUriGrants(); 6355 } 6356 } 6357 6358 @Override 6359 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6360 int modeFlags) { 6361 enforceNotIsolatedCaller("revokeUriPermission"); 6362 synchronized(this) { 6363 final ProcessRecord r = getRecordForAppLocked(caller); 6364 if (r == null) { 6365 throw new SecurityException("Unable to find app for caller " 6366 + caller 6367 + " when revoking permission to uri " + uri); 6368 } 6369 if (uri == null) { 6370 Slog.w(TAG, "revokeUriPermission: null uri"); 6371 return; 6372 } 6373 6374 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6375 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6376 if (modeFlags == 0) { 6377 return; 6378 } 6379 6380 final IPackageManager pm = AppGlobals.getPackageManager(); 6381 final String authority = uri.getAuthority(); 6382 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6383 if (pi == null) { 6384 Slog.w(TAG, "No content provider found for permission revoke: " 6385 + uri.toSafeString()); 6386 return; 6387 } 6388 6389 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6390 } 6391 } 6392 6393 /** 6394 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6395 * given package. 6396 * 6397 * @param packageName Package name to match, or {@code null} to apply to all 6398 * packages. 6399 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6400 * to all users. 6401 * @param persistable If persistable grants should be removed. 6402 */ 6403 private void removeUriPermissionsForPackageLocked( 6404 String packageName, int userHandle, boolean persistable) { 6405 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6406 throw new IllegalArgumentException("Must narrow by either package or user"); 6407 } 6408 6409 boolean persistChanged = false; 6410 6411 final int size = mGrantedUriPermissions.size(); 6412 for (int i = 0; i < size; i++) { 6413 // Only inspect grants matching user 6414 if (userHandle == UserHandle.USER_ALL 6415 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6416 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6417 .values().iterator(); 6418 while (it.hasNext()) { 6419 final UriPermission perm = it.next(); 6420 6421 // Only inspect grants matching package 6422 if (packageName == null || perm.sourcePkg.equals(packageName) 6423 || perm.targetPkg.equals(packageName)) { 6424 persistChanged |= perm.clearModes(~0, persistable); 6425 6426 // Only remove when no modes remain; any persisted grants 6427 // will keep this alive. 6428 if (perm.modeFlags == 0) { 6429 it.remove(); 6430 } 6431 } 6432 } 6433 } 6434 } 6435 6436 if (persistChanged) { 6437 schedulePersistUriGrants(); 6438 } 6439 } 6440 6441 @Override 6442 public IBinder newUriPermissionOwner(String name) { 6443 enforceNotIsolatedCaller("newUriPermissionOwner"); 6444 synchronized(this) { 6445 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6446 return owner.getExternalTokenLocked(); 6447 } 6448 } 6449 6450 @Override 6451 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6452 Uri uri, int modeFlags) { 6453 synchronized(this) { 6454 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6455 if (owner == null) { 6456 throw new IllegalArgumentException("Unknown owner: " + token); 6457 } 6458 if (fromUid != Binder.getCallingUid()) { 6459 if (Binder.getCallingUid() != Process.myUid()) { 6460 // Only system code can grant URI permissions on behalf 6461 // of other users. 6462 throw new SecurityException("nice try"); 6463 } 6464 } 6465 if (targetPkg == null) { 6466 throw new IllegalArgumentException("null target"); 6467 } 6468 if (uri == null) { 6469 throw new IllegalArgumentException("null uri"); 6470 } 6471 6472 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6473 } 6474 } 6475 6476 @Override 6477 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6478 synchronized(this) { 6479 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6480 if (owner == null) { 6481 throw new IllegalArgumentException("Unknown owner: " + token); 6482 } 6483 6484 if (uri == null) { 6485 owner.removeUriPermissionsLocked(mode); 6486 } else { 6487 owner.removeUriPermissionLocked(uri, mode); 6488 } 6489 } 6490 } 6491 6492 private void schedulePersistUriGrants() { 6493 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6494 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6495 10 * DateUtils.SECOND_IN_MILLIS); 6496 } 6497 } 6498 6499 private void writeGrantedUriPermissions() { 6500 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6501 6502 // Snapshot permissions so we can persist without lock 6503 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6504 synchronized (this) { 6505 final int size = mGrantedUriPermissions.size(); 6506 for (int i = 0 ; i < size; i++) { 6507 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6508 if (perm.persistedModeFlags != 0) { 6509 persist.add(perm.snapshot()); 6510 } 6511 } 6512 } 6513 } 6514 6515 FileOutputStream fos = null; 6516 try { 6517 fos = mGrantFile.startWrite(); 6518 6519 XmlSerializer out = new FastXmlSerializer(); 6520 out.setOutput(fos, "utf-8"); 6521 out.startDocument(null, true); 6522 out.startTag(null, TAG_URI_GRANTS); 6523 for (UriPermission.Snapshot perm : persist) { 6524 out.startTag(null, TAG_URI_GRANT); 6525 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6526 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6527 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6528 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6529 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6530 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6531 out.endTag(null, TAG_URI_GRANT); 6532 } 6533 out.endTag(null, TAG_URI_GRANTS); 6534 out.endDocument(); 6535 6536 mGrantFile.finishWrite(fos); 6537 } catch (IOException e) { 6538 if (fos != null) { 6539 mGrantFile.failWrite(fos); 6540 } 6541 } 6542 } 6543 6544 private void readGrantedUriPermissionsLocked() { 6545 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6546 6547 final long now = System.currentTimeMillis(); 6548 6549 FileInputStream fis = null; 6550 try { 6551 fis = mGrantFile.openRead(); 6552 final XmlPullParser in = Xml.newPullParser(); 6553 in.setInput(fis, null); 6554 6555 int type; 6556 while ((type = in.next()) != END_DOCUMENT) { 6557 final String tag = in.getName(); 6558 if (type == START_TAG) { 6559 if (TAG_URI_GRANT.equals(tag)) { 6560 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6561 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6562 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6563 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6564 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6565 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6566 6567 // Sanity check that provider still belongs to source package 6568 final ProviderInfo pi = getProviderInfoLocked( 6569 uri.getAuthority(), userHandle); 6570 if (pi != null && sourcePkg.equals(pi.packageName)) { 6571 int targetUid = -1; 6572 try { 6573 targetUid = AppGlobals.getPackageManager() 6574 .getPackageUid(targetPkg, userHandle); 6575 } catch (RemoteException e) { 6576 } 6577 if (targetUid != -1) { 6578 final UriPermission perm = findOrCreateUriPermissionLocked( 6579 sourcePkg, targetPkg, targetUid, uri); 6580 perm.initPersistedModes(modeFlags, createdTime); 6581 } 6582 } else { 6583 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6584 + " but instead found " + pi); 6585 } 6586 } 6587 } 6588 } 6589 } catch (FileNotFoundException e) { 6590 // Missing grants is okay 6591 } catch (IOException e) { 6592 Log.wtf(TAG, "Failed reading Uri grants", e); 6593 } catch (XmlPullParserException e) { 6594 Log.wtf(TAG, "Failed reading Uri grants", e); 6595 } finally { 6596 IoUtils.closeQuietly(fis); 6597 } 6598 } 6599 6600 @Override 6601 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6602 enforceNotIsolatedCaller("takePersistableUriPermission"); 6603 6604 Preconditions.checkFlagsArgument(modeFlags, 6605 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6606 6607 synchronized (this) { 6608 final int callingUid = Binder.getCallingUid(); 6609 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6610 if (perm == null) { 6611 throw new SecurityException("No permission grant found for UID " + callingUid 6612 + " and Uri " + uri.toSafeString()); 6613 } 6614 6615 boolean persistChanged = perm.takePersistableModes(modeFlags); 6616 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6617 6618 if (persistChanged) { 6619 schedulePersistUriGrants(); 6620 } 6621 } 6622 } 6623 6624 @Override 6625 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6626 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6627 6628 Preconditions.checkFlagsArgument(modeFlags, 6629 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6630 6631 synchronized (this) { 6632 final int callingUid = Binder.getCallingUid(); 6633 6634 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6635 if (perm == null) { 6636 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6637 + uri.toSafeString()); 6638 return; 6639 } 6640 6641 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6642 removeUriPermissionIfNeededLocked(perm); 6643 if (persistChanged) { 6644 schedulePersistUriGrants(); 6645 } 6646 } 6647 } 6648 6649 /** 6650 * Prune any older {@link UriPermission} for the given UID until outstanding 6651 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6652 * 6653 * @return if any mutations occured that require persisting. 6654 */ 6655 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6656 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6657 if (perms == null) return false; 6658 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6659 6660 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6661 for (UriPermission perm : perms.values()) { 6662 if (perm.persistedModeFlags != 0) { 6663 persisted.add(perm); 6664 } 6665 } 6666 6667 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6668 if (trimCount <= 0) return false; 6669 6670 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6671 for (int i = 0; i < trimCount; i++) { 6672 final UriPermission perm = persisted.get(i); 6673 6674 if (DEBUG_URI_PERMISSION) { 6675 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6676 } 6677 6678 perm.releasePersistableModes(~0); 6679 removeUriPermissionIfNeededLocked(perm); 6680 } 6681 6682 return true; 6683 } 6684 6685 @Override 6686 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6687 String packageName, boolean incoming) { 6688 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6689 Preconditions.checkNotNull(packageName, "packageName"); 6690 6691 final int callingUid = Binder.getCallingUid(); 6692 final IPackageManager pm = AppGlobals.getPackageManager(); 6693 try { 6694 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6695 if (packageUid != callingUid) { 6696 throw new SecurityException( 6697 "Package " + packageName + " does not belong to calling UID " + callingUid); 6698 } 6699 } catch (RemoteException e) { 6700 throw new SecurityException("Failed to verify package name ownership"); 6701 } 6702 6703 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6704 synchronized (this) { 6705 if (incoming) { 6706 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6707 if (perms == null) { 6708 Slog.w(TAG, "No permission grants found for " + packageName); 6709 } else { 6710 final int size = perms.size(); 6711 for (int i = 0; i < size; i++) { 6712 final UriPermission perm = perms.valueAt(i); 6713 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6714 result.add(perm.buildPersistedPublicApiObject()); 6715 } 6716 } 6717 } 6718 } else { 6719 final int size = mGrantedUriPermissions.size(); 6720 for (int i = 0; i < size; i++) { 6721 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6722 final int permsSize = perms.size(); 6723 for (int j = 0; j < permsSize; j++) { 6724 final UriPermission perm = perms.valueAt(j); 6725 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6726 result.add(perm.buildPersistedPublicApiObject()); 6727 } 6728 } 6729 } 6730 } 6731 } 6732 return new ParceledListSlice<android.content.UriPermission>(result); 6733 } 6734 6735 @Override 6736 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6737 synchronized (this) { 6738 ProcessRecord app = 6739 who != null ? getRecordForAppLocked(who) : null; 6740 if (app == null) return; 6741 6742 Message msg = Message.obtain(); 6743 msg.what = WAIT_FOR_DEBUGGER_MSG; 6744 msg.obj = app; 6745 msg.arg1 = waiting ? 1 : 0; 6746 mHandler.sendMessage(msg); 6747 } 6748 } 6749 6750 @Override 6751 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6752 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6753 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6754 outInfo.availMem = Process.getFreeMemory(); 6755 outInfo.totalMem = Process.getTotalMemory(); 6756 outInfo.threshold = homeAppMem; 6757 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6758 outInfo.hiddenAppThreshold = cachedAppMem; 6759 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6760 ProcessList.SERVICE_ADJ); 6761 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6762 ProcessList.VISIBLE_APP_ADJ); 6763 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6764 ProcessList.FOREGROUND_APP_ADJ); 6765 } 6766 6767 // ========================================================= 6768 // TASK MANAGEMENT 6769 // ========================================================= 6770 6771 @Override 6772 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6773 IThumbnailReceiver receiver) { 6774 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6775 6776 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6777 ActivityRecord topRecord = null; 6778 6779 synchronized(this) { 6780 if (localLOGV) Slog.v( 6781 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6782 + ", receiver=" + receiver); 6783 6784 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6785 != PackageManager.PERMISSION_GRANTED) { 6786 if (receiver != null) { 6787 // If the caller wants to wait for pending thumbnails, 6788 // it ain't gonna get them. 6789 try { 6790 receiver.finished(); 6791 } catch (RemoteException ex) { 6792 } 6793 } 6794 String msg = "Permission Denial: getTasks() from pid=" 6795 + Binder.getCallingPid() 6796 + ", uid=" + Binder.getCallingUid() 6797 + " requires " + android.Manifest.permission.GET_TASKS; 6798 Slog.w(TAG, msg); 6799 throw new SecurityException(msg); 6800 } 6801 6802 // TODO: Improve with MRU list from all ActivityStacks. 6803 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6804 6805 if (!pending.pendingRecords.isEmpty()) { 6806 mPendingThumbnails.add(pending); 6807 } 6808 } 6809 6810 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6811 6812 if (topRecord != null) { 6813 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6814 try { 6815 IApplicationThread topThumbnail = topRecord.app.thread; 6816 topThumbnail.requestThumbnail(topRecord.appToken); 6817 } catch (Exception e) { 6818 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6819 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6820 } 6821 } 6822 6823 if (pending == null && receiver != null) { 6824 // In this case all thumbnails were available and the client 6825 // is being asked to be told when the remaining ones come in... 6826 // which is unusually, since the top-most currently running 6827 // activity should never have a canned thumbnail! Oh well. 6828 try { 6829 receiver.finished(); 6830 } catch (RemoteException ex) { 6831 } 6832 } 6833 6834 return list; 6835 } 6836 6837 TaskRecord getMostRecentTask() { 6838 return mRecentTasks.get(0); 6839 } 6840 6841 @Override 6842 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6843 int flags, int userId) { 6844 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6845 false, true, "getRecentTasks", null); 6846 6847 synchronized (this) { 6848 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6849 "getRecentTasks()"); 6850 final boolean detailed = checkCallingPermission( 6851 android.Manifest.permission.GET_DETAILED_TASKS) 6852 == PackageManager.PERMISSION_GRANTED; 6853 6854 IPackageManager pm = AppGlobals.getPackageManager(); 6855 6856 final int N = mRecentTasks.size(); 6857 ArrayList<ActivityManager.RecentTaskInfo> res 6858 = new ArrayList<ActivityManager.RecentTaskInfo>( 6859 maxNum < N ? maxNum : N); 6860 for (int i=0; i<N && maxNum > 0; i++) { 6861 TaskRecord tr = mRecentTasks.get(i); 6862 // Only add calling user's recent tasks 6863 if (tr.userId != userId) continue; 6864 // Return the entry if desired by the caller. We always return 6865 // the first entry, because callers always expect this to be the 6866 // foreground app. We may filter others if the caller has 6867 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6868 // we should exclude the entry. 6869 6870 if (i == 0 6871 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6872 || (tr.intent == null) 6873 || ((tr.intent.getFlags() 6874 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6875 ActivityManager.RecentTaskInfo rti 6876 = new ActivityManager.RecentTaskInfo(); 6877 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6878 rti.persistentId = tr.taskId; 6879 rti.baseIntent = new Intent( 6880 tr.intent != null ? tr.intent : tr.affinityIntent); 6881 if (!detailed) { 6882 rti.baseIntent.replaceExtras((Bundle)null); 6883 } 6884 rti.origActivity = tr.origActivity; 6885 rti.description = tr.lastDescription; 6886 rti.stackId = tr.stack.mStackId; 6887 6888 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6889 // Check whether this activity is currently available. 6890 try { 6891 if (rti.origActivity != null) { 6892 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6893 == null) { 6894 continue; 6895 } 6896 } else if (rti.baseIntent != null) { 6897 if (pm.queryIntentActivities(rti.baseIntent, 6898 null, 0, userId) == null) { 6899 continue; 6900 } 6901 } 6902 } catch (RemoteException e) { 6903 // Will never happen. 6904 } 6905 } 6906 6907 res.add(rti); 6908 maxNum--; 6909 } 6910 } 6911 return res; 6912 } 6913 } 6914 6915 private TaskRecord recentTaskForIdLocked(int id) { 6916 final int N = mRecentTasks.size(); 6917 for (int i=0; i<N; i++) { 6918 TaskRecord tr = mRecentTasks.get(i); 6919 if (tr.taskId == id) { 6920 return tr; 6921 } 6922 } 6923 return null; 6924 } 6925 6926 @Override 6927 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6928 synchronized (this) { 6929 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6930 "getTaskThumbnails()"); 6931 TaskRecord tr = recentTaskForIdLocked(id); 6932 if (tr != null) { 6933 return tr.getTaskThumbnailsLocked(); 6934 } 6935 } 6936 return null; 6937 } 6938 6939 @Override 6940 public Bitmap getTaskTopThumbnail(int id) { 6941 synchronized (this) { 6942 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6943 "getTaskTopThumbnail()"); 6944 TaskRecord tr = recentTaskForIdLocked(id); 6945 if (tr != null) { 6946 return tr.getTaskTopThumbnailLocked(); 6947 } 6948 } 6949 return null; 6950 } 6951 6952 @Override 6953 public boolean removeSubTask(int taskId, int subTaskIndex) { 6954 synchronized (this) { 6955 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6956 "removeSubTask()"); 6957 long ident = Binder.clearCallingIdentity(); 6958 try { 6959 TaskRecord tr = recentTaskForIdLocked(taskId); 6960 if (tr != null) { 6961 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6962 } 6963 return false; 6964 } finally { 6965 Binder.restoreCallingIdentity(ident); 6966 } 6967 } 6968 } 6969 6970 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6971 if (!pr.killedByAm) { 6972 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6973 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6974 pr.processName, pr.setAdj, reason); 6975 pr.killedByAm = true; 6976 Process.killProcessQuiet(pr.pid); 6977 } 6978 } 6979 6980 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6981 tr.disposeThumbnail(); 6982 mRecentTasks.remove(tr); 6983 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6984 Intent baseIntent = new Intent( 6985 tr.intent != null ? tr.intent : tr.affinityIntent); 6986 ComponentName component = baseIntent.getComponent(); 6987 if (component == null) { 6988 Slog.w(TAG, "Now component for base intent of task: " + tr); 6989 return; 6990 } 6991 6992 // Find any running services associated with this app. 6993 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6994 6995 if (killProcesses) { 6996 // Find any running processes associated with this app. 6997 final String pkg = component.getPackageName(); 6998 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6999 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7000 for (int i=0; i<pmap.size(); i++) { 7001 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7002 for (int j=0; j<uids.size(); j++) { 7003 ProcessRecord proc = uids.valueAt(j); 7004 if (proc.userId != tr.userId) { 7005 continue; 7006 } 7007 if (!proc.pkgList.containsKey(pkg)) { 7008 continue; 7009 } 7010 procs.add(proc); 7011 } 7012 } 7013 7014 // Kill the running processes. 7015 for (int i=0; i<procs.size(); i++) { 7016 ProcessRecord pr = procs.get(i); 7017 if (pr == mHomeProcess) { 7018 // Don't kill the home process along with tasks from the same package. 7019 continue; 7020 } 7021 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7022 killUnneededProcessLocked(pr, "remove task"); 7023 } else { 7024 pr.waitingToKill = "remove task"; 7025 } 7026 } 7027 } 7028 } 7029 7030 @Override 7031 public boolean removeTask(int taskId, int flags) { 7032 synchronized (this) { 7033 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7034 "removeTask()"); 7035 long ident = Binder.clearCallingIdentity(); 7036 try { 7037 TaskRecord tr = recentTaskForIdLocked(taskId); 7038 if (tr != null) { 7039 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7040 if (r != null) { 7041 cleanUpRemovedTaskLocked(tr, flags); 7042 return true; 7043 } 7044 if (tr.mActivities.size() == 0) { 7045 // Caller is just removing a recent task that is 7046 // not actively running. That is easy! 7047 cleanUpRemovedTaskLocked(tr, flags); 7048 return true; 7049 } 7050 Slog.w(TAG, "removeTask: task " + taskId 7051 + " does not have activities to remove, " 7052 + " but numActivities=" + tr.numActivities 7053 + ": " + tr); 7054 } 7055 } finally { 7056 Binder.restoreCallingIdentity(ident); 7057 } 7058 } 7059 return false; 7060 } 7061 7062 /** 7063 * TODO: Add mController hook 7064 */ 7065 @Override 7066 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7067 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7068 "moveTaskToFront()"); 7069 7070 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7071 synchronized(this) { 7072 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7073 Binder.getCallingUid(), "Task to front")) { 7074 ActivityOptions.abort(options); 7075 return; 7076 } 7077 final long origId = Binder.clearCallingIdentity(); 7078 try { 7079 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7080 if (task == null) { 7081 return; 7082 } 7083 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7084 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7085 return; 7086 } 7087 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7088 } finally { 7089 Binder.restoreCallingIdentity(origId); 7090 } 7091 ActivityOptions.abort(options); 7092 } 7093 } 7094 7095 @Override 7096 public void moveTaskToBack(int taskId) { 7097 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7098 "moveTaskToBack()"); 7099 7100 synchronized(this) { 7101 TaskRecord tr = recentTaskForIdLocked(taskId); 7102 if (tr != null) { 7103 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7104 ActivityStack stack = tr.stack; 7105 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7106 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7107 Binder.getCallingUid(), "Task to back")) { 7108 return; 7109 } 7110 } 7111 final long origId = Binder.clearCallingIdentity(); 7112 try { 7113 stack.moveTaskToBackLocked(taskId, null); 7114 } finally { 7115 Binder.restoreCallingIdentity(origId); 7116 } 7117 } 7118 } 7119 } 7120 7121 /** 7122 * Moves an activity, and all of the other activities within the same task, to the bottom 7123 * of the history stack. The activity's order within the task is unchanged. 7124 * 7125 * @param token A reference to the activity we wish to move 7126 * @param nonRoot If false then this only works if the activity is the root 7127 * of a task; if true it will work for any activity in a task. 7128 * @return Returns true if the move completed, false if not. 7129 */ 7130 @Override 7131 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7132 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7133 synchronized(this) { 7134 final long origId = Binder.clearCallingIdentity(); 7135 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7136 if (taskId >= 0) { 7137 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7138 } 7139 Binder.restoreCallingIdentity(origId); 7140 } 7141 return false; 7142 } 7143 7144 @Override 7145 public void moveTaskBackwards(int task) { 7146 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7147 "moveTaskBackwards()"); 7148 7149 synchronized(this) { 7150 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7151 Binder.getCallingUid(), "Task backwards")) { 7152 return; 7153 } 7154 final long origId = Binder.clearCallingIdentity(); 7155 moveTaskBackwardsLocked(task); 7156 Binder.restoreCallingIdentity(origId); 7157 } 7158 } 7159 7160 private final void moveTaskBackwardsLocked(int task) { 7161 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7162 } 7163 7164 @Override 7165 public IBinder getHomeActivityToken() throws RemoteException { 7166 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7167 "getHomeActivityToken()"); 7168 synchronized (this) { 7169 return mStackSupervisor.getHomeActivityToken(); 7170 } 7171 } 7172 7173 @Override 7174 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7175 IActivityContainerCallback callback) throws RemoteException { 7176 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7177 "createActivityContainer()"); 7178 synchronized (this) { 7179 if (parentActivityToken == null) { 7180 throw new IllegalArgumentException("parent token must not be null"); 7181 } 7182 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7183 if (r == null) { 7184 return null; 7185 } 7186 return mStackSupervisor.createActivityContainer(r, callback); 7187 } 7188 } 7189 7190 @Override 7191 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7192 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7193 "deleteActivityContainer()"); 7194 synchronized (this) { 7195 mStackSupervisor.deleteActivityContainer(container); 7196 } 7197 } 7198 7199 @Override 7200 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7201 throws RemoteException { 7202 synchronized (this) { 7203 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7204 if (stack != null) { 7205 return stack.mActivityContainer; 7206 } 7207 return null; 7208 } 7209 } 7210 7211 @Override 7212 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7213 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7214 "moveTaskToStack()"); 7215 if (stackId == HOME_STACK_ID) { 7216 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7217 new RuntimeException("here").fillInStackTrace()); 7218 } 7219 synchronized (this) { 7220 long ident = Binder.clearCallingIdentity(); 7221 try { 7222 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7223 + stackId + " toTop=" + toTop); 7224 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7225 } finally { 7226 Binder.restoreCallingIdentity(ident); 7227 } 7228 } 7229 } 7230 7231 @Override 7232 public void resizeStack(int stackBoxId, Rect bounds) { 7233 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7234 "resizeStackBox()"); 7235 long ident = Binder.clearCallingIdentity(); 7236 try { 7237 mWindowManager.resizeStack(stackBoxId, bounds); 7238 } finally { 7239 Binder.restoreCallingIdentity(ident); 7240 } 7241 } 7242 7243 @Override 7244 public List<StackInfo> getAllStackInfos() { 7245 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7246 "getAllStackInfos()"); 7247 long ident = Binder.clearCallingIdentity(); 7248 try { 7249 synchronized (this) { 7250 return mStackSupervisor.getAllStackInfosLocked(); 7251 } 7252 } finally { 7253 Binder.restoreCallingIdentity(ident); 7254 } 7255 } 7256 7257 @Override 7258 public StackInfo getStackInfo(int stackId) { 7259 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7260 "getStackInfo()"); 7261 long ident = Binder.clearCallingIdentity(); 7262 try { 7263 synchronized (this) { 7264 return mStackSupervisor.getStackInfoLocked(stackId); 7265 } 7266 } finally { 7267 Binder.restoreCallingIdentity(ident); 7268 } 7269 } 7270 7271 @Override 7272 public boolean isInHomeStack(int taskId) { 7273 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7274 "getStackInfo()"); 7275 long ident = Binder.clearCallingIdentity(); 7276 try { 7277 synchronized (this) { 7278 TaskRecord tr = recentTaskForIdLocked(taskId); 7279 if (tr != null) { 7280 return tr.stack.isHomeStack(); 7281 } 7282 } 7283 } finally { 7284 Binder.restoreCallingIdentity(ident); 7285 } 7286 return false; 7287 } 7288 7289 @Override 7290 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7291 synchronized(this) { 7292 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7293 } 7294 } 7295 7296 private boolean isLockTaskAuthorized(ComponentName name) { 7297// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7298// "startLockTaskMode()"); 7299// DevicePolicyManager dpm = (DevicePolicyManager) 7300// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7301// return dpm != null && dpm.isLockTaskPermitted(name); 7302 return true; 7303 } 7304 7305 private void startLockTaskMode(TaskRecord task) { 7306 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7307 return; 7308 } 7309 long ident = Binder.clearCallingIdentity(); 7310 try { 7311 synchronized (this) { 7312 // Since we lost lock on task, make sure it is still there. 7313 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7314 if (task != null) { 7315 mStackSupervisor.setLockTaskModeLocked(task); 7316 } 7317 } 7318 } finally { 7319 Binder.restoreCallingIdentity(ident); 7320 } 7321 } 7322 7323 @Override 7324 public void startLockTaskMode(int taskId) { 7325 long ident = Binder.clearCallingIdentity(); 7326 try { 7327 final TaskRecord task; 7328 synchronized (this) { 7329 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7330 } 7331 if (task != null) { 7332 startLockTaskMode(task); 7333 } 7334 } finally { 7335 Binder.restoreCallingIdentity(ident); 7336 } 7337 } 7338 7339 @Override 7340 public void startLockTaskMode(IBinder token) { 7341 long ident = Binder.clearCallingIdentity(); 7342 try { 7343 final TaskRecord task; 7344 synchronized (this) { 7345 final ActivityRecord r = ActivityRecord.forToken(token); 7346 if (r == null) { 7347 return; 7348 } 7349 task = r.task; 7350 } 7351 if (task != null) { 7352 startLockTaskMode(task); 7353 } 7354 } finally { 7355 Binder.restoreCallingIdentity(ident); 7356 } 7357 } 7358 7359 @Override 7360 public void stopLockTaskMode() { 7361// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7362// "stopLockTaskMode()"); 7363 synchronized (this) { 7364 mStackSupervisor.setLockTaskModeLocked(null); 7365 } 7366 } 7367 7368 @Override 7369 public boolean isInLockTaskMode() { 7370 synchronized (this) { 7371 return mStackSupervisor.isInLockTaskMode(); 7372 } 7373 } 7374 7375 // ========================================================= 7376 // THUMBNAILS 7377 // ========================================================= 7378 7379 public void reportThumbnail(IBinder token, 7380 Bitmap thumbnail, CharSequence description) { 7381 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7382 final long origId = Binder.clearCallingIdentity(); 7383 sendPendingThumbnail(null, token, thumbnail, description, true); 7384 Binder.restoreCallingIdentity(origId); 7385 } 7386 7387 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7388 Bitmap thumbnail, CharSequence description, boolean always) { 7389 TaskRecord task; 7390 ArrayList<PendingThumbnailsRecord> receivers = null; 7391 7392 //System.out.println("Send pending thumbnail: " + r); 7393 7394 synchronized(this) { 7395 if (r == null) { 7396 r = ActivityRecord.isInStackLocked(token); 7397 if (r == null) { 7398 return; 7399 } 7400 } 7401 if (thumbnail == null && r.thumbHolder != null) { 7402 thumbnail = r.thumbHolder.lastThumbnail; 7403 description = r.thumbHolder.lastDescription; 7404 } 7405 if (thumbnail == null && !always) { 7406 // If there is no thumbnail, and this entry is not actually 7407 // going away, then abort for now and pick up the next 7408 // thumbnail we get. 7409 return; 7410 } 7411 task = r.task; 7412 7413 int N = mPendingThumbnails.size(); 7414 int i=0; 7415 while (i<N) { 7416 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7417 //System.out.println("Looking in " + pr.pendingRecords); 7418 if (pr.pendingRecords.remove(r)) { 7419 if (receivers == null) { 7420 receivers = new ArrayList<PendingThumbnailsRecord>(); 7421 } 7422 receivers.add(pr); 7423 if (pr.pendingRecords.size() == 0) { 7424 pr.finished = true; 7425 mPendingThumbnails.remove(i); 7426 N--; 7427 continue; 7428 } 7429 } 7430 i++; 7431 } 7432 } 7433 7434 if (receivers != null) { 7435 final int N = receivers.size(); 7436 for (int i=0; i<N; i++) { 7437 try { 7438 PendingThumbnailsRecord pr = receivers.get(i); 7439 pr.receiver.newThumbnail( 7440 task != null ? task.taskId : -1, thumbnail, description); 7441 if (pr.finished) { 7442 pr.receiver.finished(); 7443 } 7444 } catch (Exception e) { 7445 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7446 } 7447 } 7448 } 7449 } 7450 7451 // ========================================================= 7452 // CONTENT PROVIDERS 7453 // ========================================================= 7454 7455 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7456 List<ProviderInfo> providers = null; 7457 try { 7458 providers = AppGlobals.getPackageManager(). 7459 queryContentProviders(app.processName, app.uid, 7460 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7461 } catch (RemoteException ex) { 7462 } 7463 if (DEBUG_MU) 7464 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7465 int userId = app.userId; 7466 if (providers != null) { 7467 int N = providers.size(); 7468 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7469 for (int i=0; i<N; i++) { 7470 ProviderInfo cpi = 7471 (ProviderInfo)providers.get(i); 7472 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7473 cpi.name, cpi.flags); 7474 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7475 // This is a singleton provider, but a user besides the 7476 // default user is asking to initialize a process it runs 7477 // in... well, no, it doesn't actually run in this process, 7478 // it runs in the process of the default user. Get rid of it. 7479 providers.remove(i); 7480 N--; 7481 i--; 7482 continue; 7483 } 7484 7485 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7486 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7487 if (cpr == null) { 7488 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7489 mProviderMap.putProviderByClass(comp, cpr); 7490 } 7491 if (DEBUG_MU) 7492 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7493 app.pubProviders.put(cpi.name, cpr); 7494 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7495 // Don't add this if it is a platform component that is marked 7496 // to run in multiple processes, because this is actually 7497 // part of the framework so doesn't make sense to track as a 7498 // separate apk in the process. 7499 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7500 } 7501 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7502 } 7503 } 7504 return providers; 7505 } 7506 7507 /** 7508 * Check if {@link ProcessRecord} has a possible chance at accessing the 7509 * given {@link ProviderInfo}. Final permission checking is always done 7510 * in {@link ContentProvider}. 7511 */ 7512 private final String checkContentProviderPermissionLocked( 7513 ProviderInfo cpi, ProcessRecord r) { 7514 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7515 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7516 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7517 cpi.applicationInfo.uid, cpi.exported) 7518 == PackageManager.PERMISSION_GRANTED) { 7519 return null; 7520 } 7521 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7522 cpi.applicationInfo.uid, cpi.exported) 7523 == PackageManager.PERMISSION_GRANTED) { 7524 return null; 7525 } 7526 7527 PathPermission[] pps = cpi.pathPermissions; 7528 if (pps != null) { 7529 int i = pps.length; 7530 while (i > 0) { 7531 i--; 7532 PathPermission pp = pps[i]; 7533 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7534 cpi.applicationInfo.uid, cpi.exported) 7535 == PackageManager.PERMISSION_GRANTED) { 7536 return null; 7537 } 7538 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7539 cpi.applicationInfo.uid, cpi.exported) 7540 == PackageManager.PERMISSION_GRANTED) { 7541 return null; 7542 } 7543 } 7544 } 7545 7546 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7547 if (perms != null) { 7548 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7549 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7550 return null; 7551 } 7552 } 7553 } 7554 7555 String msg; 7556 if (!cpi.exported) { 7557 msg = "Permission Denial: opening provider " + cpi.name 7558 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7559 + ", uid=" + callingUid + ") that is not exported from uid " 7560 + cpi.applicationInfo.uid; 7561 } else { 7562 msg = "Permission Denial: opening provider " + cpi.name 7563 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7564 + ", uid=" + callingUid + ") requires " 7565 + cpi.readPermission + " or " + cpi.writePermission; 7566 } 7567 Slog.w(TAG, msg); 7568 return msg; 7569 } 7570 7571 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7572 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7573 if (r != null) { 7574 for (int i=0; i<r.conProviders.size(); i++) { 7575 ContentProviderConnection conn = r.conProviders.get(i); 7576 if (conn.provider == cpr) { 7577 if (DEBUG_PROVIDER) Slog.v(TAG, 7578 "Adding provider requested by " 7579 + r.processName + " from process " 7580 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7581 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7582 if (stable) { 7583 conn.stableCount++; 7584 conn.numStableIncs++; 7585 } else { 7586 conn.unstableCount++; 7587 conn.numUnstableIncs++; 7588 } 7589 return conn; 7590 } 7591 } 7592 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7593 if (stable) { 7594 conn.stableCount = 1; 7595 conn.numStableIncs = 1; 7596 } else { 7597 conn.unstableCount = 1; 7598 conn.numUnstableIncs = 1; 7599 } 7600 cpr.connections.add(conn); 7601 r.conProviders.add(conn); 7602 return conn; 7603 } 7604 cpr.addExternalProcessHandleLocked(externalProcessToken); 7605 return null; 7606 } 7607 7608 boolean decProviderCountLocked(ContentProviderConnection conn, 7609 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7610 if (conn != null) { 7611 cpr = conn.provider; 7612 if (DEBUG_PROVIDER) Slog.v(TAG, 7613 "Removing provider requested by " 7614 + conn.client.processName + " from process " 7615 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7616 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7617 if (stable) { 7618 conn.stableCount--; 7619 } else { 7620 conn.unstableCount--; 7621 } 7622 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7623 cpr.connections.remove(conn); 7624 conn.client.conProviders.remove(conn); 7625 return true; 7626 } 7627 return false; 7628 } 7629 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7630 return false; 7631 } 7632 7633 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7634 String name, IBinder token, boolean stable, int userId) { 7635 ContentProviderRecord cpr; 7636 ContentProviderConnection conn = null; 7637 ProviderInfo cpi = null; 7638 7639 synchronized(this) { 7640 ProcessRecord r = null; 7641 if (caller != null) { 7642 r = getRecordForAppLocked(caller); 7643 if (r == null) { 7644 throw new SecurityException( 7645 "Unable to find app for caller " + caller 7646 + " (pid=" + Binder.getCallingPid() 7647 + ") when getting content provider " + name); 7648 } 7649 } 7650 7651 // First check if this content provider has been published... 7652 cpr = mProviderMap.getProviderByName(name, userId); 7653 boolean providerRunning = cpr != null; 7654 if (providerRunning) { 7655 cpi = cpr.info; 7656 String msg; 7657 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7658 throw new SecurityException(msg); 7659 } 7660 7661 if (r != null && cpr.canRunHere(r)) { 7662 // This provider has been published or is in the process 7663 // of being published... but it is also allowed to run 7664 // in the caller's process, so don't make a connection 7665 // and just let the caller instantiate its own instance. 7666 ContentProviderHolder holder = cpr.newHolder(null); 7667 // don't give caller the provider object, it needs 7668 // to make its own. 7669 holder.provider = null; 7670 return holder; 7671 } 7672 7673 final long origId = Binder.clearCallingIdentity(); 7674 7675 // In this case the provider instance already exists, so we can 7676 // return it right away. 7677 conn = incProviderCountLocked(r, cpr, token, stable); 7678 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7679 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7680 // If this is a perceptible app accessing the provider, 7681 // make sure to count it as being accessed and thus 7682 // back up on the LRU list. This is good because 7683 // content providers are often expensive to start. 7684 updateLruProcessLocked(cpr.proc, false, null); 7685 } 7686 } 7687 7688 if (cpr.proc != null) { 7689 if (false) { 7690 if (cpr.name.flattenToShortString().equals( 7691 "com.android.providers.calendar/.CalendarProvider2")) { 7692 Slog.v(TAG, "****************** KILLING " 7693 + cpr.name.flattenToShortString()); 7694 Process.killProcess(cpr.proc.pid); 7695 } 7696 } 7697 boolean success = updateOomAdjLocked(cpr.proc); 7698 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7699 // NOTE: there is still a race here where a signal could be 7700 // pending on the process even though we managed to update its 7701 // adj level. Not sure what to do about this, but at least 7702 // the race is now smaller. 7703 if (!success) { 7704 // Uh oh... it looks like the provider's process 7705 // has been killed on us. We need to wait for a new 7706 // process to be started, and make sure its death 7707 // doesn't kill our process. 7708 Slog.i(TAG, 7709 "Existing provider " + cpr.name.flattenToShortString() 7710 + " is crashing; detaching " + r); 7711 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7712 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7713 if (!lastRef) { 7714 // This wasn't the last ref our process had on 7715 // the provider... we have now been killed, bail. 7716 return null; 7717 } 7718 providerRunning = false; 7719 conn = null; 7720 } 7721 } 7722 7723 Binder.restoreCallingIdentity(origId); 7724 } 7725 7726 boolean singleton; 7727 if (!providerRunning) { 7728 try { 7729 cpi = AppGlobals.getPackageManager(). 7730 resolveContentProvider(name, 7731 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7732 } catch (RemoteException ex) { 7733 } 7734 if (cpi == null) { 7735 return null; 7736 } 7737 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7738 cpi.name, cpi.flags); 7739 if (singleton) { 7740 userId = 0; 7741 } 7742 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7743 7744 String msg; 7745 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7746 throw new SecurityException(msg); 7747 } 7748 7749 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7750 && !cpi.processName.equals("system")) { 7751 // If this content provider does not run in the system 7752 // process, and the system is not yet ready to run other 7753 // processes, then fail fast instead of hanging. 7754 throw new IllegalArgumentException( 7755 "Attempt to launch content provider before system ready"); 7756 } 7757 7758 // Make sure that the user who owns this provider is started. If not, 7759 // we don't want to allow it to run. 7760 if (mStartedUsers.get(userId) == null) { 7761 Slog.w(TAG, "Unable to launch app " 7762 + cpi.applicationInfo.packageName + "/" 7763 + cpi.applicationInfo.uid + " for provider " 7764 + name + ": user " + userId + " is stopped"); 7765 return null; 7766 } 7767 7768 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7769 cpr = mProviderMap.getProviderByClass(comp, userId); 7770 final boolean firstClass = cpr == null; 7771 if (firstClass) { 7772 try { 7773 ApplicationInfo ai = 7774 AppGlobals.getPackageManager(). 7775 getApplicationInfo( 7776 cpi.applicationInfo.packageName, 7777 STOCK_PM_FLAGS, userId); 7778 if (ai == null) { 7779 Slog.w(TAG, "No package info for content provider " 7780 + cpi.name); 7781 return null; 7782 } 7783 ai = getAppInfoForUser(ai, userId); 7784 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7785 } catch (RemoteException ex) { 7786 // pm is in same process, this will never happen. 7787 } 7788 } 7789 7790 if (r != null && cpr.canRunHere(r)) { 7791 // If this is a multiprocess provider, then just return its 7792 // info and allow the caller to instantiate it. Only do 7793 // this if the provider is the same user as the caller's 7794 // process, or can run as root (so can be in any process). 7795 return cpr.newHolder(null); 7796 } 7797 7798 if (DEBUG_PROVIDER) { 7799 RuntimeException e = new RuntimeException("here"); 7800 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7801 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7802 } 7803 7804 // This is single process, and our app is now connecting to it. 7805 // See if we are already in the process of launching this 7806 // provider. 7807 final int N = mLaunchingProviders.size(); 7808 int i; 7809 for (i=0; i<N; i++) { 7810 if (mLaunchingProviders.get(i) == cpr) { 7811 break; 7812 } 7813 } 7814 7815 // If the provider is not already being launched, then get it 7816 // started. 7817 if (i >= N) { 7818 final long origId = Binder.clearCallingIdentity(); 7819 7820 try { 7821 // Content provider is now in use, its package can't be stopped. 7822 try { 7823 AppGlobals.getPackageManager().setPackageStoppedState( 7824 cpr.appInfo.packageName, false, userId); 7825 } catch (RemoteException e) { 7826 } catch (IllegalArgumentException e) { 7827 Slog.w(TAG, "Failed trying to unstop package " 7828 + cpr.appInfo.packageName + ": " + e); 7829 } 7830 7831 // Use existing process if already started 7832 ProcessRecord proc = getProcessRecordLocked( 7833 cpi.processName, cpr.appInfo.uid, false); 7834 if (proc != null && proc.thread != null) { 7835 if (DEBUG_PROVIDER) { 7836 Slog.d(TAG, "Installing in existing process " + proc); 7837 } 7838 proc.pubProviders.put(cpi.name, cpr); 7839 try { 7840 proc.thread.scheduleInstallProvider(cpi); 7841 } catch (RemoteException e) { 7842 } 7843 } else { 7844 proc = startProcessLocked(cpi.processName, 7845 cpr.appInfo, false, 0, "content provider", 7846 new ComponentName(cpi.applicationInfo.packageName, 7847 cpi.name), false, false, false); 7848 if (proc == null) { 7849 Slog.w(TAG, "Unable to launch app " 7850 + cpi.applicationInfo.packageName + "/" 7851 + cpi.applicationInfo.uid + " for provider " 7852 + name + ": process is bad"); 7853 return null; 7854 } 7855 } 7856 cpr.launchingApp = proc; 7857 mLaunchingProviders.add(cpr); 7858 } finally { 7859 Binder.restoreCallingIdentity(origId); 7860 } 7861 } 7862 7863 // Make sure the provider is published (the same provider class 7864 // may be published under multiple names). 7865 if (firstClass) { 7866 mProviderMap.putProviderByClass(comp, cpr); 7867 } 7868 7869 mProviderMap.putProviderByName(name, cpr); 7870 conn = incProviderCountLocked(r, cpr, token, stable); 7871 if (conn != null) { 7872 conn.waiting = true; 7873 } 7874 } 7875 } 7876 7877 // Wait for the provider to be published... 7878 synchronized (cpr) { 7879 while (cpr.provider == null) { 7880 if (cpr.launchingApp == null) { 7881 Slog.w(TAG, "Unable to launch app " 7882 + cpi.applicationInfo.packageName + "/" 7883 + cpi.applicationInfo.uid + " for provider " 7884 + name + ": launching app became null"); 7885 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7886 UserHandle.getUserId(cpi.applicationInfo.uid), 7887 cpi.applicationInfo.packageName, 7888 cpi.applicationInfo.uid, name); 7889 return null; 7890 } 7891 try { 7892 if (DEBUG_MU) { 7893 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7894 + cpr.launchingApp); 7895 } 7896 if (conn != null) { 7897 conn.waiting = true; 7898 } 7899 cpr.wait(); 7900 } catch (InterruptedException ex) { 7901 } finally { 7902 if (conn != null) { 7903 conn.waiting = false; 7904 } 7905 } 7906 } 7907 } 7908 return cpr != null ? cpr.newHolder(conn) : null; 7909 } 7910 7911 public final ContentProviderHolder getContentProvider( 7912 IApplicationThread caller, String name, int userId, boolean stable) { 7913 enforceNotIsolatedCaller("getContentProvider"); 7914 if (caller == null) { 7915 String msg = "null IApplicationThread when getting content provider " 7916 + name; 7917 Slog.w(TAG, msg); 7918 throw new SecurityException(msg); 7919 } 7920 7921 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7922 false, true, "getContentProvider", null); 7923 return getContentProviderImpl(caller, name, null, stable, userId); 7924 } 7925 7926 public ContentProviderHolder getContentProviderExternal( 7927 String name, int userId, IBinder token) { 7928 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7929 "Do not have permission in call getContentProviderExternal()"); 7930 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7931 false, true, "getContentProvider", null); 7932 return getContentProviderExternalUnchecked(name, token, userId); 7933 } 7934 7935 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7936 IBinder token, int userId) { 7937 return getContentProviderImpl(null, name, token, true, userId); 7938 } 7939 7940 /** 7941 * Drop a content provider from a ProcessRecord's bookkeeping 7942 */ 7943 public void removeContentProvider(IBinder connection, boolean stable) { 7944 enforceNotIsolatedCaller("removeContentProvider"); 7945 long ident = Binder.clearCallingIdentity(); 7946 try { 7947 synchronized (this) { 7948 ContentProviderConnection conn; 7949 try { 7950 conn = (ContentProviderConnection)connection; 7951 } catch (ClassCastException e) { 7952 String msg ="removeContentProvider: " + connection 7953 + " not a ContentProviderConnection"; 7954 Slog.w(TAG, msg); 7955 throw new IllegalArgumentException(msg); 7956 } 7957 if (conn == null) { 7958 throw new NullPointerException("connection is null"); 7959 } 7960 if (decProviderCountLocked(conn, null, null, stable)) { 7961 updateOomAdjLocked(); 7962 } 7963 } 7964 } finally { 7965 Binder.restoreCallingIdentity(ident); 7966 } 7967 } 7968 7969 public void removeContentProviderExternal(String name, IBinder token) { 7970 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7971 "Do not have permission in call removeContentProviderExternal()"); 7972 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7973 } 7974 7975 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7976 synchronized (this) { 7977 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7978 if(cpr == null) { 7979 //remove from mProvidersByClass 7980 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7981 return; 7982 } 7983 7984 //update content provider record entry info 7985 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7986 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7987 if (localCpr.hasExternalProcessHandles()) { 7988 if (localCpr.removeExternalProcessHandleLocked(token)) { 7989 updateOomAdjLocked(); 7990 } else { 7991 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7992 + " with no external reference for token: " 7993 + token + "."); 7994 } 7995 } else { 7996 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7997 + " with no external references."); 7998 } 7999 } 8000 } 8001 8002 public final void publishContentProviders(IApplicationThread caller, 8003 List<ContentProviderHolder> providers) { 8004 if (providers == null) { 8005 return; 8006 } 8007 8008 enforceNotIsolatedCaller("publishContentProviders"); 8009 synchronized (this) { 8010 final ProcessRecord r = getRecordForAppLocked(caller); 8011 if (DEBUG_MU) 8012 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8013 if (r == null) { 8014 throw new SecurityException( 8015 "Unable to find app for caller " + caller 8016 + " (pid=" + Binder.getCallingPid() 8017 + ") when publishing content providers"); 8018 } 8019 8020 final long origId = Binder.clearCallingIdentity(); 8021 8022 final int N = providers.size(); 8023 for (int i=0; i<N; i++) { 8024 ContentProviderHolder src = providers.get(i); 8025 if (src == null || src.info == null || src.provider == null) { 8026 continue; 8027 } 8028 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8029 if (DEBUG_MU) 8030 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8031 if (dst != null) { 8032 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8033 mProviderMap.putProviderByClass(comp, dst); 8034 String names[] = dst.info.authority.split(";"); 8035 for (int j = 0; j < names.length; j++) { 8036 mProviderMap.putProviderByName(names[j], dst); 8037 } 8038 8039 int NL = mLaunchingProviders.size(); 8040 int j; 8041 for (j=0; j<NL; j++) { 8042 if (mLaunchingProviders.get(j) == dst) { 8043 mLaunchingProviders.remove(j); 8044 j--; 8045 NL--; 8046 } 8047 } 8048 synchronized (dst) { 8049 dst.provider = src.provider; 8050 dst.proc = r; 8051 dst.notifyAll(); 8052 } 8053 updateOomAdjLocked(r); 8054 } 8055 } 8056 8057 Binder.restoreCallingIdentity(origId); 8058 } 8059 } 8060 8061 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8062 ContentProviderConnection conn; 8063 try { 8064 conn = (ContentProviderConnection)connection; 8065 } catch (ClassCastException e) { 8066 String msg ="refContentProvider: " + connection 8067 + " not a ContentProviderConnection"; 8068 Slog.w(TAG, msg); 8069 throw new IllegalArgumentException(msg); 8070 } 8071 if (conn == null) { 8072 throw new NullPointerException("connection is null"); 8073 } 8074 8075 synchronized (this) { 8076 if (stable > 0) { 8077 conn.numStableIncs += stable; 8078 } 8079 stable = conn.stableCount + stable; 8080 if (stable < 0) { 8081 throw new IllegalStateException("stableCount < 0: " + stable); 8082 } 8083 8084 if (unstable > 0) { 8085 conn.numUnstableIncs += unstable; 8086 } 8087 unstable = conn.unstableCount + unstable; 8088 if (unstable < 0) { 8089 throw new IllegalStateException("unstableCount < 0: " + unstable); 8090 } 8091 8092 if ((stable+unstable) <= 0) { 8093 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8094 + stable + " unstable=" + unstable); 8095 } 8096 conn.stableCount = stable; 8097 conn.unstableCount = unstable; 8098 return !conn.dead; 8099 } 8100 } 8101 8102 public void unstableProviderDied(IBinder connection) { 8103 ContentProviderConnection conn; 8104 try { 8105 conn = (ContentProviderConnection)connection; 8106 } catch (ClassCastException e) { 8107 String msg ="refContentProvider: " + connection 8108 + " not a ContentProviderConnection"; 8109 Slog.w(TAG, msg); 8110 throw new IllegalArgumentException(msg); 8111 } 8112 if (conn == null) { 8113 throw new NullPointerException("connection is null"); 8114 } 8115 8116 // Safely retrieve the content provider associated with the connection. 8117 IContentProvider provider; 8118 synchronized (this) { 8119 provider = conn.provider.provider; 8120 } 8121 8122 if (provider == null) { 8123 // Um, yeah, we're way ahead of you. 8124 return; 8125 } 8126 8127 // Make sure the caller is being honest with us. 8128 if (provider.asBinder().pingBinder()) { 8129 // Er, no, still looks good to us. 8130 synchronized (this) { 8131 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8132 + " says " + conn + " died, but we don't agree"); 8133 return; 8134 } 8135 } 8136 8137 // Well look at that! It's dead! 8138 synchronized (this) { 8139 if (conn.provider.provider != provider) { 8140 // But something changed... good enough. 8141 return; 8142 } 8143 8144 ProcessRecord proc = conn.provider.proc; 8145 if (proc == null || proc.thread == null) { 8146 // Seems like the process is already cleaned up. 8147 return; 8148 } 8149 8150 // As far as we're concerned, this is just like receiving a 8151 // death notification... just a bit prematurely. 8152 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8153 + ") early provider death"); 8154 final long ident = Binder.clearCallingIdentity(); 8155 try { 8156 appDiedLocked(proc, proc.pid, proc.thread); 8157 } finally { 8158 Binder.restoreCallingIdentity(ident); 8159 } 8160 } 8161 } 8162 8163 @Override 8164 public void appNotRespondingViaProvider(IBinder connection) { 8165 enforceCallingPermission( 8166 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8167 8168 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8169 if (conn == null) { 8170 Slog.w(TAG, "ContentProviderConnection is null"); 8171 return; 8172 } 8173 8174 final ProcessRecord host = conn.provider.proc; 8175 if (host == null) { 8176 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8177 return; 8178 } 8179 8180 final long token = Binder.clearCallingIdentity(); 8181 try { 8182 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8183 } finally { 8184 Binder.restoreCallingIdentity(token); 8185 } 8186 } 8187 8188 public final void installSystemProviders() { 8189 List<ProviderInfo> providers; 8190 synchronized (this) { 8191 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8192 providers = generateApplicationProvidersLocked(app); 8193 if (providers != null) { 8194 for (int i=providers.size()-1; i>=0; i--) { 8195 ProviderInfo pi = (ProviderInfo)providers.get(i); 8196 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8197 Slog.w(TAG, "Not installing system proc provider " + pi.name 8198 + ": not system .apk"); 8199 providers.remove(i); 8200 } 8201 } 8202 } 8203 } 8204 if (providers != null) { 8205 mSystemThread.installSystemProviders(providers); 8206 } 8207 8208 mCoreSettingsObserver = new CoreSettingsObserver(this); 8209 8210 mUsageStatsService.monitorPackages(); 8211 } 8212 8213 /** 8214 * Allows app to retrieve the MIME type of a URI without having permission 8215 * to access its content provider. 8216 * 8217 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8218 * 8219 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8220 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8221 */ 8222 public String getProviderMimeType(Uri uri, int userId) { 8223 enforceNotIsolatedCaller("getProviderMimeType"); 8224 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8225 userId, false, true, "getProviderMimeType", null); 8226 final String name = uri.getAuthority(); 8227 final long ident = Binder.clearCallingIdentity(); 8228 ContentProviderHolder holder = null; 8229 8230 try { 8231 holder = getContentProviderExternalUnchecked(name, null, userId); 8232 if (holder != null) { 8233 return holder.provider.getType(uri); 8234 } 8235 } catch (RemoteException e) { 8236 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8237 return null; 8238 } finally { 8239 if (holder != null) { 8240 removeContentProviderExternalUnchecked(name, null, userId); 8241 } 8242 Binder.restoreCallingIdentity(ident); 8243 } 8244 8245 return null; 8246 } 8247 8248 // ========================================================= 8249 // GLOBAL MANAGEMENT 8250 // ========================================================= 8251 8252 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8253 boolean isolated) { 8254 String proc = customProcess != null ? customProcess : info.processName; 8255 BatteryStatsImpl.Uid.Proc ps = null; 8256 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8257 int uid = info.uid; 8258 if (isolated) { 8259 int userId = UserHandle.getUserId(uid); 8260 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8261 while (true) { 8262 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8263 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8264 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8265 } 8266 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8267 mNextIsolatedProcessUid++; 8268 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8269 // No process for this uid, use it. 8270 break; 8271 } 8272 stepsLeft--; 8273 if (stepsLeft <= 0) { 8274 return null; 8275 } 8276 } 8277 } 8278 return new ProcessRecord(stats, info, proc, uid); 8279 } 8280 8281 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8282 ProcessRecord app; 8283 if (!isolated) { 8284 app = getProcessRecordLocked(info.processName, info.uid, true); 8285 } else { 8286 app = null; 8287 } 8288 8289 if (app == null) { 8290 app = newProcessRecordLocked(info, null, isolated); 8291 mProcessNames.put(info.processName, app.uid, app); 8292 if (isolated) { 8293 mIsolatedProcesses.put(app.uid, app); 8294 } 8295 updateLruProcessLocked(app, false, null); 8296 updateOomAdjLocked(); 8297 } 8298 8299 // This package really, really can not be stopped. 8300 try { 8301 AppGlobals.getPackageManager().setPackageStoppedState( 8302 info.packageName, false, UserHandle.getUserId(app.uid)); 8303 } catch (RemoteException e) { 8304 } catch (IllegalArgumentException e) { 8305 Slog.w(TAG, "Failed trying to unstop package " 8306 + info.packageName + ": " + e); 8307 } 8308 8309 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8310 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8311 app.persistent = true; 8312 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8313 } 8314 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8315 mPersistentStartingProcesses.add(app); 8316 startProcessLocked(app, "added application", app.processName); 8317 } 8318 8319 return app; 8320 } 8321 8322 public void unhandledBack() { 8323 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8324 "unhandledBack()"); 8325 8326 synchronized(this) { 8327 final long origId = Binder.clearCallingIdentity(); 8328 try { 8329 getFocusedStack().unhandledBackLocked(); 8330 } finally { 8331 Binder.restoreCallingIdentity(origId); 8332 } 8333 } 8334 } 8335 8336 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8337 enforceNotIsolatedCaller("openContentUri"); 8338 final int userId = UserHandle.getCallingUserId(); 8339 String name = uri.getAuthority(); 8340 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8341 ParcelFileDescriptor pfd = null; 8342 if (cph != null) { 8343 // We record the binder invoker's uid in thread-local storage before 8344 // going to the content provider to open the file. Later, in the code 8345 // that handles all permissions checks, we look for this uid and use 8346 // that rather than the Activity Manager's own uid. The effect is that 8347 // we do the check against the caller's permissions even though it looks 8348 // to the content provider like the Activity Manager itself is making 8349 // the request. 8350 sCallerIdentity.set(new Identity( 8351 Binder.getCallingPid(), Binder.getCallingUid())); 8352 try { 8353 pfd = cph.provider.openFile(null, uri, "r", null); 8354 } catch (FileNotFoundException e) { 8355 // do nothing; pfd will be returned null 8356 } finally { 8357 // Ensure that whatever happens, we clean up the identity state 8358 sCallerIdentity.remove(); 8359 } 8360 8361 // We've got the fd now, so we're done with the provider. 8362 removeContentProviderExternalUnchecked(name, null, userId); 8363 } else { 8364 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8365 } 8366 return pfd; 8367 } 8368 8369 // Actually is sleeping or shutting down or whatever else in the future 8370 // is an inactive state. 8371 public boolean isSleepingOrShuttingDown() { 8372 return mSleeping || mShuttingDown; 8373 } 8374 8375 public void goingToSleep() { 8376 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8377 != PackageManager.PERMISSION_GRANTED) { 8378 throw new SecurityException("Requires permission " 8379 + android.Manifest.permission.DEVICE_POWER); 8380 } 8381 8382 synchronized(this) { 8383 mWentToSleep = true; 8384 updateEventDispatchingLocked(); 8385 8386 if (!mSleeping) { 8387 mSleeping = true; 8388 mStackSupervisor.goingToSleepLocked(); 8389 8390 // Initialize the wake times of all processes. 8391 checkExcessivePowerUsageLocked(false); 8392 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8393 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8394 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8395 } 8396 } 8397 } 8398 8399 @Override 8400 public boolean shutdown(int timeout) { 8401 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8402 != PackageManager.PERMISSION_GRANTED) { 8403 throw new SecurityException("Requires permission " 8404 + android.Manifest.permission.SHUTDOWN); 8405 } 8406 8407 boolean timedout = false; 8408 8409 synchronized(this) { 8410 mShuttingDown = true; 8411 updateEventDispatchingLocked(); 8412 timedout = mStackSupervisor.shutdownLocked(timeout); 8413 } 8414 8415 mAppOpsService.shutdown(); 8416 mUsageStatsService.shutdown(); 8417 mBatteryStatsService.shutdown(); 8418 synchronized (this) { 8419 mProcessStats.shutdownLocked(); 8420 } 8421 8422 return timedout; 8423 } 8424 8425 public final void activitySlept(IBinder token) { 8426 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8427 8428 final long origId = Binder.clearCallingIdentity(); 8429 8430 synchronized (this) { 8431 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8432 if (r != null) { 8433 mStackSupervisor.activitySleptLocked(r); 8434 } 8435 } 8436 8437 Binder.restoreCallingIdentity(origId); 8438 } 8439 8440 void logLockScreen(String msg) { 8441 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8442 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8443 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8444 mStackSupervisor.mDismissKeyguardOnNextActivity); 8445 } 8446 8447 private void comeOutOfSleepIfNeededLocked() { 8448 if (!mWentToSleep && !mLockScreenShown) { 8449 if (mSleeping) { 8450 mSleeping = false; 8451 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8452 } 8453 } 8454 } 8455 8456 public void wakingUp() { 8457 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8458 != PackageManager.PERMISSION_GRANTED) { 8459 throw new SecurityException("Requires permission " 8460 + android.Manifest.permission.DEVICE_POWER); 8461 } 8462 8463 synchronized(this) { 8464 mWentToSleep = false; 8465 updateEventDispatchingLocked(); 8466 comeOutOfSleepIfNeededLocked(); 8467 } 8468 } 8469 8470 private void updateEventDispatchingLocked() { 8471 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8472 } 8473 8474 public void setLockScreenShown(boolean shown) { 8475 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8476 != PackageManager.PERMISSION_GRANTED) { 8477 throw new SecurityException("Requires permission " 8478 + android.Manifest.permission.DEVICE_POWER); 8479 } 8480 8481 synchronized(this) { 8482 long ident = Binder.clearCallingIdentity(); 8483 try { 8484 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8485 mLockScreenShown = shown; 8486 comeOutOfSleepIfNeededLocked(); 8487 } finally { 8488 Binder.restoreCallingIdentity(ident); 8489 } 8490 } 8491 } 8492 8493 public void stopAppSwitches() { 8494 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8495 != PackageManager.PERMISSION_GRANTED) { 8496 throw new SecurityException("Requires permission " 8497 + android.Manifest.permission.STOP_APP_SWITCHES); 8498 } 8499 8500 synchronized(this) { 8501 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8502 + APP_SWITCH_DELAY_TIME; 8503 mDidAppSwitch = false; 8504 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8505 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8506 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8507 } 8508 } 8509 8510 public void resumeAppSwitches() { 8511 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8512 != PackageManager.PERMISSION_GRANTED) { 8513 throw new SecurityException("Requires permission " 8514 + android.Manifest.permission.STOP_APP_SWITCHES); 8515 } 8516 8517 synchronized(this) { 8518 // Note that we don't execute any pending app switches... we will 8519 // let those wait until either the timeout, or the next start 8520 // activity request. 8521 mAppSwitchesAllowedTime = 0; 8522 } 8523 } 8524 8525 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8526 String name) { 8527 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8528 return true; 8529 } 8530 8531 final int perm = checkComponentPermission( 8532 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8533 callingUid, -1, true); 8534 if (perm == PackageManager.PERMISSION_GRANTED) { 8535 return true; 8536 } 8537 8538 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8539 return false; 8540 } 8541 8542 public void setDebugApp(String packageName, boolean waitForDebugger, 8543 boolean persistent) { 8544 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8545 "setDebugApp()"); 8546 8547 long ident = Binder.clearCallingIdentity(); 8548 try { 8549 // Note that this is not really thread safe if there are multiple 8550 // callers into it at the same time, but that's not a situation we 8551 // care about. 8552 if (persistent) { 8553 final ContentResolver resolver = mContext.getContentResolver(); 8554 Settings.Global.putString( 8555 resolver, Settings.Global.DEBUG_APP, 8556 packageName); 8557 Settings.Global.putInt( 8558 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8559 waitForDebugger ? 1 : 0); 8560 } 8561 8562 synchronized (this) { 8563 if (!persistent) { 8564 mOrigDebugApp = mDebugApp; 8565 mOrigWaitForDebugger = mWaitForDebugger; 8566 } 8567 mDebugApp = packageName; 8568 mWaitForDebugger = waitForDebugger; 8569 mDebugTransient = !persistent; 8570 if (packageName != null) { 8571 forceStopPackageLocked(packageName, -1, false, false, true, true, 8572 false, UserHandle.USER_ALL, "set debug app"); 8573 } 8574 } 8575 } finally { 8576 Binder.restoreCallingIdentity(ident); 8577 } 8578 } 8579 8580 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8581 synchronized (this) { 8582 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8583 if (!isDebuggable) { 8584 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8585 throw new SecurityException("Process not debuggable: " + app.packageName); 8586 } 8587 } 8588 8589 mOpenGlTraceApp = processName; 8590 } 8591 } 8592 8593 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8594 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8595 synchronized (this) { 8596 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8597 if (!isDebuggable) { 8598 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8599 throw new SecurityException("Process not debuggable: " + app.packageName); 8600 } 8601 } 8602 mProfileApp = processName; 8603 mProfileFile = profileFile; 8604 if (mProfileFd != null) { 8605 try { 8606 mProfileFd.close(); 8607 } catch (IOException e) { 8608 } 8609 mProfileFd = null; 8610 } 8611 mProfileFd = profileFd; 8612 mProfileType = 0; 8613 mAutoStopProfiler = autoStopProfiler; 8614 } 8615 } 8616 8617 @Override 8618 public void setAlwaysFinish(boolean enabled) { 8619 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8620 "setAlwaysFinish()"); 8621 8622 Settings.Global.putInt( 8623 mContext.getContentResolver(), 8624 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8625 8626 synchronized (this) { 8627 mAlwaysFinishActivities = enabled; 8628 } 8629 } 8630 8631 @Override 8632 public void setActivityController(IActivityController controller) { 8633 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8634 "setActivityController()"); 8635 synchronized (this) { 8636 mController = controller; 8637 Watchdog.getInstance().setActivityController(controller); 8638 } 8639 } 8640 8641 @Override 8642 public void setUserIsMonkey(boolean userIsMonkey) { 8643 synchronized (this) { 8644 synchronized (mPidsSelfLocked) { 8645 final int callingPid = Binder.getCallingPid(); 8646 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8647 if (precessRecord == null) { 8648 throw new SecurityException("Unknown process: " + callingPid); 8649 } 8650 if (precessRecord.instrumentationUiAutomationConnection == null) { 8651 throw new SecurityException("Only an instrumentation process " 8652 + "with a UiAutomation can call setUserIsMonkey"); 8653 } 8654 } 8655 mUserIsMonkey = userIsMonkey; 8656 } 8657 } 8658 8659 @Override 8660 public boolean isUserAMonkey() { 8661 synchronized (this) { 8662 // If there is a controller also implies the user is a monkey. 8663 return (mUserIsMonkey || mController != null); 8664 } 8665 } 8666 8667 public void requestBugReport() { 8668 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8669 SystemProperties.set("ctl.start", "bugreport"); 8670 } 8671 8672 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8673 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8674 } 8675 8676 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8677 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8678 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8679 } 8680 return KEY_DISPATCHING_TIMEOUT; 8681 } 8682 8683 @Override 8684 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8685 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8686 != PackageManager.PERMISSION_GRANTED) { 8687 throw new SecurityException("Requires permission " 8688 + android.Manifest.permission.FILTER_EVENTS); 8689 } 8690 ProcessRecord proc; 8691 long timeout; 8692 synchronized (this) { 8693 synchronized (mPidsSelfLocked) { 8694 proc = mPidsSelfLocked.get(pid); 8695 } 8696 timeout = getInputDispatchingTimeoutLocked(proc); 8697 } 8698 8699 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8700 return -1; 8701 } 8702 8703 return timeout; 8704 } 8705 8706 /** 8707 * Handle input dispatching timeouts. 8708 * Returns whether input dispatching should be aborted or not. 8709 */ 8710 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8711 final ActivityRecord activity, final ActivityRecord parent, 8712 final boolean aboveSystem, String reason) { 8713 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8714 != PackageManager.PERMISSION_GRANTED) { 8715 throw new SecurityException("Requires permission " 8716 + android.Manifest.permission.FILTER_EVENTS); 8717 } 8718 8719 final String annotation; 8720 if (reason == null) { 8721 annotation = "Input dispatching timed out"; 8722 } else { 8723 annotation = "Input dispatching timed out (" + reason + ")"; 8724 } 8725 8726 if (proc != null) { 8727 synchronized (this) { 8728 if (proc.debugging) { 8729 return false; 8730 } 8731 8732 if (mDidDexOpt) { 8733 // Give more time since we were dexopting. 8734 mDidDexOpt = false; 8735 return false; 8736 } 8737 8738 if (proc.instrumentationClass != null) { 8739 Bundle info = new Bundle(); 8740 info.putString("shortMsg", "keyDispatchingTimedOut"); 8741 info.putString("longMsg", annotation); 8742 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8743 return true; 8744 } 8745 } 8746 mHandler.post(new Runnable() { 8747 @Override 8748 public void run() { 8749 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8750 } 8751 }); 8752 } 8753 8754 return true; 8755 } 8756 8757 public Bundle getAssistContextExtras(int requestType) { 8758 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8759 "getAssistContextExtras()"); 8760 PendingAssistExtras pae; 8761 Bundle extras = new Bundle(); 8762 synchronized (this) { 8763 ActivityRecord activity = getFocusedStack().mResumedActivity; 8764 if (activity == null) { 8765 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8766 return null; 8767 } 8768 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8769 if (activity.app == null || activity.app.thread == null) { 8770 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8771 return extras; 8772 } 8773 if (activity.app.pid == Binder.getCallingPid()) { 8774 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8775 return extras; 8776 } 8777 pae = new PendingAssistExtras(activity); 8778 try { 8779 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8780 requestType); 8781 mPendingAssistExtras.add(pae); 8782 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8783 } catch (RemoteException e) { 8784 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8785 return extras; 8786 } 8787 } 8788 synchronized (pae) { 8789 while (!pae.haveResult) { 8790 try { 8791 pae.wait(); 8792 } catch (InterruptedException e) { 8793 } 8794 } 8795 if (pae.result != null) { 8796 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8797 } 8798 } 8799 synchronized (this) { 8800 mPendingAssistExtras.remove(pae); 8801 mHandler.removeCallbacks(pae); 8802 } 8803 return extras; 8804 } 8805 8806 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8807 PendingAssistExtras pae = (PendingAssistExtras)token; 8808 synchronized (pae) { 8809 pae.result = extras; 8810 pae.haveResult = true; 8811 pae.notifyAll(); 8812 } 8813 } 8814 8815 public void registerProcessObserver(IProcessObserver observer) { 8816 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8817 "registerProcessObserver()"); 8818 synchronized (this) { 8819 mProcessObservers.register(observer); 8820 } 8821 } 8822 8823 @Override 8824 public void unregisterProcessObserver(IProcessObserver observer) { 8825 synchronized (this) { 8826 mProcessObservers.unregister(observer); 8827 } 8828 } 8829 8830 @Override 8831 public boolean convertFromTranslucent(IBinder token) { 8832 final long origId = Binder.clearCallingIdentity(); 8833 try { 8834 synchronized (this) { 8835 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8836 if (r == null) { 8837 return false; 8838 } 8839 if (r.changeWindowTranslucency(true)) { 8840 mWindowManager.setAppFullscreen(token, true); 8841 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8842 return true; 8843 } 8844 return false; 8845 } 8846 } finally { 8847 Binder.restoreCallingIdentity(origId); 8848 } 8849 } 8850 8851 @Override 8852 public boolean convertToTranslucent(IBinder token) { 8853 final long origId = Binder.clearCallingIdentity(); 8854 try { 8855 synchronized (this) { 8856 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8857 if (r == null) { 8858 return false; 8859 } 8860 if (r.changeWindowTranslucency(false)) { 8861 r.task.stack.convertToTranslucent(r); 8862 mWindowManager.setAppFullscreen(token, false); 8863 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8864 return true; 8865 } 8866 return false; 8867 } 8868 } finally { 8869 Binder.restoreCallingIdentity(origId); 8870 } 8871 } 8872 8873 @Override 8874 public void setImmersive(IBinder token, boolean immersive) { 8875 synchronized(this) { 8876 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8877 if (r == null) { 8878 throw new IllegalArgumentException(); 8879 } 8880 r.immersive = immersive; 8881 8882 // update associated state if we're frontmost 8883 if (r == mFocusedActivity) { 8884 if (DEBUG_IMMERSIVE) { 8885 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8886 } 8887 applyUpdateLockStateLocked(r); 8888 } 8889 } 8890 } 8891 8892 @Override 8893 public boolean isImmersive(IBinder token) { 8894 synchronized (this) { 8895 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8896 if (r == null) { 8897 throw new IllegalArgumentException(); 8898 } 8899 return r.immersive; 8900 } 8901 } 8902 8903 public boolean isTopActivityImmersive() { 8904 enforceNotIsolatedCaller("startActivity"); 8905 synchronized (this) { 8906 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8907 return (r != null) ? r.immersive : false; 8908 } 8909 } 8910 8911 public final void enterSafeMode() { 8912 synchronized(this) { 8913 // It only makes sense to do this before the system is ready 8914 // and started launching other packages. 8915 if (!mSystemReady) { 8916 try { 8917 AppGlobals.getPackageManager().enterSafeMode(); 8918 } catch (RemoteException e) { 8919 } 8920 } 8921 } 8922 } 8923 8924 public final void showSafeModeOverlay() { 8925 View v = LayoutInflater.from(mContext).inflate( 8926 com.android.internal.R.layout.safe_mode, null); 8927 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8928 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8929 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8930 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8931 lp.gravity = Gravity.BOTTOM | Gravity.START; 8932 lp.format = v.getBackground().getOpacity(); 8933 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8934 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8935 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8936 ((WindowManager)mContext.getSystemService( 8937 Context.WINDOW_SERVICE)).addView(v, lp); 8938 } 8939 8940 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8941 if (!(sender instanceof PendingIntentRecord)) { 8942 return; 8943 } 8944 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8945 synchronized (stats) { 8946 if (mBatteryStatsService.isOnBattery()) { 8947 mBatteryStatsService.enforceCallingPermission(); 8948 PendingIntentRecord rec = (PendingIntentRecord)sender; 8949 int MY_UID = Binder.getCallingUid(); 8950 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8951 BatteryStatsImpl.Uid.Pkg pkg = 8952 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8953 sourcePkg != null ? sourcePkg : rec.key.packageName); 8954 pkg.incWakeupsLocked(); 8955 } 8956 } 8957 } 8958 8959 public boolean killPids(int[] pids, String pReason, boolean secure) { 8960 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8961 throw new SecurityException("killPids only available to the system"); 8962 } 8963 String reason = (pReason == null) ? "Unknown" : pReason; 8964 // XXX Note: don't acquire main activity lock here, because the window 8965 // manager calls in with its locks held. 8966 8967 boolean killed = false; 8968 synchronized (mPidsSelfLocked) { 8969 int[] types = new int[pids.length]; 8970 int worstType = 0; 8971 for (int i=0; i<pids.length; i++) { 8972 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8973 if (proc != null) { 8974 int type = proc.setAdj; 8975 types[i] = type; 8976 if (type > worstType) { 8977 worstType = type; 8978 } 8979 } 8980 } 8981 8982 // If the worst oom_adj is somewhere in the cached proc LRU range, 8983 // then constrain it so we will kill all cached procs. 8984 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8985 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8986 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8987 } 8988 8989 // If this is not a secure call, don't let it kill processes that 8990 // are important. 8991 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8992 worstType = ProcessList.SERVICE_ADJ; 8993 } 8994 8995 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8996 for (int i=0; i<pids.length; i++) { 8997 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8998 if (proc == null) { 8999 continue; 9000 } 9001 int adj = proc.setAdj; 9002 if (adj >= worstType && !proc.killedByAm) { 9003 killUnneededProcessLocked(proc, reason); 9004 killed = true; 9005 } 9006 } 9007 } 9008 return killed; 9009 } 9010 9011 @Override 9012 public void killUid(int uid, String reason) { 9013 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9014 throw new SecurityException("killUid only available to the system"); 9015 } 9016 synchronized (this) { 9017 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9018 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9019 reason != null ? reason : "kill uid"); 9020 } 9021 } 9022 9023 @Override 9024 public boolean killProcessesBelowForeground(String reason) { 9025 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9026 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9027 } 9028 9029 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9030 } 9031 9032 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9033 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9034 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9035 } 9036 9037 boolean killed = false; 9038 synchronized (mPidsSelfLocked) { 9039 final int size = mPidsSelfLocked.size(); 9040 for (int i = 0; i < size; i++) { 9041 final int pid = mPidsSelfLocked.keyAt(i); 9042 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9043 if (proc == null) continue; 9044 9045 final int adj = proc.setAdj; 9046 if (adj > belowAdj && !proc.killedByAm) { 9047 killUnneededProcessLocked(proc, reason); 9048 killed = true; 9049 } 9050 } 9051 } 9052 return killed; 9053 } 9054 9055 @Override 9056 public void hang(final IBinder who, boolean allowRestart) { 9057 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9058 != PackageManager.PERMISSION_GRANTED) { 9059 throw new SecurityException("Requires permission " 9060 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9061 } 9062 9063 final IBinder.DeathRecipient death = new DeathRecipient() { 9064 @Override 9065 public void binderDied() { 9066 synchronized (this) { 9067 notifyAll(); 9068 } 9069 } 9070 }; 9071 9072 try { 9073 who.linkToDeath(death, 0); 9074 } catch (RemoteException e) { 9075 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9076 return; 9077 } 9078 9079 synchronized (this) { 9080 Watchdog.getInstance().setAllowRestart(allowRestart); 9081 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9082 synchronized (death) { 9083 while (who.isBinderAlive()) { 9084 try { 9085 death.wait(); 9086 } catch (InterruptedException e) { 9087 } 9088 } 9089 } 9090 Watchdog.getInstance().setAllowRestart(true); 9091 } 9092 } 9093 9094 @Override 9095 public void restart() { 9096 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9097 != PackageManager.PERMISSION_GRANTED) { 9098 throw new SecurityException("Requires permission " 9099 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9100 } 9101 9102 Log.i(TAG, "Sending shutdown broadcast..."); 9103 9104 BroadcastReceiver br = new BroadcastReceiver() { 9105 @Override public void onReceive(Context context, Intent intent) { 9106 // Now the broadcast is done, finish up the low-level shutdown. 9107 Log.i(TAG, "Shutting down activity manager..."); 9108 shutdown(10000); 9109 Log.i(TAG, "Shutdown complete, restarting!"); 9110 Process.killProcess(Process.myPid()); 9111 System.exit(10); 9112 } 9113 }; 9114 9115 // First send the high-level shut down broadcast. 9116 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9117 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9118 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9119 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9120 mContext.sendOrderedBroadcastAsUser(intent, 9121 UserHandle.ALL, null, br, mHandler, 0, null, null); 9122 */ 9123 br.onReceive(mContext, intent); 9124 } 9125 9126 private long getLowRamTimeSinceIdle(long now) { 9127 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9128 } 9129 9130 @Override 9131 public void performIdleMaintenance() { 9132 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9133 != PackageManager.PERMISSION_GRANTED) { 9134 throw new SecurityException("Requires permission " 9135 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9136 } 9137 9138 synchronized (this) { 9139 final long now = SystemClock.uptimeMillis(); 9140 final long timeSinceLastIdle = now - mLastIdleTime; 9141 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9142 mLastIdleTime = now; 9143 mLowRamTimeSinceLastIdle = 0; 9144 if (mLowRamStartTime != 0) { 9145 mLowRamStartTime = now; 9146 } 9147 9148 StringBuilder sb = new StringBuilder(128); 9149 sb.append("Idle maintenance over "); 9150 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9151 sb.append(" low RAM for "); 9152 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9153 Slog.i(TAG, sb.toString()); 9154 9155 // If at least 1/3 of our time since the last idle period has been spent 9156 // with RAM low, then we want to kill processes. 9157 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9158 9159 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9160 ProcessRecord proc = mLruProcesses.get(i); 9161 if (proc.notCachedSinceIdle) { 9162 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9163 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9164 if (doKilling && proc.initialIdlePss != 0 9165 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9166 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9167 + " from " + proc.initialIdlePss + ")"); 9168 } 9169 } 9170 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9171 proc.notCachedSinceIdle = true; 9172 proc.initialIdlePss = 0; 9173 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9174 mSleeping, now); 9175 } 9176 } 9177 9178 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9179 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9180 } 9181 } 9182 9183 public final void startRunning(String pkg, String cls, String action, 9184 String data) { 9185 synchronized(this) { 9186 if (mStartRunning) { 9187 return; 9188 } 9189 mStartRunning = true; 9190 mTopComponent = pkg != null && cls != null 9191 ? new ComponentName(pkg, cls) : null; 9192 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9193 mTopData = data; 9194 if (!mSystemReady) { 9195 return; 9196 } 9197 } 9198 9199 systemReady(null); 9200 } 9201 9202 private void retrieveSettings() { 9203 final ContentResolver resolver = mContext.getContentResolver(); 9204 String debugApp = Settings.Global.getString( 9205 resolver, Settings.Global.DEBUG_APP); 9206 boolean waitForDebugger = Settings.Global.getInt( 9207 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9208 boolean alwaysFinishActivities = Settings.Global.getInt( 9209 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9210 boolean forceRtl = Settings.Global.getInt( 9211 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9212 // Transfer any global setting for forcing RTL layout, into a System Property 9213 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9214 9215 Configuration configuration = new Configuration(); 9216 Settings.System.getConfiguration(resolver, configuration); 9217 if (forceRtl) { 9218 // This will take care of setting the correct layout direction flags 9219 configuration.setLayoutDirection(configuration.locale); 9220 } 9221 9222 synchronized (this) { 9223 mDebugApp = mOrigDebugApp = debugApp; 9224 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9225 mAlwaysFinishActivities = alwaysFinishActivities; 9226 // This happens before any activities are started, so we can 9227 // change mConfiguration in-place. 9228 updateConfigurationLocked(configuration, null, false, true); 9229 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9230 } 9231 } 9232 9233 public boolean testIsSystemReady() { 9234 // no need to synchronize(this) just to read & return the value 9235 return mSystemReady; 9236 } 9237 9238 private static File getCalledPreBootReceiversFile() { 9239 File dataDir = Environment.getDataDirectory(); 9240 File systemDir = new File(dataDir, "system"); 9241 File fname = new File(systemDir, "called_pre_boots.dat"); 9242 return fname; 9243 } 9244 9245 static final int LAST_DONE_VERSION = 10000; 9246 9247 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9248 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9249 File file = getCalledPreBootReceiversFile(); 9250 FileInputStream fis = null; 9251 try { 9252 fis = new FileInputStream(file); 9253 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9254 int fvers = dis.readInt(); 9255 if (fvers == LAST_DONE_VERSION) { 9256 String vers = dis.readUTF(); 9257 String codename = dis.readUTF(); 9258 String build = dis.readUTF(); 9259 if (android.os.Build.VERSION.RELEASE.equals(vers) 9260 && android.os.Build.VERSION.CODENAME.equals(codename) 9261 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9262 int num = dis.readInt(); 9263 while (num > 0) { 9264 num--; 9265 String pkg = dis.readUTF(); 9266 String cls = dis.readUTF(); 9267 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9268 } 9269 } 9270 } 9271 } catch (FileNotFoundException e) { 9272 } catch (IOException e) { 9273 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9274 } finally { 9275 if (fis != null) { 9276 try { 9277 fis.close(); 9278 } catch (IOException e) { 9279 } 9280 } 9281 } 9282 return lastDoneReceivers; 9283 } 9284 9285 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9286 File file = getCalledPreBootReceiversFile(); 9287 FileOutputStream fos = null; 9288 DataOutputStream dos = null; 9289 try { 9290 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9291 fos = new FileOutputStream(file); 9292 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9293 dos.writeInt(LAST_DONE_VERSION); 9294 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9295 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9296 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9297 dos.writeInt(list.size()); 9298 for (int i=0; i<list.size(); i++) { 9299 dos.writeUTF(list.get(i).getPackageName()); 9300 dos.writeUTF(list.get(i).getClassName()); 9301 } 9302 } catch (IOException e) { 9303 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9304 file.delete(); 9305 } finally { 9306 FileUtils.sync(fos); 9307 if (dos != null) { 9308 try { 9309 dos.close(); 9310 } catch (IOException e) { 9311 // TODO Auto-generated catch block 9312 e.printStackTrace(); 9313 } 9314 } 9315 } 9316 } 9317 9318 public void systemReady(final Runnable goingCallback) { 9319 synchronized(this) { 9320 if (mSystemReady) { 9321 if (goingCallback != null) goingCallback.run(); 9322 return; 9323 } 9324 9325 // Check to see if there are any update receivers to run. 9326 if (!mDidUpdate) { 9327 if (mWaitingUpdate) { 9328 return; 9329 } 9330 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9331 List<ResolveInfo> ris = null; 9332 try { 9333 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9334 intent, null, 0, 0); 9335 } catch (RemoteException e) { 9336 } 9337 if (ris != null) { 9338 for (int i=ris.size()-1; i>=0; i--) { 9339 if ((ris.get(i).activityInfo.applicationInfo.flags 9340 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9341 ris.remove(i); 9342 } 9343 } 9344 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9345 9346 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9347 9348 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9349 for (int i=0; i<ris.size(); i++) { 9350 ActivityInfo ai = ris.get(i).activityInfo; 9351 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9352 if (lastDoneReceivers.contains(comp)) { 9353 // We already did the pre boot receiver for this app with the current 9354 // platform version, so don't do it again... 9355 ris.remove(i); 9356 i--; 9357 // ...however, do keep it as one that has been done, so we don't 9358 // forget about it when rewriting the file of last done receivers. 9359 doneReceivers.add(comp); 9360 } 9361 } 9362 9363 final int[] users = getUsersLocked(); 9364 for (int i=0; i<ris.size(); i++) { 9365 ActivityInfo ai = ris.get(i).activityInfo; 9366 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9367 doneReceivers.add(comp); 9368 intent.setComponent(comp); 9369 for (int j=0; j<users.length; j++) { 9370 IIntentReceiver finisher = null; 9371 if (i == ris.size()-1 && j == users.length-1) { 9372 finisher = new IIntentReceiver.Stub() { 9373 public void performReceive(Intent intent, int resultCode, 9374 String data, Bundle extras, boolean ordered, 9375 boolean sticky, int sendingUser) { 9376 // The raw IIntentReceiver interface is called 9377 // with the AM lock held, so redispatch to 9378 // execute our code without the lock. 9379 mHandler.post(new Runnable() { 9380 public void run() { 9381 synchronized (ActivityManagerService.this) { 9382 mDidUpdate = true; 9383 } 9384 writeLastDonePreBootReceivers(doneReceivers); 9385 showBootMessage(mContext.getText( 9386 R.string.android_upgrading_complete), 9387 false); 9388 systemReady(goingCallback); 9389 } 9390 }); 9391 } 9392 }; 9393 } 9394 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9395 + " for user " + users[j]); 9396 broadcastIntentLocked(null, null, intent, null, finisher, 9397 0, null, null, null, AppOpsManager.OP_NONE, 9398 true, false, MY_PID, Process.SYSTEM_UID, 9399 users[j]); 9400 if (finisher != null) { 9401 mWaitingUpdate = true; 9402 } 9403 } 9404 } 9405 } 9406 if (mWaitingUpdate) { 9407 return; 9408 } 9409 mDidUpdate = true; 9410 } 9411 9412 mAppOpsService.systemReady(); 9413 mSystemReady = true; 9414 if (!mStartRunning) { 9415 return; 9416 } 9417 } 9418 9419 ArrayList<ProcessRecord> procsToKill = null; 9420 synchronized(mPidsSelfLocked) { 9421 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9422 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9423 if (!isAllowedWhileBooting(proc.info)){ 9424 if (procsToKill == null) { 9425 procsToKill = new ArrayList<ProcessRecord>(); 9426 } 9427 procsToKill.add(proc); 9428 } 9429 } 9430 } 9431 9432 synchronized(this) { 9433 if (procsToKill != null) { 9434 for (int i=procsToKill.size()-1; i>=0; i--) { 9435 ProcessRecord proc = procsToKill.get(i); 9436 Slog.i(TAG, "Removing system update proc: " + proc); 9437 removeProcessLocked(proc, true, false, "system update done"); 9438 } 9439 } 9440 9441 // Now that we have cleaned up any update processes, we 9442 // are ready to start launching real processes and know that 9443 // we won't trample on them any more. 9444 mProcessesReady = true; 9445 } 9446 9447 Slog.i(TAG, "System now ready"); 9448 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9449 SystemClock.uptimeMillis()); 9450 9451 synchronized(this) { 9452 // Make sure we have no pre-ready processes sitting around. 9453 9454 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9455 ResolveInfo ri = mContext.getPackageManager() 9456 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9457 STOCK_PM_FLAGS); 9458 CharSequence errorMsg = null; 9459 if (ri != null) { 9460 ActivityInfo ai = ri.activityInfo; 9461 ApplicationInfo app = ai.applicationInfo; 9462 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9463 mTopAction = Intent.ACTION_FACTORY_TEST; 9464 mTopData = null; 9465 mTopComponent = new ComponentName(app.packageName, 9466 ai.name); 9467 } else { 9468 errorMsg = mContext.getResources().getText( 9469 com.android.internal.R.string.factorytest_not_system); 9470 } 9471 } else { 9472 errorMsg = mContext.getResources().getText( 9473 com.android.internal.R.string.factorytest_no_action); 9474 } 9475 if (errorMsg != null) { 9476 mTopAction = null; 9477 mTopData = null; 9478 mTopComponent = null; 9479 Message msg = Message.obtain(); 9480 msg.what = SHOW_FACTORY_ERROR_MSG; 9481 msg.getData().putCharSequence("msg", errorMsg); 9482 mHandler.sendMessage(msg); 9483 } 9484 } 9485 } 9486 9487 retrieveSettings(); 9488 9489 synchronized (this) { 9490 readGrantedUriPermissionsLocked(); 9491 } 9492 9493 if (goingCallback != null) goingCallback.run(); 9494 9495 synchronized (this) { 9496 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9497 try { 9498 List apps = AppGlobals.getPackageManager(). 9499 getPersistentApplications(STOCK_PM_FLAGS); 9500 if (apps != null) { 9501 int N = apps.size(); 9502 int i; 9503 for (i=0; i<N; i++) { 9504 ApplicationInfo info 9505 = (ApplicationInfo)apps.get(i); 9506 if (info != null && 9507 !info.packageName.equals("android")) { 9508 addAppLocked(info, false); 9509 } 9510 } 9511 } 9512 } catch (RemoteException ex) { 9513 // pm is in same process, this will never happen. 9514 } 9515 } 9516 9517 // Start up initial activity. 9518 mBooting = true; 9519 9520 try { 9521 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9522 Message msg = Message.obtain(); 9523 msg.what = SHOW_UID_ERROR_MSG; 9524 mHandler.sendMessage(msg); 9525 } 9526 } catch (RemoteException e) { 9527 } 9528 9529 long ident = Binder.clearCallingIdentity(); 9530 try { 9531 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9532 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9533 | Intent.FLAG_RECEIVER_FOREGROUND); 9534 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9535 broadcastIntentLocked(null, null, intent, 9536 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9537 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9538 intent = new Intent(Intent.ACTION_USER_STARTING); 9539 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9540 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9541 broadcastIntentLocked(null, null, intent, 9542 null, new IIntentReceiver.Stub() { 9543 @Override 9544 public void performReceive(Intent intent, int resultCode, String data, 9545 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9546 throws RemoteException { 9547 } 9548 }, 0, null, null, 9549 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9550 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9551 } finally { 9552 Binder.restoreCallingIdentity(ident); 9553 } 9554 mStackSupervisor.resumeTopActivitiesLocked(); 9555 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9556 } 9557 } 9558 9559 private boolean makeAppCrashingLocked(ProcessRecord app, 9560 String shortMsg, String longMsg, String stackTrace) { 9561 app.crashing = true; 9562 app.crashingReport = generateProcessError(app, 9563 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9564 startAppProblemLocked(app); 9565 app.stopFreezingAllLocked(); 9566 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9567 } 9568 9569 private void makeAppNotRespondingLocked(ProcessRecord app, 9570 String activity, String shortMsg, String longMsg) { 9571 app.notResponding = true; 9572 app.notRespondingReport = generateProcessError(app, 9573 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9574 activity, shortMsg, longMsg, null); 9575 startAppProblemLocked(app); 9576 app.stopFreezingAllLocked(); 9577 } 9578 9579 /** 9580 * Generate a process error record, suitable for attachment to a ProcessRecord. 9581 * 9582 * @param app The ProcessRecord in which the error occurred. 9583 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9584 * ActivityManager.AppErrorStateInfo 9585 * @param activity The activity associated with the crash, if known. 9586 * @param shortMsg Short message describing the crash. 9587 * @param longMsg Long message describing the crash. 9588 * @param stackTrace Full crash stack trace, may be null. 9589 * 9590 * @return Returns a fully-formed AppErrorStateInfo record. 9591 */ 9592 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9593 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9594 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9595 9596 report.condition = condition; 9597 report.processName = app.processName; 9598 report.pid = app.pid; 9599 report.uid = app.info.uid; 9600 report.tag = activity; 9601 report.shortMsg = shortMsg; 9602 report.longMsg = longMsg; 9603 report.stackTrace = stackTrace; 9604 9605 return report; 9606 } 9607 9608 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9609 synchronized (this) { 9610 app.crashing = false; 9611 app.crashingReport = null; 9612 app.notResponding = false; 9613 app.notRespondingReport = null; 9614 if (app.anrDialog == fromDialog) { 9615 app.anrDialog = null; 9616 } 9617 if (app.waitDialog == fromDialog) { 9618 app.waitDialog = null; 9619 } 9620 if (app.pid > 0 && app.pid != MY_PID) { 9621 handleAppCrashLocked(app, null, null, null); 9622 killUnneededProcessLocked(app, "user request after error"); 9623 } 9624 } 9625 } 9626 9627 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9628 String stackTrace) { 9629 long now = SystemClock.uptimeMillis(); 9630 9631 Long crashTime; 9632 if (!app.isolated) { 9633 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9634 } else { 9635 crashTime = null; 9636 } 9637 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9638 // This process loses! 9639 Slog.w(TAG, "Process " + app.info.processName 9640 + " has crashed too many times: killing!"); 9641 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9642 app.userId, app.info.processName, app.uid); 9643 mStackSupervisor.handleAppCrashLocked(app); 9644 if (!app.persistent) { 9645 // We don't want to start this process again until the user 9646 // explicitly does so... but for persistent process, we really 9647 // need to keep it running. If a persistent process is actually 9648 // repeatedly crashing, then badness for everyone. 9649 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9650 app.info.processName); 9651 if (!app.isolated) { 9652 // XXX We don't have a way to mark isolated processes 9653 // as bad, since they don't have a peristent identity. 9654 mBadProcesses.put(app.info.processName, app.uid, 9655 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9656 mProcessCrashTimes.remove(app.info.processName, app.uid); 9657 } 9658 app.bad = true; 9659 app.removed = true; 9660 // Don't let services in this process be restarted and potentially 9661 // annoy the user repeatedly. Unless it is persistent, since those 9662 // processes run critical code. 9663 removeProcessLocked(app, false, false, "crash"); 9664 mStackSupervisor.resumeTopActivitiesLocked(); 9665 return false; 9666 } 9667 mStackSupervisor.resumeTopActivitiesLocked(); 9668 } else { 9669 mStackSupervisor.finishTopRunningActivityLocked(app); 9670 } 9671 9672 // Bump up the crash count of any services currently running in the proc. 9673 for (int i=app.services.size()-1; i>=0; i--) { 9674 // Any services running in the application need to be placed 9675 // back in the pending list. 9676 ServiceRecord sr = app.services.valueAt(i); 9677 sr.crashCount++; 9678 } 9679 9680 // If the crashing process is what we consider to be the "home process" and it has been 9681 // replaced by a third-party app, clear the package preferred activities from packages 9682 // with a home activity running in the process to prevent a repeatedly crashing app 9683 // from blocking the user to manually clear the list. 9684 final ArrayList<ActivityRecord> activities = app.activities; 9685 if (app == mHomeProcess && activities.size() > 0 9686 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9687 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9688 final ActivityRecord r = activities.get(activityNdx); 9689 if (r.isHomeActivity()) { 9690 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9691 try { 9692 ActivityThread.getPackageManager() 9693 .clearPackagePreferredActivities(r.packageName); 9694 } catch (RemoteException c) { 9695 // pm is in same process, this will never happen. 9696 } 9697 } 9698 } 9699 } 9700 9701 if (!app.isolated) { 9702 // XXX Can't keep track of crash times for isolated processes, 9703 // because they don't have a perisistent identity. 9704 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9705 } 9706 9707 return true; 9708 } 9709 9710 void startAppProblemLocked(ProcessRecord app) { 9711 if (app.userId == mCurrentUserId) { 9712 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9713 mContext, app.info.packageName, app.info.flags); 9714 } else { 9715 // If this app is not running under the current user, then we 9716 // can't give it a report button because that would require 9717 // launching the report UI under a different user. 9718 app.errorReportReceiver = null; 9719 } 9720 skipCurrentReceiverLocked(app); 9721 } 9722 9723 void skipCurrentReceiverLocked(ProcessRecord app) { 9724 for (BroadcastQueue queue : mBroadcastQueues) { 9725 queue.skipCurrentReceiverLocked(app); 9726 } 9727 } 9728 9729 /** 9730 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9731 * The application process will exit immediately after this call returns. 9732 * @param app object of the crashing app, null for the system server 9733 * @param crashInfo describing the exception 9734 */ 9735 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9736 ProcessRecord r = findAppProcess(app, "Crash"); 9737 final String processName = app == null ? "system_server" 9738 : (r == null ? "unknown" : r.processName); 9739 9740 handleApplicationCrashInner("crash", r, processName, crashInfo); 9741 } 9742 9743 /* Native crash reporting uses this inner version because it needs to be somewhat 9744 * decoupled from the AM-managed cleanup lifecycle 9745 */ 9746 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9747 ApplicationErrorReport.CrashInfo crashInfo) { 9748 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9749 UserHandle.getUserId(Binder.getCallingUid()), processName, 9750 r == null ? -1 : r.info.flags, 9751 crashInfo.exceptionClassName, 9752 crashInfo.exceptionMessage, 9753 crashInfo.throwFileName, 9754 crashInfo.throwLineNumber); 9755 9756 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9757 9758 crashApplication(r, crashInfo); 9759 } 9760 9761 public void handleApplicationStrictModeViolation( 9762 IBinder app, 9763 int violationMask, 9764 StrictMode.ViolationInfo info) { 9765 ProcessRecord r = findAppProcess(app, "StrictMode"); 9766 if (r == null) { 9767 return; 9768 } 9769 9770 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9771 Integer stackFingerprint = info.hashCode(); 9772 boolean logIt = true; 9773 synchronized (mAlreadyLoggedViolatedStacks) { 9774 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9775 logIt = false; 9776 // TODO: sub-sample into EventLog for these, with 9777 // the info.durationMillis? Then we'd get 9778 // the relative pain numbers, without logging all 9779 // the stack traces repeatedly. We'd want to do 9780 // likewise in the client code, which also does 9781 // dup suppression, before the Binder call. 9782 } else { 9783 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9784 mAlreadyLoggedViolatedStacks.clear(); 9785 } 9786 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9787 } 9788 } 9789 if (logIt) { 9790 logStrictModeViolationToDropBox(r, info); 9791 } 9792 } 9793 9794 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9795 AppErrorResult result = new AppErrorResult(); 9796 synchronized (this) { 9797 final long origId = Binder.clearCallingIdentity(); 9798 9799 Message msg = Message.obtain(); 9800 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9801 HashMap<String, Object> data = new HashMap<String, Object>(); 9802 data.put("result", result); 9803 data.put("app", r); 9804 data.put("violationMask", violationMask); 9805 data.put("info", info); 9806 msg.obj = data; 9807 mHandler.sendMessage(msg); 9808 9809 Binder.restoreCallingIdentity(origId); 9810 } 9811 int res = result.get(); 9812 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9813 } 9814 } 9815 9816 // Depending on the policy in effect, there could be a bunch of 9817 // these in quick succession so we try to batch these together to 9818 // minimize disk writes, number of dropbox entries, and maximize 9819 // compression, by having more fewer, larger records. 9820 private void logStrictModeViolationToDropBox( 9821 ProcessRecord process, 9822 StrictMode.ViolationInfo info) { 9823 if (info == null) { 9824 return; 9825 } 9826 final boolean isSystemApp = process == null || 9827 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9828 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9829 final String processName = process == null ? "unknown" : process.processName; 9830 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9831 final DropBoxManager dbox = (DropBoxManager) 9832 mContext.getSystemService(Context.DROPBOX_SERVICE); 9833 9834 // Exit early if the dropbox isn't configured to accept this report type. 9835 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9836 9837 boolean bufferWasEmpty; 9838 boolean needsFlush; 9839 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9840 synchronized (sb) { 9841 bufferWasEmpty = sb.length() == 0; 9842 appendDropBoxProcessHeaders(process, processName, sb); 9843 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9844 sb.append("System-App: ").append(isSystemApp).append("\n"); 9845 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9846 if (info.violationNumThisLoop != 0) { 9847 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9848 } 9849 if (info.numAnimationsRunning != 0) { 9850 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9851 } 9852 if (info.broadcastIntentAction != null) { 9853 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9854 } 9855 if (info.durationMillis != -1) { 9856 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9857 } 9858 if (info.numInstances != -1) { 9859 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9860 } 9861 if (info.tags != null) { 9862 for (String tag : info.tags) { 9863 sb.append("Span-Tag: ").append(tag).append("\n"); 9864 } 9865 } 9866 sb.append("\n"); 9867 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9868 sb.append(info.crashInfo.stackTrace); 9869 } 9870 sb.append("\n"); 9871 9872 // Only buffer up to ~64k. Various logging bits truncate 9873 // things at 128k. 9874 needsFlush = (sb.length() > 64 * 1024); 9875 } 9876 9877 // Flush immediately if the buffer's grown too large, or this 9878 // is a non-system app. Non-system apps are isolated with a 9879 // different tag & policy and not batched. 9880 // 9881 // Batching is useful during internal testing with 9882 // StrictMode settings turned up high. Without batching, 9883 // thousands of separate files could be created on boot. 9884 if (!isSystemApp || needsFlush) { 9885 new Thread("Error dump: " + dropboxTag) { 9886 @Override 9887 public void run() { 9888 String report; 9889 synchronized (sb) { 9890 report = sb.toString(); 9891 sb.delete(0, sb.length()); 9892 sb.trimToSize(); 9893 } 9894 if (report.length() != 0) { 9895 dbox.addText(dropboxTag, report); 9896 } 9897 } 9898 }.start(); 9899 return; 9900 } 9901 9902 // System app batching: 9903 if (!bufferWasEmpty) { 9904 // An existing dropbox-writing thread is outstanding, so 9905 // we don't need to start it up. The existing thread will 9906 // catch the buffer appends we just did. 9907 return; 9908 } 9909 9910 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9911 // (After this point, we shouldn't access AMS internal data structures.) 9912 new Thread("Error dump: " + dropboxTag) { 9913 @Override 9914 public void run() { 9915 // 5 second sleep to let stacks arrive and be batched together 9916 try { 9917 Thread.sleep(5000); // 5 seconds 9918 } catch (InterruptedException e) {} 9919 9920 String errorReport; 9921 synchronized (mStrictModeBuffer) { 9922 errorReport = mStrictModeBuffer.toString(); 9923 if (errorReport.length() == 0) { 9924 return; 9925 } 9926 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9927 mStrictModeBuffer.trimToSize(); 9928 } 9929 dbox.addText(dropboxTag, errorReport); 9930 } 9931 }.start(); 9932 } 9933 9934 /** 9935 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9936 * @param app object of the crashing app, null for the system server 9937 * @param tag reported by the caller 9938 * @param crashInfo describing the context of the error 9939 * @return true if the process should exit immediately (WTF is fatal) 9940 */ 9941 public boolean handleApplicationWtf(IBinder app, String tag, 9942 ApplicationErrorReport.CrashInfo crashInfo) { 9943 ProcessRecord r = findAppProcess(app, "WTF"); 9944 final String processName = app == null ? "system_server" 9945 : (r == null ? "unknown" : r.processName); 9946 9947 EventLog.writeEvent(EventLogTags.AM_WTF, 9948 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9949 processName, 9950 r == null ? -1 : r.info.flags, 9951 tag, crashInfo.exceptionMessage); 9952 9953 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9954 9955 if (r != null && r.pid != Process.myPid() && 9956 Settings.Global.getInt(mContext.getContentResolver(), 9957 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9958 crashApplication(r, crashInfo); 9959 return true; 9960 } else { 9961 return false; 9962 } 9963 } 9964 9965 /** 9966 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9967 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9968 */ 9969 private ProcessRecord findAppProcess(IBinder app, String reason) { 9970 if (app == null) { 9971 return null; 9972 } 9973 9974 synchronized (this) { 9975 final int NP = mProcessNames.getMap().size(); 9976 for (int ip=0; ip<NP; ip++) { 9977 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9978 final int NA = apps.size(); 9979 for (int ia=0; ia<NA; ia++) { 9980 ProcessRecord p = apps.valueAt(ia); 9981 if (p.thread != null && p.thread.asBinder() == app) { 9982 return p; 9983 } 9984 } 9985 } 9986 9987 Slog.w(TAG, "Can't find mystery application for " + reason 9988 + " from pid=" + Binder.getCallingPid() 9989 + " uid=" + Binder.getCallingUid() + ": " + app); 9990 return null; 9991 } 9992 } 9993 9994 /** 9995 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9996 * to append various headers to the dropbox log text. 9997 */ 9998 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9999 StringBuilder sb) { 10000 // Watchdog thread ends up invoking this function (with 10001 // a null ProcessRecord) to add the stack file to dropbox. 10002 // Do not acquire a lock on this (am) in such cases, as it 10003 // could cause a potential deadlock, if and when watchdog 10004 // is invoked due to unavailability of lock on am and it 10005 // would prevent watchdog from killing system_server. 10006 if (process == null) { 10007 sb.append("Process: ").append(processName).append("\n"); 10008 return; 10009 } 10010 // Note: ProcessRecord 'process' is guarded by the service 10011 // instance. (notably process.pkgList, which could otherwise change 10012 // concurrently during execution of this method) 10013 synchronized (this) { 10014 sb.append("Process: ").append(processName).append("\n"); 10015 int flags = process.info.flags; 10016 IPackageManager pm = AppGlobals.getPackageManager(); 10017 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10018 for (int ip=0; ip<process.pkgList.size(); ip++) { 10019 String pkg = process.pkgList.keyAt(ip); 10020 sb.append("Package: ").append(pkg); 10021 try { 10022 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10023 if (pi != null) { 10024 sb.append(" v").append(pi.versionCode); 10025 if (pi.versionName != null) { 10026 sb.append(" (").append(pi.versionName).append(")"); 10027 } 10028 } 10029 } catch (RemoteException e) { 10030 Slog.e(TAG, "Error getting package info: " + pkg, e); 10031 } 10032 sb.append("\n"); 10033 } 10034 } 10035 } 10036 10037 private static String processClass(ProcessRecord process) { 10038 if (process == null || process.pid == MY_PID) { 10039 return "system_server"; 10040 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10041 return "system_app"; 10042 } else { 10043 return "data_app"; 10044 } 10045 } 10046 10047 /** 10048 * Write a description of an error (crash, WTF, ANR) to the drop box. 10049 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10050 * @param process which caused the error, null means the system server 10051 * @param activity which triggered the error, null if unknown 10052 * @param parent activity related to the error, null if unknown 10053 * @param subject line related to the error, null if absent 10054 * @param report in long form describing the error, null if absent 10055 * @param logFile to include in the report, null if none 10056 * @param crashInfo giving an application stack trace, null if absent 10057 */ 10058 public void addErrorToDropBox(String eventType, 10059 ProcessRecord process, String processName, ActivityRecord activity, 10060 ActivityRecord parent, String subject, 10061 final String report, final File logFile, 10062 final ApplicationErrorReport.CrashInfo crashInfo) { 10063 // NOTE -- this must never acquire the ActivityManagerService lock, 10064 // otherwise the watchdog may be prevented from resetting the system. 10065 10066 final String dropboxTag = processClass(process) + "_" + eventType; 10067 final DropBoxManager dbox = (DropBoxManager) 10068 mContext.getSystemService(Context.DROPBOX_SERVICE); 10069 10070 // Exit early if the dropbox isn't configured to accept this report type. 10071 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10072 10073 final StringBuilder sb = new StringBuilder(1024); 10074 appendDropBoxProcessHeaders(process, processName, sb); 10075 if (activity != null) { 10076 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10077 } 10078 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10079 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10080 } 10081 if (parent != null && parent != activity) { 10082 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10083 } 10084 if (subject != null) { 10085 sb.append("Subject: ").append(subject).append("\n"); 10086 } 10087 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10088 if (Debug.isDebuggerConnected()) { 10089 sb.append("Debugger: Connected\n"); 10090 } 10091 sb.append("\n"); 10092 10093 // Do the rest in a worker thread to avoid blocking the caller on I/O 10094 // (After this point, we shouldn't access AMS internal data structures.) 10095 Thread worker = new Thread("Error dump: " + dropboxTag) { 10096 @Override 10097 public void run() { 10098 if (report != null) { 10099 sb.append(report); 10100 } 10101 if (logFile != null) { 10102 try { 10103 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10104 "\n\n[[TRUNCATED]]")); 10105 } catch (IOException e) { 10106 Slog.e(TAG, "Error reading " + logFile, e); 10107 } 10108 } 10109 if (crashInfo != null && crashInfo.stackTrace != null) { 10110 sb.append(crashInfo.stackTrace); 10111 } 10112 10113 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10114 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10115 if (lines > 0) { 10116 sb.append("\n"); 10117 10118 // Merge several logcat streams, and take the last N lines 10119 InputStreamReader input = null; 10120 try { 10121 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10122 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10123 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10124 10125 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10126 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10127 input = new InputStreamReader(logcat.getInputStream()); 10128 10129 int num; 10130 char[] buf = new char[8192]; 10131 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10132 } catch (IOException e) { 10133 Slog.e(TAG, "Error running logcat", e); 10134 } finally { 10135 if (input != null) try { input.close(); } catch (IOException e) {} 10136 } 10137 } 10138 10139 dbox.addText(dropboxTag, sb.toString()); 10140 } 10141 }; 10142 10143 if (process == null) { 10144 // If process is null, we are being called from some internal code 10145 // and may be about to die -- run this synchronously. 10146 worker.run(); 10147 } else { 10148 worker.start(); 10149 } 10150 } 10151 10152 /** 10153 * Bring up the "unexpected error" dialog box for a crashing app. 10154 * Deal with edge cases (intercepts from instrumented applications, 10155 * ActivityController, error intent receivers, that sort of thing). 10156 * @param r the application crashing 10157 * @param crashInfo describing the failure 10158 */ 10159 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10160 long timeMillis = System.currentTimeMillis(); 10161 String shortMsg = crashInfo.exceptionClassName; 10162 String longMsg = crashInfo.exceptionMessage; 10163 String stackTrace = crashInfo.stackTrace; 10164 if (shortMsg != null && longMsg != null) { 10165 longMsg = shortMsg + ": " + longMsg; 10166 } else if (shortMsg != null) { 10167 longMsg = shortMsg; 10168 } 10169 10170 AppErrorResult result = new AppErrorResult(); 10171 synchronized (this) { 10172 if (mController != null) { 10173 try { 10174 String name = r != null ? r.processName : null; 10175 int pid = r != null ? r.pid : Binder.getCallingPid(); 10176 if (!mController.appCrashed(name, pid, 10177 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10178 Slog.w(TAG, "Force-killing crashed app " + name 10179 + " at watcher's request"); 10180 Process.killProcess(pid); 10181 return; 10182 } 10183 } catch (RemoteException e) { 10184 mController = null; 10185 Watchdog.getInstance().setActivityController(null); 10186 } 10187 } 10188 10189 final long origId = Binder.clearCallingIdentity(); 10190 10191 // If this process is running instrumentation, finish it. 10192 if (r != null && r.instrumentationClass != null) { 10193 Slog.w(TAG, "Error in app " + r.processName 10194 + " running instrumentation " + r.instrumentationClass + ":"); 10195 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10196 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10197 Bundle info = new Bundle(); 10198 info.putString("shortMsg", shortMsg); 10199 info.putString("longMsg", longMsg); 10200 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10201 Binder.restoreCallingIdentity(origId); 10202 return; 10203 } 10204 10205 // If we can't identify the process or it's already exceeded its crash quota, 10206 // quit right away without showing a crash dialog. 10207 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10208 Binder.restoreCallingIdentity(origId); 10209 return; 10210 } 10211 10212 Message msg = Message.obtain(); 10213 msg.what = SHOW_ERROR_MSG; 10214 HashMap data = new HashMap(); 10215 data.put("result", result); 10216 data.put("app", r); 10217 msg.obj = data; 10218 mHandler.sendMessage(msg); 10219 10220 Binder.restoreCallingIdentity(origId); 10221 } 10222 10223 int res = result.get(); 10224 10225 Intent appErrorIntent = null; 10226 synchronized (this) { 10227 if (r != null && !r.isolated) { 10228 // XXX Can't keep track of crash time for isolated processes, 10229 // since they don't have a persistent identity. 10230 mProcessCrashTimes.put(r.info.processName, r.uid, 10231 SystemClock.uptimeMillis()); 10232 } 10233 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10234 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10235 } 10236 } 10237 10238 if (appErrorIntent != null) { 10239 try { 10240 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10241 } catch (ActivityNotFoundException e) { 10242 Slog.w(TAG, "bug report receiver dissappeared", e); 10243 } 10244 } 10245 } 10246 10247 Intent createAppErrorIntentLocked(ProcessRecord r, 10248 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10249 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10250 if (report == null) { 10251 return null; 10252 } 10253 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10254 result.setComponent(r.errorReportReceiver); 10255 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10256 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10257 return result; 10258 } 10259 10260 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10261 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10262 if (r.errorReportReceiver == null) { 10263 return null; 10264 } 10265 10266 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10267 return null; 10268 } 10269 10270 ApplicationErrorReport report = new ApplicationErrorReport(); 10271 report.packageName = r.info.packageName; 10272 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10273 report.processName = r.processName; 10274 report.time = timeMillis; 10275 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10276 10277 if (r.crashing || r.forceCrashReport) { 10278 report.type = ApplicationErrorReport.TYPE_CRASH; 10279 report.crashInfo = crashInfo; 10280 } else if (r.notResponding) { 10281 report.type = ApplicationErrorReport.TYPE_ANR; 10282 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10283 10284 report.anrInfo.activity = r.notRespondingReport.tag; 10285 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10286 report.anrInfo.info = r.notRespondingReport.longMsg; 10287 } 10288 10289 return report; 10290 } 10291 10292 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10293 enforceNotIsolatedCaller("getProcessesInErrorState"); 10294 // assume our apps are happy - lazy create the list 10295 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10296 10297 final boolean allUsers = ActivityManager.checkUidPermission( 10298 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10299 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10300 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10301 10302 synchronized (this) { 10303 10304 // iterate across all processes 10305 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10306 ProcessRecord app = mLruProcesses.get(i); 10307 if (!allUsers && app.userId != userId) { 10308 continue; 10309 } 10310 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10311 // This one's in trouble, so we'll generate a report for it 10312 // crashes are higher priority (in case there's a crash *and* an anr) 10313 ActivityManager.ProcessErrorStateInfo report = null; 10314 if (app.crashing) { 10315 report = app.crashingReport; 10316 } else if (app.notResponding) { 10317 report = app.notRespondingReport; 10318 } 10319 10320 if (report != null) { 10321 if (errList == null) { 10322 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10323 } 10324 errList.add(report); 10325 } else { 10326 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10327 " crashing = " + app.crashing + 10328 " notResponding = " + app.notResponding); 10329 } 10330 } 10331 } 10332 } 10333 10334 return errList; 10335 } 10336 10337 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10338 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10339 if (currApp != null) { 10340 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10341 } 10342 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10343 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10344 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10345 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10346 if (currApp != null) { 10347 currApp.lru = 0; 10348 } 10349 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10350 } else if (adj >= ProcessList.SERVICE_ADJ) { 10351 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10352 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10353 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10354 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10355 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10356 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10357 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10358 } else { 10359 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10360 } 10361 } 10362 10363 private void fillInProcMemInfo(ProcessRecord app, 10364 ActivityManager.RunningAppProcessInfo outInfo) { 10365 outInfo.pid = app.pid; 10366 outInfo.uid = app.info.uid; 10367 if (mHeavyWeightProcess == app) { 10368 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10369 } 10370 if (app.persistent) { 10371 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10372 } 10373 if (app.activities.size() > 0) { 10374 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10375 } 10376 outInfo.lastTrimLevel = app.trimMemoryLevel; 10377 int adj = app.curAdj; 10378 outInfo.importance = oomAdjToImportance(adj, outInfo); 10379 outInfo.importanceReasonCode = app.adjTypeCode; 10380 } 10381 10382 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10383 enforceNotIsolatedCaller("getRunningAppProcesses"); 10384 // Lazy instantiation of list 10385 List<ActivityManager.RunningAppProcessInfo> runList = null; 10386 final boolean allUsers = ActivityManager.checkUidPermission( 10387 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10388 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10389 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10390 synchronized (this) { 10391 // Iterate across all processes 10392 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10393 ProcessRecord app = mLruProcesses.get(i); 10394 if (!allUsers && app.userId != userId) { 10395 continue; 10396 } 10397 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10398 // Generate process state info for running application 10399 ActivityManager.RunningAppProcessInfo currApp = 10400 new ActivityManager.RunningAppProcessInfo(app.processName, 10401 app.pid, app.getPackageList()); 10402 fillInProcMemInfo(app, currApp); 10403 if (app.adjSource instanceof ProcessRecord) { 10404 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10405 currApp.importanceReasonImportance = oomAdjToImportance( 10406 app.adjSourceOom, null); 10407 } else if (app.adjSource instanceof ActivityRecord) { 10408 ActivityRecord r = (ActivityRecord)app.adjSource; 10409 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10410 } 10411 if (app.adjTarget instanceof ComponentName) { 10412 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10413 } 10414 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10415 // + " lru=" + currApp.lru); 10416 if (runList == null) { 10417 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10418 } 10419 runList.add(currApp); 10420 } 10421 } 10422 } 10423 return runList; 10424 } 10425 10426 public List<ApplicationInfo> getRunningExternalApplications() { 10427 enforceNotIsolatedCaller("getRunningExternalApplications"); 10428 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10429 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10430 if (runningApps != null && runningApps.size() > 0) { 10431 Set<String> extList = new HashSet<String>(); 10432 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10433 if (app.pkgList != null) { 10434 for (String pkg : app.pkgList) { 10435 extList.add(pkg); 10436 } 10437 } 10438 } 10439 IPackageManager pm = AppGlobals.getPackageManager(); 10440 for (String pkg : extList) { 10441 try { 10442 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10443 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10444 retList.add(info); 10445 } 10446 } catch (RemoteException e) { 10447 } 10448 } 10449 } 10450 return retList; 10451 } 10452 10453 @Override 10454 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10455 enforceNotIsolatedCaller("getMyMemoryState"); 10456 synchronized (this) { 10457 ProcessRecord proc; 10458 synchronized (mPidsSelfLocked) { 10459 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10460 } 10461 fillInProcMemInfo(proc, outInfo); 10462 } 10463 } 10464 10465 @Override 10466 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10467 if (checkCallingPermission(android.Manifest.permission.DUMP) 10468 != PackageManager.PERMISSION_GRANTED) { 10469 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10470 + Binder.getCallingPid() 10471 + ", uid=" + Binder.getCallingUid() 10472 + " without permission " 10473 + android.Manifest.permission.DUMP); 10474 return; 10475 } 10476 10477 boolean dumpAll = false; 10478 boolean dumpClient = false; 10479 String dumpPackage = null; 10480 10481 int opti = 0; 10482 while (opti < args.length) { 10483 String opt = args[opti]; 10484 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10485 break; 10486 } 10487 opti++; 10488 if ("-a".equals(opt)) { 10489 dumpAll = true; 10490 } else if ("-c".equals(opt)) { 10491 dumpClient = true; 10492 } else if ("-h".equals(opt)) { 10493 pw.println("Activity manager dump options:"); 10494 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10495 pw.println(" cmd may be one of:"); 10496 pw.println(" a[ctivities]: activity stack state"); 10497 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10498 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10499 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10500 pw.println(" o[om]: out of memory management"); 10501 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10502 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10503 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10504 pw.println(" service [COMP_SPEC]: service client-side state"); 10505 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10506 pw.println(" all: dump all activities"); 10507 pw.println(" top: dump the top activity"); 10508 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10509 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10510 pw.println(" a partial substring in a component name, a"); 10511 pw.println(" hex object identifier."); 10512 pw.println(" -a: include all available server state."); 10513 pw.println(" -c: include client state."); 10514 return; 10515 } else { 10516 pw.println("Unknown argument: " + opt + "; use -h for help"); 10517 } 10518 } 10519 10520 long origId = Binder.clearCallingIdentity(); 10521 boolean more = false; 10522 // Is the caller requesting to dump a particular piece of data? 10523 if (opti < args.length) { 10524 String cmd = args[opti]; 10525 opti++; 10526 if ("activities".equals(cmd) || "a".equals(cmd)) { 10527 synchronized (this) { 10528 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10529 } 10530 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10531 String[] newArgs; 10532 String name; 10533 if (opti >= args.length) { 10534 name = null; 10535 newArgs = EMPTY_STRING_ARRAY; 10536 } else { 10537 name = args[opti]; 10538 opti++; 10539 newArgs = new String[args.length - opti]; 10540 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10541 args.length - opti); 10542 } 10543 synchronized (this) { 10544 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10545 } 10546 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10547 String[] newArgs; 10548 String name; 10549 if (opti >= args.length) { 10550 name = null; 10551 newArgs = EMPTY_STRING_ARRAY; 10552 } else { 10553 name = args[opti]; 10554 opti++; 10555 newArgs = new String[args.length - opti]; 10556 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10557 args.length - opti); 10558 } 10559 synchronized (this) { 10560 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10561 } 10562 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10563 String[] newArgs; 10564 String name; 10565 if (opti >= args.length) { 10566 name = null; 10567 newArgs = EMPTY_STRING_ARRAY; 10568 } else { 10569 name = args[opti]; 10570 opti++; 10571 newArgs = new String[args.length - opti]; 10572 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10573 args.length - opti); 10574 } 10575 synchronized (this) { 10576 dumpProcessesLocked(fd, pw, args, opti, true, name); 10577 } 10578 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10579 synchronized (this) { 10580 dumpOomLocked(fd, pw, args, opti, true); 10581 } 10582 } else if ("provider".equals(cmd)) { 10583 String[] newArgs; 10584 String name; 10585 if (opti >= args.length) { 10586 name = null; 10587 newArgs = EMPTY_STRING_ARRAY; 10588 } else { 10589 name = args[opti]; 10590 opti++; 10591 newArgs = new String[args.length - opti]; 10592 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10593 } 10594 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10595 pw.println("No providers match: " + name); 10596 pw.println("Use -h for help."); 10597 } 10598 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10599 synchronized (this) { 10600 dumpProvidersLocked(fd, pw, args, opti, true, null); 10601 } 10602 } else if ("service".equals(cmd)) { 10603 String[] newArgs; 10604 String name; 10605 if (opti >= args.length) { 10606 name = null; 10607 newArgs = EMPTY_STRING_ARRAY; 10608 } else { 10609 name = args[opti]; 10610 opti++; 10611 newArgs = new String[args.length - opti]; 10612 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10613 args.length - opti); 10614 } 10615 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10616 pw.println("No services match: " + name); 10617 pw.println("Use -h for help."); 10618 } 10619 } else if ("package".equals(cmd)) { 10620 String[] newArgs; 10621 if (opti >= args.length) { 10622 pw.println("package: no package name specified"); 10623 pw.println("Use -h for help."); 10624 } else { 10625 dumpPackage = args[opti]; 10626 opti++; 10627 newArgs = new String[args.length - opti]; 10628 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10629 args.length - opti); 10630 args = newArgs; 10631 opti = 0; 10632 more = true; 10633 } 10634 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10635 synchronized (this) { 10636 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10637 } 10638 } else { 10639 // Dumping a single activity? 10640 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10641 pw.println("Bad activity command, or no activities match: " + cmd); 10642 pw.println("Use -h for help."); 10643 } 10644 } 10645 if (!more) { 10646 Binder.restoreCallingIdentity(origId); 10647 return; 10648 } 10649 } 10650 10651 // No piece of data specified, dump everything. 10652 synchronized (this) { 10653 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10654 pw.println(); 10655 if (dumpAll) { 10656 pw.println("-------------------------------------------------------------------------------"); 10657 } 10658 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10659 pw.println(); 10660 if (dumpAll) { 10661 pw.println("-------------------------------------------------------------------------------"); 10662 } 10663 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10664 pw.println(); 10665 if (dumpAll) { 10666 pw.println("-------------------------------------------------------------------------------"); 10667 } 10668 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10669 pw.println(); 10670 if (dumpAll) { 10671 pw.println("-------------------------------------------------------------------------------"); 10672 } 10673 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10674 pw.println(); 10675 if (dumpAll) { 10676 pw.println("-------------------------------------------------------------------------------"); 10677 } 10678 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10679 } 10680 Binder.restoreCallingIdentity(origId); 10681 } 10682 10683 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10684 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10685 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10686 10687 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10688 dumpPackage); 10689 boolean needSep = printedAnything; 10690 10691 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10692 dumpPackage, needSep, " mFocusedActivity: "); 10693 if (printed) { 10694 printedAnything = true; 10695 needSep = false; 10696 } 10697 10698 if (dumpPackage == null) { 10699 if (needSep) { 10700 pw.println(); 10701 } 10702 needSep = true; 10703 printedAnything = true; 10704 mStackSupervisor.dump(pw, " "); 10705 } 10706 10707 if (mRecentTasks.size() > 0) { 10708 boolean printedHeader = false; 10709 10710 final int N = mRecentTasks.size(); 10711 for (int i=0; i<N; i++) { 10712 TaskRecord tr = mRecentTasks.get(i); 10713 if (dumpPackage != null) { 10714 if (tr.realActivity == null || 10715 !dumpPackage.equals(tr.realActivity)) { 10716 continue; 10717 } 10718 } 10719 if (!printedHeader) { 10720 if (needSep) { 10721 pw.println(); 10722 } 10723 pw.println(" Recent tasks:"); 10724 printedHeader = true; 10725 printedAnything = true; 10726 } 10727 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10728 pw.println(tr); 10729 if (dumpAll) { 10730 mRecentTasks.get(i).dump(pw, " "); 10731 } 10732 } 10733 } 10734 10735 if (!printedAnything) { 10736 pw.println(" (nothing)"); 10737 } 10738 } 10739 10740 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10741 int opti, boolean dumpAll, String dumpPackage) { 10742 boolean needSep = false; 10743 boolean printedAnything = false; 10744 int numPers = 0; 10745 10746 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10747 10748 if (dumpAll) { 10749 final int NP = mProcessNames.getMap().size(); 10750 for (int ip=0; ip<NP; ip++) { 10751 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10752 final int NA = procs.size(); 10753 for (int ia=0; ia<NA; ia++) { 10754 ProcessRecord r = procs.valueAt(ia); 10755 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10756 continue; 10757 } 10758 if (!needSep) { 10759 pw.println(" All known processes:"); 10760 needSep = true; 10761 printedAnything = true; 10762 } 10763 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10764 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10765 pw.print(" "); pw.println(r); 10766 r.dump(pw, " "); 10767 if (r.persistent) { 10768 numPers++; 10769 } 10770 } 10771 } 10772 } 10773 10774 if (mIsolatedProcesses.size() > 0) { 10775 boolean printed = false; 10776 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10777 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10778 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10779 continue; 10780 } 10781 if (!printed) { 10782 if (needSep) { 10783 pw.println(); 10784 } 10785 pw.println(" Isolated process list (sorted by uid):"); 10786 printedAnything = true; 10787 printed = true; 10788 needSep = true; 10789 } 10790 pw.println(String.format("%sIsolated #%2d: %s", 10791 " ", i, r.toString())); 10792 } 10793 } 10794 10795 if (mLruProcesses.size() > 0) { 10796 if (needSep) { 10797 pw.println(); 10798 } 10799 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10800 pw.print(" total, non-act at "); 10801 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10802 pw.print(", non-svc at "); 10803 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10804 pw.println("):"); 10805 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10806 needSep = true; 10807 printedAnything = true; 10808 } 10809 10810 if (dumpAll || dumpPackage != null) { 10811 synchronized (mPidsSelfLocked) { 10812 boolean printed = false; 10813 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10814 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10815 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10816 continue; 10817 } 10818 if (!printed) { 10819 if (needSep) pw.println(); 10820 needSep = true; 10821 pw.println(" PID mappings:"); 10822 printed = true; 10823 printedAnything = true; 10824 } 10825 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10826 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10827 } 10828 } 10829 } 10830 10831 if (mForegroundProcesses.size() > 0) { 10832 synchronized (mPidsSelfLocked) { 10833 boolean printed = false; 10834 for (int i=0; i<mForegroundProcesses.size(); i++) { 10835 ProcessRecord r = mPidsSelfLocked.get( 10836 mForegroundProcesses.valueAt(i).pid); 10837 if (dumpPackage != null && (r == null 10838 || !r.pkgList.containsKey(dumpPackage))) { 10839 continue; 10840 } 10841 if (!printed) { 10842 if (needSep) pw.println(); 10843 needSep = true; 10844 pw.println(" Foreground Processes:"); 10845 printed = true; 10846 printedAnything = true; 10847 } 10848 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10849 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10850 } 10851 } 10852 } 10853 10854 if (mPersistentStartingProcesses.size() > 0) { 10855 if (needSep) pw.println(); 10856 needSep = true; 10857 printedAnything = true; 10858 pw.println(" Persisent processes that are starting:"); 10859 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10860 "Starting Norm", "Restarting PERS", dumpPackage); 10861 } 10862 10863 if (mRemovedProcesses.size() > 0) { 10864 if (needSep) pw.println(); 10865 needSep = true; 10866 printedAnything = true; 10867 pw.println(" Processes that are being removed:"); 10868 dumpProcessList(pw, this, mRemovedProcesses, " ", 10869 "Removed Norm", "Removed PERS", dumpPackage); 10870 } 10871 10872 if (mProcessesOnHold.size() > 0) { 10873 if (needSep) pw.println(); 10874 needSep = true; 10875 printedAnything = true; 10876 pw.println(" Processes that are on old until the system is ready:"); 10877 dumpProcessList(pw, this, mProcessesOnHold, " ", 10878 "OnHold Norm", "OnHold PERS", dumpPackage); 10879 } 10880 10881 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10882 10883 if (mProcessCrashTimes.getMap().size() > 0) { 10884 boolean printed = false; 10885 long now = SystemClock.uptimeMillis(); 10886 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10887 final int NP = pmap.size(); 10888 for (int ip=0; ip<NP; ip++) { 10889 String pname = pmap.keyAt(ip); 10890 SparseArray<Long> uids = pmap.valueAt(ip); 10891 final int N = uids.size(); 10892 for (int i=0; i<N; i++) { 10893 int puid = uids.keyAt(i); 10894 ProcessRecord r = mProcessNames.get(pname, puid); 10895 if (dumpPackage != null && (r == null 10896 || !r.pkgList.containsKey(dumpPackage))) { 10897 continue; 10898 } 10899 if (!printed) { 10900 if (needSep) pw.println(); 10901 needSep = true; 10902 pw.println(" Time since processes crashed:"); 10903 printed = true; 10904 printedAnything = true; 10905 } 10906 pw.print(" Process "); pw.print(pname); 10907 pw.print(" uid "); pw.print(puid); 10908 pw.print(": last crashed "); 10909 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10910 pw.println(" ago"); 10911 } 10912 } 10913 } 10914 10915 if (mBadProcesses.getMap().size() > 0) { 10916 boolean printed = false; 10917 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10918 final int NP = pmap.size(); 10919 for (int ip=0; ip<NP; ip++) { 10920 String pname = pmap.keyAt(ip); 10921 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10922 final int N = uids.size(); 10923 for (int i=0; i<N; i++) { 10924 int puid = uids.keyAt(i); 10925 ProcessRecord r = mProcessNames.get(pname, puid); 10926 if (dumpPackage != null && (r == null 10927 || !r.pkgList.containsKey(dumpPackage))) { 10928 continue; 10929 } 10930 if (!printed) { 10931 if (needSep) pw.println(); 10932 needSep = true; 10933 pw.println(" Bad processes:"); 10934 printedAnything = true; 10935 } 10936 BadProcessInfo info = uids.valueAt(i); 10937 pw.print(" Bad process "); pw.print(pname); 10938 pw.print(" uid "); pw.print(puid); 10939 pw.print(": crashed at time "); pw.println(info.time); 10940 if (info.shortMsg != null) { 10941 pw.print(" Short msg: "); pw.println(info.shortMsg); 10942 } 10943 if (info.longMsg != null) { 10944 pw.print(" Long msg: "); pw.println(info.longMsg); 10945 } 10946 if (info.stack != null) { 10947 pw.println(" Stack:"); 10948 int lastPos = 0; 10949 for (int pos=0; pos<info.stack.length(); pos++) { 10950 if (info.stack.charAt(pos) == '\n') { 10951 pw.print(" "); 10952 pw.write(info.stack, lastPos, pos-lastPos); 10953 pw.println(); 10954 lastPos = pos+1; 10955 } 10956 } 10957 if (lastPos < info.stack.length()) { 10958 pw.print(" "); 10959 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10960 pw.println(); 10961 } 10962 } 10963 } 10964 } 10965 } 10966 10967 if (dumpPackage == null) { 10968 pw.println(); 10969 needSep = false; 10970 pw.println(" mStartedUsers:"); 10971 for (int i=0; i<mStartedUsers.size(); i++) { 10972 UserStartedState uss = mStartedUsers.valueAt(i); 10973 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10974 pw.print(": "); uss.dump("", pw); 10975 } 10976 pw.print(" mStartedUserArray: ["); 10977 for (int i=0; i<mStartedUserArray.length; i++) { 10978 if (i > 0) pw.print(", "); 10979 pw.print(mStartedUserArray[i]); 10980 } 10981 pw.println("]"); 10982 pw.print(" mUserLru: ["); 10983 for (int i=0; i<mUserLru.size(); i++) { 10984 if (i > 0) pw.print(", "); 10985 pw.print(mUserLru.get(i)); 10986 } 10987 pw.println("]"); 10988 if (dumpAll) { 10989 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10990 } 10991 } 10992 if (mHomeProcess != null && (dumpPackage == null 10993 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10994 if (needSep) { 10995 pw.println(); 10996 needSep = false; 10997 } 10998 pw.println(" mHomeProcess: " + mHomeProcess); 10999 } 11000 if (mPreviousProcess != null && (dumpPackage == null 11001 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11002 if (needSep) { 11003 pw.println(); 11004 needSep = false; 11005 } 11006 pw.println(" mPreviousProcess: " + mPreviousProcess); 11007 } 11008 if (dumpAll) { 11009 StringBuilder sb = new StringBuilder(128); 11010 sb.append(" mPreviousProcessVisibleTime: "); 11011 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11012 pw.println(sb); 11013 } 11014 if (mHeavyWeightProcess != null && (dumpPackage == null 11015 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11016 if (needSep) { 11017 pw.println(); 11018 needSep = false; 11019 } 11020 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11021 } 11022 if (dumpPackage == null) { 11023 pw.println(" mConfiguration: " + mConfiguration); 11024 } 11025 if (dumpAll) { 11026 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11027 if (mCompatModePackages.getPackages().size() > 0) { 11028 boolean printed = false; 11029 for (Map.Entry<String, Integer> entry 11030 : mCompatModePackages.getPackages().entrySet()) { 11031 String pkg = entry.getKey(); 11032 int mode = entry.getValue(); 11033 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11034 continue; 11035 } 11036 if (!printed) { 11037 pw.println(" mScreenCompatPackages:"); 11038 printed = true; 11039 } 11040 pw.print(" "); pw.print(pkg); pw.print(": "); 11041 pw.print(mode); pw.println(); 11042 } 11043 } 11044 } 11045 if (dumpPackage == null) { 11046 if (mSleeping || mWentToSleep || mLockScreenShown) { 11047 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11048 + " mLockScreenShown " + mLockScreenShown); 11049 } 11050 if (mShuttingDown) { 11051 pw.println(" mShuttingDown=" + mShuttingDown); 11052 } 11053 } 11054 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11055 || mOrigWaitForDebugger) { 11056 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11057 || dumpPackage.equals(mOrigDebugApp)) { 11058 if (needSep) { 11059 pw.println(); 11060 needSep = false; 11061 } 11062 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11063 + " mDebugTransient=" + mDebugTransient 11064 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11065 } 11066 } 11067 if (mOpenGlTraceApp != null) { 11068 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11069 if (needSep) { 11070 pw.println(); 11071 needSep = false; 11072 } 11073 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11074 } 11075 } 11076 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11077 || mProfileFd != null) { 11078 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11079 if (needSep) { 11080 pw.println(); 11081 needSep = false; 11082 } 11083 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11084 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11085 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11086 + mAutoStopProfiler); 11087 } 11088 } 11089 if (dumpPackage == null) { 11090 if (mAlwaysFinishActivities || mController != null) { 11091 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11092 + " mController=" + mController); 11093 } 11094 if (dumpAll) { 11095 pw.println(" Total persistent processes: " + numPers); 11096 pw.println(" mStartRunning=" + mStartRunning 11097 + " mProcessesReady=" + mProcessesReady 11098 + " mSystemReady=" + mSystemReady); 11099 pw.println(" mBooting=" + mBooting 11100 + " mBooted=" + mBooted 11101 + " mFactoryTest=" + mFactoryTest); 11102 pw.print(" mLastPowerCheckRealtime="); 11103 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11104 pw.println(""); 11105 pw.print(" mLastPowerCheckUptime="); 11106 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11107 pw.println(""); 11108 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11109 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11110 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11111 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11112 + " (" + mLruProcesses.size() + " total)" 11113 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11114 + " mNumServiceProcs=" + mNumServiceProcs 11115 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11116 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11117 + " mLastMemoryLevel" + mLastMemoryLevel 11118 + " mLastNumProcesses" + mLastNumProcesses); 11119 long now = SystemClock.uptimeMillis(); 11120 pw.print(" mLastIdleTime="); 11121 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11122 pw.print(" mLowRamSinceLastIdle="); 11123 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11124 pw.println(); 11125 } 11126 } 11127 11128 if (!printedAnything) { 11129 pw.println(" (nothing)"); 11130 } 11131 } 11132 11133 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11134 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11135 if (mProcessesToGc.size() > 0) { 11136 boolean printed = false; 11137 long now = SystemClock.uptimeMillis(); 11138 for (int i=0; i<mProcessesToGc.size(); i++) { 11139 ProcessRecord proc = mProcessesToGc.get(i); 11140 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11141 continue; 11142 } 11143 if (!printed) { 11144 if (needSep) pw.println(); 11145 needSep = true; 11146 pw.println(" Processes that are waiting to GC:"); 11147 printed = true; 11148 } 11149 pw.print(" Process "); pw.println(proc); 11150 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11151 pw.print(", last gced="); 11152 pw.print(now-proc.lastRequestedGc); 11153 pw.print(" ms ago, last lowMem="); 11154 pw.print(now-proc.lastLowMemory); 11155 pw.println(" ms ago"); 11156 11157 } 11158 } 11159 return needSep; 11160 } 11161 11162 void printOomLevel(PrintWriter pw, String name, int adj) { 11163 pw.print(" "); 11164 if (adj >= 0) { 11165 pw.print(' '); 11166 if (adj < 10) pw.print(' '); 11167 } else { 11168 if (adj > -10) pw.print(' '); 11169 } 11170 pw.print(adj); 11171 pw.print(": "); 11172 pw.print(name); 11173 pw.print(" ("); 11174 pw.print(mProcessList.getMemLevel(adj)/1024); 11175 pw.println(" kB)"); 11176 } 11177 11178 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11179 int opti, boolean dumpAll) { 11180 boolean needSep = false; 11181 11182 if (mLruProcesses.size() > 0) { 11183 if (needSep) pw.println(); 11184 needSep = true; 11185 pw.println(" OOM levels:"); 11186 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11187 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11188 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11189 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11190 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11191 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11192 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11193 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11194 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11195 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11196 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11197 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11198 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11199 11200 if (needSep) pw.println(); 11201 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11202 pw.print(" total, non-act at "); 11203 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11204 pw.print(", non-svc at "); 11205 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11206 pw.println("):"); 11207 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11208 needSep = true; 11209 } 11210 11211 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11212 11213 pw.println(); 11214 pw.println(" mHomeProcess: " + mHomeProcess); 11215 pw.println(" mPreviousProcess: " + mPreviousProcess); 11216 if (mHeavyWeightProcess != null) { 11217 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11218 } 11219 11220 return true; 11221 } 11222 11223 /** 11224 * There are three ways to call this: 11225 * - no provider specified: dump all the providers 11226 * - a flattened component name that matched an existing provider was specified as the 11227 * first arg: dump that one provider 11228 * - the first arg isn't the flattened component name of an existing provider: 11229 * dump all providers whose component contains the first arg as a substring 11230 */ 11231 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11232 int opti, boolean dumpAll) { 11233 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11234 } 11235 11236 static class ItemMatcher { 11237 ArrayList<ComponentName> components; 11238 ArrayList<String> strings; 11239 ArrayList<Integer> objects; 11240 boolean all; 11241 11242 ItemMatcher() { 11243 all = true; 11244 } 11245 11246 void build(String name) { 11247 ComponentName componentName = ComponentName.unflattenFromString(name); 11248 if (componentName != null) { 11249 if (components == null) { 11250 components = new ArrayList<ComponentName>(); 11251 } 11252 components.add(componentName); 11253 all = false; 11254 } else { 11255 int objectId = 0; 11256 // Not a '/' separated full component name; maybe an object ID? 11257 try { 11258 objectId = Integer.parseInt(name, 16); 11259 if (objects == null) { 11260 objects = new ArrayList<Integer>(); 11261 } 11262 objects.add(objectId); 11263 all = false; 11264 } catch (RuntimeException e) { 11265 // Not an integer; just do string match. 11266 if (strings == null) { 11267 strings = new ArrayList<String>(); 11268 } 11269 strings.add(name); 11270 all = false; 11271 } 11272 } 11273 } 11274 11275 int build(String[] args, int opti) { 11276 for (; opti<args.length; opti++) { 11277 String name = args[opti]; 11278 if ("--".equals(name)) { 11279 return opti+1; 11280 } 11281 build(name); 11282 } 11283 return opti; 11284 } 11285 11286 boolean match(Object object, ComponentName comp) { 11287 if (all) { 11288 return true; 11289 } 11290 if (components != null) { 11291 for (int i=0; i<components.size(); i++) { 11292 if (components.get(i).equals(comp)) { 11293 return true; 11294 } 11295 } 11296 } 11297 if (objects != null) { 11298 for (int i=0; i<objects.size(); i++) { 11299 if (System.identityHashCode(object) == objects.get(i)) { 11300 return true; 11301 } 11302 } 11303 } 11304 if (strings != null) { 11305 String flat = comp.flattenToString(); 11306 for (int i=0; i<strings.size(); i++) { 11307 if (flat.contains(strings.get(i))) { 11308 return true; 11309 } 11310 } 11311 } 11312 return false; 11313 } 11314 } 11315 11316 /** 11317 * There are three things that cmd can be: 11318 * - a flattened component name that matches an existing activity 11319 * - the cmd arg isn't the flattened component name of an existing activity: 11320 * dump all activity whose component contains the cmd as a substring 11321 * - A hex number of the ActivityRecord object instance. 11322 */ 11323 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11324 int opti, boolean dumpAll) { 11325 ArrayList<ActivityRecord> activities; 11326 11327 synchronized (this) { 11328 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11329 } 11330 11331 if (activities.size() <= 0) { 11332 return false; 11333 } 11334 11335 String[] newArgs = new String[args.length - opti]; 11336 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11337 11338 TaskRecord lastTask = null; 11339 boolean needSep = false; 11340 for (int i=activities.size()-1; i>=0; i--) { 11341 ActivityRecord r = activities.get(i); 11342 if (needSep) { 11343 pw.println(); 11344 } 11345 needSep = true; 11346 synchronized (this) { 11347 if (lastTask != r.task) { 11348 lastTask = r.task; 11349 pw.print("TASK "); pw.print(lastTask.affinity); 11350 pw.print(" id="); pw.println(lastTask.taskId); 11351 if (dumpAll) { 11352 lastTask.dump(pw, " "); 11353 } 11354 } 11355 } 11356 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11357 } 11358 return true; 11359 } 11360 11361 /** 11362 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11363 * there is a thread associated with the activity. 11364 */ 11365 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11366 final ActivityRecord r, String[] args, boolean dumpAll) { 11367 String innerPrefix = prefix + " "; 11368 synchronized (this) { 11369 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11370 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11371 pw.print(" pid="); 11372 if (r.app != null) pw.println(r.app.pid); 11373 else pw.println("(not running)"); 11374 if (dumpAll) { 11375 r.dump(pw, innerPrefix); 11376 } 11377 } 11378 if (r.app != null && r.app.thread != null) { 11379 // flush anything that is already in the PrintWriter since the thread is going 11380 // to write to the file descriptor directly 11381 pw.flush(); 11382 try { 11383 TransferPipe tp = new TransferPipe(); 11384 try { 11385 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11386 r.appToken, innerPrefix, args); 11387 tp.go(fd); 11388 } finally { 11389 tp.kill(); 11390 } 11391 } catch (IOException e) { 11392 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11393 } catch (RemoteException e) { 11394 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11395 } 11396 } 11397 } 11398 11399 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11400 int opti, boolean dumpAll, String dumpPackage) { 11401 boolean needSep = false; 11402 boolean onlyHistory = false; 11403 boolean printedAnything = false; 11404 11405 if ("history".equals(dumpPackage)) { 11406 if (opti < args.length && "-s".equals(args[opti])) { 11407 dumpAll = false; 11408 } 11409 onlyHistory = true; 11410 dumpPackage = null; 11411 } 11412 11413 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11414 if (!onlyHistory && dumpAll) { 11415 if (mRegisteredReceivers.size() > 0) { 11416 boolean printed = false; 11417 Iterator it = mRegisteredReceivers.values().iterator(); 11418 while (it.hasNext()) { 11419 ReceiverList r = (ReceiverList)it.next(); 11420 if (dumpPackage != null && (r.app == null || 11421 !dumpPackage.equals(r.app.info.packageName))) { 11422 continue; 11423 } 11424 if (!printed) { 11425 pw.println(" Registered Receivers:"); 11426 needSep = true; 11427 printed = true; 11428 printedAnything = true; 11429 } 11430 pw.print(" * "); pw.println(r); 11431 r.dump(pw, " "); 11432 } 11433 } 11434 11435 if (mReceiverResolver.dump(pw, needSep ? 11436 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11437 " ", dumpPackage, false)) { 11438 needSep = true; 11439 printedAnything = true; 11440 } 11441 } 11442 11443 for (BroadcastQueue q : mBroadcastQueues) { 11444 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11445 printedAnything |= needSep; 11446 } 11447 11448 needSep = true; 11449 11450 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11451 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11452 if (needSep) { 11453 pw.println(); 11454 } 11455 needSep = true; 11456 printedAnything = true; 11457 pw.print(" Sticky broadcasts for user "); 11458 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11459 StringBuilder sb = new StringBuilder(128); 11460 for (Map.Entry<String, ArrayList<Intent>> ent 11461 : mStickyBroadcasts.valueAt(user).entrySet()) { 11462 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11463 if (dumpAll) { 11464 pw.println(":"); 11465 ArrayList<Intent> intents = ent.getValue(); 11466 final int N = intents.size(); 11467 for (int i=0; i<N; i++) { 11468 sb.setLength(0); 11469 sb.append(" Intent: "); 11470 intents.get(i).toShortString(sb, false, true, false, false); 11471 pw.println(sb.toString()); 11472 Bundle bundle = intents.get(i).getExtras(); 11473 if (bundle != null) { 11474 pw.print(" "); 11475 pw.println(bundle.toString()); 11476 } 11477 } 11478 } else { 11479 pw.println(""); 11480 } 11481 } 11482 } 11483 } 11484 11485 if (!onlyHistory && dumpAll) { 11486 pw.println(); 11487 for (BroadcastQueue queue : mBroadcastQueues) { 11488 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11489 + queue.mBroadcastsScheduled); 11490 } 11491 pw.println(" mHandler:"); 11492 mHandler.dump(new PrintWriterPrinter(pw), " "); 11493 needSep = true; 11494 printedAnything = true; 11495 } 11496 11497 if (!printedAnything) { 11498 pw.println(" (nothing)"); 11499 } 11500 } 11501 11502 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11503 int opti, boolean dumpAll, String dumpPackage) { 11504 boolean needSep; 11505 boolean printedAnything = false; 11506 11507 ItemMatcher matcher = new ItemMatcher(); 11508 matcher.build(args, opti); 11509 11510 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11511 11512 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11513 printedAnything |= needSep; 11514 11515 if (mLaunchingProviders.size() > 0) { 11516 boolean printed = false; 11517 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11518 ContentProviderRecord r = mLaunchingProviders.get(i); 11519 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11520 continue; 11521 } 11522 if (!printed) { 11523 if (needSep) pw.println(); 11524 needSep = true; 11525 pw.println(" Launching content providers:"); 11526 printed = true; 11527 printedAnything = true; 11528 } 11529 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11530 pw.println(r); 11531 } 11532 } 11533 11534 if (mGrantedUriPermissions.size() > 0) { 11535 boolean printed = false; 11536 int dumpUid = -2; 11537 if (dumpPackage != null) { 11538 try { 11539 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11540 } catch (NameNotFoundException e) { 11541 dumpUid = -1; 11542 } 11543 } 11544 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11545 int uid = mGrantedUriPermissions.keyAt(i); 11546 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11547 continue; 11548 } 11549 ArrayMap<Uri, UriPermission> perms 11550 = mGrantedUriPermissions.valueAt(i); 11551 if (!printed) { 11552 if (needSep) pw.println(); 11553 needSep = true; 11554 pw.println(" Granted Uri Permissions:"); 11555 printed = true; 11556 printedAnything = true; 11557 } 11558 pw.print(" * UID "); pw.print(uid); 11559 pw.println(" holds:"); 11560 for (UriPermission perm : perms.values()) { 11561 pw.print(" "); pw.println(perm); 11562 if (dumpAll) { 11563 perm.dump(pw, " "); 11564 } 11565 } 11566 } 11567 } 11568 11569 if (!printedAnything) { 11570 pw.println(" (nothing)"); 11571 } 11572 } 11573 11574 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11575 int opti, boolean dumpAll, String dumpPackage) { 11576 boolean printed = false; 11577 11578 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11579 11580 if (mIntentSenderRecords.size() > 0) { 11581 Iterator<WeakReference<PendingIntentRecord>> it 11582 = mIntentSenderRecords.values().iterator(); 11583 while (it.hasNext()) { 11584 WeakReference<PendingIntentRecord> ref = it.next(); 11585 PendingIntentRecord rec = ref != null ? ref.get(): null; 11586 if (dumpPackage != null && (rec == null 11587 || !dumpPackage.equals(rec.key.packageName))) { 11588 continue; 11589 } 11590 printed = true; 11591 if (rec != null) { 11592 pw.print(" * "); pw.println(rec); 11593 if (dumpAll) { 11594 rec.dump(pw, " "); 11595 } 11596 } else { 11597 pw.print(" * "); pw.println(ref); 11598 } 11599 } 11600 } 11601 11602 if (!printed) { 11603 pw.println(" (nothing)"); 11604 } 11605 } 11606 11607 private static final int dumpProcessList(PrintWriter pw, 11608 ActivityManagerService service, List list, 11609 String prefix, String normalLabel, String persistentLabel, 11610 String dumpPackage) { 11611 int numPers = 0; 11612 final int N = list.size()-1; 11613 for (int i=N; i>=0; i--) { 11614 ProcessRecord r = (ProcessRecord)list.get(i); 11615 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11616 continue; 11617 } 11618 pw.println(String.format("%s%s #%2d: %s", 11619 prefix, (r.persistent ? persistentLabel : normalLabel), 11620 i, r.toString())); 11621 if (r.persistent) { 11622 numPers++; 11623 } 11624 } 11625 return numPers; 11626 } 11627 11628 private static final boolean dumpProcessOomList(PrintWriter pw, 11629 ActivityManagerService service, List<ProcessRecord> origList, 11630 String prefix, String normalLabel, String persistentLabel, 11631 boolean inclDetails, String dumpPackage) { 11632 11633 ArrayList<Pair<ProcessRecord, Integer>> list 11634 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11635 for (int i=0; i<origList.size(); i++) { 11636 ProcessRecord r = origList.get(i); 11637 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11638 continue; 11639 } 11640 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11641 } 11642 11643 if (list.size() <= 0) { 11644 return false; 11645 } 11646 11647 Comparator<Pair<ProcessRecord, Integer>> comparator 11648 = new Comparator<Pair<ProcessRecord, Integer>>() { 11649 @Override 11650 public int compare(Pair<ProcessRecord, Integer> object1, 11651 Pair<ProcessRecord, Integer> object2) { 11652 if (object1.first.setAdj != object2.first.setAdj) { 11653 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11654 } 11655 if (object1.second.intValue() != object2.second.intValue()) { 11656 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11657 } 11658 return 0; 11659 } 11660 }; 11661 11662 Collections.sort(list, comparator); 11663 11664 final long curRealtime = SystemClock.elapsedRealtime(); 11665 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11666 final long curUptime = SystemClock.uptimeMillis(); 11667 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11668 11669 for (int i=list.size()-1; i>=0; i--) { 11670 ProcessRecord r = list.get(i).first; 11671 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11672 char schedGroup; 11673 switch (r.setSchedGroup) { 11674 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11675 schedGroup = 'B'; 11676 break; 11677 case Process.THREAD_GROUP_DEFAULT: 11678 schedGroup = 'F'; 11679 break; 11680 default: 11681 schedGroup = '?'; 11682 break; 11683 } 11684 char foreground; 11685 if (r.foregroundActivities) { 11686 foreground = 'A'; 11687 } else if (r.foregroundServices) { 11688 foreground = 'S'; 11689 } else { 11690 foreground = ' '; 11691 } 11692 String procState = ProcessList.makeProcStateString(r.curProcState); 11693 pw.print(prefix); 11694 pw.print(r.persistent ? persistentLabel : normalLabel); 11695 pw.print(" #"); 11696 int num = (origList.size()-1)-list.get(i).second; 11697 if (num < 10) pw.print(' '); 11698 pw.print(num); 11699 pw.print(": "); 11700 pw.print(oomAdj); 11701 pw.print(' '); 11702 pw.print(schedGroup); 11703 pw.print('/'); 11704 pw.print(foreground); 11705 pw.print('/'); 11706 pw.print(procState); 11707 pw.print(" trm:"); 11708 if (r.trimMemoryLevel < 10) pw.print(' '); 11709 pw.print(r.trimMemoryLevel); 11710 pw.print(' '); 11711 pw.print(r.toShortString()); 11712 pw.print(" ("); 11713 pw.print(r.adjType); 11714 pw.println(')'); 11715 if (r.adjSource != null || r.adjTarget != null) { 11716 pw.print(prefix); 11717 pw.print(" "); 11718 if (r.adjTarget instanceof ComponentName) { 11719 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11720 } else if (r.adjTarget != null) { 11721 pw.print(r.adjTarget.toString()); 11722 } else { 11723 pw.print("{null}"); 11724 } 11725 pw.print("<="); 11726 if (r.adjSource instanceof ProcessRecord) { 11727 pw.print("Proc{"); 11728 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11729 pw.println("}"); 11730 } else if (r.adjSource != null) { 11731 pw.println(r.adjSource.toString()); 11732 } else { 11733 pw.println("{null}"); 11734 } 11735 } 11736 if (inclDetails) { 11737 pw.print(prefix); 11738 pw.print(" "); 11739 pw.print("oom: max="); pw.print(r.maxAdj); 11740 pw.print(" curRaw="); pw.print(r.curRawAdj); 11741 pw.print(" setRaw="); pw.print(r.setRawAdj); 11742 pw.print(" cur="); pw.print(r.curAdj); 11743 pw.print(" set="); pw.println(r.setAdj); 11744 pw.print(prefix); 11745 pw.print(" "); 11746 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11747 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11748 pw.print(" lastPss="); pw.print(r.lastPss); 11749 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11750 pw.print(prefix); 11751 pw.print(" "); 11752 pw.print("keeping="); pw.print(r.keeping); 11753 pw.print(" cached="); pw.print(r.cached); 11754 pw.print(" empty="); pw.print(r.empty); 11755 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11756 11757 if (!r.keeping) { 11758 if (r.lastWakeTime != 0) { 11759 long wtime; 11760 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11761 synchronized (stats) { 11762 wtime = stats.getProcessWakeTime(r.info.uid, 11763 r.pid, curRealtime); 11764 } 11765 long timeUsed = wtime - r.lastWakeTime; 11766 pw.print(prefix); 11767 pw.print(" "); 11768 pw.print("keep awake over "); 11769 TimeUtils.formatDuration(realtimeSince, pw); 11770 pw.print(" used "); 11771 TimeUtils.formatDuration(timeUsed, pw); 11772 pw.print(" ("); 11773 pw.print((timeUsed*100)/realtimeSince); 11774 pw.println("%)"); 11775 } 11776 if (r.lastCpuTime != 0) { 11777 long timeUsed = r.curCpuTime - r.lastCpuTime; 11778 pw.print(prefix); 11779 pw.print(" "); 11780 pw.print("run cpu over "); 11781 TimeUtils.formatDuration(uptimeSince, pw); 11782 pw.print(" used "); 11783 TimeUtils.formatDuration(timeUsed, pw); 11784 pw.print(" ("); 11785 pw.print((timeUsed*100)/uptimeSince); 11786 pw.println("%)"); 11787 } 11788 } 11789 } 11790 } 11791 return true; 11792 } 11793 11794 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11795 ArrayList<ProcessRecord> procs; 11796 synchronized (this) { 11797 if (args != null && args.length > start 11798 && args[start].charAt(0) != '-') { 11799 procs = new ArrayList<ProcessRecord>(); 11800 int pid = -1; 11801 try { 11802 pid = Integer.parseInt(args[start]); 11803 } catch (NumberFormatException e) { 11804 } 11805 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11806 ProcessRecord proc = mLruProcesses.get(i); 11807 if (proc.pid == pid) { 11808 procs.add(proc); 11809 } else if (proc.processName.equals(args[start])) { 11810 procs.add(proc); 11811 } 11812 } 11813 if (procs.size() <= 0) { 11814 return null; 11815 } 11816 } else { 11817 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11818 } 11819 } 11820 return procs; 11821 } 11822 11823 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11824 PrintWriter pw, String[] args) { 11825 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11826 if (procs == null) { 11827 pw.println("No process found for: " + args[0]); 11828 return; 11829 } 11830 11831 long uptime = SystemClock.uptimeMillis(); 11832 long realtime = SystemClock.elapsedRealtime(); 11833 pw.println("Applications Graphics Acceleration Info:"); 11834 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11835 11836 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11837 ProcessRecord r = procs.get(i); 11838 if (r.thread != null) { 11839 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11840 pw.flush(); 11841 try { 11842 TransferPipe tp = new TransferPipe(); 11843 try { 11844 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11845 tp.go(fd); 11846 } finally { 11847 tp.kill(); 11848 } 11849 } catch (IOException e) { 11850 pw.println("Failure while dumping the app: " + r); 11851 pw.flush(); 11852 } catch (RemoteException e) { 11853 pw.println("Got a RemoteException while dumping the app " + r); 11854 pw.flush(); 11855 } 11856 } 11857 } 11858 } 11859 11860 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11861 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11862 if (procs == null) { 11863 pw.println("No process found for: " + args[0]); 11864 return; 11865 } 11866 11867 pw.println("Applications Database Info:"); 11868 11869 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11870 ProcessRecord r = procs.get(i); 11871 if (r.thread != null) { 11872 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11873 pw.flush(); 11874 try { 11875 TransferPipe tp = new TransferPipe(); 11876 try { 11877 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11878 tp.go(fd); 11879 } finally { 11880 tp.kill(); 11881 } 11882 } catch (IOException e) { 11883 pw.println("Failure while dumping the app: " + r); 11884 pw.flush(); 11885 } catch (RemoteException e) { 11886 pw.println("Got a RemoteException while dumping the app " + r); 11887 pw.flush(); 11888 } 11889 } 11890 } 11891 } 11892 11893 final static class MemItem { 11894 final boolean isProc; 11895 final String label; 11896 final String shortLabel; 11897 final long pss; 11898 final int id; 11899 final boolean hasActivities; 11900 ArrayList<MemItem> subitems; 11901 11902 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11903 boolean _hasActivities) { 11904 isProc = true; 11905 label = _label; 11906 shortLabel = _shortLabel; 11907 pss = _pss; 11908 id = _id; 11909 hasActivities = _hasActivities; 11910 } 11911 11912 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11913 isProc = false; 11914 label = _label; 11915 shortLabel = _shortLabel; 11916 pss = _pss; 11917 id = _id; 11918 hasActivities = false; 11919 } 11920 } 11921 11922 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11923 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11924 if (sort && !isCompact) { 11925 Collections.sort(items, new Comparator<MemItem>() { 11926 @Override 11927 public int compare(MemItem lhs, MemItem rhs) { 11928 if (lhs.pss < rhs.pss) { 11929 return 1; 11930 } else if (lhs.pss > rhs.pss) { 11931 return -1; 11932 } 11933 return 0; 11934 } 11935 }); 11936 } 11937 11938 for (int i=0; i<items.size(); i++) { 11939 MemItem mi = items.get(i); 11940 if (!isCompact) { 11941 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11942 } else if (mi.isProc) { 11943 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11944 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11945 pw.println(mi.hasActivities ? ",a" : ",e"); 11946 } else { 11947 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11948 pw.println(mi.pss); 11949 } 11950 if (mi.subitems != null) { 11951 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11952 true, isCompact); 11953 } 11954 } 11955 } 11956 11957 // These are in KB. 11958 static final long[] DUMP_MEM_BUCKETS = new long[] { 11959 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11960 120*1024, 160*1024, 200*1024, 11961 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11962 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11963 }; 11964 11965 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11966 boolean stackLike) { 11967 int start = label.lastIndexOf('.'); 11968 if (start >= 0) start++; 11969 else start = 0; 11970 int end = label.length(); 11971 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11972 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11973 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11974 out.append(bucket); 11975 out.append(stackLike ? "MB." : "MB "); 11976 out.append(label, start, end); 11977 return; 11978 } 11979 } 11980 out.append(memKB/1024); 11981 out.append(stackLike ? "MB." : "MB "); 11982 out.append(label, start, end); 11983 } 11984 11985 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11986 ProcessList.NATIVE_ADJ, 11987 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11988 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11989 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11990 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11991 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11992 }; 11993 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11994 "Native", 11995 "System", "Persistent", "Foreground", 11996 "Visible", "Perceptible", 11997 "Heavy Weight", "Backup", 11998 "A Services", "Home", 11999 "Previous", "B Services", "Cached" 12000 }; 12001 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12002 "native", 12003 "sys", "pers", "fore", 12004 "vis", "percept", 12005 "heavy", "backup", 12006 "servicea", "home", 12007 "prev", "serviceb", "cached" 12008 }; 12009 12010 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12011 long realtime, boolean isCheckinRequest, boolean isCompact) { 12012 if (isCheckinRequest || isCompact) { 12013 // short checkin version 12014 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12015 } else { 12016 pw.println("Applications Memory Usage (kB):"); 12017 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12018 } 12019 } 12020 12021 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12022 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12023 boolean dumpDetails = false; 12024 boolean dumpFullDetails = false; 12025 boolean dumpDalvik = false; 12026 boolean oomOnly = false; 12027 boolean isCompact = false; 12028 boolean localOnly = false; 12029 12030 int opti = 0; 12031 while (opti < args.length) { 12032 String opt = args[opti]; 12033 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12034 break; 12035 } 12036 opti++; 12037 if ("-a".equals(opt)) { 12038 dumpDetails = true; 12039 dumpFullDetails = true; 12040 dumpDalvik = true; 12041 } else if ("-d".equals(opt)) { 12042 dumpDalvik = true; 12043 } else if ("-c".equals(opt)) { 12044 isCompact = true; 12045 } else if ("--oom".equals(opt)) { 12046 oomOnly = true; 12047 } else if ("--local".equals(opt)) { 12048 localOnly = true; 12049 } else if ("-h".equals(opt)) { 12050 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12051 pw.println(" -a: include all available information for each process."); 12052 pw.println(" -d: include dalvik details when dumping process details."); 12053 pw.println(" -c: dump in a compact machine-parseable representation."); 12054 pw.println(" --oom: only show processes organized by oom adj."); 12055 pw.println(" --local: only collect details locally, don't call process."); 12056 pw.println("If [process] is specified it can be the name or "); 12057 pw.println("pid of a specific process to dump."); 12058 return; 12059 } else { 12060 pw.println("Unknown argument: " + opt + "; use -h for help"); 12061 } 12062 } 12063 12064 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12065 long uptime = SystemClock.uptimeMillis(); 12066 long realtime = SystemClock.elapsedRealtime(); 12067 final long[] tmpLong = new long[1]; 12068 12069 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12070 if (procs == null) { 12071 // No Java processes. Maybe they want to print a native process. 12072 if (args != null && args.length > opti 12073 && args[opti].charAt(0) != '-') { 12074 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12075 = new ArrayList<ProcessCpuTracker.Stats>(); 12076 updateCpuStatsNow(); 12077 int findPid = -1; 12078 try { 12079 findPid = Integer.parseInt(args[opti]); 12080 } catch (NumberFormatException e) { 12081 } 12082 synchronized (mProcessCpuThread) { 12083 final int N = mProcessCpuTracker.countStats(); 12084 for (int i=0; i<N; i++) { 12085 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12086 if (st.pid == findPid || (st.baseName != null 12087 && st.baseName.equals(args[opti]))) { 12088 nativeProcs.add(st); 12089 } 12090 } 12091 } 12092 if (nativeProcs.size() > 0) { 12093 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12094 isCompact); 12095 Debug.MemoryInfo mi = null; 12096 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12097 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12098 final int pid = r.pid; 12099 if (!isCheckinRequest && dumpDetails) { 12100 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12101 } 12102 if (mi == null) { 12103 mi = new Debug.MemoryInfo(); 12104 } 12105 if (dumpDetails || (!brief && !oomOnly)) { 12106 Debug.getMemoryInfo(pid, mi); 12107 } else { 12108 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12109 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12110 } 12111 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12112 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12113 if (isCheckinRequest) { 12114 pw.println(); 12115 } 12116 } 12117 return; 12118 } 12119 } 12120 pw.println("No process found for: " + args[opti]); 12121 return; 12122 } 12123 12124 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12125 dumpDetails = true; 12126 } 12127 12128 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12129 12130 String[] innerArgs = new String[args.length-opti]; 12131 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12132 12133 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12134 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12135 long nativePss=0, dalvikPss=0, otherPss=0; 12136 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12137 12138 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12139 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12140 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12141 12142 long totalPss = 0; 12143 long cachedPss = 0; 12144 12145 Debug.MemoryInfo mi = null; 12146 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12147 final ProcessRecord r = procs.get(i); 12148 final IApplicationThread thread; 12149 final int pid; 12150 final int oomAdj; 12151 final boolean hasActivities; 12152 synchronized (this) { 12153 thread = r.thread; 12154 pid = r.pid; 12155 oomAdj = r.getSetAdjWithServices(); 12156 hasActivities = r.activities.size() > 0; 12157 } 12158 if (thread != null) { 12159 if (!isCheckinRequest && dumpDetails) { 12160 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12161 } 12162 if (mi == null) { 12163 mi = new Debug.MemoryInfo(); 12164 } 12165 if (dumpDetails || (!brief && !oomOnly)) { 12166 Debug.getMemoryInfo(pid, mi); 12167 } else { 12168 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12169 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12170 } 12171 if (dumpDetails) { 12172 if (localOnly) { 12173 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12174 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12175 if (isCheckinRequest) { 12176 pw.println(); 12177 } 12178 } else { 12179 try { 12180 pw.flush(); 12181 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12182 dumpDalvik, innerArgs); 12183 } catch (RemoteException e) { 12184 if (!isCheckinRequest) { 12185 pw.println("Got RemoteException!"); 12186 pw.flush(); 12187 } 12188 } 12189 } 12190 } 12191 12192 final long myTotalPss = mi.getTotalPss(); 12193 final long myTotalUss = mi.getTotalUss(); 12194 12195 synchronized (this) { 12196 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12197 // Record this for posterity if the process has been stable. 12198 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12199 } 12200 } 12201 12202 if (!isCheckinRequest && mi != null) { 12203 totalPss += myTotalPss; 12204 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12205 (hasActivities ? " / activities)" : ")"), 12206 r.processName, myTotalPss, pid, hasActivities); 12207 procMems.add(pssItem); 12208 procMemsMap.put(pid, pssItem); 12209 12210 nativePss += mi.nativePss; 12211 dalvikPss += mi.dalvikPss; 12212 otherPss += mi.otherPss; 12213 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12214 long mem = mi.getOtherPss(j); 12215 miscPss[j] += mem; 12216 otherPss -= mem; 12217 } 12218 12219 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12220 cachedPss += myTotalPss; 12221 } 12222 12223 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12224 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12225 || oomIndex == (oomPss.length-1)) { 12226 oomPss[oomIndex] += myTotalPss; 12227 if (oomProcs[oomIndex] == null) { 12228 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12229 } 12230 oomProcs[oomIndex].add(pssItem); 12231 break; 12232 } 12233 } 12234 } 12235 } 12236 } 12237 12238 if (!isCheckinRequest && procs.size() > 1) { 12239 // If we are showing aggregations, also look for native processes to 12240 // include so that our aggregations are more accurate. 12241 updateCpuStatsNow(); 12242 synchronized (mProcessCpuThread) { 12243 final int N = mProcessCpuTracker.countStats(); 12244 for (int i=0; i<N; i++) { 12245 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12246 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12247 if (mi == null) { 12248 mi = new Debug.MemoryInfo(); 12249 } 12250 if (!brief && !oomOnly) { 12251 Debug.getMemoryInfo(st.pid, mi); 12252 } else { 12253 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12254 mi.nativePrivateDirty = (int)tmpLong[0]; 12255 } 12256 12257 final long myTotalPss = mi.getTotalPss(); 12258 totalPss += myTotalPss; 12259 12260 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12261 st.name, myTotalPss, st.pid, false); 12262 procMems.add(pssItem); 12263 12264 nativePss += mi.nativePss; 12265 dalvikPss += mi.dalvikPss; 12266 otherPss += mi.otherPss; 12267 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12268 long mem = mi.getOtherPss(j); 12269 miscPss[j] += mem; 12270 otherPss -= mem; 12271 } 12272 oomPss[0] += myTotalPss; 12273 if (oomProcs[0] == null) { 12274 oomProcs[0] = new ArrayList<MemItem>(); 12275 } 12276 oomProcs[0].add(pssItem); 12277 } 12278 } 12279 } 12280 12281 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12282 12283 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12284 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12285 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12286 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12287 String label = Debug.MemoryInfo.getOtherLabel(j); 12288 catMems.add(new MemItem(label, label, miscPss[j], j)); 12289 } 12290 12291 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12292 for (int j=0; j<oomPss.length; j++) { 12293 if (oomPss[j] != 0) { 12294 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12295 : DUMP_MEM_OOM_LABEL[j]; 12296 MemItem item = new MemItem(label, label, oomPss[j], 12297 DUMP_MEM_OOM_ADJ[j]); 12298 item.subitems = oomProcs[j]; 12299 oomMems.add(item); 12300 } 12301 } 12302 12303 if (!brief && !oomOnly && !isCompact) { 12304 pw.println(); 12305 pw.println("Total PSS by process:"); 12306 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12307 pw.println(); 12308 } 12309 if (!isCompact) { 12310 pw.println("Total PSS by OOM adjustment:"); 12311 } 12312 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12313 if (!brief && !oomOnly) { 12314 PrintWriter out = categoryPw != null ? categoryPw : pw; 12315 if (!isCompact) { 12316 out.println(); 12317 out.println("Total PSS by category:"); 12318 } 12319 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12320 } 12321 if (!isCompact) { 12322 pw.println(); 12323 } 12324 MemInfoReader memInfo = new MemInfoReader(); 12325 memInfo.readMemInfo(); 12326 if (!brief) { 12327 if (!isCompact) { 12328 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12329 pw.print(" kB (status "); 12330 switch (mLastMemoryLevel) { 12331 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12332 pw.println("normal)"); 12333 break; 12334 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12335 pw.println("moderate)"); 12336 break; 12337 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12338 pw.println("low)"); 12339 break; 12340 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12341 pw.println("critical)"); 12342 break; 12343 default: 12344 pw.print(mLastMemoryLevel); 12345 pw.println(")"); 12346 break; 12347 } 12348 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12349 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12350 pw.print(cachedPss); pw.print(" cached pss + "); 12351 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12352 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12353 } else { 12354 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12355 pw.print(cachedPss + memInfo.getCachedSizeKb() 12356 + memInfo.getFreeSizeKb()); pw.print(","); 12357 pw.println(totalPss - cachedPss); 12358 } 12359 } 12360 if (!isCompact) { 12361 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12362 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12363 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12364 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12365 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12366 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12367 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12368 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12369 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12370 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12371 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12372 } 12373 if (!brief) { 12374 if (memInfo.getZramTotalSizeKb() != 0) { 12375 if (!isCompact) { 12376 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12377 pw.print(" kB physical used for "); 12378 pw.print(memInfo.getSwapTotalSizeKb() 12379 - memInfo.getSwapFreeSizeKb()); 12380 pw.print(" kB in swap ("); 12381 pw.print(memInfo.getSwapTotalSizeKb()); 12382 pw.println(" kB total swap)"); 12383 } else { 12384 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12385 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12386 pw.println(memInfo.getSwapFreeSizeKb()); 12387 } 12388 } 12389 final int[] SINGLE_LONG_FORMAT = new int[] { 12390 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12391 }; 12392 long[] longOut = new long[1]; 12393 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12394 SINGLE_LONG_FORMAT, null, longOut, null); 12395 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12396 longOut[0] = 0; 12397 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12398 SINGLE_LONG_FORMAT, null, longOut, null); 12399 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12400 longOut[0] = 0; 12401 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12402 SINGLE_LONG_FORMAT, null, longOut, null); 12403 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12404 longOut[0] = 0; 12405 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12406 SINGLE_LONG_FORMAT, null, longOut, null); 12407 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12408 if (!isCompact) { 12409 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12410 pw.print(" KSM: "); pw.print(sharing); 12411 pw.print(" kB saved from shared "); 12412 pw.print(shared); pw.println(" kB"); 12413 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12414 pw.print(voltile); pw.println(" kB volatile"); 12415 } 12416 pw.print(" Tuning: "); 12417 pw.print(ActivityManager.staticGetMemoryClass()); 12418 pw.print(" (large "); 12419 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12420 pw.print("), oom "); 12421 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12422 pw.print(" kB"); 12423 pw.print(", restore limit "); 12424 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12425 pw.print(" kB"); 12426 if (ActivityManager.isLowRamDeviceStatic()) { 12427 pw.print(" (low-ram)"); 12428 } 12429 if (ActivityManager.isHighEndGfx()) { 12430 pw.print(" (high-end-gfx)"); 12431 } 12432 pw.println(); 12433 } else { 12434 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12435 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12436 pw.println(voltile); 12437 pw.print("tuning,"); 12438 pw.print(ActivityManager.staticGetMemoryClass()); 12439 pw.print(','); 12440 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12441 pw.print(','); 12442 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12443 if (ActivityManager.isLowRamDeviceStatic()) { 12444 pw.print(",low-ram"); 12445 } 12446 if (ActivityManager.isHighEndGfx()) { 12447 pw.print(",high-end-gfx"); 12448 } 12449 pw.println(); 12450 } 12451 } 12452 } 12453 } 12454 12455 /** 12456 * Searches array of arguments for the specified string 12457 * @param args array of argument strings 12458 * @param value value to search for 12459 * @return true if the value is contained in the array 12460 */ 12461 private static boolean scanArgs(String[] args, String value) { 12462 if (args != null) { 12463 for (String arg : args) { 12464 if (value.equals(arg)) { 12465 return true; 12466 } 12467 } 12468 } 12469 return false; 12470 } 12471 12472 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12473 ContentProviderRecord cpr, boolean always) { 12474 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12475 12476 if (!inLaunching || always) { 12477 synchronized (cpr) { 12478 cpr.launchingApp = null; 12479 cpr.notifyAll(); 12480 } 12481 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12482 String names[] = cpr.info.authority.split(";"); 12483 for (int j = 0; j < names.length; j++) { 12484 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12485 } 12486 } 12487 12488 for (int i=0; i<cpr.connections.size(); i++) { 12489 ContentProviderConnection conn = cpr.connections.get(i); 12490 if (conn.waiting) { 12491 // If this connection is waiting for the provider, then we don't 12492 // need to mess with its process unless we are always removing 12493 // or for some reason the provider is not currently launching. 12494 if (inLaunching && !always) { 12495 continue; 12496 } 12497 } 12498 ProcessRecord capp = conn.client; 12499 conn.dead = true; 12500 if (conn.stableCount > 0) { 12501 if (!capp.persistent && capp.thread != null 12502 && capp.pid != 0 12503 && capp.pid != MY_PID) { 12504 killUnneededProcessLocked(capp, "depends on provider " 12505 + cpr.name.flattenToShortString() 12506 + " in dying proc " + (proc != null ? proc.processName : "??")); 12507 } 12508 } else if (capp.thread != null && conn.provider.provider != null) { 12509 try { 12510 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12511 } catch (RemoteException e) { 12512 } 12513 // In the protocol here, we don't expect the client to correctly 12514 // clean up this connection, we'll just remove it. 12515 cpr.connections.remove(i); 12516 conn.client.conProviders.remove(conn); 12517 } 12518 } 12519 12520 if (inLaunching && always) { 12521 mLaunchingProviders.remove(cpr); 12522 } 12523 return inLaunching; 12524 } 12525 12526 /** 12527 * Main code for cleaning up a process when it has gone away. This is 12528 * called both as a result of the process dying, or directly when stopping 12529 * a process when running in single process mode. 12530 */ 12531 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12532 boolean restarting, boolean allowRestart, int index) { 12533 if (index >= 0) { 12534 removeLruProcessLocked(app); 12535 ProcessList.remove(app.pid); 12536 } 12537 12538 mProcessesToGc.remove(app); 12539 mPendingPssProcesses.remove(app); 12540 12541 // Dismiss any open dialogs. 12542 if (app.crashDialog != null && !app.forceCrashReport) { 12543 app.crashDialog.dismiss(); 12544 app.crashDialog = null; 12545 } 12546 if (app.anrDialog != null) { 12547 app.anrDialog.dismiss(); 12548 app.anrDialog = null; 12549 } 12550 if (app.waitDialog != null) { 12551 app.waitDialog.dismiss(); 12552 app.waitDialog = null; 12553 } 12554 12555 app.crashing = false; 12556 app.notResponding = false; 12557 12558 app.resetPackageList(mProcessStats); 12559 app.unlinkDeathRecipient(); 12560 app.makeInactive(mProcessStats); 12561 app.forcingToForeground = null; 12562 updateProcessForegroundLocked(app, false, false); 12563 app.foregroundActivities = false; 12564 app.hasShownUi = false; 12565 app.treatLikeActivity = false; 12566 app.hasAboveClient = false; 12567 12568 mServices.killServicesLocked(app, allowRestart); 12569 12570 boolean restart = false; 12571 12572 // Remove published content providers. 12573 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12574 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12575 final boolean always = app.bad || !allowRestart; 12576 if (removeDyingProviderLocked(app, cpr, always) || always) { 12577 // We left the provider in the launching list, need to 12578 // restart it. 12579 restart = true; 12580 } 12581 12582 cpr.provider = null; 12583 cpr.proc = null; 12584 } 12585 app.pubProviders.clear(); 12586 12587 // Take care of any launching providers waiting for this process. 12588 if (checkAppInLaunchingProvidersLocked(app, false)) { 12589 restart = true; 12590 } 12591 12592 // Unregister from connected content providers. 12593 if (!app.conProviders.isEmpty()) { 12594 for (int i=0; i<app.conProviders.size(); i++) { 12595 ContentProviderConnection conn = app.conProviders.get(i); 12596 conn.provider.connections.remove(conn); 12597 } 12598 app.conProviders.clear(); 12599 } 12600 12601 // At this point there may be remaining entries in mLaunchingProviders 12602 // where we were the only one waiting, so they are no longer of use. 12603 // Look for these and clean up if found. 12604 // XXX Commented out for now. Trying to figure out a way to reproduce 12605 // the actual situation to identify what is actually going on. 12606 if (false) { 12607 for (int i=0; i<mLaunchingProviders.size(); i++) { 12608 ContentProviderRecord cpr = (ContentProviderRecord) 12609 mLaunchingProviders.get(i); 12610 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12611 synchronized (cpr) { 12612 cpr.launchingApp = null; 12613 cpr.notifyAll(); 12614 } 12615 } 12616 } 12617 } 12618 12619 skipCurrentReceiverLocked(app); 12620 12621 // Unregister any receivers. 12622 for (int i=app.receivers.size()-1; i>=0; i--) { 12623 removeReceiverLocked(app.receivers.valueAt(i)); 12624 } 12625 app.receivers.clear(); 12626 12627 // If the app is undergoing backup, tell the backup manager about it 12628 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12629 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12630 + mBackupTarget.appInfo + " died during backup"); 12631 try { 12632 IBackupManager bm = IBackupManager.Stub.asInterface( 12633 ServiceManager.getService(Context.BACKUP_SERVICE)); 12634 bm.agentDisconnected(app.info.packageName); 12635 } catch (RemoteException e) { 12636 // can't happen; backup manager is local 12637 } 12638 } 12639 12640 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12641 ProcessChangeItem item = mPendingProcessChanges.get(i); 12642 if (item.pid == app.pid) { 12643 mPendingProcessChanges.remove(i); 12644 mAvailProcessChanges.add(item); 12645 } 12646 } 12647 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12648 12649 // If the caller is restarting this app, then leave it in its 12650 // current lists and let the caller take care of it. 12651 if (restarting) { 12652 return; 12653 } 12654 12655 if (!app.persistent || app.isolated) { 12656 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12657 "Removing non-persistent process during cleanup: " + app); 12658 mProcessNames.remove(app.processName, app.uid); 12659 mIsolatedProcesses.remove(app.uid); 12660 if (mHeavyWeightProcess == app) { 12661 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12662 mHeavyWeightProcess.userId, 0)); 12663 mHeavyWeightProcess = null; 12664 } 12665 } else if (!app.removed) { 12666 // This app is persistent, so we need to keep its record around. 12667 // If it is not already on the pending app list, add it there 12668 // and start a new process for it. 12669 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12670 mPersistentStartingProcesses.add(app); 12671 restart = true; 12672 } 12673 } 12674 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12675 "Clean-up removing on hold: " + app); 12676 mProcessesOnHold.remove(app); 12677 12678 if (app == mHomeProcess) { 12679 mHomeProcess = null; 12680 } 12681 if (app == mPreviousProcess) { 12682 mPreviousProcess = null; 12683 } 12684 12685 if (restart && !app.isolated) { 12686 // We have components that still need to be running in the 12687 // process, so re-launch it. 12688 mProcessNames.put(app.processName, app.uid, app); 12689 startProcessLocked(app, "restart", app.processName); 12690 } else if (app.pid > 0 && app.pid != MY_PID) { 12691 // Goodbye! 12692 boolean removed; 12693 synchronized (mPidsSelfLocked) { 12694 mPidsSelfLocked.remove(app.pid); 12695 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12696 } 12697 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12698 app.processName, app.info.uid); 12699 if (app.isolated) { 12700 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12701 } 12702 app.setPid(0); 12703 } 12704 } 12705 12706 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12707 // Look through the content providers we are waiting to have launched, 12708 // and if any run in this process then either schedule a restart of 12709 // the process or kill the client waiting for it if this process has 12710 // gone bad. 12711 int NL = mLaunchingProviders.size(); 12712 boolean restart = false; 12713 for (int i=0; i<NL; i++) { 12714 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12715 if (cpr.launchingApp == app) { 12716 if (!alwaysBad && !app.bad) { 12717 restart = true; 12718 } else { 12719 removeDyingProviderLocked(app, cpr, true); 12720 // cpr should have been removed from mLaunchingProviders 12721 NL = mLaunchingProviders.size(); 12722 i--; 12723 } 12724 } 12725 } 12726 return restart; 12727 } 12728 12729 // ========================================================= 12730 // SERVICES 12731 // ========================================================= 12732 12733 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12734 int flags) { 12735 enforceNotIsolatedCaller("getServices"); 12736 synchronized (this) { 12737 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12738 } 12739 } 12740 12741 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12742 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12743 synchronized (this) { 12744 return mServices.getRunningServiceControlPanelLocked(name); 12745 } 12746 } 12747 12748 public ComponentName startService(IApplicationThread caller, Intent service, 12749 String resolvedType, int userId) { 12750 enforceNotIsolatedCaller("startService"); 12751 // Refuse possible leaked file descriptors 12752 if (service != null && service.hasFileDescriptors() == true) { 12753 throw new IllegalArgumentException("File descriptors passed in Intent"); 12754 } 12755 12756 if (DEBUG_SERVICE) 12757 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12758 synchronized(this) { 12759 final int callingPid = Binder.getCallingPid(); 12760 final int callingUid = Binder.getCallingUid(); 12761 final long origId = Binder.clearCallingIdentity(); 12762 ComponentName res = mServices.startServiceLocked(caller, service, 12763 resolvedType, callingPid, callingUid, userId); 12764 Binder.restoreCallingIdentity(origId); 12765 return res; 12766 } 12767 } 12768 12769 ComponentName startServiceInPackage(int uid, 12770 Intent service, String resolvedType, int userId) { 12771 synchronized(this) { 12772 if (DEBUG_SERVICE) 12773 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12774 final long origId = Binder.clearCallingIdentity(); 12775 ComponentName res = mServices.startServiceLocked(null, service, 12776 resolvedType, -1, uid, userId); 12777 Binder.restoreCallingIdentity(origId); 12778 return res; 12779 } 12780 } 12781 12782 public int stopService(IApplicationThread caller, Intent service, 12783 String resolvedType, int userId) { 12784 enforceNotIsolatedCaller("stopService"); 12785 // Refuse possible leaked file descriptors 12786 if (service != null && service.hasFileDescriptors() == true) { 12787 throw new IllegalArgumentException("File descriptors passed in Intent"); 12788 } 12789 12790 synchronized(this) { 12791 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12792 } 12793 } 12794 12795 public IBinder peekService(Intent service, String resolvedType) { 12796 enforceNotIsolatedCaller("peekService"); 12797 // Refuse possible leaked file descriptors 12798 if (service != null && service.hasFileDescriptors() == true) { 12799 throw new IllegalArgumentException("File descriptors passed in Intent"); 12800 } 12801 synchronized(this) { 12802 return mServices.peekServiceLocked(service, resolvedType); 12803 } 12804 } 12805 12806 public boolean stopServiceToken(ComponentName className, IBinder token, 12807 int startId) { 12808 synchronized(this) { 12809 return mServices.stopServiceTokenLocked(className, token, startId); 12810 } 12811 } 12812 12813 public void setServiceForeground(ComponentName className, IBinder token, 12814 int id, Notification notification, boolean removeNotification) { 12815 synchronized(this) { 12816 mServices.setServiceForegroundLocked(className, token, id, notification, 12817 removeNotification); 12818 } 12819 } 12820 12821 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12822 boolean requireFull, String name, String callerPackage) { 12823 final int callingUserId = UserHandle.getUserId(callingUid); 12824 if (callingUserId != userId) { 12825 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12826 if ((requireFull || checkComponentPermission( 12827 android.Manifest.permission.INTERACT_ACROSS_USERS, 12828 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12829 && checkComponentPermission( 12830 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12831 callingPid, callingUid, -1, true) 12832 != PackageManager.PERMISSION_GRANTED) { 12833 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12834 // In this case, they would like to just execute as their 12835 // owner user instead of failing. 12836 userId = callingUserId; 12837 } else { 12838 StringBuilder builder = new StringBuilder(128); 12839 builder.append("Permission Denial: "); 12840 builder.append(name); 12841 if (callerPackage != null) { 12842 builder.append(" from "); 12843 builder.append(callerPackage); 12844 } 12845 builder.append(" asks to run as user "); 12846 builder.append(userId); 12847 builder.append(" but is calling from user "); 12848 builder.append(UserHandle.getUserId(callingUid)); 12849 builder.append("; this requires "); 12850 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12851 if (!requireFull) { 12852 builder.append(" or "); 12853 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12854 } 12855 String msg = builder.toString(); 12856 Slog.w(TAG, msg); 12857 throw new SecurityException(msg); 12858 } 12859 } 12860 } 12861 if (userId == UserHandle.USER_CURRENT 12862 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12863 // Note that we may be accessing this outside of a lock... 12864 // shouldn't be a big deal, if this is being called outside 12865 // of a locked context there is intrinsically a race with 12866 // the value the caller will receive and someone else changing it. 12867 userId = mCurrentUserId; 12868 } 12869 if (!allowAll && userId < 0) { 12870 throw new IllegalArgumentException( 12871 "Call does not support special user #" + userId); 12872 } 12873 } 12874 return userId; 12875 } 12876 12877 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12878 String className, int flags) { 12879 boolean result = false; 12880 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12881 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12882 if (ActivityManager.checkUidPermission( 12883 android.Manifest.permission.INTERACT_ACROSS_USERS, 12884 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12885 ComponentName comp = new ComponentName(aInfo.packageName, className); 12886 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12887 + " requests FLAG_SINGLE_USER, but app does not hold " 12888 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12889 Slog.w(TAG, msg); 12890 throw new SecurityException(msg); 12891 } 12892 result = true; 12893 } 12894 } else if (componentProcessName == aInfo.packageName) { 12895 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12896 } else if ("system".equals(componentProcessName)) { 12897 result = true; 12898 } 12899 if (DEBUG_MU) { 12900 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12901 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12902 } 12903 return result; 12904 } 12905 12906 public int bindService(IApplicationThread caller, IBinder token, 12907 Intent service, String resolvedType, 12908 IServiceConnection connection, int flags, int userId) { 12909 enforceNotIsolatedCaller("bindService"); 12910 // Refuse possible leaked file descriptors 12911 if (service != null && service.hasFileDescriptors() == true) { 12912 throw new IllegalArgumentException("File descriptors passed in Intent"); 12913 } 12914 12915 synchronized(this) { 12916 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12917 connection, flags, userId); 12918 } 12919 } 12920 12921 public boolean unbindService(IServiceConnection connection) { 12922 synchronized (this) { 12923 return mServices.unbindServiceLocked(connection); 12924 } 12925 } 12926 12927 public void publishService(IBinder token, Intent intent, IBinder service) { 12928 // Refuse possible leaked file descriptors 12929 if (intent != null && intent.hasFileDescriptors() == true) { 12930 throw new IllegalArgumentException("File descriptors passed in Intent"); 12931 } 12932 12933 synchronized(this) { 12934 if (!(token instanceof ServiceRecord)) { 12935 throw new IllegalArgumentException("Invalid service token"); 12936 } 12937 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12938 } 12939 } 12940 12941 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12942 // Refuse possible leaked file descriptors 12943 if (intent != null && intent.hasFileDescriptors() == true) { 12944 throw new IllegalArgumentException("File descriptors passed in Intent"); 12945 } 12946 12947 synchronized(this) { 12948 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12949 } 12950 } 12951 12952 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12953 synchronized(this) { 12954 if (!(token instanceof ServiceRecord)) { 12955 throw new IllegalArgumentException("Invalid service token"); 12956 } 12957 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12958 } 12959 } 12960 12961 // ========================================================= 12962 // BACKUP AND RESTORE 12963 // ========================================================= 12964 12965 // Cause the target app to be launched if necessary and its backup agent 12966 // instantiated. The backup agent will invoke backupAgentCreated() on the 12967 // activity manager to announce its creation. 12968 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12969 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12970 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12971 12972 synchronized(this) { 12973 // !!! TODO: currently no check here that we're already bound 12974 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12975 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12976 synchronized (stats) { 12977 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12978 } 12979 12980 // Backup agent is now in use, its package can't be stopped. 12981 try { 12982 AppGlobals.getPackageManager().setPackageStoppedState( 12983 app.packageName, false, UserHandle.getUserId(app.uid)); 12984 } catch (RemoteException e) { 12985 } catch (IllegalArgumentException e) { 12986 Slog.w(TAG, "Failed trying to unstop package " 12987 + app.packageName + ": " + e); 12988 } 12989 12990 BackupRecord r = new BackupRecord(ss, app, backupMode); 12991 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12992 ? new ComponentName(app.packageName, app.backupAgentName) 12993 : new ComponentName("android", "FullBackupAgent"); 12994 // startProcessLocked() returns existing proc's record if it's already running 12995 ProcessRecord proc = startProcessLocked(app.processName, app, 12996 false, 0, "backup", hostingName, false, false, false); 12997 if (proc == null) { 12998 Slog.e(TAG, "Unable to start backup agent process " + r); 12999 return false; 13000 } 13001 13002 r.app = proc; 13003 mBackupTarget = r; 13004 mBackupAppName = app.packageName; 13005 13006 // Try not to kill the process during backup 13007 updateOomAdjLocked(proc); 13008 13009 // If the process is already attached, schedule the creation of the backup agent now. 13010 // If it is not yet live, this will be done when it attaches to the framework. 13011 if (proc.thread != null) { 13012 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13013 try { 13014 proc.thread.scheduleCreateBackupAgent(app, 13015 compatibilityInfoForPackageLocked(app), backupMode); 13016 } catch (RemoteException e) { 13017 // Will time out on the backup manager side 13018 } 13019 } else { 13020 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13021 } 13022 // Invariants: at this point, the target app process exists and the application 13023 // is either already running or in the process of coming up. mBackupTarget and 13024 // mBackupAppName describe the app, so that when it binds back to the AM we 13025 // know that it's scheduled for a backup-agent operation. 13026 } 13027 13028 return true; 13029 } 13030 13031 @Override 13032 public void clearPendingBackup() { 13033 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13034 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13035 13036 synchronized (this) { 13037 mBackupTarget = null; 13038 mBackupAppName = null; 13039 } 13040 } 13041 13042 // A backup agent has just come up 13043 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13044 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13045 + " = " + agent); 13046 13047 synchronized(this) { 13048 if (!agentPackageName.equals(mBackupAppName)) { 13049 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13050 return; 13051 } 13052 } 13053 13054 long oldIdent = Binder.clearCallingIdentity(); 13055 try { 13056 IBackupManager bm = IBackupManager.Stub.asInterface( 13057 ServiceManager.getService(Context.BACKUP_SERVICE)); 13058 bm.agentConnected(agentPackageName, agent); 13059 } catch (RemoteException e) { 13060 // can't happen; the backup manager service is local 13061 } catch (Exception e) { 13062 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13063 e.printStackTrace(); 13064 } finally { 13065 Binder.restoreCallingIdentity(oldIdent); 13066 } 13067 } 13068 13069 // done with this agent 13070 public void unbindBackupAgent(ApplicationInfo appInfo) { 13071 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13072 if (appInfo == null) { 13073 Slog.w(TAG, "unbind backup agent for null app"); 13074 return; 13075 } 13076 13077 synchronized(this) { 13078 try { 13079 if (mBackupAppName == null) { 13080 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13081 return; 13082 } 13083 13084 if (!mBackupAppName.equals(appInfo.packageName)) { 13085 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13086 return; 13087 } 13088 13089 // Not backing this app up any more; reset its OOM adjustment 13090 final ProcessRecord proc = mBackupTarget.app; 13091 updateOomAdjLocked(proc); 13092 13093 // If the app crashed during backup, 'thread' will be null here 13094 if (proc.thread != null) { 13095 try { 13096 proc.thread.scheduleDestroyBackupAgent(appInfo, 13097 compatibilityInfoForPackageLocked(appInfo)); 13098 } catch (Exception e) { 13099 Slog.e(TAG, "Exception when unbinding backup agent:"); 13100 e.printStackTrace(); 13101 } 13102 } 13103 } finally { 13104 mBackupTarget = null; 13105 mBackupAppName = null; 13106 } 13107 } 13108 } 13109 // ========================================================= 13110 // BROADCASTS 13111 // ========================================================= 13112 13113 private final List getStickiesLocked(String action, IntentFilter filter, 13114 List cur, int userId) { 13115 final ContentResolver resolver = mContext.getContentResolver(); 13116 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13117 if (stickies == null) { 13118 return cur; 13119 } 13120 final ArrayList<Intent> list = stickies.get(action); 13121 if (list == null) { 13122 return cur; 13123 } 13124 int N = list.size(); 13125 for (int i=0; i<N; i++) { 13126 Intent intent = list.get(i); 13127 if (filter.match(resolver, intent, true, TAG) >= 0) { 13128 if (cur == null) { 13129 cur = new ArrayList<Intent>(); 13130 } 13131 cur.add(intent); 13132 } 13133 } 13134 return cur; 13135 } 13136 13137 boolean isPendingBroadcastProcessLocked(int pid) { 13138 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13139 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13140 } 13141 13142 void skipPendingBroadcastLocked(int pid) { 13143 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13144 for (BroadcastQueue queue : mBroadcastQueues) { 13145 queue.skipPendingBroadcastLocked(pid); 13146 } 13147 } 13148 13149 // The app just attached; send any pending broadcasts that it should receive 13150 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13151 boolean didSomething = false; 13152 for (BroadcastQueue queue : mBroadcastQueues) { 13153 didSomething |= queue.sendPendingBroadcastsLocked(app); 13154 } 13155 return didSomething; 13156 } 13157 13158 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13159 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13160 enforceNotIsolatedCaller("registerReceiver"); 13161 int callingUid; 13162 int callingPid; 13163 synchronized(this) { 13164 ProcessRecord callerApp = null; 13165 if (caller != null) { 13166 callerApp = getRecordForAppLocked(caller); 13167 if (callerApp == null) { 13168 throw new SecurityException( 13169 "Unable to find app for caller " + caller 13170 + " (pid=" + Binder.getCallingPid() 13171 + ") when registering receiver " + receiver); 13172 } 13173 if (callerApp.info.uid != Process.SYSTEM_UID && 13174 !callerApp.pkgList.containsKey(callerPackage) && 13175 !"android".equals(callerPackage)) { 13176 throw new SecurityException("Given caller package " + callerPackage 13177 + " is not running in process " + callerApp); 13178 } 13179 callingUid = callerApp.info.uid; 13180 callingPid = callerApp.pid; 13181 } else { 13182 callerPackage = null; 13183 callingUid = Binder.getCallingUid(); 13184 callingPid = Binder.getCallingPid(); 13185 } 13186 13187 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13188 true, true, "registerReceiver", callerPackage); 13189 13190 List allSticky = null; 13191 13192 // Look for any matching sticky broadcasts... 13193 Iterator actions = filter.actionsIterator(); 13194 if (actions != null) { 13195 while (actions.hasNext()) { 13196 String action = (String)actions.next(); 13197 allSticky = getStickiesLocked(action, filter, allSticky, 13198 UserHandle.USER_ALL); 13199 allSticky = getStickiesLocked(action, filter, allSticky, 13200 UserHandle.getUserId(callingUid)); 13201 } 13202 } else { 13203 allSticky = getStickiesLocked(null, filter, allSticky, 13204 UserHandle.USER_ALL); 13205 allSticky = getStickiesLocked(null, filter, allSticky, 13206 UserHandle.getUserId(callingUid)); 13207 } 13208 13209 // The first sticky in the list is returned directly back to 13210 // the client. 13211 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13212 13213 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13214 + ": " + sticky); 13215 13216 if (receiver == null) { 13217 return sticky; 13218 } 13219 13220 ReceiverList rl 13221 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13222 if (rl == null) { 13223 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13224 userId, receiver); 13225 if (rl.app != null) { 13226 rl.app.receivers.add(rl); 13227 } else { 13228 try { 13229 receiver.asBinder().linkToDeath(rl, 0); 13230 } catch (RemoteException e) { 13231 return sticky; 13232 } 13233 rl.linkedToDeath = true; 13234 } 13235 mRegisteredReceivers.put(receiver.asBinder(), rl); 13236 } else if (rl.uid != callingUid) { 13237 throw new IllegalArgumentException( 13238 "Receiver requested to register for uid " + callingUid 13239 + " was previously registered for uid " + rl.uid); 13240 } else if (rl.pid != callingPid) { 13241 throw new IllegalArgumentException( 13242 "Receiver requested to register for pid " + callingPid 13243 + " was previously registered for pid " + rl.pid); 13244 } else if (rl.userId != userId) { 13245 throw new IllegalArgumentException( 13246 "Receiver requested to register for user " + userId 13247 + " was previously registered for user " + rl.userId); 13248 } 13249 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13250 permission, callingUid, userId); 13251 rl.add(bf); 13252 if (!bf.debugCheck()) { 13253 Slog.w(TAG, "==> For Dynamic broadast"); 13254 } 13255 mReceiverResolver.addFilter(bf); 13256 13257 // Enqueue broadcasts for all existing stickies that match 13258 // this filter. 13259 if (allSticky != null) { 13260 ArrayList receivers = new ArrayList(); 13261 receivers.add(bf); 13262 13263 int N = allSticky.size(); 13264 for (int i=0; i<N; i++) { 13265 Intent intent = (Intent)allSticky.get(i); 13266 BroadcastQueue queue = broadcastQueueForIntent(intent); 13267 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13268 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13269 null, null, false, true, true, -1); 13270 queue.enqueueParallelBroadcastLocked(r); 13271 queue.scheduleBroadcastsLocked(); 13272 } 13273 } 13274 13275 return sticky; 13276 } 13277 } 13278 13279 public void unregisterReceiver(IIntentReceiver receiver) { 13280 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13281 13282 final long origId = Binder.clearCallingIdentity(); 13283 try { 13284 boolean doTrim = false; 13285 13286 synchronized(this) { 13287 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13288 if (rl != null) { 13289 if (rl.curBroadcast != null) { 13290 BroadcastRecord r = rl.curBroadcast; 13291 final boolean doNext = finishReceiverLocked( 13292 receiver.asBinder(), r.resultCode, r.resultData, 13293 r.resultExtras, r.resultAbort); 13294 if (doNext) { 13295 doTrim = true; 13296 r.queue.processNextBroadcast(false); 13297 } 13298 } 13299 13300 if (rl.app != null) { 13301 rl.app.receivers.remove(rl); 13302 } 13303 removeReceiverLocked(rl); 13304 if (rl.linkedToDeath) { 13305 rl.linkedToDeath = false; 13306 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13307 } 13308 } 13309 } 13310 13311 // If we actually concluded any broadcasts, we might now be able 13312 // to trim the recipients' apps from our working set 13313 if (doTrim) { 13314 trimApplications(); 13315 return; 13316 } 13317 13318 } finally { 13319 Binder.restoreCallingIdentity(origId); 13320 } 13321 } 13322 13323 void removeReceiverLocked(ReceiverList rl) { 13324 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13325 int N = rl.size(); 13326 for (int i=0; i<N; i++) { 13327 mReceiverResolver.removeFilter(rl.get(i)); 13328 } 13329 } 13330 13331 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13332 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13333 ProcessRecord r = mLruProcesses.get(i); 13334 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13335 try { 13336 r.thread.dispatchPackageBroadcast(cmd, packages); 13337 } catch (RemoteException ex) { 13338 } 13339 } 13340 } 13341 } 13342 13343 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13344 int[] users) { 13345 List<ResolveInfo> receivers = null; 13346 try { 13347 HashSet<ComponentName> singleUserReceivers = null; 13348 boolean scannedFirstReceivers = false; 13349 for (int user : users) { 13350 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13351 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13352 if (user != 0 && newReceivers != null) { 13353 // If this is not the primary user, we need to check for 13354 // any receivers that should be filtered out. 13355 for (int i=0; i<newReceivers.size(); i++) { 13356 ResolveInfo ri = newReceivers.get(i); 13357 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13358 newReceivers.remove(i); 13359 i--; 13360 } 13361 } 13362 } 13363 if (newReceivers != null && newReceivers.size() == 0) { 13364 newReceivers = null; 13365 } 13366 if (receivers == null) { 13367 receivers = newReceivers; 13368 } else if (newReceivers != null) { 13369 // We need to concatenate the additional receivers 13370 // found with what we have do far. This would be easy, 13371 // but we also need to de-dup any receivers that are 13372 // singleUser. 13373 if (!scannedFirstReceivers) { 13374 // Collect any single user receivers we had already retrieved. 13375 scannedFirstReceivers = true; 13376 for (int i=0; i<receivers.size(); i++) { 13377 ResolveInfo ri = receivers.get(i); 13378 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13379 ComponentName cn = new ComponentName( 13380 ri.activityInfo.packageName, ri.activityInfo.name); 13381 if (singleUserReceivers == null) { 13382 singleUserReceivers = new HashSet<ComponentName>(); 13383 } 13384 singleUserReceivers.add(cn); 13385 } 13386 } 13387 } 13388 // Add the new results to the existing results, tracking 13389 // and de-dupping single user receivers. 13390 for (int i=0; i<newReceivers.size(); i++) { 13391 ResolveInfo ri = newReceivers.get(i); 13392 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13393 ComponentName cn = new ComponentName( 13394 ri.activityInfo.packageName, ri.activityInfo.name); 13395 if (singleUserReceivers == null) { 13396 singleUserReceivers = new HashSet<ComponentName>(); 13397 } 13398 if (!singleUserReceivers.contains(cn)) { 13399 singleUserReceivers.add(cn); 13400 receivers.add(ri); 13401 } 13402 } else { 13403 receivers.add(ri); 13404 } 13405 } 13406 } 13407 } 13408 } catch (RemoteException ex) { 13409 // pm is in same process, this will never happen. 13410 } 13411 return receivers; 13412 } 13413 13414 private final int broadcastIntentLocked(ProcessRecord callerApp, 13415 String callerPackage, Intent intent, String resolvedType, 13416 IIntentReceiver resultTo, int resultCode, String resultData, 13417 Bundle map, String requiredPermission, int appOp, 13418 boolean ordered, boolean sticky, int callingPid, int callingUid, 13419 int userId) { 13420 intent = new Intent(intent); 13421 13422 // By default broadcasts do not go to stopped apps. 13423 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13424 13425 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13426 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13427 + " ordered=" + ordered + " userid=" + userId); 13428 if ((resultTo != null) && !ordered) { 13429 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13430 } 13431 13432 userId = handleIncomingUser(callingPid, callingUid, userId, 13433 true, false, "broadcast", callerPackage); 13434 13435 // Make sure that the user who is receiving this broadcast is started. 13436 // If not, we will just skip it. 13437 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13438 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13439 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13440 Slog.w(TAG, "Skipping broadcast of " + intent 13441 + ": user " + userId + " is stopped"); 13442 return ActivityManager.BROADCAST_SUCCESS; 13443 } 13444 } 13445 13446 /* 13447 * Prevent non-system code (defined here to be non-persistent 13448 * processes) from sending protected broadcasts. 13449 */ 13450 int callingAppId = UserHandle.getAppId(callingUid); 13451 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13452 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13453 callingUid == 0) { 13454 // Always okay. 13455 } else if (callerApp == null || !callerApp.persistent) { 13456 try { 13457 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13458 intent.getAction())) { 13459 String msg = "Permission Denial: not allowed to send broadcast " 13460 + intent.getAction() + " from pid=" 13461 + callingPid + ", uid=" + callingUid; 13462 Slog.w(TAG, msg); 13463 throw new SecurityException(msg); 13464 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13465 // Special case for compatibility: we don't want apps to send this, 13466 // but historically it has not been protected and apps may be using it 13467 // to poke their own app widget. So, instead of making it protected, 13468 // just limit it to the caller. 13469 if (callerApp == null) { 13470 String msg = "Permission Denial: not allowed to send broadcast " 13471 + intent.getAction() + " from unknown caller."; 13472 Slog.w(TAG, msg); 13473 throw new SecurityException(msg); 13474 } else if (intent.getComponent() != null) { 13475 // They are good enough to send to an explicit component... verify 13476 // it is being sent to the calling app. 13477 if (!intent.getComponent().getPackageName().equals( 13478 callerApp.info.packageName)) { 13479 String msg = "Permission Denial: not allowed to send broadcast " 13480 + intent.getAction() + " to " 13481 + intent.getComponent().getPackageName() + " from " 13482 + callerApp.info.packageName; 13483 Slog.w(TAG, msg); 13484 throw new SecurityException(msg); 13485 } 13486 } else { 13487 // Limit broadcast to their own package. 13488 intent.setPackage(callerApp.info.packageName); 13489 } 13490 } 13491 } catch (RemoteException e) { 13492 Slog.w(TAG, "Remote exception", e); 13493 return ActivityManager.BROADCAST_SUCCESS; 13494 } 13495 } 13496 13497 // Handle special intents: if this broadcast is from the package 13498 // manager about a package being removed, we need to remove all of 13499 // its activities from the history stack. 13500 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13501 intent.getAction()); 13502 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13503 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13504 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13505 || uidRemoved) { 13506 if (checkComponentPermission( 13507 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13508 callingPid, callingUid, -1, true) 13509 == PackageManager.PERMISSION_GRANTED) { 13510 if (uidRemoved) { 13511 final Bundle intentExtras = intent.getExtras(); 13512 final int uid = intentExtras != null 13513 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13514 if (uid >= 0) { 13515 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13516 synchronized (bs) { 13517 bs.removeUidStatsLocked(uid); 13518 } 13519 mAppOpsService.uidRemoved(uid); 13520 } 13521 } else { 13522 // If resources are unavailable just force stop all 13523 // those packages and flush the attribute cache as well. 13524 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13525 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13526 if (list != null && (list.length > 0)) { 13527 for (String pkg : list) { 13528 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13529 "storage unmount"); 13530 } 13531 sendPackageBroadcastLocked( 13532 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13533 } 13534 } else { 13535 Uri data = intent.getData(); 13536 String ssp; 13537 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13538 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13539 intent.getAction()); 13540 boolean fullUninstall = removed && 13541 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13542 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13543 forceStopPackageLocked(ssp, UserHandle.getAppId( 13544 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13545 false, fullUninstall, userId, 13546 removed ? "pkg removed" : "pkg changed"); 13547 } 13548 if (removed) { 13549 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13550 new String[] {ssp}, userId); 13551 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13552 mAppOpsService.packageRemoved( 13553 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13554 13555 // Remove all permissions granted from/to this package 13556 removeUriPermissionsForPackageLocked(ssp, userId, true); 13557 } 13558 } 13559 } 13560 } 13561 } 13562 } else { 13563 String msg = "Permission Denial: " + intent.getAction() 13564 + " broadcast from " + callerPackage + " (pid=" + callingPid 13565 + ", uid=" + callingUid + ")" 13566 + " requires " 13567 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13568 Slog.w(TAG, msg); 13569 throw new SecurityException(msg); 13570 } 13571 13572 // Special case for adding a package: by default turn on compatibility 13573 // mode. 13574 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13575 Uri data = intent.getData(); 13576 String ssp; 13577 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13578 mCompatModePackages.handlePackageAddedLocked(ssp, 13579 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13580 } 13581 } 13582 13583 /* 13584 * If this is the time zone changed action, queue up a message that will reset the timezone 13585 * of all currently running processes. This message will get queued up before the broadcast 13586 * happens. 13587 */ 13588 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13589 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13590 } 13591 13592 /* 13593 * If the user set the time, let all running processes know. 13594 */ 13595 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13596 final int is24Hour = intent.getBooleanExtra( 13597 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13598 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13599 } 13600 13601 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13602 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13603 } 13604 13605 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13606 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13607 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13608 } 13609 13610 // Add to the sticky list if requested. 13611 if (sticky) { 13612 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13613 callingPid, callingUid) 13614 != PackageManager.PERMISSION_GRANTED) { 13615 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13616 + callingPid + ", uid=" + callingUid 13617 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13618 Slog.w(TAG, msg); 13619 throw new SecurityException(msg); 13620 } 13621 if (requiredPermission != null) { 13622 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13623 + " and enforce permission " + requiredPermission); 13624 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13625 } 13626 if (intent.getComponent() != null) { 13627 throw new SecurityException( 13628 "Sticky broadcasts can't target a specific component"); 13629 } 13630 // We use userId directly here, since the "all" target is maintained 13631 // as a separate set of sticky broadcasts. 13632 if (userId != UserHandle.USER_ALL) { 13633 // But first, if this is not a broadcast to all users, then 13634 // make sure it doesn't conflict with an existing broadcast to 13635 // all users. 13636 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13637 UserHandle.USER_ALL); 13638 if (stickies != null) { 13639 ArrayList<Intent> list = stickies.get(intent.getAction()); 13640 if (list != null) { 13641 int N = list.size(); 13642 int i; 13643 for (i=0; i<N; i++) { 13644 if (intent.filterEquals(list.get(i))) { 13645 throw new IllegalArgumentException( 13646 "Sticky broadcast " + intent + " for user " 13647 + userId + " conflicts with existing global broadcast"); 13648 } 13649 } 13650 } 13651 } 13652 } 13653 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13654 if (stickies == null) { 13655 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13656 mStickyBroadcasts.put(userId, stickies); 13657 } 13658 ArrayList<Intent> list = stickies.get(intent.getAction()); 13659 if (list == null) { 13660 list = new ArrayList<Intent>(); 13661 stickies.put(intent.getAction(), list); 13662 } 13663 int N = list.size(); 13664 int i; 13665 for (i=0; i<N; i++) { 13666 if (intent.filterEquals(list.get(i))) { 13667 // This sticky already exists, replace it. 13668 list.set(i, new Intent(intent)); 13669 break; 13670 } 13671 } 13672 if (i >= N) { 13673 list.add(new Intent(intent)); 13674 } 13675 } 13676 13677 int[] users; 13678 if (userId == UserHandle.USER_ALL) { 13679 // Caller wants broadcast to go to all started users. 13680 users = mStartedUserArray; 13681 } else { 13682 // Caller wants broadcast to go to one specific user. 13683 users = new int[] {userId}; 13684 } 13685 13686 // Figure out who all will receive this broadcast. 13687 List receivers = null; 13688 List<BroadcastFilter> registeredReceivers = null; 13689 // Need to resolve the intent to interested receivers... 13690 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13691 == 0) { 13692 receivers = collectReceiverComponents(intent, resolvedType, users); 13693 } 13694 if (intent.getComponent() == null) { 13695 registeredReceivers = mReceiverResolver.queryIntent(intent, 13696 resolvedType, false, userId); 13697 } 13698 13699 final boolean replacePending = 13700 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13701 13702 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13703 + " replacePending=" + replacePending); 13704 13705 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13706 if (!ordered && NR > 0) { 13707 // If we are not serializing this broadcast, then send the 13708 // registered receivers separately so they don't wait for the 13709 // components to be launched. 13710 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13711 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13712 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13713 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13714 ordered, sticky, false, userId); 13715 if (DEBUG_BROADCAST) Slog.v( 13716 TAG, "Enqueueing parallel broadcast " + r); 13717 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13718 if (!replaced) { 13719 queue.enqueueParallelBroadcastLocked(r); 13720 queue.scheduleBroadcastsLocked(); 13721 } 13722 registeredReceivers = null; 13723 NR = 0; 13724 } 13725 13726 // Merge into one list. 13727 int ir = 0; 13728 if (receivers != null) { 13729 // A special case for PACKAGE_ADDED: do not allow the package 13730 // being added to see this broadcast. This prevents them from 13731 // using this as a back door to get run as soon as they are 13732 // installed. Maybe in the future we want to have a special install 13733 // broadcast or such for apps, but we'd like to deliberately make 13734 // this decision. 13735 String skipPackages[] = null; 13736 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13737 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13738 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13739 Uri data = intent.getData(); 13740 if (data != null) { 13741 String pkgName = data.getSchemeSpecificPart(); 13742 if (pkgName != null) { 13743 skipPackages = new String[] { pkgName }; 13744 } 13745 } 13746 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13747 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13748 } 13749 if (skipPackages != null && (skipPackages.length > 0)) { 13750 for (String skipPackage : skipPackages) { 13751 if (skipPackage != null) { 13752 int NT = receivers.size(); 13753 for (int it=0; it<NT; it++) { 13754 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13755 if (curt.activityInfo.packageName.equals(skipPackage)) { 13756 receivers.remove(it); 13757 it--; 13758 NT--; 13759 } 13760 } 13761 } 13762 } 13763 } 13764 13765 int NT = receivers != null ? receivers.size() : 0; 13766 int it = 0; 13767 ResolveInfo curt = null; 13768 BroadcastFilter curr = null; 13769 while (it < NT && ir < NR) { 13770 if (curt == null) { 13771 curt = (ResolveInfo)receivers.get(it); 13772 } 13773 if (curr == null) { 13774 curr = registeredReceivers.get(ir); 13775 } 13776 if (curr.getPriority() >= curt.priority) { 13777 // Insert this broadcast record into the final list. 13778 receivers.add(it, curr); 13779 ir++; 13780 curr = null; 13781 it++; 13782 NT++; 13783 } else { 13784 // Skip to the next ResolveInfo in the final list. 13785 it++; 13786 curt = null; 13787 } 13788 } 13789 } 13790 while (ir < NR) { 13791 if (receivers == null) { 13792 receivers = new ArrayList(); 13793 } 13794 receivers.add(registeredReceivers.get(ir)); 13795 ir++; 13796 } 13797 13798 if ((receivers != null && receivers.size() > 0) 13799 || resultTo != null) { 13800 BroadcastQueue queue = broadcastQueueForIntent(intent); 13801 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13802 callerPackage, callingPid, callingUid, resolvedType, 13803 requiredPermission, appOp, receivers, resultTo, resultCode, 13804 resultData, map, ordered, sticky, false, userId); 13805 if (DEBUG_BROADCAST) Slog.v( 13806 TAG, "Enqueueing ordered broadcast " + r 13807 + ": prev had " + queue.mOrderedBroadcasts.size()); 13808 if (DEBUG_BROADCAST) { 13809 int seq = r.intent.getIntExtra("seq", -1); 13810 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13811 } 13812 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13813 if (!replaced) { 13814 queue.enqueueOrderedBroadcastLocked(r); 13815 queue.scheduleBroadcastsLocked(); 13816 } 13817 } 13818 13819 return ActivityManager.BROADCAST_SUCCESS; 13820 } 13821 13822 final Intent verifyBroadcastLocked(Intent intent) { 13823 // Refuse possible leaked file descriptors 13824 if (intent != null && intent.hasFileDescriptors() == true) { 13825 throw new IllegalArgumentException("File descriptors passed in Intent"); 13826 } 13827 13828 int flags = intent.getFlags(); 13829 13830 if (!mProcessesReady) { 13831 // if the caller really truly claims to know what they're doing, go 13832 // ahead and allow the broadcast without launching any receivers 13833 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13834 intent = new Intent(intent); 13835 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13836 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13837 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13838 + " before boot completion"); 13839 throw new IllegalStateException("Cannot broadcast before boot completed"); 13840 } 13841 } 13842 13843 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13844 throw new IllegalArgumentException( 13845 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13846 } 13847 13848 return intent; 13849 } 13850 13851 public final int broadcastIntent(IApplicationThread caller, 13852 Intent intent, String resolvedType, IIntentReceiver resultTo, 13853 int resultCode, String resultData, Bundle map, 13854 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13855 enforceNotIsolatedCaller("broadcastIntent"); 13856 synchronized(this) { 13857 intent = verifyBroadcastLocked(intent); 13858 13859 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13860 final int callingPid = Binder.getCallingPid(); 13861 final int callingUid = Binder.getCallingUid(); 13862 final long origId = Binder.clearCallingIdentity(); 13863 int res = broadcastIntentLocked(callerApp, 13864 callerApp != null ? callerApp.info.packageName : null, 13865 intent, resolvedType, resultTo, 13866 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13867 callingPid, callingUid, userId); 13868 Binder.restoreCallingIdentity(origId); 13869 return res; 13870 } 13871 } 13872 13873 int broadcastIntentInPackage(String packageName, int uid, 13874 Intent intent, String resolvedType, IIntentReceiver resultTo, 13875 int resultCode, String resultData, Bundle map, 13876 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13877 synchronized(this) { 13878 intent = verifyBroadcastLocked(intent); 13879 13880 final long origId = Binder.clearCallingIdentity(); 13881 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13882 resultTo, resultCode, resultData, map, requiredPermission, 13883 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13884 Binder.restoreCallingIdentity(origId); 13885 return res; 13886 } 13887 } 13888 13889 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13890 // Refuse possible leaked file descriptors 13891 if (intent != null && intent.hasFileDescriptors() == true) { 13892 throw new IllegalArgumentException("File descriptors passed in Intent"); 13893 } 13894 13895 userId = handleIncomingUser(Binder.getCallingPid(), 13896 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13897 13898 synchronized(this) { 13899 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13900 != PackageManager.PERMISSION_GRANTED) { 13901 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13902 + Binder.getCallingPid() 13903 + ", uid=" + Binder.getCallingUid() 13904 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13905 Slog.w(TAG, msg); 13906 throw new SecurityException(msg); 13907 } 13908 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13909 if (stickies != null) { 13910 ArrayList<Intent> list = stickies.get(intent.getAction()); 13911 if (list != null) { 13912 int N = list.size(); 13913 int i; 13914 for (i=0; i<N; i++) { 13915 if (intent.filterEquals(list.get(i))) { 13916 list.remove(i); 13917 break; 13918 } 13919 } 13920 if (list.size() <= 0) { 13921 stickies.remove(intent.getAction()); 13922 } 13923 } 13924 if (stickies.size() <= 0) { 13925 mStickyBroadcasts.remove(userId); 13926 } 13927 } 13928 } 13929 } 13930 13931 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13932 String resultData, Bundle resultExtras, boolean resultAbort) { 13933 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13934 if (r == null) { 13935 Slog.w(TAG, "finishReceiver called but not found on queue"); 13936 return false; 13937 } 13938 13939 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13940 } 13941 13942 void backgroundServicesFinishedLocked(int userId) { 13943 for (BroadcastQueue queue : mBroadcastQueues) { 13944 queue.backgroundServicesFinishedLocked(userId); 13945 } 13946 } 13947 13948 public void finishReceiver(IBinder who, int resultCode, String resultData, 13949 Bundle resultExtras, boolean resultAbort) { 13950 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13951 13952 // Refuse possible leaked file descriptors 13953 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13954 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13955 } 13956 13957 final long origId = Binder.clearCallingIdentity(); 13958 try { 13959 boolean doNext = false; 13960 BroadcastRecord r; 13961 13962 synchronized(this) { 13963 r = broadcastRecordForReceiverLocked(who); 13964 if (r != null) { 13965 doNext = r.queue.finishReceiverLocked(r, resultCode, 13966 resultData, resultExtras, resultAbort, true); 13967 } 13968 } 13969 13970 if (doNext) { 13971 r.queue.processNextBroadcast(false); 13972 } 13973 trimApplications(); 13974 } finally { 13975 Binder.restoreCallingIdentity(origId); 13976 } 13977 } 13978 13979 // ========================================================= 13980 // INSTRUMENTATION 13981 // ========================================================= 13982 13983 public boolean startInstrumentation(ComponentName className, 13984 String profileFile, int flags, Bundle arguments, 13985 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13986 int userId) { 13987 enforceNotIsolatedCaller("startInstrumentation"); 13988 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13989 userId, false, true, "startInstrumentation", null); 13990 // Refuse possible leaked file descriptors 13991 if (arguments != null && arguments.hasFileDescriptors()) { 13992 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13993 } 13994 13995 synchronized(this) { 13996 InstrumentationInfo ii = null; 13997 ApplicationInfo ai = null; 13998 try { 13999 ii = mContext.getPackageManager().getInstrumentationInfo( 14000 className, STOCK_PM_FLAGS); 14001 ai = AppGlobals.getPackageManager().getApplicationInfo( 14002 ii.targetPackage, STOCK_PM_FLAGS, userId); 14003 } catch (PackageManager.NameNotFoundException e) { 14004 } catch (RemoteException e) { 14005 } 14006 if (ii == null) { 14007 reportStartInstrumentationFailure(watcher, className, 14008 "Unable to find instrumentation info for: " + className); 14009 return false; 14010 } 14011 if (ai == null) { 14012 reportStartInstrumentationFailure(watcher, className, 14013 "Unable to find instrumentation target package: " + ii.targetPackage); 14014 return false; 14015 } 14016 14017 int match = mContext.getPackageManager().checkSignatures( 14018 ii.targetPackage, ii.packageName); 14019 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14020 String msg = "Permission Denial: starting instrumentation " 14021 + className + " from pid=" 14022 + Binder.getCallingPid() 14023 + ", uid=" + Binder.getCallingPid() 14024 + " not allowed because package " + ii.packageName 14025 + " does not have a signature matching the target " 14026 + ii.targetPackage; 14027 reportStartInstrumentationFailure(watcher, className, msg); 14028 throw new SecurityException(msg); 14029 } 14030 14031 final long origId = Binder.clearCallingIdentity(); 14032 // Instrumentation can kill and relaunch even persistent processes 14033 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14034 "start instr"); 14035 ProcessRecord app = addAppLocked(ai, false); 14036 app.instrumentationClass = className; 14037 app.instrumentationInfo = ai; 14038 app.instrumentationProfileFile = profileFile; 14039 app.instrumentationArguments = arguments; 14040 app.instrumentationWatcher = watcher; 14041 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14042 app.instrumentationResultClass = className; 14043 Binder.restoreCallingIdentity(origId); 14044 } 14045 14046 return true; 14047 } 14048 14049 /** 14050 * Report errors that occur while attempting to start Instrumentation. Always writes the 14051 * error to the logs, but if somebody is watching, send the report there too. This enables 14052 * the "am" command to report errors with more information. 14053 * 14054 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14055 * @param cn The component name of the instrumentation. 14056 * @param report The error report. 14057 */ 14058 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14059 ComponentName cn, String report) { 14060 Slog.w(TAG, report); 14061 try { 14062 if (watcher != null) { 14063 Bundle results = new Bundle(); 14064 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14065 results.putString("Error", report); 14066 watcher.instrumentationStatus(cn, -1, results); 14067 } 14068 } catch (RemoteException e) { 14069 Slog.w(TAG, e); 14070 } 14071 } 14072 14073 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14074 if (app.instrumentationWatcher != null) { 14075 try { 14076 // NOTE: IInstrumentationWatcher *must* be oneway here 14077 app.instrumentationWatcher.instrumentationFinished( 14078 app.instrumentationClass, 14079 resultCode, 14080 results); 14081 } catch (RemoteException e) { 14082 } 14083 } 14084 if (app.instrumentationUiAutomationConnection != null) { 14085 try { 14086 app.instrumentationUiAutomationConnection.shutdown(); 14087 } catch (RemoteException re) { 14088 /* ignore */ 14089 } 14090 // Only a UiAutomation can set this flag and now that 14091 // it is finished we make sure it is reset to its default. 14092 mUserIsMonkey = false; 14093 } 14094 app.instrumentationWatcher = null; 14095 app.instrumentationUiAutomationConnection = null; 14096 app.instrumentationClass = null; 14097 app.instrumentationInfo = null; 14098 app.instrumentationProfileFile = null; 14099 app.instrumentationArguments = null; 14100 14101 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14102 "finished inst"); 14103 } 14104 14105 public void finishInstrumentation(IApplicationThread target, 14106 int resultCode, Bundle results) { 14107 int userId = UserHandle.getCallingUserId(); 14108 // Refuse possible leaked file descriptors 14109 if (results != null && results.hasFileDescriptors()) { 14110 throw new IllegalArgumentException("File descriptors passed in Intent"); 14111 } 14112 14113 synchronized(this) { 14114 ProcessRecord app = getRecordForAppLocked(target); 14115 if (app == null) { 14116 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14117 return; 14118 } 14119 final long origId = Binder.clearCallingIdentity(); 14120 finishInstrumentationLocked(app, resultCode, results); 14121 Binder.restoreCallingIdentity(origId); 14122 } 14123 } 14124 14125 // ========================================================= 14126 // CONFIGURATION 14127 // ========================================================= 14128 14129 public ConfigurationInfo getDeviceConfigurationInfo() { 14130 ConfigurationInfo config = new ConfigurationInfo(); 14131 synchronized (this) { 14132 config.reqTouchScreen = mConfiguration.touchscreen; 14133 config.reqKeyboardType = mConfiguration.keyboard; 14134 config.reqNavigation = mConfiguration.navigation; 14135 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14136 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14137 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14138 } 14139 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14140 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14141 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14142 } 14143 config.reqGlEsVersion = GL_ES_VERSION; 14144 } 14145 return config; 14146 } 14147 14148 ActivityStack getFocusedStack() { 14149 return mStackSupervisor.getFocusedStack(); 14150 } 14151 14152 public Configuration getConfiguration() { 14153 Configuration ci; 14154 synchronized(this) { 14155 ci = new Configuration(mConfiguration); 14156 } 14157 return ci; 14158 } 14159 14160 public void updatePersistentConfiguration(Configuration values) { 14161 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14162 "updateConfiguration()"); 14163 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14164 "updateConfiguration()"); 14165 if (values == null) { 14166 throw new NullPointerException("Configuration must not be null"); 14167 } 14168 14169 synchronized(this) { 14170 final long origId = Binder.clearCallingIdentity(); 14171 updateConfigurationLocked(values, null, true, false); 14172 Binder.restoreCallingIdentity(origId); 14173 } 14174 } 14175 14176 public void updateConfiguration(Configuration values) { 14177 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14178 "updateConfiguration()"); 14179 14180 synchronized(this) { 14181 if (values == null && mWindowManager != null) { 14182 // sentinel: fetch the current configuration from the window manager 14183 values = mWindowManager.computeNewConfiguration(); 14184 } 14185 14186 if (mWindowManager != null) { 14187 mProcessList.applyDisplaySize(mWindowManager); 14188 } 14189 14190 final long origId = Binder.clearCallingIdentity(); 14191 if (values != null) { 14192 Settings.System.clearConfiguration(values); 14193 } 14194 updateConfigurationLocked(values, null, false, false); 14195 Binder.restoreCallingIdentity(origId); 14196 } 14197 } 14198 14199 /** 14200 * Do either or both things: (1) change the current configuration, and (2) 14201 * make sure the given activity is running with the (now) current 14202 * configuration. Returns true if the activity has been left running, or 14203 * false if <var>starting</var> is being destroyed to match the new 14204 * configuration. 14205 * @param persistent TODO 14206 */ 14207 boolean updateConfigurationLocked(Configuration values, 14208 ActivityRecord starting, boolean persistent, boolean initLocale) { 14209 int changes = 0; 14210 14211 if (values != null) { 14212 Configuration newConfig = new Configuration(mConfiguration); 14213 changes = newConfig.updateFrom(values); 14214 if (changes != 0) { 14215 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14216 Slog.i(TAG, "Updating configuration to: " + values); 14217 } 14218 14219 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14220 14221 if (values.locale != null && !initLocale) { 14222 saveLocaleLocked(values.locale, 14223 !values.locale.equals(mConfiguration.locale), 14224 values.userSetLocale); 14225 } 14226 14227 mConfigurationSeq++; 14228 if (mConfigurationSeq <= 0) { 14229 mConfigurationSeq = 1; 14230 } 14231 newConfig.seq = mConfigurationSeq; 14232 mConfiguration = newConfig; 14233 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14234 14235 final Configuration configCopy = new Configuration(mConfiguration); 14236 14237 // TODO: If our config changes, should we auto dismiss any currently 14238 // showing dialogs? 14239 mShowDialogs = shouldShowDialogs(newConfig); 14240 14241 AttributeCache ac = AttributeCache.instance(); 14242 if (ac != null) { 14243 ac.updateConfiguration(configCopy); 14244 } 14245 14246 // Make sure all resources in our process are updated 14247 // right now, so that anyone who is going to retrieve 14248 // resource values after we return will be sure to get 14249 // the new ones. This is especially important during 14250 // boot, where the first config change needs to guarantee 14251 // all resources have that config before following boot 14252 // code is executed. 14253 mSystemThread.applyConfigurationToResources(configCopy); 14254 14255 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14256 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14257 msg.obj = new Configuration(configCopy); 14258 mHandler.sendMessage(msg); 14259 } 14260 14261 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14262 ProcessRecord app = mLruProcesses.get(i); 14263 try { 14264 if (app.thread != null) { 14265 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14266 + app.processName + " new config " + mConfiguration); 14267 app.thread.scheduleConfigurationChanged(configCopy); 14268 } 14269 } catch (Exception e) { 14270 } 14271 } 14272 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14273 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14274 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14275 | Intent.FLAG_RECEIVER_FOREGROUND); 14276 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14277 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14278 Process.SYSTEM_UID, UserHandle.USER_ALL); 14279 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14280 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14281 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14282 broadcastIntentLocked(null, null, intent, 14283 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14284 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14285 } 14286 } 14287 } 14288 14289 boolean kept = true; 14290 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14291 // mainStack is null during startup. 14292 if (mainStack != null) { 14293 if (changes != 0 && starting == null) { 14294 // If the configuration changed, and the caller is not already 14295 // in the process of starting an activity, then find the top 14296 // activity to check if its configuration needs to change. 14297 starting = mainStack.topRunningActivityLocked(null); 14298 } 14299 14300 if (starting != null) { 14301 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14302 // And we need to make sure at this point that all other activities 14303 // are made visible with the correct configuration. 14304 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14305 } 14306 } 14307 14308 if (values != null && mWindowManager != null) { 14309 mWindowManager.setNewConfiguration(mConfiguration); 14310 } 14311 14312 return kept; 14313 } 14314 14315 /** 14316 * Decide based on the configuration whether we should shouw the ANR, 14317 * crash, etc dialogs. The idea is that if there is no affordnace to 14318 * press the on-screen buttons, we shouldn't show the dialog. 14319 * 14320 * A thought: SystemUI might also want to get told about this, the Power 14321 * dialog / global actions also might want different behaviors. 14322 */ 14323 private static final boolean shouldShowDialogs(Configuration config) { 14324 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14325 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14326 } 14327 14328 /** 14329 * Save the locale. You must be inside a synchronized (this) block. 14330 */ 14331 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14332 if(isDiff) { 14333 SystemProperties.set("user.language", l.getLanguage()); 14334 SystemProperties.set("user.region", l.getCountry()); 14335 } 14336 14337 if(isPersist) { 14338 SystemProperties.set("persist.sys.language", l.getLanguage()); 14339 SystemProperties.set("persist.sys.country", l.getCountry()); 14340 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14341 } 14342 } 14343 14344 @Override 14345 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14346 ActivityRecord srec = ActivityRecord.forToken(token); 14347 return srec != null && srec.task.affinity != null && 14348 srec.task.affinity.equals(destAffinity); 14349 } 14350 14351 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14352 Intent resultData) { 14353 14354 synchronized (this) { 14355 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14356 if (stack != null) { 14357 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14358 } 14359 return false; 14360 } 14361 } 14362 14363 public int getLaunchedFromUid(IBinder activityToken) { 14364 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14365 if (srec == null) { 14366 return -1; 14367 } 14368 return srec.launchedFromUid; 14369 } 14370 14371 public String getLaunchedFromPackage(IBinder activityToken) { 14372 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14373 if (srec == null) { 14374 return null; 14375 } 14376 return srec.launchedFromPackage; 14377 } 14378 14379 // ========================================================= 14380 // LIFETIME MANAGEMENT 14381 // ========================================================= 14382 14383 // Returns which broadcast queue the app is the current [or imminent] receiver 14384 // on, or 'null' if the app is not an active broadcast recipient. 14385 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14386 BroadcastRecord r = app.curReceiver; 14387 if (r != null) { 14388 return r.queue; 14389 } 14390 14391 // It's not the current receiver, but it might be starting up to become one 14392 synchronized (this) { 14393 for (BroadcastQueue queue : mBroadcastQueues) { 14394 r = queue.mPendingBroadcast; 14395 if (r != null && r.curApp == app) { 14396 // found it; report which queue it's in 14397 return queue; 14398 } 14399 } 14400 } 14401 14402 return null; 14403 } 14404 14405 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14406 boolean doingAll, long now) { 14407 if (mAdjSeq == app.adjSeq) { 14408 // This adjustment has already been computed. 14409 return app.curRawAdj; 14410 } 14411 14412 if (app.thread == null) { 14413 app.adjSeq = mAdjSeq; 14414 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14415 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14416 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14417 } 14418 14419 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14420 app.adjSource = null; 14421 app.adjTarget = null; 14422 app.empty = false; 14423 app.cached = false; 14424 14425 final int activitiesSize = app.activities.size(); 14426 14427 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14428 // The max adjustment doesn't allow this app to be anything 14429 // below foreground, so it is not worth doing work for it. 14430 app.adjType = "fixed"; 14431 app.adjSeq = mAdjSeq; 14432 app.curRawAdj = app.maxAdj; 14433 app.foregroundActivities = false; 14434 app.keeping = true; 14435 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14436 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14437 // System process can do UI, and when they do we want to have 14438 // them trim their memory after the user leaves the UI. To 14439 // facilitate this, here we need to determine whether or not it 14440 // is currently showing UI. 14441 app.systemNoUi = true; 14442 if (app == TOP_APP) { 14443 app.systemNoUi = false; 14444 } else if (activitiesSize > 0) { 14445 for (int j = 0; j < activitiesSize; j++) { 14446 final ActivityRecord r = app.activities.get(j); 14447 if (r.visible) { 14448 app.systemNoUi = false; 14449 } 14450 } 14451 } 14452 if (!app.systemNoUi) { 14453 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14454 } 14455 return (app.curAdj=app.maxAdj); 14456 } 14457 14458 app.keeping = false; 14459 app.systemNoUi = false; 14460 14461 // Determine the importance of the process, starting with most 14462 // important to least, and assign an appropriate OOM adjustment. 14463 int adj; 14464 int schedGroup; 14465 int procState; 14466 boolean foregroundActivities = false; 14467 boolean interesting = false; 14468 BroadcastQueue queue; 14469 if (app == TOP_APP) { 14470 // The last app on the list is the foreground app. 14471 adj = ProcessList.FOREGROUND_APP_ADJ; 14472 schedGroup = Process.THREAD_GROUP_DEFAULT; 14473 app.adjType = "top-activity"; 14474 foregroundActivities = true; 14475 interesting = true; 14476 procState = ActivityManager.PROCESS_STATE_TOP; 14477 } else if (app.instrumentationClass != null) { 14478 // Don't want to kill running instrumentation. 14479 adj = ProcessList.FOREGROUND_APP_ADJ; 14480 schedGroup = Process.THREAD_GROUP_DEFAULT; 14481 app.adjType = "instrumentation"; 14482 interesting = true; 14483 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14484 } else if ((queue = isReceivingBroadcast(app)) != null) { 14485 // An app that is currently receiving a broadcast also 14486 // counts as being in the foreground for OOM killer purposes. 14487 // It's placed in a sched group based on the nature of the 14488 // broadcast as reflected by which queue it's active in. 14489 adj = ProcessList.FOREGROUND_APP_ADJ; 14490 schedGroup = (queue == mFgBroadcastQueue) 14491 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14492 app.adjType = "broadcast"; 14493 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14494 } else if (app.executingServices.size() > 0) { 14495 // An app that is currently executing a service callback also 14496 // counts as being in the foreground. 14497 adj = ProcessList.FOREGROUND_APP_ADJ; 14498 schedGroup = app.execServicesFg ? 14499 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14500 app.adjType = "exec-service"; 14501 procState = ActivityManager.PROCESS_STATE_SERVICE; 14502 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14503 } else { 14504 // As far as we know the process is empty. We may change our mind later. 14505 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14506 // At this point we don't actually know the adjustment. Use the cached adj 14507 // value that the caller wants us to. 14508 adj = cachedAdj; 14509 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14510 app.cached = true; 14511 app.empty = true; 14512 app.adjType = "cch-empty"; 14513 } 14514 14515 // Examine all activities if not already foreground. 14516 if (!foregroundActivities && activitiesSize > 0) { 14517 for (int j = 0; j < activitiesSize; j++) { 14518 final ActivityRecord r = app.activities.get(j); 14519 if (r.app != app) { 14520 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14521 + app + "?!?"); 14522 continue; 14523 } 14524 if (r.visible) { 14525 // App has a visible activity; only upgrade adjustment. 14526 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14527 adj = ProcessList.VISIBLE_APP_ADJ; 14528 app.adjType = "visible"; 14529 } 14530 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14531 procState = ActivityManager.PROCESS_STATE_TOP; 14532 } 14533 schedGroup = Process.THREAD_GROUP_DEFAULT; 14534 app.cached = false; 14535 app.empty = false; 14536 foregroundActivities = true; 14537 break; 14538 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14539 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14540 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14541 app.adjType = "pausing"; 14542 } 14543 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14544 procState = ActivityManager.PROCESS_STATE_TOP; 14545 } 14546 schedGroup = Process.THREAD_GROUP_DEFAULT; 14547 app.cached = false; 14548 app.empty = false; 14549 foregroundActivities = true; 14550 } else if (r.state == ActivityState.STOPPING) { 14551 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14552 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14553 app.adjType = "stopping"; 14554 } 14555 // For the process state, we will at this point consider the 14556 // process to be cached. It will be cached either as an activity 14557 // or empty depending on whether the activity is finishing. We do 14558 // this so that we can treat the process as cached for purposes of 14559 // memory trimming (determing current memory level, trim command to 14560 // send to process) since there can be an arbitrary number of stopping 14561 // processes and they should soon all go into the cached state. 14562 if (!r.finishing) { 14563 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14564 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14565 } 14566 } 14567 app.cached = false; 14568 app.empty = false; 14569 foregroundActivities = true; 14570 } else { 14571 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14572 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14573 app.adjType = "cch-act"; 14574 } 14575 } 14576 } 14577 } 14578 14579 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14580 if (app.foregroundServices) { 14581 // The user is aware of this app, so make it visible. 14582 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14583 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14584 app.cached = false; 14585 app.adjType = "fg-service"; 14586 schedGroup = Process.THREAD_GROUP_DEFAULT; 14587 } else if (app.forcingToForeground != null) { 14588 // The user is aware of this app, so make it visible. 14589 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14590 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14591 app.cached = false; 14592 app.adjType = "force-fg"; 14593 app.adjSource = app.forcingToForeground; 14594 schedGroup = Process.THREAD_GROUP_DEFAULT; 14595 } 14596 } 14597 14598 if (app.foregroundServices) { 14599 interesting = true; 14600 } 14601 14602 if (app == mHeavyWeightProcess) { 14603 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14604 // We don't want to kill the current heavy-weight process. 14605 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14606 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14607 app.cached = false; 14608 app.adjType = "heavy"; 14609 } 14610 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14611 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14612 } 14613 } 14614 14615 if (app == mHomeProcess) { 14616 if (adj > ProcessList.HOME_APP_ADJ) { 14617 // This process is hosting what we currently consider to be the 14618 // home app, so we don't want to let it go into the background. 14619 adj = ProcessList.HOME_APP_ADJ; 14620 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14621 app.cached = false; 14622 app.adjType = "home"; 14623 } 14624 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14625 procState = ActivityManager.PROCESS_STATE_HOME; 14626 } 14627 } 14628 14629 if (app == mPreviousProcess && app.activities.size() > 0) { 14630 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14631 // This was the previous process that showed UI to the user. 14632 // We want to try to keep it around more aggressively, to give 14633 // a good experience around switching between two apps. 14634 adj = ProcessList.PREVIOUS_APP_ADJ; 14635 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14636 app.cached = false; 14637 app.adjType = "previous"; 14638 } 14639 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14640 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14641 } 14642 } 14643 14644 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14645 + " reason=" + app.adjType); 14646 14647 // By default, we use the computed adjustment. It may be changed if 14648 // there are applications dependent on our services or providers, but 14649 // this gives us a baseline and makes sure we don't get into an 14650 // infinite recursion. 14651 app.adjSeq = mAdjSeq; 14652 app.curRawAdj = adj; 14653 app.hasStartedServices = false; 14654 14655 if (mBackupTarget != null && app == mBackupTarget.app) { 14656 // If possible we want to avoid killing apps while they're being backed up 14657 if (adj > ProcessList.BACKUP_APP_ADJ) { 14658 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14659 adj = ProcessList.BACKUP_APP_ADJ; 14660 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14661 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14662 } 14663 app.adjType = "backup"; 14664 app.cached = false; 14665 } 14666 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14667 procState = ActivityManager.PROCESS_STATE_BACKUP; 14668 } 14669 } 14670 14671 boolean mayBeTop = false; 14672 14673 for (int is = app.services.size()-1; 14674 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14675 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14676 || procState > ActivityManager.PROCESS_STATE_TOP); 14677 is--) { 14678 ServiceRecord s = app.services.valueAt(is); 14679 if (s.startRequested) { 14680 app.hasStartedServices = true; 14681 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14682 procState = ActivityManager.PROCESS_STATE_SERVICE; 14683 } 14684 if (app.hasShownUi && app != mHomeProcess) { 14685 // If this process has shown some UI, let it immediately 14686 // go to the LRU list because it may be pretty heavy with 14687 // UI stuff. We'll tag it with a label just to help 14688 // debug and understand what is going on. 14689 if (adj > ProcessList.SERVICE_ADJ) { 14690 app.adjType = "cch-started-ui-services"; 14691 } 14692 } else { 14693 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14694 // This service has seen some activity within 14695 // recent memory, so we will keep its process ahead 14696 // of the background processes. 14697 if (adj > ProcessList.SERVICE_ADJ) { 14698 adj = ProcessList.SERVICE_ADJ; 14699 app.adjType = "started-services"; 14700 app.cached = false; 14701 } 14702 } 14703 // If we have let the service slide into the background 14704 // state, still have some text describing what it is doing 14705 // even though the service no longer has an impact. 14706 if (adj > ProcessList.SERVICE_ADJ) { 14707 app.adjType = "cch-started-services"; 14708 } 14709 } 14710 // Don't kill this process because it is doing work; it 14711 // has said it is doing work. 14712 app.keeping = true; 14713 } 14714 for (int conni = s.connections.size()-1; 14715 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14716 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14717 || procState > ActivityManager.PROCESS_STATE_TOP); 14718 conni--) { 14719 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14720 for (int i = 0; 14721 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14722 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14723 || procState > ActivityManager.PROCESS_STATE_TOP); 14724 i++) { 14725 // XXX should compute this based on the max of 14726 // all connected clients. 14727 ConnectionRecord cr = clist.get(i); 14728 if (cr.binding.client == app) { 14729 // Binding to ourself is not interesting. 14730 continue; 14731 } 14732 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14733 ProcessRecord client = cr.binding.client; 14734 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14735 TOP_APP, doingAll, now); 14736 int clientProcState = client.curProcState; 14737 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14738 // If the other app is cached for any reason, for purposes here 14739 // we are going to consider it empty. The specific cached state 14740 // doesn't propagate except under certain conditions. 14741 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14742 } 14743 String adjType = null; 14744 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14745 // Not doing bind OOM management, so treat 14746 // this guy more like a started service. 14747 if (app.hasShownUi && app != mHomeProcess) { 14748 // If this process has shown some UI, let it immediately 14749 // go to the LRU list because it may be pretty heavy with 14750 // UI stuff. We'll tag it with a label just to help 14751 // debug and understand what is going on. 14752 if (adj > clientAdj) { 14753 adjType = "cch-bound-ui-services"; 14754 } 14755 app.cached = false; 14756 clientAdj = adj; 14757 clientProcState = procState; 14758 } else { 14759 if (now >= (s.lastActivity 14760 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14761 // This service has not seen activity within 14762 // recent memory, so allow it to drop to the 14763 // LRU list if there is no other reason to keep 14764 // it around. We'll also tag it with a label just 14765 // to help debug and undertand what is going on. 14766 if (adj > clientAdj) { 14767 adjType = "cch-bound-services"; 14768 } 14769 clientAdj = adj; 14770 } 14771 } 14772 } 14773 if (adj > clientAdj) { 14774 // If this process has recently shown UI, and 14775 // the process that is binding to it is less 14776 // important than being visible, then we don't 14777 // care about the binding as much as we care 14778 // about letting this process get into the LRU 14779 // list to be killed and restarted if needed for 14780 // memory. 14781 if (app.hasShownUi && app != mHomeProcess 14782 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14783 adjType = "cch-bound-ui-services"; 14784 } else { 14785 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14786 |Context.BIND_IMPORTANT)) != 0) { 14787 adj = clientAdj; 14788 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14789 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14790 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14791 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14792 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14793 adj = clientAdj; 14794 } else { 14795 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14796 adj = ProcessList.VISIBLE_APP_ADJ; 14797 } 14798 } 14799 if (!client.cached) { 14800 app.cached = false; 14801 } 14802 if (client.keeping) { 14803 app.keeping = true; 14804 } 14805 adjType = "service"; 14806 } 14807 } 14808 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14809 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14810 schedGroup = Process.THREAD_GROUP_DEFAULT; 14811 } 14812 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14813 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14814 // Special handling of clients who are in the top state. 14815 // We *may* want to consider this process to be in the 14816 // top state as well, but only if there is not another 14817 // reason for it to be running. Being on the top is a 14818 // special state, meaning you are specifically running 14819 // for the current top app. If the process is already 14820 // running in the background for some other reason, it 14821 // is more important to continue considering it to be 14822 // in the background state. 14823 mayBeTop = true; 14824 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14825 } else { 14826 // Special handling for above-top states (persistent 14827 // processes). These should not bring the current process 14828 // into the top state, since they are not on top. Instead 14829 // give them the best state after that. 14830 clientProcState = 14831 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14832 } 14833 } 14834 } else { 14835 if (clientProcState < 14836 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14837 clientProcState = 14838 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14839 } 14840 } 14841 if (procState > clientProcState) { 14842 procState = clientProcState; 14843 } 14844 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14845 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14846 app.pendingUiClean = true; 14847 } 14848 if (adjType != null) { 14849 app.adjType = adjType; 14850 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14851 .REASON_SERVICE_IN_USE; 14852 app.adjSource = cr.binding.client; 14853 app.adjSourceOom = clientAdj; 14854 app.adjTarget = s.name; 14855 } 14856 } 14857 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14858 app.treatLikeActivity = true; 14859 } 14860 final ActivityRecord a = cr.activity; 14861 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14862 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14863 (a.visible || a.state == ActivityState.RESUMED 14864 || a.state == ActivityState.PAUSING)) { 14865 adj = ProcessList.FOREGROUND_APP_ADJ; 14866 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14867 schedGroup = Process.THREAD_GROUP_DEFAULT; 14868 } 14869 app.cached = false; 14870 app.adjType = "service"; 14871 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14872 .REASON_SERVICE_IN_USE; 14873 app.adjSource = a; 14874 app.adjSourceOom = adj; 14875 app.adjTarget = s.name; 14876 } 14877 } 14878 } 14879 } 14880 } 14881 14882 for (int provi = app.pubProviders.size()-1; 14883 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14884 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14885 || procState > ActivityManager.PROCESS_STATE_TOP); 14886 provi--) { 14887 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14888 for (int i = cpr.connections.size()-1; 14889 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14890 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14891 || procState > ActivityManager.PROCESS_STATE_TOP); 14892 i--) { 14893 ContentProviderConnection conn = cpr.connections.get(i); 14894 ProcessRecord client = conn.client; 14895 if (client == app) { 14896 // Being our own client is not interesting. 14897 continue; 14898 } 14899 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14900 int clientProcState = client.curProcState; 14901 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14902 // If the other app is cached for any reason, for purposes here 14903 // we are going to consider it empty. 14904 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14905 } 14906 if (adj > clientAdj) { 14907 if (app.hasShownUi && app != mHomeProcess 14908 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14909 app.adjType = "cch-ui-provider"; 14910 } else { 14911 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14912 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14913 app.adjType = "provider"; 14914 } 14915 app.cached &= client.cached; 14916 app.keeping |= client.keeping; 14917 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14918 .REASON_PROVIDER_IN_USE; 14919 app.adjSource = client; 14920 app.adjSourceOom = clientAdj; 14921 app.adjTarget = cpr.name; 14922 } 14923 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14924 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14925 // Special handling of clients who are in the top state. 14926 // We *may* want to consider this process to be in the 14927 // top state as well, but only if there is not another 14928 // reason for it to be running. Being on the top is a 14929 // special state, meaning you are specifically running 14930 // for the current top app. If the process is already 14931 // running in the background for some other reason, it 14932 // is more important to continue considering it to be 14933 // in the background state. 14934 mayBeTop = true; 14935 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14936 } else { 14937 // Special handling for above-top states (persistent 14938 // processes). These should not bring the current process 14939 // into the top state, since they are not on top. Instead 14940 // give them the best state after that. 14941 clientProcState = 14942 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14943 } 14944 } 14945 if (procState > clientProcState) { 14946 procState = clientProcState; 14947 } 14948 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14949 schedGroup = Process.THREAD_GROUP_DEFAULT; 14950 } 14951 } 14952 // If the provider has external (non-framework) process 14953 // dependencies, ensure that its adjustment is at least 14954 // FOREGROUND_APP_ADJ. 14955 if (cpr.hasExternalProcessHandles()) { 14956 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14957 adj = ProcessList.FOREGROUND_APP_ADJ; 14958 schedGroup = Process.THREAD_GROUP_DEFAULT; 14959 app.cached = false; 14960 app.keeping = true; 14961 app.adjType = "provider"; 14962 app.adjTarget = cpr.name; 14963 } 14964 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14965 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14966 } 14967 } 14968 } 14969 14970 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14971 // A client of one of our services or providers is in the top state. We 14972 // *may* want to be in the top state, but not if we are already running in 14973 // the background for some other reason. For the decision here, we are going 14974 // to pick out a few specific states that we want to remain in when a client 14975 // is top (states that tend to be longer-term) and otherwise allow it to go 14976 // to the top state. 14977 switch (procState) { 14978 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14979 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14980 case ActivityManager.PROCESS_STATE_SERVICE: 14981 // These all are longer-term states, so pull them up to the top 14982 // of the background states, but not all the way to the top state. 14983 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14984 break; 14985 default: 14986 // Otherwise, top is a better choice, so take it. 14987 procState = ActivityManager.PROCESS_STATE_TOP; 14988 break; 14989 } 14990 } 14991 14992 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 14993 if (app.hasClientActivities) { 14994 // This is a cached process, but with client activities. Mark it so. 14995 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14996 app.adjType = "cch-client-act"; 14997 } else if (app.treatLikeActivity) { 14998 // This is a cached process, but somebody wants us to treat it like it has 14999 // an activity, okay! 15000 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15001 app.adjType = "cch-as-act"; 15002 } 15003 } 15004 15005 if (adj == ProcessList.SERVICE_ADJ) { 15006 if (doingAll) { 15007 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15008 mNewNumServiceProcs++; 15009 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15010 if (!app.serviceb) { 15011 // This service isn't far enough down on the LRU list to 15012 // normally be a B service, but if we are low on RAM and it 15013 // is large we want to force it down since we would prefer to 15014 // keep launcher over it. 15015 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15016 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15017 app.serviceHighRam = true; 15018 app.serviceb = true; 15019 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15020 } else { 15021 mNewNumAServiceProcs++; 15022 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15023 } 15024 } else { 15025 app.serviceHighRam = false; 15026 } 15027 } 15028 if (app.serviceb) { 15029 adj = ProcessList.SERVICE_B_ADJ; 15030 } 15031 } 15032 15033 app.curRawAdj = adj; 15034 15035 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15036 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15037 if (adj > app.maxAdj) { 15038 adj = app.maxAdj; 15039 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15040 schedGroup = Process.THREAD_GROUP_DEFAULT; 15041 } 15042 } 15043 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15044 app.keeping = true; 15045 } 15046 15047 // Do final modification to adj. Everything we do between here and applying 15048 // the final setAdj must be done in this function, because we will also use 15049 // it when computing the final cached adj later. Note that we don't need to 15050 // worry about this for max adj above, since max adj will always be used to 15051 // keep it out of the cached vaues. 15052 adj = app.modifyRawOomAdj(adj); 15053 15054 app.curProcState = procState; 15055 15056 int importance = app.memImportance; 15057 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15058 app.curAdj = adj; 15059 app.curSchedGroup = schedGroup; 15060 if (!interesting) { 15061 // For this reporting, if there is not something explicitly 15062 // interesting in this process then we will push it to the 15063 // background importance. 15064 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15065 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15066 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15067 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15068 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15069 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15070 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15071 } else if (adj >= ProcessList.SERVICE_ADJ) { 15072 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15073 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15074 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15075 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15076 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15077 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15078 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15079 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15080 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15081 } else { 15082 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15083 } 15084 } 15085 15086 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15087 if (foregroundActivities != app.foregroundActivities) { 15088 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15089 } 15090 if (changes != 0) { 15091 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15092 app.memImportance = importance; 15093 app.foregroundActivities = foregroundActivities; 15094 int i = mPendingProcessChanges.size()-1; 15095 ProcessChangeItem item = null; 15096 while (i >= 0) { 15097 item = mPendingProcessChanges.get(i); 15098 if (item.pid == app.pid) { 15099 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15100 break; 15101 } 15102 i--; 15103 } 15104 if (i < 0) { 15105 // No existing item in pending changes; need a new one. 15106 final int NA = mAvailProcessChanges.size(); 15107 if (NA > 0) { 15108 item = mAvailProcessChanges.remove(NA-1); 15109 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15110 } else { 15111 item = new ProcessChangeItem(); 15112 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15113 } 15114 item.changes = 0; 15115 item.pid = app.pid; 15116 item.uid = app.info.uid; 15117 if (mPendingProcessChanges.size() == 0) { 15118 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15119 "*** Enqueueing dispatch processes changed!"); 15120 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15121 } 15122 mPendingProcessChanges.add(item); 15123 } 15124 item.changes |= changes; 15125 item.importance = importance; 15126 item.foregroundActivities = foregroundActivities; 15127 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15128 + Integer.toHexString(System.identityHashCode(item)) 15129 + " " + app.toShortString() + ": changes=" + item.changes 15130 + " importance=" + item.importance 15131 + " foreground=" + item.foregroundActivities 15132 + " type=" + app.adjType + " source=" + app.adjSource 15133 + " target=" + app.adjTarget); 15134 } 15135 15136 return app.curRawAdj; 15137 } 15138 15139 /** 15140 * Schedule PSS collection of a process. 15141 */ 15142 void requestPssLocked(ProcessRecord proc, int procState) { 15143 if (mPendingPssProcesses.contains(proc)) { 15144 return; 15145 } 15146 if (mPendingPssProcesses.size() == 0) { 15147 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15148 } 15149 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15150 proc.pssProcState = procState; 15151 mPendingPssProcesses.add(proc); 15152 } 15153 15154 /** 15155 * Schedule PSS collection of all processes. 15156 */ 15157 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15158 if (!always) { 15159 if (now < (mLastFullPssTime + 15160 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15161 return; 15162 } 15163 } 15164 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15165 mLastFullPssTime = now; 15166 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15167 mPendingPssProcesses.clear(); 15168 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15169 ProcessRecord app = mLruProcesses.get(i); 15170 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15171 app.pssProcState = app.setProcState; 15172 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15173 mSleeping, now); 15174 mPendingPssProcesses.add(app); 15175 } 15176 } 15177 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15178 } 15179 15180 /** 15181 * Ask a given process to GC right now. 15182 */ 15183 final void performAppGcLocked(ProcessRecord app) { 15184 try { 15185 app.lastRequestedGc = SystemClock.uptimeMillis(); 15186 if (app.thread != null) { 15187 if (app.reportLowMemory) { 15188 app.reportLowMemory = false; 15189 app.thread.scheduleLowMemory(); 15190 } else { 15191 app.thread.processInBackground(); 15192 } 15193 } 15194 } catch (Exception e) { 15195 // whatever. 15196 } 15197 } 15198 15199 /** 15200 * Returns true if things are idle enough to perform GCs. 15201 */ 15202 private final boolean canGcNowLocked() { 15203 boolean processingBroadcasts = false; 15204 for (BroadcastQueue q : mBroadcastQueues) { 15205 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15206 processingBroadcasts = true; 15207 } 15208 } 15209 return !processingBroadcasts 15210 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15211 } 15212 15213 /** 15214 * Perform GCs on all processes that are waiting for it, but only 15215 * if things are idle. 15216 */ 15217 final void performAppGcsLocked() { 15218 final int N = mProcessesToGc.size(); 15219 if (N <= 0) { 15220 return; 15221 } 15222 if (canGcNowLocked()) { 15223 while (mProcessesToGc.size() > 0) { 15224 ProcessRecord proc = mProcessesToGc.remove(0); 15225 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15226 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15227 <= SystemClock.uptimeMillis()) { 15228 // To avoid spamming the system, we will GC processes one 15229 // at a time, waiting a few seconds between each. 15230 performAppGcLocked(proc); 15231 scheduleAppGcsLocked(); 15232 return; 15233 } else { 15234 // It hasn't been long enough since we last GCed this 15235 // process... put it in the list to wait for its time. 15236 addProcessToGcListLocked(proc); 15237 break; 15238 } 15239 } 15240 } 15241 15242 scheduleAppGcsLocked(); 15243 } 15244 } 15245 15246 /** 15247 * If all looks good, perform GCs on all processes waiting for them. 15248 */ 15249 final void performAppGcsIfAppropriateLocked() { 15250 if (canGcNowLocked()) { 15251 performAppGcsLocked(); 15252 return; 15253 } 15254 // Still not idle, wait some more. 15255 scheduleAppGcsLocked(); 15256 } 15257 15258 /** 15259 * Schedule the execution of all pending app GCs. 15260 */ 15261 final void scheduleAppGcsLocked() { 15262 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15263 15264 if (mProcessesToGc.size() > 0) { 15265 // Schedule a GC for the time to the next process. 15266 ProcessRecord proc = mProcessesToGc.get(0); 15267 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15268 15269 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15270 long now = SystemClock.uptimeMillis(); 15271 if (when < (now+GC_TIMEOUT)) { 15272 when = now + GC_TIMEOUT; 15273 } 15274 mHandler.sendMessageAtTime(msg, when); 15275 } 15276 } 15277 15278 /** 15279 * Add a process to the array of processes waiting to be GCed. Keeps the 15280 * list in sorted order by the last GC time. The process can't already be 15281 * on the list. 15282 */ 15283 final void addProcessToGcListLocked(ProcessRecord proc) { 15284 boolean added = false; 15285 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15286 if (mProcessesToGc.get(i).lastRequestedGc < 15287 proc.lastRequestedGc) { 15288 added = true; 15289 mProcessesToGc.add(i+1, proc); 15290 break; 15291 } 15292 } 15293 if (!added) { 15294 mProcessesToGc.add(0, proc); 15295 } 15296 } 15297 15298 /** 15299 * Set up to ask a process to GC itself. This will either do it 15300 * immediately, or put it on the list of processes to gc the next 15301 * time things are idle. 15302 */ 15303 final void scheduleAppGcLocked(ProcessRecord app) { 15304 long now = SystemClock.uptimeMillis(); 15305 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15306 return; 15307 } 15308 if (!mProcessesToGc.contains(app)) { 15309 addProcessToGcListLocked(app); 15310 scheduleAppGcsLocked(); 15311 } 15312 } 15313 15314 final void checkExcessivePowerUsageLocked(boolean doKills) { 15315 updateCpuStatsNow(); 15316 15317 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15318 boolean doWakeKills = doKills; 15319 boolean doCpuKills = doKills; 15320 if (mLastPowerCheckRealtime == 0) { 15321 doWakeKills = false; 15322 } 15323 if (mLastPowerCheckUptime == 0) { 15324 doCpuKills = false; 15325 } 15326 if (stats.isScreenOn()) { 15327 doWakeKills = false; 15328 } 15329 final long curRealtime = SystemClock.elapsedRealtime(); 15330 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15331 final long curUptime = SystemClock.uptimeMillis(); 15332 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15333 mLastPowerCheckRealtime = curRealtime; 15334 mLastPowerCheckUptime = curUptime; 15335 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15336 doWakeKills = false; 15337 } 15338 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15339 doCpuKills = false; 15340 } 15341 int i = mLruProcesses.size(); 15342 while (i > 0) { 15343 i--; 15344 ProcessRecord app = mLruProcesses.get(i); 15345 if (!app.keeping) { 15346 long wtime; 15347 synchronized (stats) { 15348 wtime = stats.getProcessWakeTime(app.info.uid, 15349 app.pid, curRealtime); 15350 } 15351 long wtimeUsed = wtime - app.lastWakeTime; 15352 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15353 if (DEBUG_POWER) { 15354 StringBuilder sb = new StringBuilder(128); 15355 sb.append("Wake for "); 15356 app.toShortString(sb); 15357 sb.append(": over "); 15358 TimeUtils.formatDuration(realtimeSince, sb); 15359 sb.append(" used "); 15360 TimeUtils.formatDuration(wtimeUsed, sb); 15361 sb.append(" ("); 15362 sb.append((wtimeUsed*100)/realtimeSince); 15363 sb.append("%)"); 15364 Slog.i(TAG, sb.toString()); 15365 sb.setLength(0); 15366 sb.append("CPU for "); 15367 app.toShortString(sb); 15368 sb.append(": over "); 15369 TimeUtils.formatDuration(uptimeSince, sb); 15370 sb.append(" used "); 15371 TimeUtils.formatDuration(cputimeUsed, sb); 15372 sb.append(" ("); 15373 sb.append((cputimeUsed*100)/uptimeSince); 15374 sb.append("%)"); 15375 Slog.i(TAG, sb.toString()); 15376 } 15377 // If a process has held a wake lock for more 15378 // than 50% of the time during this period, 15379 // that sounds bad. Kill! 15380 if (doWakeKills && realtimeSince > 0 15381 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15382 synchronized (stats) { 15383 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15384 realtimeSince, wtimeUsed); 15385 } 15386 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15387 + " during " + realtimeSince); 15388 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15389 } else if (doCpuKills && uptimeSince > 0 15390 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15391 synchronized (stats) { 15392 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15393 uptimeSince, cputimeUsed); 15394 } 15395 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15396 + " during " + uptimeSince); 15397 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15398 } else { 15399 app.lastWakeTime = wtime; 15400 app.lastCpuTime = app.curCpuTime; 15401 } 15402 } 15403 } 15404 } 15405 15406 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15407 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15408 boolean success = true; 15409 15410 if (app.curRawAdj != app.setRawAdj) { 15411 if (wasKeeping && !app.keeping) { 15412 // This app is no longer something we want to keep. Note 15413 // its current wake lock time to later know to kill it if 15414 // it is not behaving well. 15415 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15416 synchronized (stats) { 15417 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15418 app.pid, SystemClock.elapsedRealtime()); 15419 } 15420 app.lastCpuTime = app.curCpuTime; 15421 } 15422 15423 app.setRawAdj = app.curRawAdj; 15424 } 15425 15426 if (app.curAdj != app.setAdj) { 15427 ProcessList.setOomAdj(app.pid, app.curAdj); 15428 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15429 TAG, "Set " + app.pid + " " + app.processName + 15430 " adj " + app.curAdj + ": " + app.adjType); 15431 app.setAdj = app.curAdj; 15432 } 15433 15434 if (app.setSchedGroup != app.curSchedGroup) { 15435 app.setSchedGroup = app.curSchedGroup; 15436 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15437 "Setting process group of " + app.processName 15438 + " to " + app.curSchedGroup); 15439 if (app.waitingToKill != null && 15440 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15441 killUnneededProcessLocked(app, app.waitingToKill); 15442 success = false; 15443 } else { 15444 if (true) { 15445 long oldId = Binder.clearCallingIdentity(); 15446 try { 15447 Process.setProcessGroup(app.pid, app.curSchedGroup); 15448 } catch (Exception e) { 15449 Slog.w(TAG, "Failed setting process group of " + app.pid 15450 + " to " + app.curSchedGroup); 15451 e.printStackTrace(); 15452 } finally { 15453 Binder.restoreCallingIdentity(oldId); 15454 } 15455 } else { 15456 if (app.thread != null) { 15457 try { 15458 app.thread.setSchedulingGroup(app.curSchedGroup); 15459 } catch (RemoteException e) { 15460 } 15461 } 15462 } 15463 Process.setSwappiness(app.pid, 15464 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15465 } 15466 } 15467 if (app.repProcState != app.curProcState) { 15468 app.repProcState = app.curProcState; 15469 if (!reportingProcessState && app.thread != null) { 15470 try { 15471 if (false) { 15472 //RuntimeException h = new RuntimeException("here"); 15473 Slog.i(TAG, "Sending new process state " + app.repProcState 15474 + " to " + app /*, h*/); 15475 } 15476 app.thread.setProcessState(app.repProcState); 15477 } catch (RemoteException e) { 15478 } 15479 } 15480 } 15481 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15482 app.setProcState)) { 15483 app.lastStateTime = now; 15484 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15485 mSleeping, now); 15486 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15487 + ProcessList.makeProcStateString(app.setProcState) + " to " 15488 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15489 + (app.nextPssTime-now) + ": " + app); 15490 } else { 15491 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15492 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15493 requestPssLocked(app, app.setProcState); 15494 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15495 mSleeping, now); 15496 } else if (false && DEBUG_PSS) { 15497 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15498 } 15499 } 15500 if (app.setProcState != app.curProcState) { 15501 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15502 "Proc state change of " + app.processName 15503 + " to " + app.curProcState); 15504 app.setProcState = app.curProcState; 15505 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15506 app.notCachedSinceIdle = false; 15507 } 15508 if (!doingAll) { 15509 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15510 } else { 15511 app.procStateChanged = true; 15512 } 15513 } 15514 return success; 15515 } 15516 15517 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15518 if (proc.thread != null && proc.baseProcessTracker != null) { 15519 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15520 } 15521 } 15522 15523 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15524 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15525 if (app.thread == null) { 15526 return false; 15527 } 15528 15529 final boolean wasKeeping = app.keeping; 15530 15531 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15532 15533 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15534 reportingProcessState, now); 15535 } 15536 15537 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15538 boolean oomAdj) { 15539 if (isForeground != proc.foregroundServices) { 15540 proc.foregroundServices = isForeground; 15541 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15542 proc.info.uid); 15543 if (isForeground) { 15544 if (curProcs == null) { 15545 curProcs = new ArrayList<ProcessRecord>(); 15546 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15547 } 15548 if (!curProcs.contains(proc)) { 15549 curProcs.add(proc); 15550 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15551 proc.info.packageName, proc.info.uid); 15552 } 15553 } else { 15554 if (curProcs != null) { 15555 if (curProcs.remove(proc)) { 15556 mBatteryStatsService.noteEvent( 15557 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15558 proc.info.packageName, proc.info.uid); 15559 if (curProcs.size() <= 0) { 15560 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15561 } 15562 } 15563 } 15564 } 15565 if (oomAdj) { 15566 updateOomAdjLocked(); 15567 } 15568 } 15569 } 15570 15571 private final ActivityRecord resumedAppLocked() { 15572 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15573 String pkg; 15574 int uid; 15575 if (act != null) { 15576 pkg = act.packageName; 15577 uid = act.info.applicationInfo.uid; 15578 } else { 15579 pkg = null; 15580 uid = -1; 15581 } 15582 // Has the UID or resumed package name changed? 15583 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15584 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15585 if (mCurResumedPackage != null) { 15586 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15587 mCurResumedPackage, mCurResumedUid); 15588 } 15589 mCurResumedPackage = pkg; 15590 mCurResumedUid = uid; 15591 if (mCurResumedPackage != null) { 15592 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15593 mCurResumedPackage, mCurResumedUid); 15594 } 15595 } 15596 return act; 15597 } 15598 15599 final boolean updateOomAdjLocked(ProcessRecord app) { 15600 return updateOomAdjLocked(app, false); 15601 } 15602 15603 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15604 final ActivityRecord TOP_ACT = resumedAppLocked(); 15605 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15606 final boolean wasCached = app.cached; 15607 15608 mAdjSeq++; 15609 15610 // This is the desired cached adjusment we want to tell it to use. 15611 // If our app is currently cached, we know it, and that is it. Otherwise, 15612 // we don't know it yet, and it needs to now be cached we will then 15613 // need to do a complete oom adj. 15614 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15615 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15616 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15617 SystemClock.uptimeMillis()); 15618 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15619 // Changed to/from cached state, so apps after it in the LRU 15620 // list may also be changed. 15621 updateOomAdjLocked(); 15622 } 15623 return success; 15624 } 15625 15626 final void updateOomAdjLocked() { 15627 final ActivityRecord TOP_ACT = resumedAppLocked(); 15628 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15629 final long now = SystemClock.uptimeMillis(); 15630 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15631 final int N = mLruProcesses.size(); 15632 15633 if (false) { 15634 RuntimeException e = new RuntimeException(); 15635 e.fillInStackTrace(); 15636 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15637 } 15638 15639 mAdjSeq++; 15640 mNewNumServiceProcs = 0; 15641 mNewNumAServiceProcs = 0; 15642 15643 final int emptyProcessLimit; 15644 final int cachedProcessLimit; 15645 if (mProcessLimit <= 0) { 15646 emptyProcessLimit = cachedProcessLimit = 0; 15647 } else if (mProcessLimit == 1) { 15648 emptyProcessLimit = 1; 15649 cachedProcessLimit = 0; 15650 } else { 15651 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15652 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15653 } 15654 15655 // Let's determine how many processes we have running vs. 15656 // how many slots we have for background processes; we may want 15657 // to put multiple processes in a slot of there are enough of 15658 // them. 15659 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15660 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15661 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15662 if (numEmptyProcs > cachedProcessLimit) { 15663 // If there are more empty processes than our limit on cached 15664 // processes, then use the cached process limit for the factor. 15665 // This ensures that the really old empty processes get pushed 15666 // down to the bottom, so if we are running low on memory we will 15667 // have a better chance at keeping around more cached processes 15668 // instead of a gazillion empty processes. 15669 numEmptyProcs = cachedProcessLimit; 15670 } 15671 int emptyFactor = numEmptyProcs/numSlots; 15672 if (emptyFactor < 1) emptyFactor = 1; 15673 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15674 if (cachedFactor < 1) cachedFactor = 1; 15675 int stepCached = 0; 15676 int stepEmpty = 0; 15677 int numCached = 0; 15678 int numEmpty = 0; 15679 int numTrimming = 0; 15680 15681 mNumNonCachedProcs = 0; 15682 mNumCachedHiddenProcs = 0; 15683 15684 // First update the OOM adjustment for each of the 15685 // application processes based on their current state. 15686 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15687 int nextCachedAdj = curCachedAdj+1; 15688 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15689 int nextEmptyAdj = curEmptyAdj+2; 15690 for (int i=N-1; i>=0; i--) { 15691 ProcessRecord app = mLruProcesses.get(i); 15692 if (!app.killedByAm && app.thread != null) { 15693 app.procStateChanged = false; 15694 final boolean wasKeeping = app.keeping; 15695 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15696 15697 // If we haven't yet assigned the final cached adj 15698 // to the process, do that now. 15699 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15700 switch (app.curProcState) { 15701 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15702 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15703 // This process is a cached process holding activities... 15704 // assign it the next cached value for that type, and then 15705 // step that cached level. 15706 app.curRawAdj = curCachedAdj; 15707 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15708 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15709 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15710 + ")"); 15711 if (curCachedAdj != nextCachedAdj) { 15712 stepCached++; 15713 if (stepCached >= cachedFactor) { 15714 stepCached = 0; 15715 curCachedAdj = nextCachedAdj; 15716 nextCachedAdj += 2; 15717 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15718 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15719 } 15720 } 15721 } 15722 break; 15723 default: 15724 // For everything else, assign next empty cached process 15725 // level and bump that up. Note that this means that 15726 // long-running services that have dropped down to the 15727 // cached level will be treated as empty (since their process 15728 // state is still as a service), which is what we want. 15729 app.curRawAdj = curEmptyAdj; 15730 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15731 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15732 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15733 + ")"); 15734 if (curEmptyAdj != nextEmptyAdj) { 15735 stepEmpty++; 15736 if (stepEmpty >= emptyFactor) { 15737 stepEmpty = 0; 15738 curEmptyAdj = nextEmptyAdj; 15739 nextEmptyAdj += 2; 15740 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15741 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15742 } 15743 } 15744 } 15745 break; 15746 } 15747 } 15748 15749 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15750 15751 // Count the number of process types. 15752 switch (app.curProcState) { 15753 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15754 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15755 mNumCachedHiddenProcs++; 15756 numCached++; 15757 if (numCached > cachedProcessLimit) { 15758 killUnneededProcessLocked(app, "cached #" + numCached); 15759 } 15760 break; 15761 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15762 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15763 && app.lastActivityTime < oldTime) { 15764 killUnneededProcessLocked(app, "empty for " 15765 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15766 / 1000) + "s"); 15767 } else { 15768 numEmpty++; 15769 if (numEmpty > emptyProcessLimit) { 15770 killUnneededProcessLocked(app, "empty #" + numEmpty); 15771 } 15772 } 15773 break; 15774 default: 15775 mNumNonCachedProcs++; 15776 break; 15777 } 15778 15779 if (app.isolated && app.services.size() <= 0) { 15780 // If this is an isolated process, and there are no 15781 // services running in it, then the process is no longer 15782 // needed. We agressively kill these because we can by 15783 // definition not re-use the same process again, and it is 15784 // good to avoid having whatever code was running in them 15785 // left sitting around after no longer needed. 15786 killUnneededProcessLocked(app, "isolated not needed"); 15787 } 15788 15789 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15790 && !app.killedByAm) { 15791 numTrimming++; 15792 } 15793 } 15794 } 15795 15796 mNumServiceProcs = mNewNumServiceProcs; 15797 15798 // Now determine the memory trimming level of background processes. 15799 // Unfortunately we need to start at the back of the list to do this 15800 // properly. We only do this if the number of background apps we 15801 // are managing to keep around is less than half the maximum we desire; 15802 // if we are keeping a good number around, we'll let them use whatever 15803 // memory they want. 15804 final int numCachedAndEmpty = numCached + numEmpty; 15805 int memFactor; 15806 if (numCached <= ProcessList.TRIM_CACHED_APPS 15807 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15808 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15809 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15810 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15811 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15812 } else { 15813 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15814 } 15815 } else { 15816 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15817 } 15818 // We always allow the memory level to go up (better). We only allow it to go 15819 // down if we are in a state where that is allowed, *and* the total number of processes 15820 // has gone down since last time. 15821 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15822 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15823 + " last=" + mLastNumProcesses); 15824 if (memFactor > mLastMemoryLevel) { 15825 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15826 memFactor = mLastMemoryLevel; 15827 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15828 } 15829 } 15830 mLastMemoryLevel = memFactor; 15831 mLastNumProcesses = mLruProcesses.size(); 15832 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15833 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15834 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15835 if (mLowRamStartTime == 0) { 15836 mLowRamStartTime = now; 15837 } 15838 int step = 0; 15839 int fgTrimLevel; 15840 switch (memFactor) { 15841 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15842 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15843 break; 15844 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15845 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15846 break; 15847 default: 15848 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15849 break; 15850 } 15851 int factor = numTrimming/3; 15852 int minFactor = 2; 15853 if (mHomeProcess != null) minFactor++; 15854 if (mPreviousProcess != null) minFactor++; 15855 if (factor < minFactor) factor = minFactor; 15856 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15857 for (int i=N-1; i>=0; i--) { 15858 ProcessRecord app = mLruProcesses.get(i); 15859 if (allChanged || app.procStateChanged) { 15860 setProcessTrackerState(app, trackerMemFactor, now); 15861 app.procStateChanged = false; 15862 } 15863 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15864 && !app.killedByAm) { 15865 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15866 try { 15867 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15868 "Trimming memory of " + app.processName 15869 + " to " + curLevel); 15870 app.thread.scheduleTrimMemory(curLevel); 15871 } catch (RemoteException e) { 15872 } 15873 if (false) { 15874 // For now we won't do this; our memory trimming seems 15875 // to be good enough at this point that destroying 15876 // activities causes more harm than good. 15877 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15878 && app != mHomeProcess && app != mPreviousProcess) { 15879 // Need to do this on its own message because the stack may not 15880 // be in a consistent state at this point. 15881 // For these apps we will also finish their activities 15882 // to help them free memory. 15883 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15884 } 15885 } 15886 } 15887 app.trimMemoryLevel = curLevel; 15888 step++; 15889 if (step >= factor) { 15890 step = 0; 15891 switch (curLevel) { 15892 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15893 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15894 break; 15895 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15896 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15897 break; 15898 } 15899 } 15900 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15901 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15902 && app.thread != null) { 15903 try { 15904 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15905 "Trimming memory of heavy-weight " + app.processName 15906 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15907 app.thread.scheduleTrimMemory( 15908 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15909 } catch (RemoteException e) { 15910 } 15911 } 15912 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15913 } else { 15914 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15915 || app.systemNoUi) && app.pendingUiClean) { 15916 // If this application is now in the background and it 15917 // had done UI, then give it the special trim level to 15918 // have it free UI resources. 15919 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15920 if (app.trimMemoryLevel < level && app.thread != null) { 15921 try { 15922 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15923 "Trimming memory of bg-ui " + app.processName 15924 + " to " + level); 15925 app.thread.scheduleTrimMemory(level); 15926 } catch (RemoteException e) { 15927 } 15928 } 15929 app.pendingUiClean = false; 15930 } 15931 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15932 try { 15933 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15934 "Trimming memory of fg " + app.processName 15935 + " to " + fgTrimLevel); 15936 app.thread.scheduleTrimMemory(fgTrimLevel); 15937 } catch (RemoteException e) { 15938 } 15939 } 15940 app.trimMemoryLevel = fgTrimLevel; 15941 } 15942 } 15943 } else { 15944 if (mLowRamStartTime != 0) { 15945 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15946 mLowRamStartTime = 0; 15947 } 15948 for (int i=N-1; i>=0; i--) { 15949 ProcessRecord app = mLruProcesses.get(i); 15950 if (allChanged || app.procStateChanged) { 15951 setProcessTrackerState(app, trackerMemFactor, now); 15952 app.procStateChanged = false; 15953 } 15954 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15955 || app.systemNoUi) && app.pendingUiClean) { 15956 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15957 && app.thread != null) { 15958 try { 15959 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15960 "Trimming memory of ui hidden " + app.processName 15961 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15962 app.thread.scheduleTrimMemory( 15963 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15964 } catch (RemoteException e) { 15965 } 15966 } 15967 app.pendingUiClean = false; 15968 } 15969 app.trimMemoryLevel = 0; 15970 } 15971 } 15972 15973 if (mAlwaysFinishActivities) { 15974 // Need to do this on its own message because the stack may not 15975 // be in a consistent state at this point. 15976 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15977 } 15978 15979 if (allChanged) { 15980 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15981 } 15982 15983 if (mProcessStats.shouldWriteNowLocked(now)) { 15984 mHandler.post(new Runnable() { 15985 @Override public void run() { 15986 synchronized (ActivityManagerService.this) { 15987 mProcessStats.writeStateAsyncLocked(); 15988 } 15989 } 15990 }); 15991 } 15992 15993 if (DEBUG_OOM_ADJ) { 15994 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15995 } 15996 } 15997 15998 final void trimApplications() { 15999 synchronized (this) { 16000 int i; 16001 16002 // First remove any unused application processes whose package 16003 // has been removed. 16004 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16005 final ProcessRecord app = mRemovedProcesses.get(i); 16006 if (app.activities.size() == 0 16007 && app.curReceiver == null && app.services.size() == 0) { 16008 Slog.i( 16009 TAG, "Exiting empty application process " 16010 + app.processName + " (" 16011 + (app.thread != null ? app.thread.asBinder() : null) 16012 + ")\n"); 16013 if (app.pid > 0 && app.pid != MY_PID) { 16014 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16015 app.processName, app.setAdj, "empty"); 16016 app.killedByAm = true; 16017 Process.killProcessQuiet(app.pid); 16018 } else { 16019 try { 16020 app.thread.scheduleExit(); 16021 } catch (Exception e) { 16022 // Ignore exceptions. 16023 } 16024 } 16025 cleanUpApplicationRecordLocked(app, false, true, -1); 16026 mRemovedProcesses.remove(i); 16027 16028 if (app.persistent) { 16029 if (app.persistent) { 16030 addAppLocked(app.info, false); 16031 } 16032 } 16033 } 16034 } 16035 16036 // Now update the oom adj for all processes. 16037 updateOomAdjLocked(); 16038 } 16039 } 16040 16041 /** This method sends the specified signal to each of the persistent apps */ 16042 public void signalPersistentProcesses(int sig) throws RemoteException { 16043 if (sig != Process.SIGNAL_USR1) { 16044 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16045 } 16046 16047 synchronized (this) { 16048 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16049 != PackageManager.PERMISSION_GRANTED) { 16050 throw new SecurityException("Requires permission " 16051 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16052 } 16053 16054 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16055 ProcessRecord r = mLruProcesses.get(i); 16056 if (r.thread != null && r.persistent) { 16057 Process.sendSignal(r.pid, sig); 16058 } 16059 } 16060 } 16061 } 16062 16063 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16064 if (proc == null || proc == mProfileProc) { 16065 proc = mProfileProc; 16066 path = mProfileFile; 16067 profileType = mProfileType; 16068 clearProfilerLocked(); 16069 } 16070 if (proc == null) { 16071 return; 16072 } 16073 try { 16074 proc.thread.profilerControl(false, path, null, profileType); 16075 } catch (RemoteException e) { 16076 throw new IllegalStateException("Process disappeared"); 16077 } 16078 } 16079 16080 private void clearProfilerLocked() { 16081 if (mProfileFd != null) { 16082 try { 16083 mProfileFd.close(); 16084 } catch (IOException e) { 16085 } 16086 } 16087 mProfileApp = null; 16088 mProfileProc = null; 16089 mProfileFile = null; 16090 mProfileType = 0; 16091 mAutoStopProfiler = false; 16092 } 16093 16094 public boolean profileControl(String process, int userId, boolean start, 16095 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16096 16097 try { 16098 synchronized (this) { 16099 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16100 // its own permission. 16101 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16102 != PackageManager.PERMISSION_GRANTED) { 16103 throw new SecurityException("Requires permission " 16104 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16105 } 16106 16107 if (start && fd == null) { 16108 throw new IllegalArgumentException("null fd"); 16109 } 16110 16111 ProcessRecord proc = null; 16112 if (process != null) { 16113 proc = findProcessLocked(process, userId, "profileControl"); 16114 } 16115 16116 if (start && (proc == null || proc.thread == null)) { 16117 throw new IllegalArgumentException("Unknown process: " + process); 16118 } 16119 16120 if (start) { 16121 stopProfilerLocked(null, null, 0); 16122 setProfileApp(proc.info, proc.processName, path, fd, false); 16123 mProfileProc = proc; 16124 mProfileType = profileType; 16125 try { 16126 fd = fd.dup(); 16127 } catch (IOException e) { 16128 fd = null; 16129 } 16130 proc.thread.profilerControl(start, path, fd, profileType); 16131 fd = null; 16132 mProfileFd = null; 16133 } else { 16134 stopProfilerLocked(proc, path, profileType); 16135 if (fd != null) { 16136 try { 16137 fd.close(); 16138 } catch (IOException e) { 16139 } 16140 } 16141 } 16142 16143 return true; 16144 } 16145 } catch (RemoteException e) { 16146 throw new IllegalStateException("Process disappeared"); 16147 } finally { 16148 if (fd != null) { 16149 try { 16150 fd.close(); 16151 } catch (IOException e) { 16152 } 16153 } 16154 } 16155 } 16156 16157 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16158 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16159 userId, true, true, callName, null); 16160 ProcessRecord proc = null; 16161 try { 16162 int pid = Integer.parseInt(process); 16163 synchronized (mPidsSelfLocked) { 16164 proc = mPidsSelfLocked.get(pid); 16165 } 16166 } catch (NumberFormatException e) { 16167 } 16168 16169 if (proc == null) { 16170 ArrayMap<String, SparseArray<ProcessRecord>> all 16171 = mProcessNames.getMap(); 16172 SparseArray<ProcessRecord> procs = all.get(process); 16173 if (procs != null && procs.size() > 0) { 16174 proc = procs.valueAt(0); 16175 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16176 for (int i=1; i<procs.size(); i++) { 16177 ProcessRecord thisProc = procs.valueAt(i); 16178 if (thisProc.userId == userId) { 16179 proc = thisProc; 16180 break; 16181 } 16182 } 16183 } 16184 } 16185 } 16186 16187 return proc; 16188 } 16189 16190 public boolean dumpHeap(String process, int userId, boolean managed, 16191 String path, ParcelFileDescriptor fd) throws RemoteException { 16192 16193 try { 16194 synchronized (this) { 16195 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16196 // its own permission (same as profileControl). 16197 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16198 != PackageManager.PERMISSION_GRANTED) { 16199 throw new SecurityException("Requires permission " 16200 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16201 } 16202 16203 if (fd == null) { 16204 throw new IllegalArgumentException("null fd"); 16205 } 16206 16207 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16208 if (proc == null || proc.thread == null) { 16209 throw new IllegalArgumentException("Unknown process: " + process); 16210 } 16211 16212 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16213 if (!isDebuggable) { 16214 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16215 throw new SecurityException("Process not debuggable: " + proc); 16216 } 16217 } 16218 16219 proc.thread.dumpHeap(managed, path, fd); 16220 fd = null; 16221 return true; 16222 } 16223 } catch (RemoteException e) { 16224 throw new IllegalStateException("Process disappeared"); 16225 } finally { 16226 if (fd != null) { 16227 try { 16228 fd.close(); 16229 } catch (IOException e) { 16230 } 16231 } 16232 } 16233 } 16234 16235 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16236 public void monitor() { 16237 synchronized (this) { } 16238 } 16239 16240 void onCoreSettingsChange(Bundle settings) { 16241 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16242 ProcessRecord processRecord = mLruProcesses.get(i); 16243 try { 16244 if (processRecord.thread != null) { 16245 processRecord.thread.setCoreSettings(settings); 16246 } 16247 } catch (RemoteException re) { 16248 /* ignore */ 16249 } 16250 } 16251 } 16252 16253 // Multi-user methods 16254 16255 /** 16256 * Start user, if its not already running, but don't bring it to foreground. 16257 */ 16258 @Override 16259 public boolean startUserInBackground(final int userId) { 16260 return startUser(userId, /* foreground */ false); 16261 } 16262 16263 /** 16264 * Refreshes the list of users related to the current user when either a 16265 * user switch happens or when a new related user is started in the 16266 * background. 16267 */ 16268 private void updateRelatedUserIdsLocked() { 16269 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16270 int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null 16271 for (int i = 0; i < relatedUserIds.length; i++) { 16272 relatedUserIds[i] = relatedUsers.get(i).id; 16273 } 16274 mRelatedUserIds = relatedUserIds; 16275 } 16276 16277 @Override 16278 public boolean switchUser(final int userId) { 16279 return startUser(userId, /* foregound */ true); 16280 } 16281 16282 private boolean startUser(final int userId, boolean foreground) { 16283 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16284 != PackageManager.PERMISSION_GRANTED) { 16285 String msg = "Permission Denial: switchUser() from pid=" 16286 + Binder.getCallingPid() 16287 + ", uid=" + Binder.getCallingUid() 16288 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16289 Slog.w(TAG, msg); 16290 throw new SecurityException(msg); 16291 } 16292 16293 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16294 16295 final long ident = Binder.clearCallingIdentity(); 16296 try { 16297 synchronized (this) { 16298 final int oldUserId = mCurrentUserId; 16299 if (oldUserId == userId) { 16300 return true; 16301 } 16302 16303 mStackSupervisor.setLockTaskModeLocked(null); 16304 16305 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16306 if (userInfo == null) { 16307 Slog.w(TAG, "No user info for user #" + userId); 16308 return false; 16309 } 16310 16311 if (foreground) { 16312 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16313 R.anim.screen_user_enter); 16314 } 16315 16316 boolean needStart = false; 16317 16318 // If the user we are switching to is not currently started, then 16319 // we need to start it now. 16320 if (mStartedUsers.get(userId) == null) { 16321 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16322 updateStartedUserArrayLocked(); 16323 needStart = true; 16324 } 16325 16326 final Integer userIdInt = Integer.valueOf(userId); 16327 mUserLru.remove(userIdInt); 16328 mUserLru.add(userIdInt); 16329 16330 if (foreground) { 16331 mCurrentUserId = userId; 16332 updateRelatedUserIdsLocked(); 16333 mWindowManager.setCurrentUser(userId, mRelatedUserIds); 16334 // Once the internal notion of the active user has switched, we lock the device 16335 // with the option to show the user switcher on the keyguard. 16336 mWindowManager.lockNow(null); 16337 } else { 16338 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16339 updateRelatedUserIdsLocked(); 16340 mWindowManager.updateRelatedUserIds(mRelatedUserIds); 16341 mUserLru.remove(currentUserIdInt); 16342 mUserLru.add(currentUserIdInt); 16343 } 16344 16345 final UserStartedState uss = mStartedUsers.get(userId); 16346 16347 // Make sure user is in the started state. If it is currently 16348 // stopping, we need to knock that off. 16349 if (uss.mState == UserStartedState.STATE_STOPPING) { 16350 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16351 // so we can just fairly silently bring the user back from 16352 // the almost-dead. 16353 uss.mState = UserStartedState.STATE_RUNNING; 16354 updateStartedUserArrayLocked(); 16355 needStart = true; 16356 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16357 // This means ACTION_SHUTDOWN has been sent, so we will 16358 // need to treat this as a new boot of the user. 16359 uss.mState = UserStartedState.STATE_BOOTING; 16360 updateStartedUserArrayLocked(); 16361 needStart = true; 16362 } 16363 16364 if (foreground) { 16365 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16366 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16367 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16368 oldUserId, userId, uss)); 16369 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16370 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16371 } 16372 16373 if (needStart) { 16374 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16375 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16376 | Intent.FLAG_RECEIVER_FOREGROUND); 16377 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16378 broadcastIntentLocked(null, null, intent, 16379 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16380 false, false, MY_PID, Process.SYSTEM_UID, userId); 16381 } 16382 16383 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16384 if (userId != 0) { 16385 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16386 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16387 broadcastIntentLocked(null, null, intent, null, 16388 new IIntentReceiver.Stub() { 16389 public void performReceive(Intent intent, int resultCode, 16390 String data, Bundle extras, boolean ordered, 16391 boolean sticky, int sendingUser) { 16392 userInitialized(uss, userId); 16393 } 16394 }, 0, null, null, null, AppOpsManager.OP_NONE, 16395 true, false, MY_PID, Process.SYSTEM_UID, 16396 userId); 16397 uss.initializing = true; 16398 } else { 16399 getUserManagerLocked().makeInitialized(userInfo.id); 16400 } 16401 } 16402 16403 if (foreground) { 16404 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16405 if (homeInFront) { 16406 startHomeActivityLocked(userId); 16407 } else { 16408 mStackSupervisor.resumeTopActivitiesLocked(); 16409 } 16410 EventLogTags.writeAmSwitchUser(userId); 16411 getUserManagerLocked().userForeground(userId); 16412 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16413 } 16414 16415 if (needStart) { 16416 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16417 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16418 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16419 broadcastIntentLocked(null, null, intent, 16420 null, new IIntentReceiver.Stub() { 16421 @Override 16422 public void performReceive(Intent intent, int resultCode, String data, 16423 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16424 throws RemoteException { 16425 } 16426 }, 0, null, null, 16427 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16428 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16429 } 16430 } 16431 } finally { 16432 Binder.restoreCallingIdentity(ident); 16433 } 16434 16435 return true; 16436 } 16437 16438 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16439 long ident = Binder.clearCallingIdentity(); 16440 try { 16441 Intent intent; 16442 if (oldUserId >= 0) { 16443 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16444 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16445 | Intent.FLAG_RECEIVER_FOREGROUND); 16446 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16447 broadcastIntentLocked(null, null, intent, 16448 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16449 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16450 } 16451 if (newUserId >= 0) { 16452 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16453 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16454 | Intent.FLAG_RECEIVER_FOREGROUND); 16455 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16456 broadcastIntentLocked(null, null, intent, 16457 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16458 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16459 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16460 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16461 | Intent.FLAG_RECEIVER_FOREGROUND); 16462 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16463 broadcastIntentLocked(null, null, intent, 16464 null, null, 0, null, null, 16465 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16466 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16467 } 16468 } finally { 16469 Binder.restoreCallingIdentity(ident); 16470 } 16471 } 16472 16473 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16474 final int newUserId) { 16475 final int N = mUserSwitchObservers.beginBroadcast(); 16476 if (N > 0) { 16477 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16478 int mCount = 0; 16479 @Override 16480 public void sendResult(Bundle data) throws RemoteException { 16481 synchronized (ActivityManagerService.this) { 16482 if (mCurUserSwitchCallback == this) { 16483 mCount++; 16484 if (mCount == N) { 16485 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16486 } 16487 } 16488 } 16489 } 16490 }; 16491 synchronized (this) { 16492 uss.switching = true; 16493 mCurUserSwitchCallback = callback; 16494 } 16495 for (int i=0; i<N; i++) { 16496 try { 16497 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16498 newUserId, callback); 16499 } catch (RemoteException e) { 16500 } 16501 } 16502 } else { 16503 synchronized (this) { 16504 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16505 } 16506 } 16507 mUserSwitchObservers.finishBroadcast(); 16508 } 16509 16510 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16511 synchronized (this) { 16512 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16513 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16514 } 16515 } 16516 16517 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16518 mCurUserSwitchCallback = null; 16519 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16520 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16521 oldUserId, newUserId, uss)); 16522 } 16523 16524 void userInitialized(UserStartedState uss, int newUserId) { 16525 completeSwitchAndInitalize(uss, newUserId, true, false); 16526 } 16527 16528 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16529 completeSwitchAndInitalize(uss, newUserId, false, true); 16530 } 16531 16532 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16533 boolean clearInitializing, boolean clearSwitching) { 16534 boolean unfrozen = false; 16535 synchronized (this) { 16536 if (clearInitializing) { 16537 uss.initializing = false; 16538 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16539 } 16540 if (clearSwitching) { 16541 uss.switching = false; 16542 } 16543 if (!uss.switching && !uss.initializing) { 16544 mWindowManager.stopFreezingScreen(); 16545 unfrozen = true; 16546 } 16547 } 16548 if (unfrozen) { 16549 final int N = mUserSwitchObservers.beginBroadcast(); 16550 for (int i=0; i<N; i++) { 16551 try { 16552 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16553 } catch (RemoteException e) { 16554 } 16555 } 16556 mUserSwitchObservers.finishBroadcast(); 16557 } 16558 } 16559 16560 void scheduleStartRelatedUsersLocked() { 16561 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16562 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16563 DateUtils.SECOND_IN_MILLIS); 16564 } 16565 } 16566 16567 void startRelatedUsersLocked() { 16568 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16569 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16570 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16571 for (UserInfo relatedUser : relatedUsers) { 16572 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16573 toStart.add(relatedUser); 16574 } 16575 } 16576 final int n = toStart.size(); 16577 int i = 0; 16578 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16579 startUserInBackground(toStart.get(i).id); 16580 } 16581 if (i < n) { 16582 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16583 } 16584 } 16585 16586 void finishUserSwitch(UserStartedState uss) { 16587 synchronized (this) { 16588 if (uss.mState == UserStartedState.STATE_BOOTING 16589 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16590 uss.mState = UserStartedState.STATE_RUNNING; 16591 final int userId = uss.mHandle.getIdentifier(); 16592 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16593 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16594 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16595 broadcastIntentLocked(null, null, intent, 16596 null, null, 0, null, null, 16597 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16598 true, false, MY_PID, Process.SYSTEM_UID, userId); 16599 } 16600 16601 startRelatedUsersLocked(); 16602 16603 int num = mUserLru.size(); 16604 int i = 0; 16605 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16606 Integer oldUserId = mUserLru.get(i); 16607 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16608 if (oldUss == null) { 16609 // Shouldn't happen, but be sane if it does. 16610 mUserLru.remove(i); 16611 num--; 16612 continue; 16613 } 16614 if (oldUss.mState == UserStartedState.STATE_STOPPING 16615 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16616 // This user is already stopping, doesn't count. 16617 num--; 16618 i++; 16619 continue; 16620 } 16621 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16622 // Owner and current can't be stopped, but count as running. 16623 i++; 16624 continue; 16625 } 16626 // This is a user to be stopped. 16627 stopUserLocked(oldUserId, null); 16628 num--; 16629 i++; 16630 } 16631 } 16632 } 16633 16634 @Override 16635 public int stopUser(final int userId, final IStopUserCallback callback) { 16636 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16637 != PackageManager.PERMISSION_GRANTED) { 16638 String msg = "Permission Denial: switchUser() from pid=" 16639 + Binder.getCallingPid() 16640 + ", uid=" + Binder.getCallingUid() 16641 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16642 Slog.w(TAG, msg); 16643 throw new SecurityException(msg); 16644 } 16645 if (userId <= 0) { 16646 throw new IllegalArgumentException("Can't stop primary user " + userId); 16647 } 16648 synchronized (this) { 16649 return stopUserLocked(userId, callback); 16650 } 16651 } 16652 16653 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16654 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16655 if (mCurrentUserId == userId) { 16656 return ActivityManager.USER_OP_IS_CURRENT; 16657 } 16658 16659 final UserStartedState uss = mStartedUsers.get(userId); 16660 if (uss == null) { 16661 // User is not started, nothing to do... but we do need to 16662 // callback if requested. 16663 if (callback != null) { 16664 mHandler.post(new Runnable() { 16665 @Override 16666 public void run() { 16667 try { 16668 callback.userStopped(userId); 16669 } catch (RemoteException e) { 16670 } 16671 } 16672 }); 16673 } 16674 return ActivityManager.USER_OP_SUCCESS; 16675 } 16676 16677 if (callback != null) { 16678 uss.mStopCallbacks.add(callback); 16679 } 16680 16681 if (uss.mState != UserStartedState.STATE_STOPPING 16682 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16683 uss.mState = UserStartedState.STATE_STOPPING; 16684 updateStartedUserArrayLocked(); 16685 16686 long ident = Binder.clearCallingIdentity(); 16687 try { 16688 // We are going to broadcast ACTION_USER_STOPPING and then 16689 // once that is done send a final ACTION_SHUTDOWN and then 16690 // stop the user. 16691 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16692 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16693 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16694 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16695 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16696 // This is the result receiver for the final shutdown broadcast. 16697 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16698 @Override 16699 public void performReceive(Intent intent, int resultCode, String data, 16700 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16701 finishUserStop(uss); 16702 } 16703 }; 16704 // This is the result receiver for the initial stopping broadcast. 16705 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16706 @Override 16707 public void performReceive(Intent intent, int resultCode, String data, 16708 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16709 // On to the next. 16710 synchronized (ActivityManagerService.this) { 16711 if (uss.mState != UserStartedState.STATE_STOPPING) { 16712 // Whoops, we are being started back up. Abort, abort! 16713 return; 16714 } 16715 uss.mState = UserStartedState.STATE_SHUTDOWN; 16716 } 16717 broadcastIntentLocked(null, null, shutdownIntent, 16718 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16719 true, false, MY_PID, Process.SYSTEM_UID, userId); 16720 } 16721 }; 16722 // Kick things off. 16723 broadcastIntentLocked(null, null, stoppingIntent, 16724 null, stoppingReceiver, 0, null, null, 16725 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16726 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16727 } finally { 16728 Binder.restoreCallingIdentity(ident); 16729 } 16730 } 16731 16732 return ActivityManager.USER_OP_SUCCESS; 16733 } 16734 16735 void finishUserStop(UserStartedState uss) { 16736 final int userId = uss.mHandle.getIdentifier(); 16737 boolean stopped; 16738 ArrayList<IStopUserCallback> callbacks; 16739 synchronized (this) { 16740 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16741 if (mStartedUsers.get(userId) != uss) { 16742 stopped = false; 16743 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16744 stopped = false; 16745 } else { 16746 stopped = true; 16747 // User can no longer run. 16748 mStartedUsers.remove(userId); 16749 mUserLru.remove(Integer.valueOf(userId)); 16750 updateStartedUserArrayLocked(); 16751 16752 // Clean up all state and processes associated with the user. 16753 // Kill all the processes for the user. 16754 forceStopUserLocked(userId, "finish user"); 16755 } 16756 } 16757 16758 for (int i=0; i<callbacks.size(); i++) { 16759 try { 16760 if (stopped) callbacks.get(i).userStopped(userId); 16761 else callbacks.get(i).userStopAborted(userId); 16762 } catch (RemoteException e) { 16763 } 16764 } 16765 16766 mStackSupervisor.removeUserLocked(userId); 16767 } 16768 16769 @Override 16770 public UserInfo getCurrentUser() { 16771 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16772 != PackageManager.PERMISSION_GRANTED) && ( 16773 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16774 != PackageManager.PERMISSION_GRANTED)) { 16775 String msg = "Permission Denial: getCurrentUser() from pid=" 16776 + Binder.getCallingPid() 16777 + ", uid=" + Binder.getCallingUid() 16778 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16779 Slog.w(TAG, msg); 16780 throw new SecurityException(msg); 16781 } 16782 synchronized (this) { 16783 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16784 } 16785 } 16786 16787 int getCurrentUserIdLocked() { 16788 return mCurrentUserId; 16789 } 16790 16791 @Override 16792 public boolean isUserRunning(int userId, boolean orStopped) { 16793 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16794 != PackageManager.PERMISSION_GRANTED) { 16795 String msg = "Permission Denial: isUserRunning() from pid=" 16796 + Binder.getCallingPid() 16797 + ", uid=" + Binder.getCallingUid() 16798 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16799 Slog.w(TAG, msg); 16800 throw new SecurityException(msg); 16801 } 16802 synchronized (this) { 16803 return isUserRunningLocked(userId, orStopped); 16804 } 16805 } 16806 16807 boolean isUserRunningLocked(int userId, boolean orStopped) { 16808 UserStartedState state = mStartedUsers.get(userId); 16809 if (state == null) { 16810 return false; 16811 } 16812 if (orStopped) { 16813 return true; 16814 } 16815 return state.mState != UserStartedState.STATE_STOPPING 16816 && state.mState != UserStartedState.STATE_SHUTDOWN; 16817 } 16818 16819 @Override 16820 public int[] getRunningUserIds() { 16821 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16822 != PackageManager.PERMISSION_GRANTED) { 16823 String msg = "Permission Denial: isUserRunning() from pid=" 16824 + Binder.getCallingPid() 16825 + ", uid=" + Binder.getCallingUid() 16826 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16827 Slog.w(TAG, msg); 16828 throw new SecurityException(msg); 16829 } 16830 synchronized (this) { 16831 return mStartedUserArray; 16832 } 16833 } 16834 16835 private void updateStartedUserArrayLocked() { 16836 int num = 0; 16837 for (int i=0; i<mStartedUsers.size(); i++) { 16838 UserStartedState uss = mStartedUsers.valueAt(i); 16839 // This list does not include stopping users. 16840 if (uss.mState != UserStartedState.STATE_STOPPING 16841 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16842 num++; 16843 } 16844 } 16845 mStartedUserArray = new int[num]; 16846 num = 0; 16847 for (int i=0; i<mStartedUsers.size(); i++) { 16848 UserStartedState uss = mStartedUsers.valueAt(i); 16849 if (uss.mState != UserStartedState.STATE_STOPPING 16850 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16851 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16852 num++; 16853 } 16854 } 16855 } 16856 16857 @Override 16858 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16859 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16860 != PackageManager.PERMISSION_GRANTED) { 16861 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16862 + Binder.getCallingPid() 16863 + ", uid=" + Binder.getCallingUid() 16864 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16865 Slog.w(TAG, msg); 16866 throw new SecurityException(msg); 16867 } 16868 16869 mUserSwitchObservers.register(observer); 16870 } 16871 16872 @Override 16873 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16874 mUserSwitchObservers.unregister(observer); 16875 } 16876 16877 private boolean userExists(int userId) { 16878 if (userId == 0) { 16879 return true; 16880 } 16881 UserManagerService ums = getUserManagerLocked(); 16882 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16883 } 16884 16885 int[] getUsersLocked() { 16886 UserManagerService ums = getUserManagerLocked(); 16887 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16888 } 16889 16890 UserManagerService getUserManagerLocked() { 16891 if (mUserManager == null) { 16892 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16893 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16894 } 16895 return mUserManager; 16896 } 16897 16898 private int applyUserId(int uid, int userId) { 16899 return UserHandle.getUid(userId, uid); 16900 } 16901 16902 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16903 if (info == null) return null; 16904 ApplicationInfo newInfo = new ApplicationInfo(info); 16905 newInfo.uid = applyUserId(info.uid, userId); 16906 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16907 + info.packageName; 16908 return newInfo; 16909 } 16910 16911 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16912 if (aInfo == null 16913 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16914 return aInfo; 16915 } 16916 16917 ActivityInfo info = new ActivityInfo(aInfo); 16918 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16919 return info; 16920 } 16921} 16922