ActivityManagerService.java revision aea74a5977ca9f1054926eb24f247562c3a4a6ba
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack 1019 private UserManagerService mUserManager; 1020 1021 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1022 final ProcessRecord mApp; 1023 final int mPid; 1024 final IApplicationThread mAppThread; 1025 1026 AppDeathRecipient(ProcessRecord app, int pid, 1027 IApplicationThread thread) { 1028 if (localLOGV) Slog.v( 1029 TAG, "New death recipient " + this 1030 + " for thread " + thread.asBinder()); 1031 mApp = app; 1032 mPid = pid; 1033 mAppThread = thread; 1034 } 1035 1036 @Override 1037 public void binderDied() { 1038 if (localLOGV) Slog.v( 1039 TAG, "Death received in " + this 1040 + " for thread " + mAppThread.asBinder()); 1041 synchronized(ActivityManagerService.this) { 1042 appDiedLocked(mApp, mPid, mAppThread); 1043 } 1044 } 1045 } 1046 1047 static final int SHOW_ERROR_MSG = 1; 1048 static final int SHOW_NOT_RESPONDING_MSG = 2; 1049 static final int SHOW_FACTORY_ERROR_MSG = 3; 1050 static final int UPDATE_CONFIGURATION_MSG = 4; 1051 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1052 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1053 static final int SERVICE_TIMEOUT_MSG = 12; 1054 static final int UPDATE_TIME_ZONE = 13; 1055 static final int SHOW_UID_ERROR_MSG = 14; 1056 static final int IM_FEELING_LUCKY_MSG = 15; 1057 static final int PROC_START_TIMEOUT_MSG = 20; 1058 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1059 static final int KILL_APPLICATION_MSG = 22; 1060 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1061 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1062 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1063 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1064 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1065 static final int CLEAR_DNS_CACHE_MSG = 28; 1066 static final int UPDATE_HTTP_PROXY_MSG = 29; 1067 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1068 static final int DISPATCH_PROCESSES_CHANGED = 31; 1069 static final int DISPATCH_PROCESS_DIED = 32; 1070 static final int REPORT_MEM_USAGE_MSG = 33; 1071 static final int REPORT_USER_SWITCH_MSG = 34; 1072 static final int CONTINUE_USER_SWITCH_MSG = 35; 1073 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1074 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1075 static final int PERSIST_URI_GRANTS_MSG = 38; 1076 static final int REQUEST_ALL_PSS_MSG = 39; 1077 static final int START_RELATED_USERS_MSG = 40; 1078 static final int UPDATE_TIME = 41; 1079 1080 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1081 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1082 static final int FIRST_COMPAT_MODE_MSG = 300; 1083 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1084 1085 AlertDialog mUidAlert; 1086 CompatModeDialog mCompatModeDialog; 1087 long mLastMemUsageReportTime = 0; 1088 1089 /** 1090 * Flag whether the current user is a "monkey", i.e. whether 1091 * the UI is driven by a UI automation tool. 1092 */ 1093 private boolean mUserIsMonkey; 1094 1095 final ServiceThread mHandlerThread; 1096 final MainHandler mHandler; 1097 1098 final class MainHandler extends Handler { 1099 public MainHandler(Looper looper) { 1100 super(looper, null, true); 1101 } 1102 1103 @Override 1104 public void handleMessage(Message msg) { 1105 switch (msg.what) { 1106 case SHOW_ERROR_MSG: { 1107 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1108 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1109 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1110 synchronized (ActivityManagerService.this) { 1111 ProcessRecord proc = (ProcessRecord)data.get("app"); 1112 AppErrorResult res = (AppErrorResult) data.get("result"); 1113 if (proc != null && proc.crashDialog != null) { 1114 Slog.e(TAG, "App already has crash dialog: " + proc); 1115 if (res != null) { 1116 res.set(0); 1117 } 1118 return; 1119 } 1120 if (!showBackground && UserHandle.getAppId(proc.uid) 1121 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1122 && proc.pid != MY_PID) { 1123 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1124 if (res != null) { 1125 res.set(0); 1126 } 1127 return; 1128 } 1129 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1130 Dialog d = new AppErrorDialog(mContext, 1131 ActivityManagerService.this, res, proc); 1132 d.show(); 1133 proc.crashDialog = d; 1134 } else { 1135 // The device is asleep, so just pretend that the user 1136 // saw a crash dialog and hit "force quit". 1137 if (res != null) { 1138 res.set(0); 1139 } 1140 } 1141 } 1142 1143 ensureBootCompleted(); 1144 } break; 1145 case SHOW_NOT_RESPONDING_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1148 ProcessRecord proc = (ProcessRecord)data.get("app"); 1149 if (proc != null && proc.anrDialog != null) { 1150 Slog.e(TAG, "App already has anr dialog: " + proc); 1151 return; 1152 } 1153 1154 Intent intent = new Intent("android.intent.action.ANR"); 1155 if (!mProcessesReady) { 1156 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1157 | Intent.FLAG_RECEIVER_FOREGROUND); 1158 } 1159 broadcastIntentLocked(null, null, intent, 1160 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1161 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1162 1163 if (mShowDialogs) { 1164 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1165 mContext, proc, (ActivityRecord)data.get("activity"), 1166 msg.arg1 != 0); 1167 d.show(); 1168 proc.anrDialog = d; 1169 } else { 1170 // Just kill the app if there is no dialog to be shown. 1171 killAppAtUsersRequest(proc, null); 1172 } 1173 } 1174 1175 ensureBootCompleted(); 1176 } break; 1177 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1178 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1179 synchronized (ActivityManagerService.this) { 1180 ProcessRecord proc = (ProcessRecord) data.get("app"); 1181 if (proc == null) { 1182 Slog.e(TAG, "App not found when showing strict mode dialog."); 1183 break; 1184 } 1185 if (proc.crashDialog != null) { 1186 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1187 return; 1188 } 1189 AppErrorResult res = (AppErrorResult) data.get("result"); 1190 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1191 Dialog d = new StrictModeViolationDialog(mContext, 1192 ActivityManagerService.this, res, proc); 1193 d.show(); 1194 proc.crashDialog = d; 1195 } else { 1196 // The device is asleep, so just pretend that the user 1197 // saw a crash dialog and hit "force quit". 1198 res.set(0); 1199 } 1200 } 1201 ensureBootCompleted(); 1202 } break; 1203 case SHOW_FACTORY_ERROR_MSG: { 1204 Dialog d = new FactoryErrorDialog( 1205 mContext, msg.getData().getCharSequence("msg")); 1206 d.show(); 1207 ensureBootCompleted(); 1208 } break; 1209 case UPDATE_CONFIGURATION_MSG: { 1210 final ContentResolver resolver = mContext.getContentResolver(); 1211 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1212 } break; 1213 case GC_BACKGROUND_PROCESSES_MSG: { 1214 synchronized (ActivityManagerService.this) { 1215 performAppGcsIfAppropriateLocked(); 1216 } 1217 } break; 1218 case WAIT_FOR_DEBUGGER_MSG: { 1219 synchronized (ActivityManagerService.this) { 1220 ProcessRecord app = (ProcessRecord)msg.obj; 1221 if (msg.arg1 != 0) { 1222 if (!app.waitedForDebugger) { 1223 Dialog d = new AppWaitingForDebuggerDialog( 1224 ActivityManagerService.this, 1225 mContext, app); 1226 app.waitDialog = d; 1227 app.waitedForDebugger = true; 1228 d.show(); 1229 } 1230 } else { 1231 if (app.waitDialog != null) { 1232 app.waitDialog.dismiss(); 1233 app.waitDialog = null; 1234 } 1235 } 1236 } 1237 } break; 1238 case SERVICE_TIMEOUT_MSG: { 1239 if (mDidDexOpt) { 1240 mDidDexOpt = false; 1241 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1242 nmsg.obj = msg.obj; 1243 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1244 return; 1245 } 1246 mServices.serviceTimeout((ProcessRecord)msg.obj); 1247 } break; 1248 case UPDATE_TIME_ZONE: { 1249 synchronized (ActivityManagerService.this) { 1250 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1251 ProcessRecord r = mLruProcesses.get(i); 1252 if (r.thread != null) { 1253 try { 1254 r.thread.updateTimeZone(); 1255 } catch (RemoteException ex) { 1256 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1257 } 1258 } 1259 } 1260 } 1261 } break; 1262 case CLEAR_DNS_CACHE_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1265 ProcessRecord r = mLruProcesses.get(i); 1266 if (r.thread != null) { 1267 try { 1268 r.thread.clearDnsCache(); 1269 } catch (RemoteException ex) { 1270 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1271 } 1272 } 1273 } 1274 } 1275 } break; 1276 case UPDATE_HTTP_PROXY_MSG: { 1277 ProxyProperties proxy = (ProxyProperties)msg.obj; 1278 String host = ""; 1279 String port = ""; 1280 String exclList = ""; 1281 String pacFileUrl = null; 1282 if (proxy != null) { 1283 host = proxy.getHost(); 1284 port = Integer.toString(proxy.getPort()); 1285 exclList = proxy.getExclusionList(); 1286 pacFileUrl = proxy.getPacFileUrl(); 1287 } 1288 synchronized (ActivityManagerService.this) { 1289 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1290 ProcessRecord r = mLruProcesses.get(i); 1291 if (r.thread != null) { 1292 try { 1293 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1294 } catch (RemoteException ex) { 1295 Slog.w(TAG, "Failed to update http proxy for: " + 1296 r.info.processName); 1297 } 1298 } 1299 } 1300 } 1301 } break; 1302 case SHOW_UID_ERROR_MSG: { 1303 String title = "System UIDs Inconsistent"; 1304 String text = "UIDs on the system are inconsistent, you need to wipe your" 1305 + " data partition or your device will be unstable."; 1306 Log.e(TAG, title + ": " + text); 1307 if (mShowDialogs) { 1308 // XXX This is a temporary dialog, no need to localize. 1309 AlertDialog d = new BaseErrorDialog(mContext); 1310 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1311 d.setCancelable(false); 1312 d.setTitle(title); 1313 d.setMessage(text); 1314 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1315 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1316 mUidAlert = d; 1317 d.show(); 1318 } 1319 } break; 1320 case IM_FEELING_LUCKY_MSG: { 1321 if (mUidAlert != null) { 1322 mUidAlert.dismiss(); 1323 mUidAlert = null; 1324 } 1325 } break; 1326 case PROC_START_TIMEOUT_MSG: { 1327 if (mDidDexOpt) { 1328 mDidDexOpt = false; 1329 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1330 nmsg.obj = msg.obj; 1331 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1332 return; 1333 } 1334 ProcessRecord app = (ProcessRecord)msg.obj; 1335 synchronized (ActivityManagerService.this) { 1336 processStartTimedOutLocked(app); 1337 } 1338 } break; 1339 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1340 synchronized (ActivityManagerService.this) { 1341 doPendingActivityLaunchesLocked(true); 1342 } 1343 } break; 1344 case KILL_APPLICATION_MSG: { 1345 synchronized (ActivityManagerService.this) { 1346 int appid = msg.arg1; 1347 boolean restart = (msg.arg2 == 1); 1348 Bundle bundle = (Bundle)msg.obj; 1349 String pkg = bundle.getString("pkg"); 1350 String reason = bundle.getString("reason"); 1351 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1352 false, UserHandle.USER_ALL, reason); 1353 } 1354 } break; 1355 case FINALIZE_PENDING_INTENT_MSG: { 1356 ((PendingIntentRecord)msg.obj).completeFinalize(); 1357 } break; 1358 case POST_HEAVY_NOTIFICATION_MSG: { 1359 INotificationManager inm = NotificationManager.getService(); 1360 if (inm == null) { 1361 return; 1362 } 1363 1364 ActivityRecord root = (ActivityRecord)msg.obj; 1365 ProcessRecord process = root.app; 1366 if (process == null) { 1367 return; 1368 } 1369 1370 try { 1371 Context context = mContext.createPackageContext(process.info.packageName, 0); 1372 String text = mContext.getString(R.string.heavy_weight_notification, 1373 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1374 Notification notification = new Notification(); 1375 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1376 notification.when = 0; 1377 notification.flags = Notification.FLAG_ONGOING_EVENT; 1378 notification.tickerText = text; 1379 notification.defaults = 0; // please be quiet 1380 notification.sound = null; 1381 notification.vibrate = null; 1382 notification.setLatestEventInfo(context, text, 1383 mContext.getText(R.string.heavy_weight_notification_detail), 1384 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1385 PendingIntent.FLAG_CANCEL_CURRENT, null, 1386 new UserHandle(root.userId))); 1387 1388 try { 1389 int[] outId = new int[1]; 1390 inm.enqueueNotificationWithTag("android", "android", null, 1391 R.string.heavy_weight_notification, 1392 notification, outId, root.userId); 1393 } catch (RuntimeException e) { 1394 Slog.w(ActivityManagerService.TAG, 1395 "Error showing notification for heavy-weight app", e); 1396 } catch (RemoteException e) { 1397 } 1398 } catch (NameNotFoundException e) { 1399 Slog.w(TAG, "Unable to create context for heavy notification", e); 1400 } 1401 } break; 1402 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1403 INotificationManager inm = NotificationManager.getService(); 1404 if (inm == null) { 1405 return; 1406 } 1407 try { 1408 inm.cancelNotificationWithTag("android", null, 1409 R.string.heavy_weight_notification, msg.arg1); 1410 } catch (RuntimeException e) { 1411 Slog.w(ActivityManagerService.TAG, 1412 "Error canceling notification for service", e); 1413 } catch (RemoteException e) { 1414 } 1415 } break; 1416 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1417 synchronized (ActivityManagerService.this) { 1418 checkExcessivePowerUsageLocked(true); 1419 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1420 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1421 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1422 } 1423 } break; 1424 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 ActivityRecord ar = (ActivityRecord)msg.obj; 1427 if (mCompatModeDialog != null) { 1428 if (mCompatModeDialog.mAppInfo.packageName.equals( 1429 ar.info.applicationInfo.packageName)) { 1430 return; 1431 } 1432 mCompatModeDialog.dismiss(); 1433 mCompatModeDialog = null; 1434 } 1435 if (ar != null && false) { 1436 if (mCompatModePackages.getPackageAskCompatModeLocked( 1437 ar.packageName)) { 1438 int mode = mCompatModePackages.computeCompatModeLocked( 1439 ar.info.applicationInfo); 1440 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1441 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1442 mCompatModeDialog = new CompatModeDialog( 1443 ActivityManagerService.this, mContext, 1444 ar.info.applicationInfo); 1445 mCompatModeDialog.show(); 1446 } 1447 } 1448 } 1449 } 1450 break; 1451 } 1452 case DISPATCH_PROCESSES_CHANGED: { 1453 dispatchProcessesChanged(); 1454 break; 1455 } 1456 case DISPATCH_PROCESS_DIED: { 1457 final int pid = msg.arg1; 1458 final int uid = msg.arg2; 1459 dispatchProcessDied(pid, uid); 1460 break; 1461 } 1462 case REPORT_MEM_USAGE_MSG: { 1463 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1464 Thread thread = new Thread() { 1465 @Override public void run() { 1466 final SparseArray<ProcessMemInfo> infoMap 1467 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1468 for (int i=0, N=memInfos.size(); i<N; i++) { 1469 ProcessMemInfo mi = memInfos.get(i); 1470 infoMap.put(mi.pid, mi); 1471 } 1472 updateCpuStatsNow(); 1473 synchronized (mProcessCpuThread) { 1474 final int N = mProcessCpuTracker.countStats(); 1475 for (int i=0; i<N; i++) { 1476 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1477 if (st.vsize > 0) { 1478 long pss = Debug.getPss(st.pid, null); 1479 if (pss > 0) { 1480 if (infoMap.indexOfKey(st.pid) < 0) { 1481 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1482 ProcessList.NATIVE_ADJ, -1, "native", null); 1483 mi.pss = pss; 1484 memInfos.add(mi); 1485 } 1486 } 1487 } 1488 } 1489 } 1490 1491 long totalPss = 0; 1492 for (int i=0, N=memInfos.size(); i<N; i++) { 1493 ProcessMemInfo mi = memInfos.get(i); 1494 if (mi.pss == 0) { 1495 mi.pss = Debug.getPss(mi.pid, null); 1496 } 1497 totalPss += mi.pss; 1498 } 1499 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1500 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1501 if (lhs.oomAdj != rhs.oomAdj) { 1502 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1503 } 1504 if (lhs.pss != rhs.pss) { 1505 return lhs.pss < rhs.pss ? 1 : -1; 1506 } 1507 return 0; 1508 } 1509 }); 1510 1511 StringBuilder tag = new StringBuilder(128); 1512 StringBuilder stack = new StringBuilder(128); 1513 tag.append("Low on memory -- "); 1514 appendMemBucket(tag, totalPss, "total", false); 1515 appendMemBucket(stack, totalPss, "total", true); 1516 1517 StringBuilder logBuilder = new StringBuilder(1024); 1518 logBuilder.append("Low on memory:\n"); 1519 1520 boolean firstLine = true; 1521 int lastOomAdj = Integer.MIN_VALUE; 1522 for (int i=0, N=memInfos.size(); i<N; i++) { 1523 ProcessMemInfo mi = memInfos.get(i); 1524 1525 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1526 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1527 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1528 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1529 if (lastOomAdj != mi.oomAdj) { 1530 lastOomAdj = mi.oomAdj; 1531 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1532 tag.append(" / "); 1533 } 1534 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1535 if (firstLine) { 1536 stack.append(":"); 1537 firstLine = false; 1538 } 1539 stack.append("\n\t at "); 1540 } else { 1541 stack.append("$"); 1542 } 1543 } else { 1544 tag.append(" "); 1545 stack.append("$"); 1546 } 1547 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1548 appendMemBucket(tag, mi.pss, mi.name, false); 1549 } 1550 appendMemBucket(stack, mi.pss, mi.name, true); 1551 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1552 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1553 stack.append("("); 1554 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1555 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1556 stack.append(DUMP_MEM_OOM_LABEL[k]); 1557 stack.append(":"); 1558 stack.append(DUMP_MEM_OOM_ADJ[k]); 1559 } 1560 } 1561 stack.append(")"); 1562 } 1563 } 1564 1565 logBuilder.append(" "); 1566 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1567 logBuilder.append(' '); 1568 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1569 logBuilder.append(' '); 1570 ProcessList.appendRamKb(logBuilder, mi.pss); 1571 logBuilder.append(" kB: "); 1572 logBuilder.append(mi.name); 1573 logBuilder.append(" ("); 1574 logBuilder.append(mi.pid); 1575 logBuilder.append(") "); 1576 logBuilder.append(mi.adjType); 1577 logBuilder.append('\n'); 1578 if (mi.adjReason != null) { 1579 logBuilder.append(" "); 1580 logBuilder.append(mi.adjReason); 1581 logBuilder.append('\n'); 1582 } 1583 } 1584 1585 logBuilder.append(" "); 1586 ProcessList.appendRamKb(logBuilder, totalPss); 1587 logBuilder.append(" kB: TOTAL\n"); 1588 1589 long[] infos = new long[Debug.MEMINFO_COUNT]; 1590 Debug.getMemInfo(infos); 1591 logBuilder.append(" MemInfo: "); 1592 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1593 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1594 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1595 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1596 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1597 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1598 logBuilder.append(" ZRAM: "); 1599 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1600 logBuilder.append(" kB RAM, "); 1601 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1602 logBuilder.append(" kB swap total, "); 1603 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1604 logBuilder.append(" kB swap free\n"); 1605 } 1606 Slog.i(TAG, logBuilder.toString()); 1607 1608 StringBuilder dropBuilder = new StringBuilder(1024); 1609 /* 1610 StringWriter oomSw = new StringWriter(); 1611 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1612 StringWriter catSw = new StringWriter(); 1613 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1614 String[] emptyArgs = new String[] { }; 1615 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1616 oomPw.flush(); 1617 String oomString = oomSw.toString(); 1618 */ 1619 dropBuilder.append(stack); 1620 dropBuilder.append('\n'); 1621 dropBuilder.append('\n'); 1622 dropBuilder.append(logBuilder); 1623 dropBuilder.append('\n'); 1624 /* 1625 dropBuilder.append(oomString); 1626 dropBuilder.append('\n'); 1627 */ 1628 StringWriter catSw = new StringWriter(); 1629 synchronized (ActivityManagerService.this) { 1630 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1631 String[] emptyArgs = new String[] { }; 1632 catPw.println(); 1633 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1634 catPw.println(); 1635 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1636 false, false, null); 1637 catPw.println(); 1638 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1639 catPw.flush(); 1640 } 1641 dropBuilder.append(catSw.toString()); 1642 addErrorToDropBox("lowmem", null, "system_server", null, 1643 null, tag.toString(), dropBuilder.toString(), null, null); 1644 //Slog.i(TAG, "Sent to dropbox:"); 1645 //Slog.i(TAG, dropBuilder.toString()); 1646 synchronized (ActivityManagerService.this) { 1647 long now = SystemClock.uptimeMillis(); 1648 if (mLastMemUsageReportTime < now) { 1649 mLastMemUsageReportTime = now; 1650 } 1651 } 1652 } 1653 }; 1654 thread.start(); 1655 break; 1656 } 1657 case REPORT_USER_SWITCH_MSG: { 1658 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1659 break; 1660 } 1661 case CONTINUE_USER_SWITCH_MSG: { 1662 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1663 break; 1664 } 1665 case USER_SWITCH_TIMEOUT_MSG: { 1666 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1667 break; 1668 } 1669 case IMMERSIVE_MODE_LOCK_MSG: { 1670 final boolean nextState = (msg.arg1 != 0); 1671 if (mUpdateLock.isHeld() != nextState) { 1672 if (DEBUG_IMMERSIVE) { 1673 final ActivityRecord r = (ActivityRecord) msg.obj; 1674 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1675 } 1676 if (nextState) { 1677 mUpdateLock.acquire(); 1678 } else { 1679 mUpdateLock.release(); 1680 } 1681 } 1682 break; 1683 } 1684 case PERSIST_URI_GRANTS_MSG: { 1685 writeGrantedUriPermissions(); 1686 break; 1687 } 1688 case REQUEST_ALL_PSS_MSG: { 1689 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1690 break; 1691 } 1692 case START_RELATED_USERS_MSG: { 1693 synchronized (ActivityManagerService.this) { 1694 startRelatedUsersLocked(); 1695 } 1696 break; 1697 } 1698 case UPDATE_TIME: { 1699 synchronized (ActivityManagerService.this) { 1700 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1701 ProcessRecord r = mLruProcesses.get(i); 1702 if (r.thread != null) { 1703 try { 1704 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1705 } catch (RemoteException ex) { 1706 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1707 } 1708 } 1709 } 1710 } 1711 break; 1712 } 1713 } 1714 } 1715 }; 1716 1717 static final int COLLECT_PSS_BG_MSG = 1; 1718 1719 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1720 @Override 1721 public void handleMessage(Message msg) { 1722 switch (msg.what) { 1723 case COLLECT_PSS_BG_MSG: { 1724 int i=0, num=0; 1725 long start = SystemClock.uptimeMillis(); 1726 long[] tmp = new long[1]; 1727 do { 1728 ProcessRecord proc; 1729 int procState; 1730 int pid; 1731 synchronized (ActivityManagerService.this) { 1732 if (i >= mPendingPssProcesses.size()) { 1733 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1734 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1735 mPendingPssProcesses.clear(); 1736 return; 1737 } 1738 proc = mPendingPssProcesses.get(i); 1739 procState = proc.pssProcState; 1740 if (proc.thread != null && procState == proc.setProcState) { 1741 pid = proc.pid; 1742 } else { 1743 proc = null; 1744 pid = 0; 1745 } 1746 i++; 1747 } 1748 if (proc != null) { 1749 long pss = Debug.getPss(pid, tmp); 1750 synchronized (ActivityManagerService.this) { 1751 if (proc.thread != null && proc.setProcState == procState 1752 && proc.pid == pid) { 1753 num++; 1754 proc.lastPssTime = SystemClock.uptimeMillis(); 1755 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1756 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1757 + ": " + pss + " lastPss=" + proc.lastPss 1758 + " state=" + ProcessList.makeProcStateString(procState)); 1759 if (proc.initialIdlePss == 0) { 1760 proc.initialIdlePss = pss; 1761 } 1762 proc.lastPss = pss; 1763 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1764 proc.lastCachedPss = pss; 1765 } 1766 } 1767 } 1768 } 1769 } while (true); 1770 } 1771 } 1772 } 1773 }; 1774 1775 public void setSystemProcess() { 1776 try { 1777 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1778 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1779 ServiceManager.addService("meminfo", new MemBinder(this)); 1780 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1781 ServiceManager.addService("dbinfo", new DbBinder(this)); 1782 if (MONITOR_CPU_USAGE) { 1783 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1784 } 1785 ServiceManager.addService("permission", new PermissionController(this)); 1786 1787 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1788 "android", STOCK_PM_FLAGS); 1789 mSystemThread.installSystemApplicationInfo(info); 1790 1791 synchronized (this) { 1792 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1793 app.persistent = true; 1794 app.pid = MY_PID; 1795 app.maxAdj = ProcessList.SYSTEM_ADJ; 1796 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1797 mProcessNames.put(app.processName, app.uid, app); 1798 synchronized (mPidsSelfLocked) { 1799 mPidsSelfLocked.put(app.pid, app); 1800 } 1801 updateLruProcessLocked(app, false, null); 1802 updateOomAdjLocked(); 1803 } 1804 } catch (PackageManager.NameNotFoundException e) { 1805 throw new RuntimeException( 1806 "Unable to find android system package", e); 1807 } 1808 } 1809 1810 public void setWindowManager(WindowManagerService wm) { 1811 mWindowManager = wm; 1812 mStackSupervisor.setWindowManager(wm); 1813 } 1814 1815 public void startObservingNativeCrashes() { 1816 final NativeCrashListener ncl = new NativeCrashListener(this); 1817 ncl.start(); 1818 } 1819 1820 public IAppOpsService getAppOpsService() { 1821 return mAppOpsService; 1822 } 1823 1824 static class MemBinder extends Binder { 1825 ActivityManagerService mActivityManagerService; 1826 MemBinder(ActivityManagerService activityManagerService) { 1827 mActivityManagerService = activityManagerService; 1828 } 1829 1830 @Override 1831 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1832 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1833 != PackageManager.PERMISSION_GRANTED) { 1834 pw.println("Permission Denial: can't dump meminfo from from pid=" 1835 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1836 + " without permission " + android.Manifest.permission.DUMP); 1837 return; 1838 } 1839 1840 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1841 } 1842 } 1843 1844 static class GraphicsBinder extends Binder { 1845 ActivityManagerService mActivityManagerService; 1846 GraphicsBinder(ActivityManagerService activityManagerService) { 1847 mActivityManagerService = activityManagerService; 1848 } 1849 1850 @Override 1851 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1852 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1853 != PackageManager.PERMISSION_GRANTED) { 1854 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1855 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1856 + " without permission " + android.Manifest.permission.DUMP); 1857 return; 1858 } 1859 1860 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1861 } 1862 } 1863 1864 static class DbBinder extends Binder { 1865 ActivityManagerService mActivityManagerService; 1866 DbBinder(ActivityManagerService activityManagerService) { 1867 mActivityManagerService = activityManagerService; 1868 } 1869 1870 @Override 1871 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1872 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1873 != PackageManager.PERMISSION_GRANTED) { 1874 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1875 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1876 + " without permission " + android.Manifest.permission.DUMP); 1877 return; 1878 } 1879 1880 mActivityManagerService.dumpDbInfo(fd, pw, args); 1881 } 1882 } 1883 1884 static class CpuBinder extends Binder { 1885 ActivityManagerService mActivityManagerService; 1886 CpuBinder(ActivityManagerService activityManagerService) { 1887 mActivityManagerService = activityManagerService; 1888 } 1889 1890 @Override 1891 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1892 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1893 != PackageManager.PERMISSION_GRANTED) { 1894 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1895 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1896 + " without permission " + android.Manifest.permission.DUMP); 1897 return; 1898 } 1899 1900 synchronized (mActivityManagerService.mProcessCpuThread) { 1901 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1902 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1903 SystemClock.uptimeMillis())); 1904 } 1905 } 1906 } 1907 1908 public static final class Lifecycle extends SystemService { 1909 private final ActivityManagerService mService; 1910 1911 public Lifecycle(Context context) { 1912 super(context); 1913 mService = new ActivityManagerService(context); 1914 } 1915 1916 @Override 1917 public void onStart() { 1918 mService.start(); 1919 } 1920 1921 public ActivityManagerService getService() { 1922 return mService; 1923 } 1924 } 1925 1926 // Note: This method is invoked on the main thread but may need to attach various 1927 // handlers to other threads. So take care to be explicit about the looper. 1928 public ActivityManagerService(Context systemContext) { 1929 mContext = systemContext; 1930 mFactoryTest = FactoryTest.getMode(); 1931 mSystemThread = ActivityThread.currentActivityThread(); 1932 1933 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1934 1935 mHandlerThread = new ServiceThread(TAG, 1936 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1937 mHandlerThread.start(); 1938 mHandler = new MainHandler(mHandlerThread.getLooper()); 1939 1940 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1941 "foreground", BROADCAST_FG_TIMEOUT, false); 1942 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1943 "background", BROADCAST_BG_TIMEOUT, true); 1944 mBroadcastQueues[0] = mFgBroadcastQueue; 1945 mBroadcastQueues[1] = mBgBroadcastQueue; 1946 1947 mServices = new ActiveServices(this); 1948 mProviderMap = new ProviderMap(this); 1949 1950 // TODO: Move creation of battery stats service outside of activity manager service. 1951 File dataDir = Environment.getDataDirectory(); 1952 File systemDir = new File(dataDir, "system"); 1953 systemDir.mkdirs(); 1954 mBatteryStatsService = new BatteryStatsService(new File( 1955 systemDir, "batterystats.bin").toString(), mHandler); 1956 mBatteryStatsService.getActiveStatistics().readLocked(); 1957 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1958 mOnBattery = DEBUG_POWER ? true 1959 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1960 mBatteryStatsService.getActiveStatistics().setCallback(this); 1961 1962 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1963 1964 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1965 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1966 1967 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1968 1969 // User 0 is the first and only user that runs at boot. 1970 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1971 mUserLru.add(Integer.valueOf(0)); 1972 updateStartedUserArrayLocked(); 1973 1974 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1975 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1976 1977 mConfiguration.setToDefaults(); 1978 mConfiguration.setLocale(Locale.getDefault()); 1979 1980 mConfigurationSeq = mConfiguration.seq = 1; 1981 mProcessCpuTracker.init(); 1982 1983 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1984 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1985 mStackSupervisor = new ActivityStackSupervisor(this); 1986 1987 mProcessCpuThread = new Thread("CpuTracker") { 1988 @Override 1989 public void run() { 1990 while (true) { 1991 try { 1992 try { 1993 synchronized(this) { 1994 final long now = SystemClock.uptimeMillis(); 1995 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1996 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1997 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1998 // + ", write delay=" + nextWriteDelay); 1999 if (nextWriteDelay < nextCpuDelay) { 2000 nextCpuDelay = nextWriteDelay; 2001 } 2002 if (nextCpuDelay > 0) { 2003 mProcessCpuMutexFree.set(true); 2004 this.wait(nextCpuDelay); 2005 } 2006 } 2007 } catch (InterruptedException e) { 2008 } 2009 updateCpuStatsNow(); 2010 } catch (Exception e) { 2011 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2012 } 2013 } 2014 } 2015 }; 2016 2017 Watchdog.getInstance().addMonitor(this); 2018 Watchdog.getInstance().addThread(mHandler); 2019 } 2020 2021 private void start() { 2022 mProcessCpuThread.start(); 2023 2024 mBatteryStatsService.publish(mContext); 2025 mUsageStatsService.publish(mContext); 2026 mAppOpsService.publish(mContext); 2027 startRunning(null, null, null, null); 2028 } 2029 2030 @Override 2031 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2032 throws RemoteException { 2033 if (code == SYSPROPS_TRANSACTION) { 2034 // We need to tell all apps about the system property change. 2035 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2036 synchronized(this) { 2037 final int NP = mProcessNames.getMap().size(); 2038 for (int ip=0; ip<NP; ip++) { 2039 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2040 final int NA = apps.size(); 2041 for (int ia=0; ia<NA; ia++) { 2042 ProcessRecord app = apps.valueAt(ia); 2043 if (app.thread != null) { 2044 procs.add(app.thread.asBinder()); 2045 } 2046 } 2047 } 2048 } 2049 2050 int N = procs.size(); 2051 for (int i=0; i<N; i++) { 2052 Parcel data2 = Parcel.obtain(); 2053 try { 2054 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2055 } catch (RemoteException e) { 2056 } 2057 data2.recycle(); 2058 } 2059 } 2060 try { 2061 return super.onTransact(code, data, reply, flags); 2062 } catch (RuntimeException e) { 2063 // The activity manager only throws security exceptions, so let's 2064 // log all others. 2065 if (!(e instanceof SecurityException)) { 2066 Slog.wtf(TAG, "Activity Manager Crash", e); 2067 } 2068 throw e; 2069 } 2070 } 2071 2072 void updateCpuStats() { 2073 final long now = SystemClock.uptimeMillis(); 2074 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2075 return; 2076 } 2077 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2078 synchronized (mProcessCpuThread) { 2079 mProcessCpuThread.notify(); 2080 } 2081 } 2082 } 2083 2084 void updateCpuStatsNow() { 2085 synchronized (mProcessCpuThread) { 2086 mProcessCpuMutexFree.set(false); 2087 final long now = SystemClock.uptimeMillis(); 2088 boolean haveNewCpuStats = false; 2089 2090 if (MONITOR_CPU_USAGE && 2091 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2092 mLastCpuTime.set(now); 2093 haveNewCpuStats = true; 2094 mProcessCpuTracker.update(); 2095 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2096 //Slog.i(TAG, "Total CPU usage: " 2097 // + mProcessCpu.getTotalCpuPercent() + "%"); 2098 2099 // Slog the cpu usage if the property is set. 2100 if ("true".equals(SystemProperties.get("events.cpu"))) { 2101 int user = mProcessCpuTracker.getLastUserTime(); 2102 int system = mProcessCpuTracker.getLastSystemTime(); 2103 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2104 int irq = mProcessCpuTracker.getLastIrqTime(); 2105 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2106 int idle = mProcessCpuTracker.getLastIdleTime(); 2107 2108 int total = user + system + iowait + irq + softIrq + idle; 2109 if (total == 0) total = 1; 2110 2111 EventLog.writeEvent(EventLogTags.CPU, 2112 ((user+system+iowait+irq+softIrq) * 100) / total, 2113 (user * 100) / total, 2114 (system * 100) / total, 2115 (iowait * 100) / total, 2116 (irq * 100) / total, 2117 (softIrq * 100) / total); 2118 } 2119 } 2120 2121 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2122 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2123 synchronized(bstats) { 2124 synchronized(mPidsSelfLocked) { 2125 if (haveNewCpuStats) { 2126 if (mOnBattery) { 2127 int perc = bstats.startAddingCpuLocked(); 2128 int totalUTime = 0; 2129 int totalSTime = 0; 2130 final int N = mProcessCpuTracker.countStats(); 2131 for (int i=0; i<N; i++) { 2132 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2133 if (!st.working) { 2134 continue; 2135 } 2136 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2137 int otherUTime = (st.rel_utime*perc)/100; 2138 int otherSTime = (st.rel_stime*perc)/100; 2139 totalUTime += otherUTime; 2140 totalSTime += otherSTime; 2141 if (pr != null) { 2142 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2143 if (ps == null || !ps.isActive()) { 2144 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2145 pr.info.uid, pr.processName); 2146 } 2147 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2148 st.rel_stime-otherSTime); 2149 ps.addSpeedStepTimes(cpuSpeedTimes); 2150 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2151 } else { 2152 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2153 if (ps == null || !ps.isActive()) { 2154 st.batteryStats = ps = bstats.getProcessStatsLocked( 2155 bstats.mapUid(st.uid), st.name); 2156 } 2157 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2158 st.rel_stime-otherSTime); 2159 ps.addSpeedStepTimes(cpuSpeedTimes); 2160 } 2161 } 2162 bstats.finishAddingCpuLocked(perc, totalUTime, 2163 totalSTime, cpuSpeedTimes); 2164 } 2165 } 2166 } 2167 2168 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2169 mLastWriteTime = now; 2170 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2171 } 2172 } 2173 } 2174 } 2175 2176 @Override 2177 public void batteryNeedsCpuUpdate() { 2178 updateCpuStatsNow(); 2179 } 2180 2181 @Override 2182 public void batteryPowerChanged(boolean onBattery) { 2183 // When plugging in, update the CPU stats first before changing 2184 // the plug state. 2185 updateCpuStatsNow(); 2186 synchronized (this) { 2187 synchronized(mPidsSelfLocked) { 2188 mOnBattery = DEBUG_POWER ? true : onBattery; 2189 } 2190 } 2191 } 2192 2193 /** 2194 * Initialize the application bind args. These are passed to each 2195 * process when the bindApplication() IPC is sent to the process. They're 2196 * lazily setup to make sure the services are running when they're asked for. 2197 */ 2198 private HashMap<String, IBinder> getCommonServicesLocked() { 2199 if (mAppBindArgs == null) { 2200 mAppBindArgs = new HashMap<String, IBinder>(); 2201 2202 // Setup the application init args 2203 mAppBindArgs.put("package", ServiceManager.getService("package")); 2204 mAppBindArgs.put("window", ServiceManager.getService("window")); 2205 mAppBindArgs.put(Context.ALARM_SERVICE, 2206 ServiceManager.getService(Context.ALARM_SERVICE)); 2207 } 2208 return mAppBindArgs; 2209 } 2210 2211 final void setFocusedActivityLocked(ActivityRecord r) { 2212 if (mFocusedActivity != r) { 2213 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2214 mFocusedActivity = r; 2215 mStackSupervisor.setFocusedStack(r); 2216 if (r != null) { 2217 mWindowManager.setFocusedApp(r.appToken, true); 2218 } 2219 applyUpdateLockStateLocked(r); 2220 } 2221 } 2222 2223 @Override 2224 public void setFocusedStack(int stackId) { 2225 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2226 synchronized (ActivityManagerService.this) { 2227 ActivityStack stack = mStackSupervisor.getStack(stackId); 2228 if (stack != null) { 2229 ActivityRecord r = stack.topRunningActivityLocked(null); 2230 if (r != null) { 2231 setFocusedActivityLocked(r); 2232 } 2233 } 2234 } 2235 } 2236 2237 @Override 2238 public void notifyActivityDrawn(IBinder token) { 2239 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2240 synchronized (this) { 2241 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2242 if (r != null) { 2243 r.task.stack.notifyActivityDrawnLocked(r); 2244 } 2245 } 2246 } 2247 2248 final void applyUpdateLockStateLocked(ActivityRecord r) { 2249 // Modifications to the UpdateLock state are done on our handler, outside 2250 // the activity manager's locks. The new state is determined based on the 2251 // state *now* of the relevant activity record. The object is passed to 2252 // the handler solely for logging detail, not to be consulted/modified. 2253 final boolean nextState = r != null && r.immersive; 2254 mHandler.sendMessage( 2255 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2256 } 2257 2258 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2259 Message msg = Message.obtain(); 2260 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2261 msg.obj = r.task.askedCompatMode ? null : r; 2262 mHandler.sendMessage(msg); 2263 } 2264 2265 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2266 String what, Object obj, ProcessRecord srcApp) { 2267 app.lastActivityTime = now; 2268 2269 if (app.activities.size() > 0) { 2270 // Don't want to touch dependent processes that are hosting activities. 2271 return index; 2272 } 2273 2274 int lrui = mLruProcesses.lastIndexOf(app); 2275 if (lrui < 0) { 2276 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2277 + what + " " + obj + " from " + srcApp); 2278 return index; 2279 } 2280 2281 if (lrui >= index) { 2282 // Don't want to cause this to move dependent processes *back* in the 2283 // list as if they were less frequently used. 2284 return index; 2285 } 2286 2287 if (lrui >= mLruProcessActivityStart) { 2288 // Don't want to touch dependent processes that are hosting activities. 2289 return index; 2290 } 2291 2292 mLruProcesses.remove(lrui); 2293 if (index > 0) { 2294 index--; 2295 } 2296 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2297 + " in LRU list: " + app); 2298 mLruProcesses.add(index, app); 2299 return index; 2300 } 2301 2302 final void removeLruProcessLocked(ProcessRecord app) { 2303 int lrui = mLruProcesses.lastIndexOf(app); 2304 if (lrui >= 0) { 2305 if (lrui <= mLruProcessActivityStart) { 2306 mLruProcessActivityStart--; 2307 } 2308 if (lrui <= mLruProcessServiceStart) { 2309 mLruProcessServiceStart--; 2310 } 2311 mLruProcesses.remove(lrui); 2312 } 2313 } 2314 2315 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2316 ProcessRecord client) { 2317 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2318 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2319 if (!activityChange && hasActivity) { 2320 // The process has activties, so we are only going to allow activity-based 2321 // adjustments move it. It should be kept in the front of the list with other 2322 // processes that have activities, and we don't want those to change their 2323 // order except due to activity operations. 2324 return; 2325 } 2326 2327 mLruSeq++; 2328 final long now = SystemClock.uptimeMillis(); 2329 app.lastActivityTime = now; 2330 2331 // First a quick reject: if the app is already at the position we will 2332 // put it, then there is nothing to do. 2333 if (hasActivity) { 2334 final int N = mLruProcesses.size(); 2335 if (N > 0 && mLruProcesses.get(N-1) == app) { 2336 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2337 return; 2338 } 2339 } else { 2340 if (mLruProcessServiceStart > 0 2341 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2342 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2343 return; 2344 } 2345 } 2346 2347 int lrui = mLruProcesses.lastIndexOf(app); 2348 2349 if (app.persistent && lrui >= 0) { 2350 // We don't care about the position of persistent processes, as long as 2351 // they are in the list. 2352 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2353 return; 2354 } 2355 2356 /* In progress: compute new position first, so we can avoid doing work 2357 if the process is not actually going to move. Not yet working. 2358 int addIndex; 2359 int nextIndex; 2360 boolean inActivity = false, inService = false; 2361 if (hasActivity) { 2362 // Process has activities, put it at the very tipsy-top. 2363 addIndex = mLruProcesses.size(); 2364 nextIndex = mLruProcessServiceStart; 2365 inActivity = true; 2366 } else if (hasService) { 2367 // Process has services, put it at the top of the service list. 2368 addIndex = mLruProcessActivityStart; 2369 nextIndex = mLruProcessServiceStart; 2370 inActivity = true; 2371 inService = true; 2372 } else { 2373 // Process not otherwise of interest, it goes to the top of the non-service area. 2374 addIndex = mLruProcessServiceStart; 2375 if (client != null) { 2376 int clientIndex = mLruProcesses.lastIndexOf(client); 2377 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2378 + app); 2379 if (clientIndex >= 0 && addIndex > clientIndex) { 2380 addIndex = clientIndex; 2381 } 2382 } 2383 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2384 } 2385 2386 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2387 + mLruProcessActivityStart + "): " + app); 2388 */ 2389 2390 if (lrui >= 0) { 2391 if (lrui < mLruProcessActivityStart) { 2392 mLruProcessActivityStart--; 2393 } 2394 if (lrui < mLruProcessServiceStart) { 2395 mLruProcessServiceStart--; 2396 } 2397 /* 2398 if (addIndex > lrui) { 2399 addIndex--; 2400 } 2401 if (nextIndex > lrui) { 2402 nextIndex--; 2403 } 2404 */ 2405 mLruProcesses.remove(lrui); 2406 } 2407 2408 /* 2409 mLruProcesses.add(addIndex, app); 2410 if (inActivity) { 2411 mLruProcessActivityStart++; 2412 } 2413 if (inService) { 2414 mLruProcessActivityStart++; 2415 } 2416 */ 2417 2418 int nextIndex; 2419 if (hasActivity) { 2420 final int N = mLruProcesses.size(); 2421 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2422 // Process doesn't have activities, but has clients with 2423 // activities... move it up, but one below the top (the top 2424 // should always have a real activity). 2425 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2426 mLruProcesses.add(N-1, app); 2427 // To keep it from spamming the LRU list (by making a bunch of clients), 2428 // we will push down any other entries owned by the app. 2429 final int uid = app.info.uid; 2430 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2431 ProcessRecord subProc = mLruProcesses.get(i); 2432 if (subProc.info.uid == uid) { 2433 // We want to push this one down the list. If the process after 2434 // it is for the same uid, however, don't do so, because we don't 2435 // want them internally to be re-ordered. 2436 if (mLruProcesses.get(i-1).info.uid != uid) { 2437 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2438 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2439 ProcessRecord tmp = mLruProcesses.get(i); 2440 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2441 mLruProcesses.set(i-1, tmp); 2442 i--; 2443 } 2444 } else { 2445 // A gap, we can stop here. 2446 break; 2447 } 2448 } 2449 } else { 2450 // Process has activities, put it at the very tipsy-top. 2451 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2452 mLruProcesses.add(app); 2453 } 2454 nextIndex = mLruProcessServiceStart; 2455 } else if (hasService) { 2456 // Process has services, put it at the top of the service list. 2457 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2458 mLruProcesses.add(mLruProcessActivityStart, app); 2459 nextIndex = mLruProcessServiceStart; 2460 mLruProcessActivityStart++; 2461 } else { 2462 // Process not otherwise of interest, it goes to the top of the non-service area. 2463 int index = mLruProcessServiceStart; 2464 if (client != null) { 2465 // If there is a client, don't allow the process to be moved up higher 2466 // in the list than that client. 2467 int clientIndex = mLruProcesses.lastIndexOf(client); 2468 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2469 + " when updating " + app); 2470 if (clientIndex <= lrui) { 2471 // Don't allow the client index restriction to push it down farther in the 2472 // list than it already is. 2473 clientIndex = lrui; 2474 } 2475 if (clientIndex >= 0 && index > clientIndex) { 2476 index = clientIndex; 2477 } 2478 } 2479 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2480 mLruProcesses.add(index, app); 2481 nextIndex = index-1; 2482 mLruProcessActivityStart++; 2483 mLruProcessServiceStart++; 2484 } 2485 2486 // If the app is currently using a content provider or service, 2487 // bump those processes as well. 2488 for (int j=app.connections.size()-1; j>=0; j--) { 2489 ConnectionRecord cr = app.connections.valueAt(j); 2490 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2491 && cr.binding.service.app != null 2492 && cr.binding.service.app.lruSeq != mLruSeq 2493 && !cr.binding.service.app.persistent) { 2494 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2495 "service connection", cr, app); 2496 } 2497 } 2498 for (int j=app.conProviders.size()-1; j>=0; j--) { 2499 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2500 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2501 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2502 "provider reference", cpr, app); 2503 } 2504 } 2505 } 2506 2507 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2508 if (uid == Process.SYSTEM_UID) { 2509 // The system gets to run in any process. If there are multiple 2510 // processes with the same uid, just pick the first (this 2511 // should never happen). 2512 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2513 if (procs == null) return null; 2514 final int N = procs.size(); 2515 for (int i = 0; i < N; i++) { 2516 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2517 } 2518 } 2519 ProcessRecord proc = mProcessNames.get(processName, uid); 2520 if (false && proc != null && !keepIfLarge 2521 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2522 && proc.lastCachedPss >= 4000) { 2523 // Turn this condition on to cause killing to happen regularly, for testing. 2524 if (proc.baseProcessTracker != null) { 2525 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2526 } 2527 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2528 + "k from cached"); 2529 } else if (proc != null && !keepIfLarge 2530 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2531 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2532 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2533 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2534 if (proc.baseProcessTracker != null) { 2535 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2536 } 2537 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2538 + "k from cached"); 2539 } 2540 } 2541 return proc; 2542 } 2543 2544 void ensurePackageDexOpt(String packageName) { 2545 IPackageManager pm = AppGlobals.getPackageManager(); 2546 try { 2547 if (pm.performDexOpt(packageName)) { 2548 mDidDexOpt = true; 2549 } 2550 } catch (RemoteException e) { 2551 } 2552 } 2553 2554 boolean isNextTransitionForward() { 2555 int transit = mWindowManager.getPendingAppTransition(); 2556 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2557 || transit == AppTransition.TRANSIT_TASK_OPEN 2558 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2559 } 2560 2561 final ProcessRecord startProcessLocked(String processName, 2562 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2563 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2564 boolean isolated, boolean keepIfLarge) { 2565 ProcessRecord app; 2566 if (!isolated) { 2567 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2568 } else { 2569 // If this is an isolated process, it can't re-use an existing process. 2570 app = null; 2571 } 2572 // We don't have to do anything more if: 2573 // (1) There is an existing application record; and 2574 // (2) The caller doesn't think it is dead, OR there is no thread 2575 // object attached to it so we know it couldn't have crashed; and 2576 // (3) There is a pid assigned to it, so it is either starting or 2577 // already running. 2578 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2579 + " app=" + app + " knownToBeDead=" + knownToBeDead 2580 + " thread=" + (app != null ? app.thread : null) 2581 + " pid=" + (app != null ? app.pid : -1)); 2582 if (app != null && app.pid > 0) { 2583 if (!knownToBeDead || app.thread == null) { 2584 // We already have the app running, or are waiting for it to 2585 // come up (we have a pid but not yet its thread), so keep it. 2586 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2587 // If this is a new package in the process, add the package to the list 2588 app.addPackage(info.packageName, mProcessStats); 2589 return app; 2590 } 2591 2592 // An application record is attached to a previous process, 2593 // clean it up now. 2594 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2595 handleAppDiedLocked(app, true, true); 2596 } 2597 2598 String hostingNameStr = hostingName != null 2599 ? hostingName.flattenToShortString() : null; 2600 2601 if (!isolated) { 2602 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2603 // If we are in the background, then check to see if this process 2604 // is bad. If so, we will just silently fail. 2605 if (mBadProcesses.get(info.processName, info.uid) != null) { 2606 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2607 + "/" + info.processName); 2608 return null; 2609 } 2610 } else { 2611 // When the user is explicitly starting a process, then clear its 2612 // crash count so that we won't make it bad until they see at 2613 // least one crash dialog again, and make the process good again 2614 // if it had been bad. 2615 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2616 + "/" + info.processName); 2617 mProcessCrashTimes.remove(info.processName, info.uid); 2618 if (mBadProcesses.get(info.processName, info.uid) != null) { 2619 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2620 UserHandle.getUserId(info.uid), info.uid, 2621 info.processName); 2622 mBadProcesses.remove(info.processName, info.uid); 2623 if (app != null) { 2624 app.bad = false; 2625 } 2626 } 2627 } 2628 } 2629 2630 if (app == null) { 2631 app = newProcessRecordLocked(info, processName, isolated); 2632 if (app == null) { 2633 Slog.w(TAG, "Failed making new process record for " 2634 + processName + "/" + info.uid + " isolated=" + isolated); 2635 return null; 2636 } 2637 mProcessNames.put(processName, app.uid, app); 2638 if (isolated) { 2639 mIsolatedProcesses.put(app.uid, app); 2640 } 2641 } else { 2642 // If this is a new package in the process, add the package to the list 2643 app.addPackage(info.packageName, mProcessStats); 2644 } 2645 2646 // If the system is not ready yet, then hold off on starting this 2647 // process until it is. 2648 if (!mProcessesReady 2649 && !isAllowedWhileBooting(info) 2650 && !allowWhileBooting) { 2651 if (!mProcessesOnHold.contains(app)) { 2652 mProcessesOnHold.add(app); 2653 } 2654 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2655 return app; 2656 } 2657 2658 startProcessLocked(app, hostingType, hostingNameStr); 2659 return (app.pid != 0) ? app : null; 2660 } 2661 2662 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2663 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2664 } 2665 2666 private final void startProcessLocked(ProcessRecord app, 2667 String hostingType, String hostingNameStr) { 2668 if (app.pid > 0 && app.pid != MY_PID) { 2669 synchronized (mPidsSelfLocked) { 2670 mPidsSelfLocked.remove(app.pid); 2671 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2672 } 2673 app.setPid(0); 2674 } 2675 2676 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2677 "startProcessLocked removing on hold: " + app); 2678 mProcessesOnHold.remove(app); 2679 2680 updateCpuStats(); 2681 2682 try { 2683 int uid = app.uid; 2684 2685 int[] gids = null; 2686 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2687 if (!app.isolated) { 2688 int[] permGids = null; 2689 try { 2690 final PackageManager pm = mContext.getPackageManager(); 2691 permGids = pm.getPackageGids(app.info.packageName); 2692 2693 if (Environment.isExternalStorageEmulated()) { 2694 if (pm.checkPermission( 2695 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2696 app.info.packageName) == PERMISSION_GRANTED) { 2697 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2698 } else { 2699 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2700 } 2701 } 2702 } catch (PackageManager.NameNotFoundException e) { 2703 Slog.w(TAG, "Unable to retrieve gids", e); 2704 } 2705 2706 /* 2707 * Add shared application GID so applications can share some 2708 * resources like shared libraries 2709 */ 2710 if (permGids == null) { 2711 gids = new int[1]; 2712 } else { 2713 gids = new int[permGids.length + 1]; 2714 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2715 } 2716 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2717 } 2718 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2719 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2720 && mTopComponent != null 2721 && app.processName.equals(mTopComponent.getPackageName())) { 2722 uid = 0; 2723 } 2724 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2725 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2726 uid = 0; 2727 } 2728 } 2729 int debugFlags = 0; 2730 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2731 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2732 // Also turn on CheckJNI for debuggable apps. It's quite 2733 // awkward to turn on otherwise. 2734 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2735 } 2736 // Run the app in safe mode if its manifest requests so or the 2737 // system is booted in safe mode. 2738 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2739 Zygote.systemInSafeMode == true) { 2740 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2741 } 2742 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2743 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2744 } 2745 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2746 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2747 } 2748 if ("1".equals(SystemProperties.get("debug.assert"))) { 2749 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2750 } 2751 2752 // Start the process. It will either succeed and return a result containing 2753 // the PID of the new process, or else throw a RuntimeException. 2754 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2755 app.processName, uid, uid, gids, debugFlags, mountExternal, 2756 app.info.targetSdkVersion, app.info.seinfo, null); 2757 2758 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2759 synchronized (bs) { 2760 if (bs.isOnBattery()) { 2761 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2762 } 2763 } 2764 2765 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2766 UserHandle.getUserId(uid), startResult.pid, uid, 2767 app.processName, hostingType, 2768 hostingNameStr != null ? hostingNameStr : ""); 2769 2770 if (app.persistent) { 2771 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2772 } 2773 2774 StringBuilder buf = mStringBuilder; 2775 buf.setLength(0); 2776 buf.append("Start proc "); 2777 buf.append(app.processName); 2778 buf.append(" for "); 2779 buf.append(hostingType); 2780 if (hostingNameStr != null) { 2781 buf.append(" "); 2782 buf.append(hostingNameStr); 2783 } 2784 buf.append(": pid="); 2785 buf.append(startResult.pid); 2786 buf.append(" uid="); 2787 buf.append(uid); 2788 buf.append(" gids={"); 2789 if (gids != null) { 2790 for (int gi=0; gi<gids.length; gi++) { 2791 if (gi != 0) buf.append(", "); 2792 buf.append(gids[gi]); 2793 2794 } 2795 } 2796 buf.append("}"); 2797 Slog.i(TAG, buf.toString()); 2798 app.setPid(startResult.pid); 2799 app.usingWrapper = startResult.usingWrapper; 2800 app.removed = false; 2801 synchronized (mPidsSelfLocked) { 2802 this.mPidsSelfLocked.put(startResult.pid, app); 2803 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2804 msg.obj = app; 2805 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2806 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2807 } 2808 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2809 app.processName, app.info.uid); 2810 if (app.isolated) { 2811 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2812 } 2813 } catch (RuntimeException e) { 2814 // XXX do better error recovery. 2815 app.setPid(0); 2816 Slog.e(TAG, "Failure starting process " + app.processName, e); 2817 } 2818 } 2819 2820 void updateUsageStats(ActivityRecord component, boolean resumed) { 2821 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2822 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2823 if (resumed) { 2824 mUsageStatsService.noteResumeComponent(component.realActivity); 2825 synchronized (stats) { 2826 stats.noteActivityResumedLocked(component.app.uid); 2827 } 2828 } else { 2829 mUsageStatsService.notePauseComponent(component.realActivity); 2830 synchronized (stats) { 2831 stats.noteActivityPausedLocked(component.app.uid); 2832 } 2833 } 2834 } 2835 2836 Intent getHomeIntent() { 2837 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2838 intent.setComponent(mTopComponent); 2839 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2840 intent.addCategory(Intent.CATEGORY_HOME); 2841 } 2842 return intent; 2843 } 2844 2845 boolean startHomeActivityLocked(int userId) { 2846 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2847 && mTopAction == null) { 2848 // We are running in factory test mode, but unable to find 2849 // the factory test app, so just sit around displaying the 2850 // error message and don't try to start anything. 2851 return false; 2852 } 2853 Intent intent = getHomeIntent(); 2854 ActivityInfo aInfo = 2855 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2856 if (aInfo != null) { 2857 intent.setComponent(new ComponentName( 2858 aInfo.applicationInfo.packageName, aInfo.name)); 2859 // Don't do this if the home app is currently being 2860 // instrumented. 2861 aInfo = new ActivityInfo(aInfo); 2862 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2863 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2864 aInfo.applicationInfo.uid, true); 2865 if (app == null || app.instrumentationClass == null) { 2866 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2867 mStackSupervisor.startHomeActivity(intent, aInfo); 2868 } 2869 } 2870 2871 return true; 2872 } 2873 2874 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2875 ActivityInfo ai = null; 2876 ComponentName comp = intent.getComponent(); 2877 try { 2878 if (comp != null) { 2879 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2880 } else { 2881 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2882 intent, 2883 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2884 flags, userId); 2885 2886 if (info != null) { 2887 ai = info.activityInfo; 2888 } 2889 } 2890 } catch (RemoteException e) { 2891 // ignore 2892 } 2893 2894 return ai; 2895 } 2896 2897 /** 2898 * Starts the "new version setup screen" if appropriate. 2899 */ 2900 void startSetupActivityLocked() { 2901 // Only do this once per boot. 2902 if (mCheckedForSetup) { 2903 return; 2904 } 2905 2906 // We will show this screen if the current one is a different 2907 // version than the last one shown, and we are not running in 2908 // low-level factory test mode. 2909 final ContentResolver resolver = mContext.getContentResolver(); 2910 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2911 Settings.Global.getInt(resolver, 2912 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2913 mCheckedForSetup = true; 2914 2915 // See if we should be showing the platform update setup UI. 2916 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2917 List<ResolveInfo> ris = mContext.getPackageManager() 2918 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2919 2920 // We don't allow third party apps to replace this. 2921 ResolveInfo ri = null; 2922 for (int i=0; ris != null && i<ris.size(); i++) { 2923 if ((ris.get(i).activityInfo.applicationInfo.flags 2924 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2925 ri = ris.get(i); 2926 break; 2927 } 2928 } 2929 2930 if (ri != null) { 2931 String vers = ri.activityInfo.metaData != null 2932 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2933 : null; 2934 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2935 vers = ri.activityInfo.applicationInfo.metaData.getString( 2936 Intent.METADATA_SETUP_VERSION); 2937 } 2938 String lastVers = Settings.Secure.getString( 2939 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2940 if (vers != null && !vers.equals(lastVers)) { 2941 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2942 intent.setComponent(new ComponentName( 2943 ri.activityInfo.packageName, ri.activityInfo.name)); 2944 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2945 null, null, 0, 0, 0, null, 0, null, false, null, null); 2946 } 2947 } 2948 } 2949 } 2950 2951 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2952 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2953 } 2954 2955 void enforceNotIsolatedCaller(String caller) { 2956 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2957 throw new SecurityException("Isolated process not allowed to call " + caller); 2958 } 2959 } 2960 2961 @Override 2962 public int getFrontActivityScreenCompatMode() { 2963 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2964 synchronized (this) { 2965 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2966 } 2967 } 2968 2969 @Override 2970 public void setFrontActivityScreenCompatMode(int mode) { 2971 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2972 "setFrontActivityScreenCompatMode"); 2973 synchronized (this) { 2974 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2975 } 2976 } 2977 2978 @Override 2979 public int getPackageScreenCompatMode(String packageName) { 2980 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2981 synchronized (this) { 2982 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2983 } 2984 } 2985 2986 @Override 2987 public void setPackageScreenCompatMode(String packageName, int mode) { 2988 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2989 "setPackageScreenCompatMode"); 2990 synchronized (this) { 2991 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2992 } 2993 } 2994 2995 @Override 2996 public boolean getPackageAskScreenCompat(String packageName) { 2997 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2998 synchronized (this) { 2999 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3000 } 3001 } 3002 3003 @Override 3004 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3005 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3006 "setPackageAskScreenCompat"); 3007 synchronized (this) { 3008 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3009 } 3010 } 3011 3012 private void dispatchProcessesChanged() { 3013 int N; 3014 synchronized (this) { 3015 N = mPendingProcessChanges.size(); 3016 if (mActiveProcessChanges.length < N) { 3017 mActiveProcessChanges = new ProcessChangeItem[N]; 3018 } 3019 mPendingProcessChanges.toArray(mActiveProcessChanges); 3020 mAvailProcessChanges.addAll(mPendingProcessChanges); 3021 mPendingProcessChanges.clear(); 3022 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3023 } 3024 3025 int i = mProcessObservers.beginBroadcast(); 3026 while (i > 0) { 3027 i--; 3028 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3029 if (observer != null) { 3030 try { 3031 for (int j=0; j<N; j++) { 3032 ProcessChangeItem item = mActiveProcessChanges[j]; 3033 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3034 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3035 + item.pid + " uid=" + item.uid + ": " 3036 + item.foregroundActivities); 3037 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3038 item.foregroundActivities); 3039 } 3040 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3041 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3042 + item.pid + " uid=" + item.uid + ": " + item.importance); 3043 observer.onImportanceChanged(item.pid, item.uid, 3044 item.importance); 3045 } 3046 } 3047 } catch (RemoteException e) { 3048 } 3049 } 3050 } 3051 mProcessObservers.finishBroadcast(); 3052 } 3053 3054 private void dispatchProcessDied(int pid, int uid) { 3055 int i = mProcessObservers.beginBroadcast(); 3056 while (i > 0) { 3057 i--; 3058 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3059 if (observer != null) { 3060 try { 3061 observer.onProcessDied(pid, uid); 3062 } catch (RemoteException e) { 3063 } 3064 } 3065 } 3066 mProcessObservers.finishBroadcast(); 3067 } 3068 3069 final void doPendingActivityLaunchesLocked(boolean doResume) { 3070 final int N = mPendingActivityLaunches.size(); 3071 if (N <= 0) { 3072 return; 3073 } 3074 for (int i=0; i<N; i++) { 3075 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3076 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3077 doResume && i == (N-1), null); 3078 } 3079 mPendingActivityLaunches.clear(); 3080 } 3081 3082 @Override 3083 public final int startActivity(IApplicationThread caller, String callingPackage, 3084 Intent intent, String resolvedType, IBinder resultTo, 3085 String resultWho, int requestCode, int startFlags, 3086 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3087 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3088 resultWho, requestCode, 3089 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3090 } 3091 3092 @Override 3093 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3094 Intent intent, String resolvedType, IBinder resultTo, 3095 String resultWho, int requestCode, int startFlags, 3096 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3097 enforceNotIsolatedCaller("startActivity"); 3098 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3099 false, true, "startActivity", null); 3100 // TODO: Switch to user app stacks here. 3101 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3102 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3103 null, null, options, userId, null); 3104 } 3105 3106 @Override 3107 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3108 Intent intent, String resolvedType, IBinder resultTo, 3109 String resultWho, int requestCode, int startFlags, String profileFile, 3110 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3111 enforceNotIsolatedCaller("startActivityAndWait"); 3112 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3113 false, true, "startActivityAndWait", null); 3114 WaitResult res = new WaitResult(); 3115 // TODO: Switch to user app stacks here. 3116 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3117 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3118 res, null, options, UserHandle.getCallingUserId(), null); 3119 return res; 3120 } 3121 3122 @Override 3123 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3124 Intent intent, String resolvedType, IBinder resultTo, 3125 String resultWho, int requestCode, int startFlags, Configuration config, 3126 Bundle options, int userId) { 3127 enforceNotIsolatedCaller("startActivityWithConfig"); 3128 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3129 false, true, "startActivityWithConfig", null); 3130 // TODO: Switch to user app stacks here. 3131 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3132 resolvedType, resultTo, resultWho, requestCode, startFlags, 3133 null, null, null, config, options, userId, null); 3134 return ret; 3135 } 3136 3137 @Override 3138 public int startActivityIntentSender(IApplicationThread caller, 3139 IntentSender intent, Intent fillInIntent, String resolvedType, 3140 IBinder resultTo, String resultWho, int requestCode, 3141 int flagsMask, int flagsValues, Bundle options) { 3142 enforceNotIsolatedCaller("startActivityIntentSender"); 3143 // Refuse possible leaked file descriptors 3144 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3145 throw new IllegalArgumentException("File descriptors passed in Intent"); 3146 } 3147 3148 IIntentSender sender = intent.getTarget(); 3149 if (!(sender instanceof PendingIntentRecord)) { 3150 throw new IllegalArgumentException("Bad PendingIntent object"); 3151 } 3152 3153 PendingIntentRecord pir = (PendingIntentRecord)sender; 3154 3155 synchronized (this) { 3156 // If this is coming from the currently resumed activity, it is 3157 // effectively saying that app switches are allowed at this point. 3158 final ActivityStack stack = getFocusedStack(); 3159 if (stack.mResumedActivity != null && 3160 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3161 mAppSwitchesAllowedTime = 0; 3162 } 3163 } 3164 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3165 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3166 return ret; 3167 } 3168 3169 @Override 3170 public boolean startNextMatchingActivity(IBinder callingActivity, 3171 Intent intent, Bundle options) { 3172 // Refuse possible leaked file descriptors 3173 if (intent != null && intent.hasFileDescriptors() == true) { 3174 throw new IllegalArgumentException("File descriptors passed in Intent"); 3175 } 3176 3177 synchronized (this) { 3178 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3179 if (r == null) { 3180 ActivityOptions.abort(options); 3181 return false; 3182 } 3183 if (r.app == null || r.app.thread == null) { 3184 // The caller is not running... d'oh! 3185 ActivityOptions.abort(options); 3186 return false; 3187 } 3188 intent = new Intent(intent); 3189 // The caller is not allowed to change the data. 3190 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3191 // And we are resetting to find the next component... 3192 intent.setComponent(null); 3193 3194 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3195 3196 ActivityInfo aInfo = null; 3197 try { 3198 List<ResolveInfo> resolves = 3199 AppGlobals.getPackageManager().queryIntentActivities( 3200 intent, r.resolvedType, 3201 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3202 UserHandle.getCallingUserId()); 3203 3204 // Look for the original activity in the list... 3205 final int N = resolves != null ? resolves.size() : 0; 3206 for (int i=0; i<N; i++) { 3207 ResolveInfo rInfo = resolves.get(i); 3208 if (rInfo.activityInfo.packageName.equals(r.packageName) 3209 && rInfo.activityInfo.name.equals(r.info.name)) { 3210 // We found the current one... the next matching is 3211 // after it. 3212 i++; 3213 if (i<N) { 3214 aInfo = resolves.get(i).activityInfo; 3215 } 3216 if (debug) { 3217 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3218 + "/" + r.info.name); 3219 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3220 + "/" + aInfo.name); 3221 } 3222 break; 3223 } 3224 } 3225 } catch (RemoteException e) { 3226 } 3227 3228 if (aInfo == null) { 3229 // Nobody who is next! 3230 ActivityOptions.abort(options); 3231 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3232 return false; 3233 } 3234 3235 intent.setComponent(new ComponentName( 3236 aInfo.applicationInfo.packageName, aInfo.name)); 3237 intent.setFlags(intent.getFlags()&~( 3238 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3239 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3240 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3241 Intent.FLAG_ACTIVITY_NEW_TASK)); 3242 3243 // Okay now we need to start the new activity, replacing the 3244 // currently running activity. This is a little tricky because 3245 // we want to start the new one as if the current one is finished, 3246 // but not finish the current one first so that there is no flicker. 3247 // And thus... 3248 final boolean wasFinishing = r.finishing; 3249 r.finishing = true; 3250 3251 // Propagate reply information over to the new activity. 3252 final ActivityRecord resultTo = r.resultTo; 3253 final String resultWho = r.resultWho; 3254 final int requestCode = r.requestCode; 3255 r.resultTo = null; 3256 if (resultTo != null) { 3257 resultTo.removeResultsLocked(r, resultWho, requestCode); 3258 } 3259 3260 final long origId = Binder.clearCallingIdentity(); 3261 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3262 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3263 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3264 options, false, null, null); 3265 Binder.restoreCallingIdentity(origId); 3266 3267 r.finishing = wasFinishing; 3268 if (res != ActivityManager.START_SUCCESS) { 3269 return false; 3270 } 3271 return true; 3272 } 3273 } 3274 3275 final int startActivityInPackage(int uid, String callingPackage, 3276 Intent intent, String resolvedType, IBinder resultTo, 3277 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3278 IActivityContainer container) { 3279 3280 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3281 false, true, "startActivityInPackage", null); 3282 3283 // TODO: Switch to user app stacks here. 3284 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3285 resultTo, resultWho, requestCode, startFlags, 3286 null, null, null, null, options, userId, container); 3287 return ret; 3288 } 3289 3290 @Override 3291 public final int startActivities(IApplicationThread caller, String callingPackage, 3292 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3293 int userId) { 3294 enforceNotIsolatedCaller("startActivities"); 3295 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3296 false, true, "startActivity", null); 3297 // TODO: Switch to user app stacks here. 3298 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3299 resolvedTypes, resultTo, options, userId); 3300 return ret; 3301 } 3302 3303 final int startActivitiesInPackage(int uid, String callingPackage, 3304 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3305 Bundle options, int userId) { 3306 3307 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3308 false, true, "startActivityInPackage", null); 3309 // TODO: Switch to user app stacks here. 3310 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3311 resultTo, options, userId); 3312 return ret; 3313 } 3314 3315 final void addRecentTaskLocked(TaskRecord task) { 3316 int N = mRecentTasks.size(); 3317 // Quick case: check if the top-most recent task is the same. 3318 if (N > 0 && mRecentTasks.get(0) == task) { 3319 return; 3320 } 3321 // Remove any existing entries that are the same kind of task. 3322 for (int i=0; i<N; i++) { 3323 TaskRecord tr = mRecentTasks.get(i); 3324 if (task.userId == tr.userId 3325 && ((task.affinity != null && task.affinity.equals(tr.affinity)) 3326 || (task.intent != null && task.intent.filterEquals(tr.intent)))) { 3327 tr.disposeThumbnail(); 3328 mRecentTasks.remove(i); 3329 i--; 3330 N--; 3331 if (task.intent == null) { 3332 // If the new recent task we are adding is not fully 3333 // specified, then replace it with the existing recent task. 3334 task = tr; 3335 } 3336 } 3337 } 3338 if (N >= MAX_RECENT_TASKS) { 3339 mRecentTasks.remove(N-1).disposeThumbnail(); 3340 } 3341 mRecentTasks.add(0, task); 3342 } 3343 3344 @Override 3345 public void reportActivityFullyDrawn(IBinder token) { 3346 synchronized (this) { 3347 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3348 if (r == null) { 3349 return; 3350 } 3351 r.reportFullyDrawnLocked(); 3352 } 3353 } 3354 3355 @Override 3356 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3357 synchronized (this) { 3358 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3359 if (r == null) { 3360 return; 3361 } 3362 final long origId = Binder.clearCallingIdentity(); 3363 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3364 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3365 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3366 if (config != null) { 3367 r.frozenBeforeDestroy = true; 3368 if (!updateConfigurationLocked(config, r, false, false)) { 3369 mStackSupervisor.resumeTopActivitiesLocked(); 3370 } 3371 } 3372 Binder.restoreCallingIdentity(origId); 3373 } 3374 } 3375 3376 @Override 3377 public int getRequestedOrientation(IBinder token) { 3378 synchronized (this) { 3379 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3380 if (r == null) { 3381 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3382 } 3383 return mWindowManager.getAppOrientation(r.appToken); 3384 } 3385 } 3386 3387 /** 3388 * This is the internal entry point for handling Activity.finish(). 3389 * 3390 * @param token The Binder token referencing the Activity we want to finish. 3391 * @param resultCode Result code, if any, from this Activity. 3392 * @param resultData Result data (Intent), if any, from this Activity. 3393 * 3394 * @return Returns true if the activity successfully finished, or false if it is still running. 3395 */ 3396 @Override 3397 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3398 // Refuse possible leaked file descriptors 3399 if (resultData != null && resultData.hasFileDescriptors() == true) { 3400 throw new IllegalArgumentException("File descriptors passed in Intent"); 3401 } 3402 3403 synchronized(this) { 3404 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3405 if (r == null) { 3406 return true; 3407 } 3408 if (mController != null) { 3409 // Find the first activity that is not finishing. 3410 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3411 if (next != null) { 3412 // ask watcher if this is allowed 3413 boolean resumeOK = true; 3414 try { 3415 resumeOK = mController.activityResuming(next.packageName); 3416 } catch (RemoteException e) { 3417 mController = null; 3418 Watchdog.getInstance().setActivityController(null); 3419 } 3420 3421 if (!resumeOK) { 3422 return false; 3423 } 3424 } 3425 } 3426 final long origId = Binder.clearCallingIdentity(); 3427 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3428 resultData, "app-request", true); 3429 Binder.restoreCallingIdentity(origId); 3430 return res; 3431 } 3432 } 3433 3434 @Override 3435 public final void finishHeavyWeightApp() { 3436 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3437 != PackageManager.PERMISSION_GRANTED) { 3438 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3439 + Binder.getCallingPid() 3440 + ", uid=" + Binder.getCallingUid() 3441 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3442 Slog.w(TAG, msg); 3443 throw new SecurityException(msg); 3444 } 3445 3446 synchronized(this) { 3447 if (mHeavyWeightProcess == null) { 3448 return; 3449 } 3450 3451 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3452 mHeavyWeightProcess.activities); 3453 for (int i=0; i<activities.size(); i++) { 3454 ActivityRecord r = activities.get(i); 3455 if (!r.finishing) { 3456 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3457 null, "finish-heavy", true); 3458 } 3459 } 3460 3461 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3462 mHeavyWeightProcess.userId, 0)); 3463 mHeavyWeightProcess = null; 3464 } 3465 } 3466 3467 @Override 3468 public void crashApplication(int uid, int initialPid, String packageName, 3469 String message) { 3470 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3471 != PackageManager.PERMISSION_GRANTED) { 3472 String msg = "Permission Denial: crashApplication() from pid=" 3473 + Binder.getCallingPid() 3474 + ", uid=" + Binder.getCallingUid() 3475 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3476 Slog.w(TAG, msg); 3477 throw new SecurityException(msg); 3478 } 3479 3480 synchronized(this) { 3481 ProcessRecord proc = null; 3482 3483 // Figure out which process to kill. We don't trust that initialPid 3484 // still has any relation to current pids, so must scan through the 3485 // list. 3486 synchronized (mPidsSelfLocked) { 3487 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3488 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3489 if (p.uid != uid) { 3490 continue; 3491 } 3492 if (p.pid == initialPid) { 3493 proc = p; 3494 break; 3495 } 3496 if (p.pkgList.containsKey(packageName)) { 3497 proc = p; 3498 } 3499 } 3500 } 3501 3502 if (proc == null) { 3503 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3504 + " initialPid=" + initialPid 3505 + " packageName=" + packageName); 3506 return; 3507 } 3508 3509 if (proc.thread != null) { 3510 if (proc.pid == Process.myPid()) { 3511 Log.w(TAG, "crashApplication: trying to crash self!"); 3512 return; 3513 } 3514 long ident = Binder.clearCallingIdentity(); 3515 try { 3516 proc.thread.scheduleCrash(message); 3517 } catch (RemoteException e) { 3518 } 3519 Binder.restoreCallingIdentity(ident); 3520 } 3521 } 3522 } 3523 3524 @Override 3525 public final void finishSubActivity(IBinder token, String resultWho, 3526 int requestCode) { 3527 synchronized(this) { 3528 final long origId = Binder.clearCallingIdentity(); 3529 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3530 if (r != null) { 3531 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3532 } 3533 Binder.restoreCallingIdentity(origId); 3534 } 3535 } 3536 3537 @Override 3538 public boolean finishActivityAffinity(IBinder token) { 3539 synchronized(this) { 3540 final long origId = Binder.clearCallingIdentity(); 3541 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3542 boolean res = false; 3543 if (r != null) { 3544 res = r.task.stack.finishActivityAffinityLocked(r); 3545 } 3546 Binder.restoreCallingIdentity(origId); 3547 return res; 3548 } 3549 } 3550 3551 @Override 3552 public boolean willActivityBeVisible(IBinder token) { 3553 synchronized(this) { 3554 ActivityStack stack = ActivityRecord.getStackLocked(token); 3555 if (stack != null) { 3556 return stack.willActivityBeVisibleLocked(token); 3557 } 3558 return false; 3559 } 3560 } 3561 3562 @Override 3563 public void overridePendingTransition(IBinder token, String packageName, 3564 int enterAnim, int exitAnim) { 3565 synchronized(this) { 3566 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3567 if (self == null) { 3568 return; 3569 } 3570 3571 final long origId = Binder.clearCallingIdentity(); 3572 3573 if (self.state == ActivityState.RESUMED 3574 || self.state == ActivityState.PAUSING) { 3575 mWindowManager.overridePendingAppTransition(packageName, 3576 enterAnim, exitAnim, null); 3577 } 3578 3579 Binder.restoreCallingIdentity(origId); 3580 } 3581 } 3582 3583 /** 3584 * Main function for removing an existing process from the activity manager 3585 * as a result of that process going away. Clears out all connections 3586 * to the process. 3587 */ 3588 private final void handleAppDiedLocked(ProcessRecord app, 3589 boolean restarting, boolean allowRestart) { 3590 int pid = app.pid; 3591 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3592 if (!restarting) { 3593 removeLruProcessLocked(app); 3594 if (pid > 0) { 3595 ProcessList.remove(pid); 3596 } 3597 } 3598 3599 if (mProfileProc == app) { 3600 clearProfilerLocked(); 3601 } 3602 3603 // Remove this application's activities from active lists. 3604 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3605 3606 app.activities.clear(); 3607 3608 if (app.instrumentationClass != null) { 3609 Slog.w(TAG, "Crash of app " + app.processName 3610 + " running instrumentation " + app.instrumentationClass); 3611 Bundle info = new Bundle(); 3612 info.putString("shortMsg", "Process crashed."); 3613 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3614 } 3615 3616 if (!restarting) { 3617 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3618 // If there was nothing to resume, and we are not already 3619 // restarting this process, but there is a visible activity that 3620 // is hosted by the process... then make sure all visible 3621 // activities are running, taking care of restarting this 3622 // process. 3623 if (hasVisibleActivities) { 3624 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3625 } 3626 } 3627 } 3628 } 3629 3630 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3631 IBinder threadBinder = thread.asBinder(); 3632 // Find the application record. 3633 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3634 ProcessRecord rec = mLruProcesses.get(i); 3635 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3636 return i; 3637 } 3638 } 3639 return -1; 3640 } 3641 3642 final ProcessRecord getRecordForAppLocked( 3643 IApplicationThread thread) { 3644 if (thread == null) { 3645 return null; 3646 } 3647 3648 int appIndex = getLRURecordIndexForAppLocked(thread); 3649 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3650 } 3651 3652 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3653 // If there are no longer any background processes running, 3654 // and the app that died was not running instrumentation, 3655 // then tell everyone we are now low on memory. 3656 boolean haveBg = false; 3657 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3658 ProcessRecord rec = mLruProcesses.get(i); 3659 if (rec.thread != null 3660 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3661 haveBg = true; 3662 break; 3663 } 3664 } 3665 3666 if (!haveBg) { 3667 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3668 if (doReport) { 3669 long now = SystemClock.uptimeMillis(); 3670 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3671 doReport = false; 3672 } else { 3673 mLastMemUsageReportTime = now; 3674 } 3675 } 3676 final ArrayList<ProcessMemInfo> memInfos 3677 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3678 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3679 long now = SystemClock.uptimeMillis(); 3680 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3681 ProcessRecord rec = mLruProcesses.get(i); 3682 if (rec == dyingProc || rec.thread == null) { 3683 continue; 3684 } 3685 if (doReport) { 3686 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3687 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3688 } 3689 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3690 // The low memory report is overriding any current 3691 // state for a GC request. Make sure to do 3692 // heavy/important/visible/foreground processes first. 3693 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3694 rec.lastRequestedGc = 0; 3695 } else { 3696 rec.lastRequestedGc = rec.lastLowMemory; 3697 } 3698 rec.reportLowMemory = true; 3699 rec.lastLowMemory = now; 3700 mProcessesToGc.remove(rec); 3701 addProcessToGcListLocked(rec); 3702 } 3703 } 3704 if (doReport) { 3705 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3706 mHandler.sendMessage(msg); 3707 } 3708 scheduleAppGcsLocked(); 3709 } 3710 } 3711 3712 final void appDiedLocked(ProcessRecord app, int pid, 3713 IApplicationThread thread) { 3714 3715 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3716 synchronized (stats) { 3717 stats.noteProcessDiedLocked(app.info.uid, pid); 3718 } 3719 3720 // Clean up already done if the process has been re-started. 3721 if (app.pid == pid && app.thread != null && 3722 app.thread.asBinder() == thread.asBinder()) { 3723 boolean doLowMem = app.instrumentationClass == null; 3724 boolean doOomAdj = doLowMem; 3725 if (!app.killedByAm) { 3726 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3727 + ") has died."); 3728 mAllowLowerMemLevel = true; 3729 } else { 3730 // Note that we always want to do oom adj to update our state with the 3731 // new number of procs. 3732 mAllowLowerMemLevel = false; 3733 doLowMem = false; 3734 } 3735 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3736 if (DEBUG_CLEANUP) Slog.v( 3737 TAG, "Dying app: " + app + ", pid: " + pid 3738 + ", thread: " + thread.asBinder()); 3739 handleAppDiedLocked(app, false, true); 3740 3741 if (doOomAdj) { 3742 updateOomAdjLocked(); 3743 } 3744 if (doLowMem) { 3745 doLowMemReportIfNeededLocked(app); 3746 } 3747 } else if (app.pid != pid) { 3748 // A new process has already been started. 3749 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3750 + ") has died and restarted (pid " + app.pid + ")."); 3751 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3752 } else if (DEBUG_PROCESSES) { 3753 Slog.d(TAG, "Received spurious death notification for thread " 3754 + thread.asBinder()); 3755 } 3756 } 3757 3758 /** 3759 * If a stack trace dump file is configured, dump process stack traces. 3760 * @param clearTraces causes the dump file to be erased prior to the new 3761 * traces being written, if true; when false, the new traces will be 3762 * appended to any existing file content. 3763 * @param firstPids of dalvik VM processes to dump stack traces for first 3764 * @param lastPids of dalvik VM processes to dump stack traces for last 3765 * @param nativeProcs optional list of native process names to dump stack crawls 3766 * @return file containing stack traces, or null if no dump file is configured 3767 */ 3768 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3769 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3770 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3771 if (tracesPath == null || tracesPath.length() == 0) { 3772 return null; 3773 } 3774 3775 File tracesFile = new File(tracesPath); 3776 try { 3777 File tracesDir = tracesFile.getParentFile(); 3778 if (!tracesDir.exists()) { 3779 tracesFile.mkdirs(); 3780 if (!SELinux.restorecon(tracesDir)) { 3781 return null; 3782 } 3783 } 3784 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3785 3786 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3787 tracesFile.createNewFile(); 3788 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3789 } catch (IOException e) { 3790 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3791 return null; 3792 } 3793 3794 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3795 return tracesFile; 3796 } 3797 3798 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3799 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3800 // Use a FileObserver to detect when traces finish writing. 3801 // The order of traces is considered important to maintain for legibility. 3802 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3803 @Override 3804 public synchronized void onEvent(int event, String path) { notify(); } 3805 }; 3806 3807 try { 3808 observer.startWatching(); 3809 3810 // First collect all of the stacks of the most important pids. 3811 if (firstPids != null) { 3812 try { 3813 int num = firstPids.size(); 3814 for (int i = 0; i < num; i++) { 3815 synchronized (observer) { 3816 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3817 observer.wait(200); // Wait for write-close, give up after 200msec 3818 } 3819 } 3820 } catch (InterruptedException e) { 3821 Log.wtf(TAG, e); 3822 } 3823 } 3824 3825 // Next collect the stacks of the native pids 3826 if (nativeProcs != null) { 3827 int[] pids = Process.getPidsForCommands(nativeProcs); 3828 if (pids != null) { 3829 for (int pid : pids) { 3830 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3831 } 3832 } 3833 } 3834 3835 // Lastly, measure CPU usage. 3836 if (processCpuTracker != null) { 3837 processCpuTracker.init(); 3838 System.gc(); 3839 processCpuTracker.update(); 3840 try { 3841 synchronized (processCpuTracker) { 3842 processCpuTracker.wait(500); // measure over 1/2 second. 3843 } 3844 } catch (InterruptedException e) { 3845 } 3846 processCpuTracker.update(); 3847 3848 // We'll take the stack crawls of just the top apps using CPU. 3849 final int N = processCpuTracker.countWorkingStats(); 3850 int numProcs = 0; 3851 for (int i=0; i<N && numProcs<5; i++) { 3852 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3853 if (lastPids.indexOfKey(stats.pid) >= 0) { 3854 numProcs++; 3855 try { 3856 synchronized (observer) { 3857 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3858 observer.wait(200); // Wait for write-close, give up after 200msec 3859 } 3860 } catch (InterruptedException e) { 3861 Log.wtf(TAG, e); 3862 } 3863 3864 } 3865 } 3866 } 3867 } finally { 3868 observer.stopWatching(); 3869 } 3870 } 3871 3872 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3873 if (true || IS_USER_BUILD) { 3874 return; 3875 } 3876 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3877 if (tracesPath == null || tracesPath.length() == 0) { 3878 return; 3879 } 3880 3881 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3882 StrictMode.allowThreadDiskWrites(); 3883 try { 3884 final File tracesFile = new File(tracesPath); 3885 final File tracesDir = tracesFile.getParentFile(); 3886 final File tracesTmp = new File(tracesDir, "__tmp__"); 3887 try { 3888 if (!tracesDir.exists()) { 3889 tracesFile.mkdirs(); 3890 if (!SELinux.restorecon(tracesDir.getPath())) { 3891 return; 3892 } 3893 } 3894 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3895 3896 if (tracesFile.exists()) { 3897 tracesTmp.delete(); 3898 tracesFile.renameTo(tracesTmp); 3899 } 3900 StringBuilder sb = new StringBuilder(); 3901 Time tobj = new Time(); 3902 tobj.set(System.currentTimeMillis()); 3903 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3904 sb.append(": "); 3905 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3906 sb.append(" since "); 3907 sb.append(msg); 3908 FileOutputStream fos = new FileOutputStream(tracesFile); 3909 fos.write(sb.toString().getBytes()); 3910 if (app == null) { 3911 fos.write("\n*** No application process!".getBytes()); 3912 } 3913 fos.close(); 3914 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3915 } catch (IOException e) { 3916 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3917 return; 3918 } 3919 3920 if (app != null) { 3921 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3922 firstPids.add(app.pid); 3923 dumpStackTraces(tracesPath, firstPids, null, null, null); 3924 } 3925 3926 File lastTracesFile = null; 3927 File curTracesFile = null; 3928 for (int i=9; i>=0; i--) { 3929 String name = String.format(Locale.US, "slow%02d.txt", i); 3930 curTracesFile = new File(tracesDir, name); 3931 if (curTracesFile.exists()) { 3932 if (lastTracesFile != null) { 3933 curTracesFile.renameTo(lastTracesFile); 3934 } else { 3935 curTracesFile.delete(); 3936 } 3937 } 3938 lastTracesFile = curTracesFile; 3939 } 3940 tracesFile.renameTo(curTracesFile); 3941 if (tracesTmp.exists()) { 3942 tracesTmp.renameTo(tracesFile); 3943 } 3944 } finally { 3945 StrictMode.setThreadPolicy(oldPolicy); 3946 } 3947 } 3948 3949 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3950 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3951 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3952 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3953 3954 if (mController != null) { 3955 try { 3956 // 0 == continue, -1 = kill process immediately 3957 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3958 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3959 } catch (RemoteException e) { 3960 mController = null; 3961 Watchdog.getInstance().setActivityController(null); 3962 } 3963 } 3964 3965 long anrTime = SystemClock.uptimeMillis(); 3966 if (MONITOR_CPU_USAGE) { 3967 updateCpuStatsNow(); 3968 } 3969 3970 synchronized (this) { 3971 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3972 if (mShuttingDown) { 3973 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3974 return; 3975 } else if (app.notResponding) { 3976 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3977 return; 3978 } else if (app.crashing) { 3979 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3980 return; 3981 } 3982 3983 // In case we come through here for the same app before completing 3984 // this one, mark as anring now so we will bail out. 3985 app.notResponding = true; 3986 3987 // Log the ANR to the event log. 3988 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 3989 app.processName, app.info.flags, annotation); 3990 3991 // Dump thread traces as quickly as we can, starting with "interesting" processes. 3992 firstPids.add(app.pid); 3993 3994 int parentPid = app.pid; 3995 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 3996 if (parentPid != app.pid) firstPids.add(parentPid); 3997 3998 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 3999 4000 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4001 ProcessRecord r = mLruProcesses.get(i); 4002 if (r != null && r.thread != null) { 4003 int pid = r.pid; 4004 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4005 if (r.persistent) { 4006 firstPids.add(pid); 4007 } else { 4008 lastPids.put(pid, Boolean.TRUE); 4009 } 4010 } 4011 } 4012 } 4013 } 4014 4015 // Log the ANR to the main log. 4016 StringBuilder info = new StringBuilder(); 4017 info.setLength(0); 4018 info.append("ANR in ").append(app.processName); 4019 if (activity != null && activity.shortComponentName != null) { 4020 info.append(" (").append(activity.shortComponentName).append(")"); 4021 } 4022 info.append("\n"); 4023 info.append("PID: ").append(app.pid).append("\n"); 4024 if (annotation != null) { 4025 info.append("Reason: ").append(annotation).append("\n"); 4026 } 4027 if (parent != null && parent != activity) { 4028 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4029 } 4030 4031 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4032 4033 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4034 NATIVE_STACKS_OF_INTEREST); 4035 4036 String cpuInfo = null; 4037 if (MONITOR_CPU_USAGE) { 4038 updateCpuStatsNow(); 4039 synchronized (mProcessCpuThread) { 4040 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4041 } 4042 info.append(processCpuTracker.printCurrentLoad()); 4043 info.append(cpuInfo); 4044 } 4045 4046 info.append(processCpuTracker.printCurrentState(anrTime)); 4047 4048 Slog.e(TAG, info.toString()); 4049 if (tracesFile == null) { 4050 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4051 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4052 } 4053 4054 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4055 cpuInfo, tracesFile, null); 4056 4057 if (mController != null) { 4058 try { 4059 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4060 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4061 if (res != 0) { 4062 if (res < 0 && app.pid != MY_PID) { 4063 Process.killProcess(app.pid); 4064 } else { 4065 synchronized (this) { 4066 mServices.scheduleServiceTimeoutLocked(app); 4067 } 4068 } 4069 return; 4070 } 4071 } catch (RemoteException e) { 4072 mController = null; 4073 Watchdog.getInstance().setActivityController(null); 4074 } 4075 } 4076 4077 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4078 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4079 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4080 4081 synchronized (this) { 4082 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4083 killUnneededProcessLocked(app, "background ANR"); 4084 return; 4085 } 4086 4087 // Set the app's notResponding state, and look up the errorReportReceiver 4088 makeAppNotRespondingLocked(app, 4089 activity != null ? activity.shortComponentName : null, 4090 annotation != null ? "ANR " + annotation : "ANR", 4091 info.toString()); 4092 4093 // Bring up the infamous App Not Responding dialog 4094 Message msg = Message.obtain(); 4095 HashMap<String, Object> map = new HashMap<String, Object>(); 4096 msg.what = SHOW_NOT_RESPONDING_MSG; 4097 msg.obj = map; 4098 msg.arg1 = aboveSystem ? 1 : 0; 4099 map.put("app", app); 4100 if (activity != null) { 4101 map.put("activity", activity); 4102 } 4103 4104 mHandler.sendMessage(msg); 4105 } 4106 } 4107 4108 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4109 if (!mLaunchWarningShown) { 4110 mLaunchWarningShown = true; 4111 mHandler.post(new Runnable() { 4112 @Override 4113 public void run() { 4114 synchronized (ActivityManagerService.this) { 4115 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4116 d.show(); 4117 mHandler.postDelayed(new Runnable() { 4118 @Override 4119 public void run() { 4120 synchronized (ActivityManagerService.this) { 4121 d.dismiss(); 4122 mLaunchWarningShown = false; 4123 } 4124 } 4125 }, 4000); 4126 } 4127 } 4128 }); 4129 } 4130 } 4131 4132 @Override 4133 public boolean clearApplicationUserData(final String packageName, 4134 final IPackageDataObserver observer, int userId) { 4135 enforceNotIsolatedCaller("clearApplicationUserData"); 4136 int uid = Binder.getCallingUid(); 4137 int pid = Binder.getCallingPid(); 4138 userId = handleIncomingUser(pid, uid, 4139 userId, false, true, "clearApplicationUserData", null); 4140 long callingId = Binder.clearCallingIdentity(); 4141 try { 4142 IPackageManager pm = AppGlobals.getPackageManager(); 4143 int pkgUid = -1; 4144 synchronized(this) { 4145 try { 4146 pkgUid = pm.getPackageUid(packageName, userId); 4147 } catch (RemoteException e) { 4148 } 4149 if (pkgUid == -1) { 4150 Slog.w(TAG, "Invalid packageName: " + packageName); 4151 if (observer != null) { 4152 try { 4153 observer.onRemoveCompleted(packageName, false); 4154 } catch (RemoteException e) { 4155 Slog.i(TAG, "Observer no longer exists."); 4156 } 4157 } 4158 return false; 4159 } 4160 if (uid == pkgUid || checkComponentPermission( 4161 android.Manifest.permission.CLEAR_APP_USER_DATA, 4162 pid, uid, -1, true) 4163 == PackageManager.PERMISSION_GRANTED) { 4164 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4165 } else { 4166 throw new SecurityException("PID " + pid + " does not have permission " 4167 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4168 + " of package " + packageName); 4169 } 4170 } 4171 4172 try { 4173 // Clear application user data 4174 pm.clearApplicationUserData(packageName, observer, userId); 4175 4176 // Remove all permissions granted from/to this package 4177 removeUriPermissionsForPackageLocked(packageName, userId, true); 4178 4179 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4180 Uri.fromParts("package", packageName, null)); 4181 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4182 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4183 null, null, 0, null, null, null, false, false, userId); 4184 } catch (RemoteException e) { 4185 } 4186 } finally { 4187 Binder.restoreCallingIdentity(callingId); 4188 } 4189 return true; 4190 } 4191 4192 @Override 4193 public void killBackgroundProcesses(final String packageName, int userId) { 4194 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4195 != PackageManager.PERMISSION_GRANTED && 4196 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4197 != PackageManager.PERMISSION_GRANTED) { 4198 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4199 + Binder.getCallingPid() 4200 + ", uid=" + Binder.getCallingUid() 4201 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4202 Slog.w(TAG, msg); 4203 throw new SecurityException(msg); 4204 } 4205 4206 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4207 userId, true, true, "killBackgroundProcesses", null); 4208 long callingId = Binder.clearCallingIdentity(); 4209 try { 4210 IPackageManager pm = AppGlobals.getPackageManager(); 4211 synchronized(this) { 4212 int appId = -1; 4213 try { 4214 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4215 } catch (RemoteException e) { 4216 } 4217 if (appId == -1) { 4218 Slog.w(TAG, "Invalid packageName: " + packageName); 4219 return; 4220 } 4221 killPackageProcessesLocked(packageName, appId, userId, 4222 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4223 } 4224 } finally { 4225 Binder.restoreCallingIdentity(callingId); 4226 } 4227 } 4228 4229 @Override 4230 public void killAllBackgroundProcesses() { 4231 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4232 != PackageManager.PERMISSION_GRANTED) { 4233 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4234 + Binder.getCallingPid() 4235 + ", uid=" + Binder.getCallingUid() 4236 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4237 Slog.w(TAG, msg); 4238 throw new SecurityException(msg); 4239 } 4240 4241 long callingId = Binder.clearCallingIdentity(); 4242 try { 4243 synchronized(this) { 4244 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4245 final int NP = mProcessNames.getMap().size(); 4246 for (int ip=0; ip<NP; ip++) { 4247 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4248 final int NA = apps.size(); 4249 for (int ia=0; ia<NA; ia++) { 4250 ProcessRecord app = apps.valueAt(ia); 4251 if (app.persistent) { 4252 // we don't kill persistent processes 4253 continue; 4254 } 4255 if (app.removed) { 4256 procs.add(app); 4257 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4258 app.removed = true; 4259 procs.add(app); 4260 } 4261 } 4262 } 4263 4264 int N = procs.size(); 4265 for (int i=0; i<N; i++) { 4266 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4267 } 4268 mAllowLowerMemLevel = true; 4269 updateOomAdjLocked(); 4270 doLowMemReportIfNeededLocked(null); 4271 } 4272 } finally { 4273 Binder.restoreCallingIdentity(callingId); 4274 } 4275 } 4276 4277 @Override 4278 public void forceStopPackage(final String packageName, int userId) { 4279 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4280 != PackageManager.PERMISSION_GRANTED) { 4281 String msg = "Permission Denial: forceStopPackage() from pid=" 4282 + Binder.getCallingPid() 4283 + ", uid=" + Binder.getCallingUid() 4284 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4285 Slog.w(TAG, msg); 4286 throw new SecurityException(msg); 4287 } 4288 final int callingPid = Binder.getCallingPid(); 4289 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4290 userId, true, true, "forceStopPackage", null); 4291 long callingId = Binder.clearCallingIdentity(); 4292 try { 4293 IPackageManager pm = AppGlobals.getPackageManager(); 4294 synchronized(this) { 4295 int[] users = userId == UserHandle.USER_ALL 4296 ? getUsersLocked() : new int[] { userId }; 4297 for (int user : users) { 4298 int pkgUid = -1; 4299 try { 4300 pkgUid = pm.getPackageUid(packageName, user); 4301 } catch (RemoteException e) { 4302 } 4303 if (pkgUid == -1) { 4304 Slog.w(TAG, "Invalid packageName: " + packageName); 4305 continue; 4306 } 4307 try { 4308 pm.setPackageStoppedState(packageName, true, user); 4309 } catch (RemoteException e) { 4310 } catch (IllegalArgumentException e) { 4311 Slog.w(TAG, "Failed trying to unstop package " 4312 + packageName + ": " + e); 4313 } 4314 if (isUserRunningLocked(user, false)) { 4315 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4316 } 4317 } 4318 } 4319 } finally { 4320 Binder.restoreCallingIdentity(callingId); 4321 } 4322 } 4323 4324 /* 4325 * The pkg name and app id have to be specified. 4326 */ 4327 @Override 4328 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4329 if (pkg == null) { 4330 return; 4331 } 4332 // Make sure the uid is valid. 4333 if (appid < 0) { 4334 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4335 return; 4336 } 4337 int callerUid = Binder.getCallingUid(); 4338 // Only the system server can kill an application 4339 if (callerUid == Process.SYSTEM_UID) { 4340 // Post an aysnc message to kill the application 4341 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4342 msg.arg1 = appid; 4343 msg.arg2 = 0; 4344 Bundle bundle = new Bundle(); 4345 bundle.putString("pkg", pkg); 4346 bundle.putString("reason", reason); 4347 msg.obj = bundle; 4348 mHandler.sendMessage(msg); 4349 } else { 4350 throw new SecurityException(callerUid + " cannot kill pkg: " + 4351 pkg); 4352 } 4353 } 4354 4355 @Override 4356 public void closeSystemDialogs(String reason) { 4357 enforceNotIsolatedCaller("closeSystemDialogs"); 4358 4359 final int pid = Binder.getCallingPid(); 4360 final int uid = Binder.getCallingUid(); 4361 final long origId = Binder.clearCallingIdentity(); 4362 try { 4363 synchronized (this) { 4364 // Only allow this from foreground processes, so that background 4365 // applications can't abuse it to prevent system UI from being shown. 4366 if (uid >= Process.FIRST_APPLICATION_UID) { 4367 ProcessRecord proc; 4368 synchronized (mPidsSelfLocked) { 4369 proc = mPidsSelfLocked.get(pid); 4370 } 4371 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4372 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4373 + " from background process " + proc); 4374 return; 4375 } 4376 } 4377 closeSystemDialogsLocked(reason); 4378 } 4379 } finally { 4380 Binder.restoreCallingIdentity(origId); 4381 } 4382 } 4383 4384 void closeSystemDialogsLocked(String reason) { 4385 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4386 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4387 | Intent.FLAG_RECEIVER_FOREGROUND); 4388 if (reason != null) { 4389 intent.putExtra("reason", reason); 4390 } 4391 mWindowManager.closeSystemDialogs(reason); 4392 4393 mStackSupervisor.closeSystemDialogsLocked(); 4394 4395 broadcastIntentLocked(null, null, intent, null, 4396 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4397 Process.SYSTEM_UID, UserHandle.USER_ALL); 4398 } 4399 4400 @Override 4401 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4402 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4403 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4404 for (int i=pids.length-1; i>=0; i--) { 4405 ProcessRecord proc; 4406 int oomAdj; 4407 synchronized (this) { 4408 synchronized (mPidsSelfLocked) { 4409 proc = mPidsSelfLocked.get(pids[i]); 4410 oomAdj = proc != null ? proc.setAdj : 0; 4411 } 4412 } 4413 infos[i] = new Debug.MemoryInfo(); 4414 Debug.getMemoryInfo(pids[i], infos[i]); 4415 if (proc != null) { 4416 synchronized (this) { 4417 if (proc.thread != null && proc.setAdj == oomAdj) { 4418 // Record this for posterity if the process has been stable. 4419 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4420 infos[i].getTotalUss(), false, proc.pkgList); 4421 } 4422 } 4423 } 4424 } 4425 return infos; 4426 } 4427 4428 @Override 4429 public long[] getProcessPss(int[] pids) { 4430 enforceNotIsolatedCaller("getProcessPss"); 4431 long[] pss = new long[pids.length]; 4432 for (int i=pids.length-1; i>=0; i--) { 4433 ProcessRecord proc; 4434 int oomAdj; 4435 synchronized (this) { 4436 synchronized (mPidsSelfLocked) { 4437 proc = mPidsSelfLocked.get(pids[i]); 4438 oomAdj = proc != null ? proc.setAdj : 0; 4439 } 4440 } 4441 long[] tmpUss = new long[1]; 4442 pss[i] = Debug.getPss(pids[i], tmpUss); 4443 if (proc != null) { 4444 synchronized (this) { 4445 if (proc.thread != null && proc.setAdj == oomAdj) { 4446 // Record this for posterity if the process has been stable. 4447 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4448 } 4449 } 4450 } 4451 } 4452 return pss; 4453 } 4454 4455 @Override 4456 public void killApplicationProcess(String processName, int uid) { 4457 if (processName == null) { 4458 return; 4459 } 4460 4461 int callerUid = Binder.getCallingUid(); 4462 // Only the system server can kill an application 4463 if (callerUid == Process.SYSTEM_UID) { 4464 synchronized (this) { 4465 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4466 if (app != null && app.thread != null) { 4467 try { 4468 app.thread.scheduleSuicide(); 4469 } catch (RemoteException e) { 4470 // If the other end already died, then our work here is done. 4471 } 4472 } else { 4473 Slog.w(TAG, "Process/uid not found attempting kill of " 4474 + processName + " / " + uid); 4475 } 4476 } 4477 } else { 4478 throw new SecurityException(callerUid + " cannot kill app process: " + 4479 processName); 4480 } 4481 } 4482 4483 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4484 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4485 false, true, false, false, UserHandle.getUserId(uid), reason); 4486 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4487 Uri.fromParts("package", packageName, null)); 4488 if (!mProcessesReady) { 4489 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4490 | Intent.FLAG_RECEIVER_FOREGROUND); 4491 } 4492 intent.putExtra(Intent.EXTRA_UID, uid); 4493 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4494 broadcastIntentLocked(null, null, intent, 4495 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4496 false, false, 4497 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4498 } 4499 4500 private void forceStopUserLocked(int userId, String reason) { 4501 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4502 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4503 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4504 | Intent.FLAG_RECEIVER_FOREGROUND); 4505 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4506 broadcastIntentLocked(null, null, intent, 4507 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4508 false, false, 4509 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4510 } 4511 4512 private final boolean killPackageProcessesLocked(String packageName, int appId, 4513 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4514 boolean doit, boolean evenPersistent, String reason) { 4515 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4516 4517 // Remove all processes this package may have touched: all with the 4518 // same UID (except for the system or root user), and all whose name 4519 // matches the package name. 4520 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4521 final int NP = mProcessNames.getMap().size(); 4522 for (int ip=0; ip<NP; ip++) { 4523 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4524 final int NA = apps.size(); 4525 for (int ia=0; ia<NA; ia++) { 4526 ProcessRecord app = apps.valueAt(ia); 4527 if (app.persistent && !evenPersistent) { 4528 // we don't kill persistent processes 4529 continue; 4530 } 4531 if (app.removed) { 4532 if (doit) { 4533 procs.add(app); 4534 } 4535 continue; 4536 } 4537 4538 // Skip process if it doesn't meet our oom adj requirement. 4539 if (app.setAdj < minOomAdj) { 4540 continue; 4541 } 4542 4543 // If no package is specified, we call all processes under the 4544 // give user id. 4545 if (packageName == null) { 4546 if (app.userId != userId) { 4547 continue; 4548 } 4549 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4550 continue; 4551 } 4552 // Package has been specified, we want to hit all processes 4553 // that match it. We need to qualify this by the processes 4554 // that are running under the specified app and user ID. 4555 } else { 4556 if (UserHandle.getAppId(app.uid) != appId) { 4557 continue; 4558 } 4559 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4560 continue; 4561 } 4562 if (!app.pkgList.containsKey(packageName)) { 4563 continue; 4564 } 4565 } 4566 4567 // Process has passed all conditions, kill it! 4568 if (!doit) { 4569 return true; 4570 } 4571 app.removed = true; 4572 procs.add(app); 4573 } 4574 } 4575 4576 int N = procs.size(); 4577 for (int i=0; i<N; i++) { 4578 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4579 } 4580 updateOomAdjLocked(); 4581 return N > 0; 4582 } 4583 4584 private final boolean forceStopPackageLocked(String name, int appId, 4585 boolean callerWillRestart, boolean purgeCache, boolean doit, 4586 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4587 int i; 4588 int N; 4589 4590 if (userId == UserHandle.USER_ALL && name == null) { 4591 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4592 } 4593 4594 if (appId < 0 && name != null) { 4595 try { 4596 appId = UserHandle.getAppId( 4597 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4598 } catch (RemoteException e) { 4599 } 4600 } 4601 4602 if (doit) { 4603 if (name != null) { 4604 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4605 + " user=" + userId + ": " + reason); 4606 } else { 4607 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4608 } 4609 4610 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4611 for (int ip=pmap.size()-1; ip>=0; ip--) { 4612 SparseArray<Long> ba = pmap.valueAt(ip); 4613 for (i=ba.size()-1; i>=0; i--) { 4614 boolean remove = false; 4615 final int entUid = ba.keyAt(i); 4616 if (name != null) { 4617 if (userId == UserHandle.USER_ALL) { 4618 if (UserHandle.getAppId(entUid) == appId) { 4619 remove = true; 4620 } 4621 } else { 4622 if (entUid == UserHandle.getUid(userId, appId)) { 4623 remove = true; 4624 } 4625 } 4626 } else if (UserHandle.getUserId(entUid) == userId) { 4627 remove = true; 4628 } 4629 if (remove) { 4630 ba.removeAt(i); 4631 } 4632 } 4633 if (ba.size() == 0) { 4634 pmap.removeAt(ip); 4635 } 4636 } 4637 } 4638 4639 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4640 -100, callerWillRestart, true, doit, evenPersistent, 4641 name == null ? ("stop user " + userId) : ("stop " + name)); 4642 4643 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4644 if (!doit) { 4645 return true; 4646 } 4647 didSomething = true; 4648 } 4649 4650 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4651 if (!doit) { 4652 return true; 4653 } 4654 didSomething = true; 4655 } 4656 4657 if (name == null) { 4658 // Remove all sticky broadcasts from this user. 4659 mStickyBroadcasts.remove(userId); 4660 } 4661 4662 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4663 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4664 userId, providers)) { 4665 if (!doit) { 4666 return true; 4667 } 4668 didSomething = true; 4669 } 4670 N = providers.size(); 4671 for (i=0; i<N; i++) { 4672 removeDyingProviderLocked(null, providers.get(i), true); 4673 } 4674 4675 // Remove transient permissions granted from/to this package/user 4676 removeUriPermissionsForPackageLocked(name, userId, false); 4677 4678 if (name == null || uninstalling) { 4679 // Remove pending intents. For now we only do this when force 4680 // stopping users, because we have some problems when doing this 4681 // for packages -- app widgets are not currently cleaned up for 4682 // such packages, so they can be left with bad pending intents. 4683 if (mIntentSenderRecords.size() > 0) { 4684 Iterator<WeakReference<PendingIntentRecord>> it 4685 = mIntentSenderRecords.values().iterator(); 4686 while (it.hasNext()) { 4687 WeakReference<PendingIntentRecord> wpir = it.next(); 4688 if (wpir == null) { 4689 it.remove(); 4690 continue; 4691 } 4692 PendingIntentRecord pir = wpir.get(); 4693 if (pir == null) { 4694 it.remove(); 4695 continue; 4696 } 4697 if (name == null) { 4698 // Stopping user, remove all objects for the user. 4699 if (pir.key.userId != userId) { 4700 // Not the same user, skip it. 4701 continue; 4702 } 4703 } else { 4704 if (UserHandle.getAppId(pir.uid) != appId) { 4705 // Different app id, skip it. 4706 continue; 4707 } 4708 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4709 // Different user, skip it. 4710 continue; 4711 } 4712 if (!pir.key.packageName.equals(name)) { 4713 // Different package, skip it. 4714 continue; 4715 } 4716 } 4717 if (!doit) { 4718 return true; 4719 } 4720 didSomething = true; 4721 it.remove(); 4722 pir.canceled = true; 4723 if (pir.key.activity != null) { 4724 pir.key.activity.pendingResults.remove(pir.ref); 4725 } 4726 } 4727 } 4728 } 4729 4730 if (doit) { 4731 if (purgeCache && name != null) { 4732 AttributeCache ac = AttributeCache.instance(); 4733 if (ac != null) { 4734 ac.removePackage(name); 4735 } 4736 } 4737 if (mBooted) { 4738 mStackSupervisor.resumeTopActivitiesLocked(); 4739 mStackSupervisor.scheduleIdleLocked(); 4740 } 4741 } 4742 4743 return didSomething; 4744 } 4745 4746 private final boolean removeProcessLocked(ProcessRecord app, 4747 boolean callerWillRestart, boolean allowRestart, String reason) { 4748 final String name = app.processName; 4749 final int uid = app.uid; 4750 if (DEBUG_PROCESSES) Slog.d( 4751 TAG, "Force removing proc " + app.toShortString() + " (" + name 4752 + "/" + uid + ")"); 4753 4754 mProcessNames.remove(name, uid); 4755 mIsolatedProcesses.remove(app.uid); 4756 if (mHeavyWeightProcess == app) { 4757 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4758 mHeavyWeightProcess.userId, 0)); 4759 mHeavyWeightProcess = null; 4760 } 4761 boolean needRestart = false; 4762 if (app.pid > 0 && app.pid != MY_PID) { 4763 int pid = app.pid; 4764 synchronized (mPidsSelfLocked) { 4765 mPidsSelfLocked.remove(pid); 4766 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4767 } 4768 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4769 app.processName, app.info.uid); 4770 if (app.isolated) { 4771 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4772 } 4773 killUnneededProcessLocked(app, reason); 4774 handleAppDiedLocked(app, true, allowRestart); 4775 removeLruProcessLocked(app); 4776 4777 if (app.persistent && !app.isolated) { 4778 if (!callerWillRestart) { 4779 addAppLocked(app.info, false); 4780 } else { 4781 needRestart = true; 4782 } 4783 } 4784 } else { 4785 mRemovedProcesses.add(app); 4786 } 4787 4788 return needRestart; 4789 } 4790 4791 private final void processStartTimedOutLocked(ProcessRecord app) { 4792 final int pid = app.pid; 4793 boolean gone = false; 4794 synchronized (mPidsSelfLocked) { 4795 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4796 if (knownApp != null && knownApp.thread == null) { 4797 mPidsSelfLocked.remove(pid); 4798 gone = true; 4799 } 4800 } 4801 4802 if (gone) { 4803 Slog.w(TAG, "Process " + app + " failed to attach"); 4804 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4805 pid, app.uid, app.processName); 4806 mProcessNames.remove(app.processName, app.uid); 4807 mIsolatedProcesses.remove(app.uid); 4808 if (mHeavyWeightProcess == app) { 4809 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4810 mHeavyWeightProcess.userId, 0)); 4811 mHeavyWeightProcess = null; 4812 } 4813 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4814 app.processName, app.info.uid); 4815 if (app.isolated) { 4816 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4817 } 4818 // Take care of any launching providers waiting for this process. 4819 checkAppInLaunchingProvidersLocked(app, true); 4820 // Take care of any services that are waiting for the process. 4821 mServices.processStartTimedOutLocked(app); 4822 killUnneededProcessLocked(app, "start timeout"); 4823 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4824 Slog.w(TAG, "Unattached app died before backup, skipping"); 4825 try { 4826 IBackupManager bm = IBackupManager.Stub.asInterface( 4827 ServiceManager.getService(Context.BACKUP_SERVICE)); 4828 bm.agentDisconnected(app.info.packageName); 4829 } catch (RemoteException e) { 4830 // Can't happen; the backup manager is local 4831 } 4832 } 4833 if (isPendingBroadcastProcessLocked(pid)) { 4834 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4835 skipPendingBroadcastLocked(pid); 4836 } 4837 } else { 4838 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4839 } 4840 } 4841 4842 private final boolean attachApplicationLocked(IApplicationThread thread, 4843 int pid) { 4844 4845 // Find the application record that is being attached... either via 4846 // the pid if we are running in multiple processes, or just pull the 4847 // next app record if we are emulating process with anonymous threads. 4848 ProcessRecord app; 4849 if (pid != MY_PID && pid >= 0) { 4850 synchronized (mPidsSelfLocked) { 4851 app = mPidsSelfLocked.get(pid); 4852 } 4853 } else { 4854 app = null; 4855 } 4856 4857 if (app == null) { 4858 Slog.w(TAG, "No pending application record for pid " + pid 4859 + " (IApplicationThread " + thread + "); dropping process"); 4860 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4861 if (pid > 0 && pid != MY_PID) { 4862 Process.killProcessQuiet(pid); 4863 } else { 4864 try { 4865 thread.scheduleExit(); 4866 } catch (Exception e) { 4867 // Ignore exceptions. 4868 } 4869 } 4870 return false; 4871 } 4872 4873 // If this application record is still attached to a previous 4874 // process, clean it up now. 4875 if (app.thread != null) { 4876 handleAppDiedLocked(app, true, true); 4877 } 4878 4879 // Tell the process all about itself. 4880 4881 if (localLOGV) Slog.v( 4882 TAG, "Binding process pid " + pid + " to record " + app); 4883 4884 final String processName = app.processName; 4885 try { 4886 AppDeathRecipient adr = new AppDeathRecipient( 4887 app, pid, thread); 4888 thread.asBinder().linkToDeath(adr, 0); 4889 app.deathRecipient = adr; 4890 } catch (RemoteException e) { 4891 app.resetPackageList(mProcessStats); 4892 startProcessLocked(app, "link fail", processName); 4893 return false; 4894 } 4895 4896 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4897 4898 app.makeActive(thread, mProcessStats); 4899 app.curAdj = app.setAdj = -100; 4900 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4901 app.forcingToForeground = null; 4902 updateProcessForegroundLocked(app, false, false); 4903 app.hasShownUi = false; 4904 app.debugging = false; 4905 app.cached = false; 4906 4907 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4908 4909 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4910 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4911 4912 if (!normalMode) { 4913 Slog.i(TAG, "Launching preboot mode app: " + app); 4914 } 4915 4916 if (localLOGV) Slog.v( 4917 TAG, "New app record " + app 4918 + " thread=" + thread.asBinder() + " pid=" + pid); 4919 try { 4920 int testMode = IApplicationThread.DEBUG_OFF; 4921 if (mDebugApp != null && mDebugApp.equals(processName)) { 4922 testMode = mWaitForDebugger 4923 ? IApplicationThread.DEBUG_WAIT 4924 : IApplicationThread.DEBUG_ON; 4925 app.debugging = true; 4926 if (mDebugTransient) { 4927 mDebugApp = mOrigDebugApp; 4928 mWaitForDebugger = mOrigWaitForDebugger; 4929 } 4930 } 4931 String profileFile = app.instrumentationProfileFile; 4932 ParcelFileDescriptor profileFd = null; 4933 boolean profileAutoStop = false; 4934 if (mProfileApp != null && mProfileApp.equals(processName)) { 4935 mProfileProc = app; 4936 profileFile = mProfileFile; 4937 profileFd = mProfileFd; 4938 profileAutoStop = mAutoStopProfiler; 4939 } 4940 boolean enableOpenGlTrace = false; 4941 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4942 enableOpenGlTrace = true; 4943 mOpenGlTraceApp = null; 4944 } 4945 4946 // If the app is being launched for restore or full backup, set it up specially 4947 boolean isRestrictedBackupMode = false; 4948 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4949 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4950 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4951 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4952 } 4953 4954 ensurePackageDexOpt(app.instrumentationInfo != null 4955 ? app.instrumentationInfo.packageName 4956 : app.info.packageName); 4957 if (app.instrumentationClass != null) { 4958 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4959 } 4960 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4961 + processName + " with config " + mConfiguration); 4962 ApplicationInfo appInfo = app.instrumentationInfo != null 4963 ? app.instrumentationInfo : app.info; 4964 app.compat = compatibilityInfoForPackageLocked(appInfo); 4965 if (profileFd != null) { 4966 profileFd = profileFd.dup(); 4967 } 4968 thread.bindApplication(processName, appInfo, providers, 4969 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4970 app.instrumentationArguments, app.instrumentationWatcher, 4971 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4972 isRestrictedBackupMode || !normalMode, app.persistent, 4973 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4974 mCoreSettingsObserver.getCoreSettingsLocked()); 4975 updateLruProcessLocked(app, false, null); 4976 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4977 } catch (Exception e) { 4978 // todo: Yikes! What should we do? For now we will try to 4979 // start another process, but that could easily get us in 4980 // an infinite loop of restarting processes... 4981 Slog.w(TAG, "Exception thrown during bind!", e); 4982 4983 app.resetPackageList(mProcessStats); 4984 app.unlinkDeathRecipient(); 4985 startProcessLocked(app, "bind fail", processName); 4986 return false; 4987 } 4988 4989 // Remove this record from the list of starting applications. 4990 mPersistentStartingProcesses.remove(app); 4991 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 4992 "Attach application locked removing on hold: " + app); 4993 mProcessesOnHold.remove(app); 4994 4995 boolean badApp = false; 4996 boolean didSomething = false; 4997 4998 // See if the top visible activity is waiting to run in this process... 4999 if (normalMode) { 5000 try { 5001 if (mStackSupervisor.attachApplicationLocked(app)) { 5002 didSomething = true; 5003 } 5004 } catch (Exception e) { 5005 badApp = true; 5006 } 5007 } 5008 5009 // Find any services that should be running in this process... 5010 if (!badApp) { 5011 try { 5012 didSomething |= mServices.attachApplicationLocked(app, processName); 5013 } catch (Exception e) { 5014 badApp = true; 5015 } 5016 } 5017 5018 // Check if a next-broadcast receiver is in this process... 5019 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5020 try { 5021 didSomething |= sendPendingBroadcastsLocked(app); 5022 } catch (Exception e) { 5023 // If the app died trying to launch the receiver we declare it 'bad' 5024 badApp = true; 5025 } 5026 } 5027 5028 // Check whether the next backup agent is in this process... 5029 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5030 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5031 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5032 try { 5033 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5034 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5035 mBackupTarget.backupMode); 5036 } catch (Exception e) { 5037 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5038 e.printStackTrace(); 5039 } 5040 } 5041 5042 if (badApp) { 5043 // todo: Also need to kill application to deal with all 5044 // kinds of exceptions. 5045 handleAppDiedLocked(app, false, true); 5046 return false; 5047 } 5048 5049 if (!didSomething) { 5050 updateOomAdjLocked(); 5051 } 5052 5053 return true; 5054 } 5055 5056 @Override 5057 public final void attachApplication(IApplicationThread thread) { 5058 synchronized (this) { 5059 int callingPid = Binder.getCallingPid(); 5060 final long origId = Binder.clearCallingIdentity(); 5061 attachApplicationLocked(thread, callingPid); 5062 Binder.restoreCallingIdentity(origId); 5063 } 5064 } 5065 5066 @Override 5067 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5068 final long origId = Binder.clearCallingIdentity(); 5069 synchronized (this) { 5070 ActivityStack stack = ActivityRecord.getStackLocked(token); 5071 if (stack != null) { 5072 ActivityRecord r = 5073 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5074 if (stopProfiling) { 5075 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5076 try { 5077 mProfileFd.close(); 5078 } catch (IOException e) { 5079 } 5080 clearProfilerLocked(); 5081 } 5082 } 5083 } 5084 } 5085 Binder.restoreCallingIdentity(origId); 5086 } 5087 5088 void enableScreenAfterBoot() { 5089 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5090 SystemClock.uptimeMillis()); 5091 mWindowManager.enableScreenAfterBoot(); 5092 5093 synchronized (this) { 5094 updateEventDispatchingLocked(); 5095 } 5096 } 5097 5098 @Override 5099 public void showBootMessage(final CharSequence msg, final boolean always) { 5100 enforceNotIsolatedCaller("showBootMessage"); 5101 mWindowManager.showBootMessage(msg, always); 5102 } 5103 5104 @Override 5105 public void dismissKeyguardOnNextActivity() { 5106 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5107 final long token = Binder.clearCallingIdentity(); 5108 try { 5109 synchronized (this) { 5110 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5111 if (mLockScreenShown) { 5112 mLockScreenShown = false; 5113 comeOutOfSleepIfNeededLocked(); 5114 } 5115 mStackSupervisor.setDismissKeyguard(true); 5116 } 5117 } finally { 5118 Binder.restoreCallingIdentity(token); 5119 } 5120 } 5121 5122 final void finishBooting() { 5123 IntentFilter pkgFilter = new IntentFilter(); 5124 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5125 pkgFilter.addDataScheme("package"); 5126 mContext.registerReceiver(new BroadcastReceiver() { 5127 @Override 5128 public void onReceive(Context context, Intent intent) { 5129 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5130 if (pkgs != null) { 5131 for (String pkg : pkgs) { 5132 synchronized (ActivityManagerService.this) { 5133 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5134 "finished booting")) { 5135 setResultCode(Activity.RESULT_OK); 5136 return; 5137 } 5138 } 5139 } 5140 } 5141 } 5142 }, pkgFilter); 5143 5144 synchronized (this) { 5145 // Ensure that any processes we had put on hold are now started 5146 // up. 5147 final int NP = mProcessesOnHold.size(); 5148 if (NP > 0) { 5149 ArrayList<ProcessRecord> procs = 5150 new ArrayList<ProcessRecord>(mProcessesOnHold); 5151 for (int ip=0; ip<NP; ip++) { 5152 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5153 + procs.get(ip)); 5154 startProcessLocked(procs.get(ip), "on-hold", null); 5155 } 5156 } 5157 5158 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5159 // Start looking for apps that are abusing wake locks. 5160 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5161 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5162 // Tell anyone interested that we are done booting! 5163 SystemProperties.set("sys.boot_completed", "1"); 5164 SystemProperties.set("dev.bootcomplete", "1"); 5165 for (int i=0; i<mStartedUsers.size(); i++) { 5166 UserStartedState uss = mStartedUsers.valueAt(i); 5167 if (uss.mState == UserStartedState.STATE_BOOTING) { 5168 uss.mState = UserStartedState.STATE_RUNNING; 5169 final int userId = mStartedUsers.keyAt(i); 5170 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5171 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5172 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5173 broadcastIntentLocked(null, null, intent, null, 5174 new IIntentReceiver.Stub() { 5175 @Override 5176 public void performReceive(Intent intent, int resultCode, 5177 String data, Bundle extras, boolean ordered, 5178 boolean sticky, int sendingUser) { 5179 synchronized (ActivityManagerService.this) { 5180 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5181 true, false); 5182 } 5183 } 5184 }, 5185 0, null, null, 5186 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5187 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5188 userId); 5189 } 5190 } 5191 scheduleStartRelatedUsersLocked(); 5192 } 5193 } 5194 } 5195 5196 final void ensureBootCompleted() { 5197 boolean booting; 5198 boolean enableScreen; 5199 synchronized (this) { 5200 booting = mBooting; 5201 mBooting = false; 5202 enableScreen = !mBooted; 5203 mBooted = true; 5204 } 5205 5206 if (booting) { 5207 finishBooting(); 5208 } 5209 5210 if (enableScreen) { 5211 enableScreenAfterBoot(); 5212 } 5213 } 5214 5215 @Override 5216 public final void activityResumed(IBinder token) { 5217 final long origId = Binder.clearCallingIdentity(); 5218 synchronized(this) { 5219 ActivityStack stack = ActivityRecord.getStackLocked(token); 5220 if (stack != null) { 5221 ActivityRecord.activityResumedLocked(token); 5222 } 5223 } 5224 Binder.restoreCallingIdentity(origId); 5225 } 5226 5227 @Override 5228 public final void activityPaused(IBinder token) { 5229 final long origId = Binder.clearCallingIdentity(); 5230 synchronized(this) { 5231 ActivityStack stack = ActivityRecord.getStackLocked(token); 5232 if (stack != null) { 5233 stack.activityPausedLocked(token, false); 5234 } 5235 } 5236 Binder.restoreCallingIdentity(origId); 5237 } 5238 5239 @Override 5240 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5241 CharSequence description) { 5242 if (localLOGV) Slog.v( 5243 TAG, "Activity stopped: token=" + token); 5244 5245 // Refuse possible leaked file descriptors 5246 if (icicle != null && icicle.hasFileDescriptors()) { 5247 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5248 } 5249 5250 ActivityRecord r = null; 5251 5252 final long origId = Binder.clearCallingIdentity(); 5253 5254 synchronized (this) { 5255 r = ActivityRecord.isInStackLocked(token); 5256 if (r != null) { 5257 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5258 } 5259 } 5260 5261 if (r != null) { 5262 sendPendingThumbnail(r, null, null, null, false); 5263 } 5264 5265 trimApplications(); 5266 5267 Binder.restoreCallingIdentity(origId); 5268 } 5269 5270 @Override 5271 public final void activityDestroyed(IBinder token) { 5272 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5273 synchronized (this) { 5274 ActivityStack stack = ActivityRecord.getStackLocked(token); 5275 if (stack != null) { 5276 stack.activityDestroyedLocked(token); 5277 } 5278 } 5279 } 5280 5281 @Override 5282 public String getCallingPackage(IBinder token) { 5283 synchronized (this) { 5284 ActivityRecord r = getCallingRecordLocked(token); 5285 return r != null ? r.info.packageName : null; 5286 } 5287 } 5288 5289 @Override 5290 public ComponentName getCallingActivity(IBinder token) { 5291 synchronized (this) { 5292 ActivityRecord r = getCallingRecordLocked(token); 5293 return r != null ? r.intent.getComponent() : null; 5294 } 5295 } 5296 5297 private ActivityRecord getCallingRecordLocked(IBinder token) { 5298 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5299 if (r == null) { 5300 return null; 5301 } 5302 return r.resultTo; 5303 } 5304 5305 @Override 5306 public ComponentName getActivityClassForToken(IBinder token) { 5307 synchronized(this) { 5308 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5309 if (r == null) { 5310 return null; 5311 } 5312 return r.intent.getComponent(); 5313 } 5314 } 5315 5316 @Override 5317 public String getPackageForToken(IBinder token) { 5318 synchronized(this) { 5319 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5320 if (r == null) { 5321 return null; 5322 } 5323 return r.packageName; 5324 } 5325 } 5326 5327 @Override 5328 public IIntentSender getIntentSender(int type, 5329 String packageName, IBinder token, String resultWho, 5330 int requestCode, Intent[] intents, String[] resolvedTypes, 5331 int flags, Bundle options, int userId) { 5332 enforceNotIsolatedCaller("getIntentSender"); 5333 // Refuse possible leaked file descriptors 5334 if (intents != null) { 5335 if (intents.length < 1) { 5336 throw new IllegalArgumentException("Intents array length must be >= 1"); 5337 } 5338 for (int i=0; i<intents.length; i++) { 5339 Intent intent = intents[i]; 5340 if (intent != null) { 5341 if (intent.hasFileDescriptors()) { 5342 throw new IllegalArgumentException("File descriptors passed in Intent"); 5343 } 5344 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5345 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5346 throw new IllegalArgumentException( 5347 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5348 } 5349 intents[i] = new Intent(intent); 5350 } 5351 } 5352 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5353 throw new IllegalArgumentException( 5354 "Intent array length does not match resolvedTypes length"); 5355 } 5356 } 5357 if (options != null) { 5358 if (options.hasFileDescriptors()) { 5359 throw new IllegalArgumentException("File descriptors passed in options"); 5360 } 5361 } 5362 5363 synchronized(this) { 5364 int callingUid = Binder.getCallingUid(); 5365 int origUserId = userId; 5366 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5367 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5368 "getIntentSender", null); 5369 if (origUserId == UserHandle.USER_CURRENT) { 5370 // We don't want to evaluate this until the pending intent is 5371 // actually executed. However, we do want to always do the 5372 // security checking for it above. 5373 userId = UserHandle.USER_CURRENT; 5374 } 5375 try { 5376 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5377 int uid = AppGlobals.getPackageManager() 5378 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5379 if (!UserHandle.isSameApp(callingUid, uid)) { 5380 String msg = "Permission Denial: getIntentSender() from pid=" 5381 + Binder.getCallingPid() 5382 + ", uid=" + Binder.getCallingUid() 5383 + ", (need uid=" + uid + ")" 5384 + " is not allowed to send as package " + packageName; 5385 Slog.w(TAG, msg); 5386 throw new SecurityException(msg); 5387 } 5388 } 5389 5390 return getIntentSenderLocked(type, packageName, callingUid, userId, 5391 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5392 5393 } catch (RemoteException e) { 5394 throw new SecurityException(e); 5395 } 5396 } 5397 } 5398 5399 IIntentSender getIntentSenderLocked(int type, String packageName, 5400 int callingUid, int userId, IBinder token, String resultWho, 5401 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5402 Bundle options) { 5403 if (DEBUG_MU) 5404 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5405 ActivityRecord activity = null; 5406 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5407 activity = ActivityRecord.isInStackLocked(token); 5408 if (activity == null) { 5409 return null; 5410 } 5411 if (activity.finishing) { 5412 return null; 5413 } 5414 } 5415 5416 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5417 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5418 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5419 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5420 |PendingIntent.FLAG_UPDATE_CURRENT); 5421 5422 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5423 type, packageName, activity, resultWho, 5424 requestCode, intents, resolvedTypes, flags, options, userId); 5425 WeakReference<PendingIntentRecord> ref; 5426 ref = mIntentSenderRecords.get(key); 5427 PendingIntentRecord rec = ref != null ? ref.get() : null; 5428 if (rec != null) { 5429 if (!cancelCurrent) { 5430 if (updateCurrent) { 5431 if (rec.key.requestIntent != null) { 5432 rec.key.requestIntent.replaceExtras(intents != null ? 5433 intents[intents.length - 1] : null); 5434 } 5435 if (intents != null) { 5436 intents[intents.length-1] = rec.key.requestIntent; 5437 rec.key.allIntents = intents; 5438 rec.key.allResolvedTypes = resolvedTypes; 5439 } else { 5440 rec.key.allIntents = null; 5441 rec.key.allResolvedTypes = null; 5442 } 5443 } 5444 return rec; 5445 } 5446 rec.canceled = true; 5447 mIntentSenderRecords.remove(key); 5448 } 5449 if (noCreate) { 5450 return rec; 5451 } 5452 rec = new PendingIntentRecord(this, key, callingUid); 5453 mIntentSenderRecords.put(key, rec.ref); 5454 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5455 if (activity.pendingResults == null) { 5456 activity.pendingResults 5457 = new HashSet<WeakReference<PendingIntentRecord>>(); 5458 } 5459 activity.pendingResults.add(rec.ref); 5460 } 5461 return rec; 5462 } 5463 5464 @Override 5465 public void cancelIntentSender(IIntentSender sender) { 5466 if (!(sender instanceof PendingIntentRecord)) { 5467 return; 5468 } 5469 synchronized(this) { 5470 PendingIntentRecord rec = (PendingIntentRecord)sender; 5471 try { 5472 int uid = AppGlobals.getPackageManager() 5473 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5474 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5475 String msg = "Permission Denial: cancelIntentSender() from pid=" 5476 + Binder.getCallingPid() 5477 + ", uid=" + Binder.getCallingUid() 5478 + " is not allowed to cancel packges " 5479 + rec.key.packageName; 5480 Slog.w(TAG, msg); 5481 throw new SecurityException(msg); 5482 } 5483 } catch (RemoteException e) { 5484 throw new SecurityException(e); 5485 } 5486 cancelIntentSenderLocked(rec, true); 5487 } 5488 } 5489 5490 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5491 rec.canceled = true; 5492 mIntentSenderRecords.remove(rec.key); 5493 if (cleanActivity && rec.key.activity != null) { 5494 rec.key.activity.pendingResults.remove(rec.ref); 5495 } 5496 } 5497 5498 @Override 5499 public String getPackageForIntentSender(IIntentSender pendingResult) { 5500 if (!(pendingResult instanceof PendingIntentRecord)) { 5501 return null; 5502 } 5503 try { 5504 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5505 return res.key.packageName; 5506 } catch (ClassCastException e) { 5507 } 5508 return null; 5509 } 5510 5511 @Override 5512 public int getUidForIntentSender(IIntentSender sender) { 5513 if (sender instanceof PendingIntentRecord) { 5514 try { 5515 PendingIntentRecord res = (PendingIntentRecord)sender; 5516 return res.uid; 5517 } catch (ClassCastException e) { 5518 } 5519 } 5520 return -1; 5521 } 5522 5523 @Override 5524 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5525 if (!(pendingResult instanceof PendingIntentRecord)) { 5526 return false; 5527 } 5528 try { 5529 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5530 if (res.key.allIntents == null) { 5531 return false; 5532 } 5533 for (int i=0; i<res.key.allIntents.length; i++) { 5534 Intent intent = res.key.allIntents[i]; 5535 if (intent.getPackage() != null && intent.getComponent() != null) { 5536 return false; 5537 } 5538 } 5539 return true; 5540 } catch (ClassCastException e) { 5541 } 5542 return false; 5543 } 5544 5545 @Override 5546 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5547 if (!(pendingResult instanceof PendingIntentRecord)) { 5548 return false; 5549 } 5550 try { 5551 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5552 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5553 return true; 5554 } 5555 return false; 5556 } catch (ClassCastException e) { 5557 } 5558 return false; 5559 } 5560 5561 @Override 5562 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5563 if (!(pendingResult instanceof PendingIntentRecord)) { 5564 return null; 5565 } 5566 try { 5567 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5568 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5569 } catch (ClassCastException e) { 5570 } 5571 return null; 5572 } 5573 5574 @Override 5575 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5576 if (!(pendingResult instanceof PendingIntentRecord)) { 5577 return null; 5578 } 5579 try { 5580 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5581 Intent intent = res.key.requestIntent; 5582 if (intent != null) { 5583 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5584 || res.lastTagPrefix.equals(prefix))) { 5585 return res.lastTag; 5586 } 5587 res.lastTagPrefix = prefix; 5588 StringBuilder sb = new StringBuilder(128); 5589 if (prefix != null) { 5590 sb.append(prefix); 5591 } 5592 if (intent.getAction() != null) { 5593 sb.append(intent.getAction()); 5594 } else if (intent.getComponent() != null) { 5595 intent.getComponent().appendShortString(sb); 5596 } else { 5597 sb.append("?"); 5598 } 5599 return res.lastTag = sb.toString(); 5600 } 5601 } catch (ClassCastException e) { 5602 } 5603 return null; 5604 } 5605 5606 @Override 5607 public void setProcessLimit(int max) { 5608 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5609 "setProcessLimit()"); 5610 synchronized (this) { 5611 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5612 mProcessLimitOverride = max; 5613 } 5614 trimApplications(); 5615 } 5616 5617 @Override 5618 public int getProcessLimit() { 5619 synchronized (this) { 5620 return mProcessLimitOverride; 5621 } 5622 } 5623 5624 void foregroundTokenDied(ForegroundToken token) { 5625 synchronized (ActivityManagerService.this) { 5626 synchronized (mPidsSelfLocked) { 5627 ForegroundToken cur 5628 = mForegroundProcesses.get(token.pid); 5629 if (cur != token) { 5630 return; 5631 } 5632 mForegroundProcesses.remove(token.pid); 5633 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5634 if (pr == null) { 5635 return; 5636 } 5637 pr.forcingToForeground = null; 5638 updateProcessForegroundLocked(pr, false, false); 5639 } 5640 updateOomAdjLocked(); 5641 } 5642 } 5643 5644 @Override 5645 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5646 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5647 "setProcessForeground()"); 5648 synchronized(this) { 5649 boolean changed = false; 5650 5651 synchronized (mPidsSelfLocked) { 5652 ProcessRecord pr = mPidsSelfLocked.get(pid); 5653 if (pr == null && isForeground) { 5654 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5655 return; 5656 } 5657 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5658 if (oldToken != null) { 5659 oldToken.token.unlinkToDeath(oldToken, 0); 5660 mForegroundProcesses.remove(pid); 5661 if (pr != null) { 5662 pr.forcingToForeground = null; 5663 } 5664 changed = true; 5665 } 5666 if (isForeground && token != null) { 5667 ForegroundToken newToken = new ForegroundToken() { 5668 @Override 5669 public void binderDied() { 5670 foregroundTokenDied(this); 5671 } 5672 }; 5673 newToken.pid = pid; 5674 newToken.token = token; 5675 try { 5676 token.linkToDeath(newToken, 0); 5677 mForegroundProcesses.put(pid, newToken); 5678 pr.forcingToForeground = token; 5679 changed = true; 5680 } catch (RemoteException e) { 5681 // If the process died while doing this, we will later 5682 // do the cleanup with the process death link. 5683 } 5684 } 5685 } 5686 5687 if (changed) { 5688 updateOomAdjLocked(); 5689 } 5690 } 5691 } 5692 5693 // ========================================================= 5694 // PERMISSIONS 5695 // ========================================================= 5696 5697 static class PermissionController extends IPermissionController.Stub { 5698 ActivityManagerService mActivityManagerService; 5699 PermissionController(ActivityManagerService activityManagerService) { 5700 mActivityManagerService = activityManagerService; 5701 } 5702 5703 @Override 5704 public boolean checkPermission(String permission, int pid, int uid) { 5705 return mActivityManagerService.checkPermission(permission, pid, 5706 uid) == PackageManager.PERMISSION_GRANTED; 5707 } 5708 } 5709 5710 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5711 @Override 5712 public int checkComponentPermission(String permission, int pid, int uid, 5713 int owningUid, boolean exported) { 5714 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5715 owningUid, exported); 5716 } 5717 5718 @Override 5719 public Object getAMSLock() { 5720 return ActivityManagerService.this; 5721 } 5722 } 5723 5724 /** 5725 * This can be called with or without the global lock held. 5726 */ 5727 int checkComponentPermission(String permission, int pid, int uid, 5728 int owningUid, boolean exported) { 5729 // We might be performing an operation on behalf of an indirect binder 5730 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5731 // client identity accordingly before proceeding. 5732 Identity tlsIdentity = sCallerIdentity.get(); 5733 if (tlsIdentity != null) { 5734 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5735 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5736 uid = tlsIdentity.uid; 5737 pid = tlsIdentity.pid; 5738 } 5739 5740 if (pid == MY_PID) { 5741 return PackageManager.PERMISSION_GRANTED; 5742 } 5743 5744 return ActivityManager.checkComponentPermission(permission, uid, 5745 owningUid, exported); 5746 } 5747 5748 /** 5749 * As the only public entry point for permissions checking, this method 5750 * can enforce the semantic that requesting a check on a null global 5751 * permission is automatically denied. (Internally a null permission 5752 * string is used when calling {@link #checkComponentPermission} in cases 5753 * when only uid-based security is needed.) 5754 * 5755 * This can be called with or without the global lock held. 5756 */ 5757 @Override 5758 public int checkPermission(String permission, int pid, int uid) { 5759 if (permission == null) { 5760 return PackageManager.PERMISSION_DENIED; 5761 } 5762 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5763 } 5764 5765 /** 5766 * Binder IPC calls go through the public entry point. 5767 * This can be called with or without the global lock held. 5768 */ 5769 int checkCallingPermission(String permission) { 5770 return checkPermission(permission, 5771 Binder.getCallingPid(), 5772 UserHandle.getAppId(Binder.getCallingUid())); 5773 } 5774 5775 /** 5776 * This can be called with or without the global lock held. 5777 */ 5778 void enforceCallingPermission(String permission, String func) { 5779 if (checkCallingPermission(permission) 5780 == PackageManager.PERMISSION_GRANTED) { 5781 return; 5782 } 5783 5784 String msg = "Permission Denial: " + func + " from pid=" 5785 + Binder.getCallingPid() 5786 + ", uid=" + Binder.getCallingUid() 5787 + " requires " + permission; 5788 Slog.w(TAG, msg); 5789 throw new SecurityException(msg); 5790 } 5791 5792 /** 5793 * Determine if UID is holding permissions required to access {@link Uri} in 5794 * the given {@link ProviderInfo}. Final permission checking is always done 5795 * in {@link ContentProvider}. 5796 */ 5797 private final boolean checkHoldingPermissionsLocked( 5798 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5799 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5800 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5801 5802 if (pi.applicationInfo.uid == uid) { 5803 return true; 5804 } else if (!pi.exported) { 5805 return false; 5806 } 5807 5808 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5809 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5810 try { 5811 // check if target holds top-level <provider> permissions 5812 if (!readMet && pi.readPermission != null 5813 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5814 readMet = true; 5815 } 5816 if (!writeMet && pi.writePermission != null 5817 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5818 writeMet = true; 5819 } 5820 5821 // track if unprotected read/write is allowed; any denied 5822 // <path-permission> below removes this ability 5823 boolean allowDefaultRead = pi.readPermission == null; 5824 boolean allowDefaultWrite = pi.writePermission == null; 5825 5826 // check if target holds any <path-permission> that match uri 5827 final PathPermission[] pps = pi.pathPermissions; 5828 if (pps != null) { 5829 final String path = uri.getPath(); 5830 int i = pps.length; 5831 while (i > 0 && (!readMet || !writeMet)) { 5832 i--; 5833 PathPermission pp = pps[i]; 5834 if (pp.match(path)) { 5835 if (!readMet) { 5836 final String pprperm = pp.getReadPermission(); 5837 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5838 + pprperm + " for " + pp.getPath() 5839 + ": match=" + pp.match(path) 5840 + " check=" + pm.checkUidPermission(pprperm, uid)); 5841 if (pprperm != null) { 5842 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5843 readMet = true; 5844 } else { 5845 allowDefaultRead = false; 5846 } 5847 } 5848 } 5849 if (!writeMet) { 5850 final String ppwperm = pp.getWritePermission(); 5851 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5852 + ppwperm + " for " + pp.getPath() 5853 + ": match=" + pp.match(path) 5854 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5855 if (ppwperm != null) { 5856 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5857 writeMet = true; 5858 } else { 5859 allowDefaultWrite = false; 5860 } 5861 } 5862 } 5863 } 5864 } 5865 } 5866 5867 // grant unprotected <provider> read/write, if not blocked by 5868 // <path-permission> above 5869 if (allowDefaultRead) readMet = true; 5870 if (allowDefaultWrite) writeMet = true; 5871 5872 } catch (RemoteException e) { 5873 return false; 5874 } 5875 5876 return readMet && writeMet; 5877 } 5878 5879 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5880 ProviderInfo pi = null; 5881 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5882 if (cpr != null) { 5883 pi = cpr.info; 5884 } else { 5885 try { 5886 pi = AppGlobals.getPackageManager().resolveContentProvider( 5887 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5888 } catch (RemoteException ex) { 5889 } 5890 } 5891 return pi; 5892 } 5893 5894 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5895 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5896 if (targetUris != null) { 5897 return targetUris.get(uri); 5898 } else { 5899 return null; 5900 } 5901 } 5902 5903 private UriPermission findOrCreateUriPermissionLocked( 5904 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5905 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5906 if (targetUris == null) { 5907 targetUris = Maps.newArrayMap(); 5908 mGrantedUriPermissions.put(targetUid, targetUris); 5909 } 5910 5911 UriPermission perm = targetUris.get(uri); 5912 if (perm == null) { 5913 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5914 targetUris.put(uri, perm); 5915 } 5916 5917 return perm; 5918 } 5919 5920 private final boolean checkUriPermissionLocked( 5921 Uri uri, int uid, int modeFlags, int minStrength) { 5922 // Root gets to do everything. 5923 if (uid == 0) { 5924 return true; 5925 } 5926 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5927 if (perms == null) return false; 5928 UriPermission perm = perms.get(uri); 5929 if (perm == null) return false; 5930 return perm.getStrength(modeFlags) >= minStrength; 5931 } 5932 5933 @Override 5934 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5935 enforceNotIsolatedCaller("checkUriPermission"); 5936 5937 // Another redirected-binder-call permissions check as in 5938 // {@link checkComponentPermission}. 5939 Identity tlsIdentity = sCallerIdentity.get(); 5940 if (tlsIdentity != null) { 5941 uid = tlsIdentity.uid; 5942 pid = tlsIdentity.pid; 5943 } 5944 5945 // Our own process gets to do everything. 5946 if (pid == MY_PID) { 5947 return PackageManager.PERMISSION_GRANTED; 5948 } 5949 synchronized(this) { 5950 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5951 ? PackageManager.PERMISSION_GRANTED 5952 : PackageManager.PERMISSION_DENIED; 5953 } 5954 } 5955 5956 /** 5957 * Check if the targetPkg can be granted permission to access uri by 5958 * the callingUid using the given modeFlags. Throws a security exception 5959 * if callingUid is not allowed to do this. Returns the uid of the target 5960 * if the URI permission grant should be performed; returns -1 if it is not 5961 * needed (for example targetPkg already has permission to access the URI). 5962 * If you already know the uid of the target, you can supply it in 5963 * lastTargetUid else set that to -1. 5964 */ 5965 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5966 Uri uri, int modeFlags, int lastTargetUid) { 5967 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5968 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5969 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5970 if (modeFlags == 0) { 5971 return -1; 5972 } 5973 5974 if (targetPkg != null) { 5975 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5976 "Checking grant " + targetPkg + " permission to " + uri); 5977 } 5978 5979 final IPackageManager pm = AppGlobals.getPackageManager(); 5980 5981 // If this is not a content: uri, we can't do anything with it. 5982 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5983 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5984 "Can't grant URI permission for non-content URI: " + uri); 5985 return -1; 5986 } 5987 5988 final String authority = uri.getAuthority(); 5989 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 5990 if (pi == null) { 5991 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 5992 return -1; 5993 } 5994 5995 int targetUid = lastTargetUid; 5996 if (targetUid < 0 && targetPkg != null) { 5997 try { 5998 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 5999 if (targetUid < 0) { 6000 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6001 "Can't grant URI permission no uid for: " + targetPkg); 6002 return -1; 6003 } 6004 } catch (RemoteException ex) { 6005 return -1; 6006 } 6007 } 6008 6009 if (targetUid >= 0) { 6010 // First... does the target actually need this permission? 6011 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6012 // No need to grant the target this permission. 6013 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6014 "Target " + targetPkg + " already has full permission to " + uri); 6015 return -1; 6016 } 6017 } else { 6018 // First... there is no target package, so can anyone access it? 6019 boolean allowed = pi.exported; 6020 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6021 if (pi.readPermission != null) { 6022 allowed = false; 6023 } 6024 } 6025 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6026 if (pi.writePermission != null) { 6027 allowed = false; 6028 } 6029 } 6030 if (allowed) { 6031 return -1; 6032 } 6033 } 6034 6035 // Second... is the provider allowing granting of URI permissions? 6036 if (!pi.grantUriPermissions) { 6037 throw new SecurityException("Provider " + pi.packageName 6038 + "/" + pi.name 6039 + " does not allow granting of Uri permissions (uri " 6040 + uri + ")"); 6041 } 6042 if (pi.uriPermissionPatterns != null) { 6043 final int N = pi.uriPermissionPatterns.length; 6044 boolean allowed = false; 6045 for (int i=0; i<N; i++) { 6046 if (pi.uriPermissionPatterns[i] != null 6047 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6048 allowed = true; 6049 break; 6050 } 6051 } 6052 if (!allowed) { 6053 throw new SecurityException("Provider " + pi.packageName 6054 + "/" + pi.name 6055 + " does not allow granting of permission to path of Uri " 6056 + uri); 6057 } 6058 } 6059 6060 // Third... does the caller itself have permission to access 6061 // this uri? 6062 if (callingUid != Process.myUid()) { 6063 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6064 // Require they hold a strong enough Uri permission 6065 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6066 : UriPermission.STRENGTH_OWNED; 6067 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6068 throw new SecurityException("Uid " + callingUid 6069 + " does not have permission to uri " + uri); 6070 } 6071 } 6072 } 6073 6074 return targetUid; 6075 } 6076 6077 @Override 6078 public int checkGrantUriPermission(int callingUid, String targetPkg, 6079 Uri uri, int modeFlags) { 6080 enforceNotIsolatedCaller("checkGrantUriPermission"); 6081 synchronized(this) { 6082 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6083 } 6084 } 6085 6086 void grantUriPermissionUncheckedLocked( 6087 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6088 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6089 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6090 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6091 if (modeFlags == 0) { 6092 return; 6093 } 6094 6095 // So here we are: the caller has the assumed permission 6096 // to the uri, and the target doesn't. Let's now give this to 6097 // the target. 6098 6099 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6100 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6101 6102 final String authority = uri.getAuthority(); 6103 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6104 if (pi == null) { 6105 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6106 return; 6107 } 6108 6109 final UriPermission perm = findOrCreateUriPermissionLocked( 6110 pi.packageName, targetPkg, targetUid, uri); 6111 perm.grantModes(modeFlags, persistable, owner); 6112 } 6113 6114 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6115 int modeFlags, UriPermissionOwner owner) { 6116 if (targetPkg == null) { 6117 throw new NullPointerException("targetPkg"); 6118 } 6119 6120 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6121 if (targetUid < 0) { 6122 return; 6123 } 6124 6125 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6126 } 6127 6128 static class NeededUriGrants extends ArrayList<Uri> { 6129 final String targetPkg; 6130 final int targetUid; 6131 final int flags; 6132 6133 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6134 this.targetPkg = targetPkg; 6135 this.targetUid = targetUid; 6136 this.flags = flags; 6137 } 6138 } 6139 6140 /** 6141 * Like checkGrantUriPermissionLocked, but takes an Intent. 6142 */ 6143 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6144 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6145 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6146 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6147 + " clip=" + (intent != null ? intent.getClipData() : null) 6148 + " from " + intent + "; flags=0x" 6149 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6150 6151 if (targetPkg == null) { 6152 throw new NullPointerException("targetPkg"); 6153 } 6154 6155 if (intent == null) { 6156 return null; 6157 } 6158 Uri data = intent.getData(); 6159 ClipData clip = intent.getClipData(); 6160 if (data == null && clip == null) { 6161 return null; 6162 } 6163 6164 if (data != null) { 6165 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6166 mode, needed != null ? needed.targetUid : -1); 6167 if (targetUid > 0) { 6168 if (needed == null) { 6169 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6170 } 6171 needed.add(data); 6172 } 6173 } 6174 if (clip != null) { 6175 for (int i=0; i<clip.getItemCount(); i++) { 6176 Uri uri = clip.getItemAt(i).getUri(); 6177 if (uri != null) { 6178 int targetUid = -1; 6179 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6180 mode, needed != null ? needed.targetUid : -1); 6181 if (targetUid > 0) { 6182 if (needed == null) { 6183 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6184 } 6185 needed.add(uri); 6186 } 6187 } else { 6188 Intent clipIntent = clip.getItemAt(i).getIntent(); 6189 if (clipIntent != null) { 6190 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6191 callingUid, targetPkg, clipIntent, mode, needed); 6192 if (newNeeded != null) { 6193 needed = newNeeded; 6194 } 6195 } 6196 } 6197 } 6198 } 6199 6200 return needed; 6201 } 6202 6203 /** 6204 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6205 */ 6206 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6207 UriPermissionOwner owner) { 6208 if (needed != null) { 6209 for (int i=0; i<needed.size(); i++) { 6210 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6211 needed.get(i), needed.flags, owner); 6212 } 6213 } 6214 } 6215 6216 void grantUriPermissionFromIntentLocked(int callingUid, 6217 String targetPkg, Intent intent, UriPermissionOwner owner) { 6218 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6219 intent, intent != null ? intent.getFlags() : 0, null); 6220 if (needed == null) { 6221 return; 6222 } 6223 6224 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6225 } 6226 6227 @Override 6228 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6229 Uri uri, int modeFlags) { 6230 enforceNotIsolatedCaller("grantUriPermission"); 6231 synchronized(this) { 6232 final ProcessRecord r = getRecordForAppLocked(caller); 6233 if (r == null) { 6234 throw new SecurityException("Unable to find app for caller " 6235 + caller 6236 + " when granting permission to uri " + uri); 6237 } 6238 if (targetPkg == null) { 6239 throw new IllegalArgumentException("null target"); 6240 } 6241 if (uri == null) { 6242 throw new IllegalArgumentException("null uri"); 6243 } 6244 6245 // Persistable only supported through Intents 6246 Preconditions.checkFlagsArgument(modeFlags, 6247 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6248 6249 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6250 null); 6251 } 6252 } 6253 6254 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6255 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6256 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6257 ArrayMap<Uri, UriPermission> perms 6258 = mGrantedUriPermissions.get(perm.targetUid); 6259 if (perms != null) { 6260 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6261 "Removing " + perm.targetUid + " permission to " + perm.uri); 6262 perms.remove(perm.uri); 6263 if (perms.size() == 0) { 6264 mGrantedUriPermissions.remove(perm.targetUid); 6265 } 6266 } 6267 } 6268 } 6269 6270 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6271 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6272 6273 final IPackageManager pm = AppGlobals.getPackageManager(); 6274 final String authority = uri.getAuthority(); 6275 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6276 if (pi == null) { 6277 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6278 return; 6279 } 6280 6281 // Does the caller have this permission on the URI? 6282 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6283 // Right now, if you are not the original owner of the permission, 6284 // you are not allowed to revoke it. 6285 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6286 throw new SecurityException("Uid " + callingUid 6287 + " does not have permission to uri " + uri); 6288 //} 6289 } 6290 6291 boolean persistChanged = false; 6292 6293 // Go through all of the permissions and remove any that match. 6294 final List<String> SEGMENTS = uri.getPathSegments(); 6295 if (SEGMENTS != null) { 6296 final int NS = SEGMENTS.size(); 6297 int N = mGrantedUriPermissions.size(); 6298 for (int i=0; i<N; i++) { 6299 ArrayMap<Uri, UriPermission> perms 6300 = mGrantedUriPermissions.valueAt(i); 6301 Iterator<UriPermission> it = perms.values().iterator(); 6302 toploop: 6303 while (it.hasNext()) { 6304 UriPermission perm = it.next(); 6305 Uri targetUri = perm.uri; 6306 if (!authority.equals(targetUri.getAuthority())) { 6307 continue; 6308 } 6309 List<String> targetSegments = targetUri.getPathSegments(); 6310 if (targetSegments == null) { 6311 continue; 6312 } 6313 if (targetSegments.size() < NS) { 6314 continue; 6315 } 6316 for (int j=0; j<NS; j++) { 6317 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6318 continue toploop; 6319 } 6320 } 6321 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6322 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6323 persistChanged |= perm.clearModes(modeFlags, true); 6324 if (perm.modeFlags == 0) { 6325 it.remove(); 6326 } 6327 } 6328 if (perms.size() == 0) { 6329 mGrantedUriPermissions.remove( 6330 mGrantedUriPermissions.keyAt(i)); 6331 N--; 6332 i--; 6333 } 6334 } 6335 } 6336 6337 if (persistChanged) { 6338 schedulePersistUriGrants(); 6339 } 6340 } 6341 6342 @Override 6343 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6344 int modeFlags) { 6345 enforceNotIsolatedCaller("revokeUriPermission"); 6346 synchronized(this) { 6347 final ProcessRecord r = getRecordForAppLocked(caller); 6348 if (r == null) { 6349 throw new SecurityException("Unable to find app for caller " 6350 + caller 6351 + " when revoking permission to uri " + uri); 6352 } 6353 if (uri == null) { 6354 Slog.w(TAG, "revokeUriPermission: null uri"); 6355 return; 6356 } 6357 6358 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6359 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6360 if (modeFlags == 0) { 6361 return; 6362 } 6363 6364 final IPackageManager pm = AppGlobals.getPackageManager(); 6365 final String authority = uri.getAuthority(); 6366 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6367 if (pi == null) { 6368 Slog.w(TAG, "No content provider found for permission revoke: " 6369 + uri.toSafeString()); 6370 return; 6371 } 6372 6373 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6374 } 6375 } 6376 6377 /** 6378 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6379 * given package. 6380 * 6381 * @param packageName Package name to match, or {@code null} to apply to all 6382 * packages. 6383 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6384 * to all users. 6385 * @param persistable If persistable grants should be removed. 6386 */ 6387 private void removeUriPermissionsForPackageLocked( 6388 String packageName, int userHandle, boolean persistable) { 6389 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6390 throw new IllegalArgumentException("Must narrow by either package or user"); 6391 } 6392 6393 boolean persistChanged = false; 6394 6395 final int size = mGrantedUriPermissions.size(); 6396 for (int i = 0; i < size; i++) { 6397 // Only inspect grants matching user 6398 if (userHandle == UserHandle.USER_ALL 6399 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6400 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6401 .values().iterator(); 6402 while (it.hasNext()) { 6403 final UriPermission perm = it.next(); 6404 6405 // Only inspect grants matching package 6406 if (packageName == null || perm.sourcePkg.equals(packageName) 6407 || perm.targetPkg.equals(packageName)) { 6408 persistChanged |= perm.clearModes(~0, persistable); 6409 6410 // Only remove when no modes remain; any persisted grants 6411 // will keep this alive. 6412 if (perm.modeFlags == 0) { 6413 it.remove(); 6414 } 6415 } 6416 } 6417 } 6418 } 6419 6420 if (persistChanged) { 6421 schedulePersistUriGrants(); 6422 } 6423 } 6424 6425 @Override 6426 public IBinder newUriPermissionOwner(String name) { 6427 enforceNotIsolatedCaller("newUriPermissionOwner"); 6428 synchronized(this) { 6429 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6430 return owner.getExternalTokenLocked(); 6431 } 6432 } 6433 6434 @Override 6435 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6436 Uri uri, int modeFlags) { 6437 synchronized(this) { 6438 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6439 if (owner == null) { 6440 throw new IllegalArgumentException("Unknown owner: " + token); 6441 } 6442 if (fromUid != Binder.getCallingUid()) { 6443 if (Binder.getCallingUid() != Process.myUid()) { 6444 // Only system code can grant URI permissions on behalf 6445 // of other users. 6446 throw new SecurityException("nice try"); 6447 } 6448 } 6449 if (targetPkg == null) { 6450 throw new IllegalArgumentException("null target"); 6451 } 6452 if (uri == null) { 6453 throw new IllegalArgumentException("null uri"); 6454 } 6455 6456 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6457 } 6458 } 6459 6460 @Override 6461 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6462 synchronized(this) { 6463 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6464 if (owner == null) { 6465 throw new IllegalArgumentException("Unknown owner: " + token); 6466 } 6467 6468 if (uri == null) { 6469 owner.removeUriPermissionsLocked(mode); 6470 } else { 6471 owner.removeUriPermissionLocked(uri, mode); 6472 } 6473 } 6474 } 6475 6476 private void schedulePersistUriGrants() { 6477 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6478 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6479 10 * DateUtils.SECOND_IN_MILLIS); 6480 } 6481 } 6482 6483 private void writeGrantedUriPermissions() { 6484 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6485 6486 // Snapshot permissions so we can persist without lock 6487 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6488 synchronized (this) { 6489 final int size = mGrantedUriPermissions.size(); 6490 for (int i = 0 ; i < size; i++) { 6491 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6492 if (perm.persistedModeFlags != 0) { 6493 persist.add(perm.snapshot()); 6494 } 6495 } 6496 } 6497 } 6498 6499 FileOutputStream fos = null; 6500 try { 6501 fos = mGrantFile.startWrite(); 6502 6503 XmlSerializer out = new FastXmlSerializer(); 6504 out.setOutput(fos, "utf-8"); 6505 out.startDocument(null, true); 6506 out.startTag(null, TAG_URI_GRANTS); 6507 for (UriPermission.Snapshot perm : persist) { 6508 out.startTag(null, TAG_URI_GRANT); 6509 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6510 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6511 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6512 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6513 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6514 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6515 out.endTag(null, TAG_URI_GRANT); 6516 } 6517 out.endTag(null, TAG_URI_GRANTS); 6518 out.endDocument(); 6519 6520 mGrantFile.finishWrite(fos); 6521 } catch (IOException e) { 6522 if (fos != null) { 6523 mGrantFile.failWrite(fos); 6524 } 6525 } 6526 } 6527 6528 private void readGrantedUriPermissionsLocked() { 6529 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6530 6531 final long now = System.currentTimeMillis(); 6532 6533 FileInputStream fis = null; 6534 try { 6535 fis = mGrantFile.openRead(); 6536 final XmlPullParser in = Xml.newPullParser(); 6537 in.setInput(fis, null); 6538 6539 int type; 6540 while ((type = in.next()) != END_DOCUMENT) { 6541 final String tag = in.getName(); 6542 if (type == START_TAG) { 6543 if (TAG_URI_GRANT.equals(tag)) { 6544 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6545 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6546 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6547 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6548 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6549 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6550 6551 // Sanity check that provider still belongs to source package 6552 final ProviderInfo pi = getProviderInfoLocked( 6553 uri.getAuthority(), userHandle); 6554 if (pi != null && sourcePkg.equals(pi.packageName)) { 6555 int targetUid = -1; 6556 try { 6557 targetUid = AppGlobals.getPackageManager() 6558 .getPackageUid(targetPkg, userHandle); 6559 } catch (RemoteException e) { 6560 } 6561 if (targetUid != -1) { 6562 final UriPermission perm = findOrCreateUriPermissionLocked( 6563 sourcePkg, targetPkg, targetUid, uri); 6564 perm.initPersistedModes(modeFlags, createdTime); 6565 } 6566 } else { 6567 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6568 + " but instead found " + pi); 6569 } 6570 } 6571 } 6572 } 6573 } catch (FileNotFoundException e) { 6574 // Missing grants is okay 6575 } catch (IOException e) { 6576 Log.wtf(TAG, "Failed reading Uri grants", e); 6577 } catch (XmlPullParserException e) { 6578 Log.wtf(TAG, "Failed reading Uri grants", e); 6579 } finally { 6580 IoUtils.closeQuietly(fis); 6581 } 6582 } 6583 6584 @Override 6585 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6586 enforceNotIsolatedCaller("takePersistableUriPermission"); 6587 6588 Preconditions.checkFlagsArgument(modeFlags, 6589 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6590 6591 synchronized (this) { 6592 final int callingUid = Binder.getCallingUid(); 6593 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6594 if (perm == null) { 6595 throw new SecurityException("No permission grant found for UID " + callingUid 6596 + " and Uri " + uri.toSafeString()); 6597 } 6598 6599 boolean persistChanged = perm.takePersistableModes(modeFlags); 6600 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6601 6602 if (persistChanged) { 6603 schedulePersistUriGrants(); 6604 } 6605 } 6606 } 6607 6608 @Override 6609 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6610 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6611 6612 Preconditions.checkFlagsArgument(modeFlags, 6613 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6614 6615 synchronized (this) { 6616 final int callingUid = Binder.getCallingUid(); 6617 6618 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6619 if (perm == null) { 6620 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6621 + uri.toSafeString()); 6622 return; 6623 } 6624 6625 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6626 removeUriPermissionIfNeededLocked(perm); 6627 if (persistChanged) { 6628 schedulePersistUriGrants(); 6629 } 6630 } 6631 } 6632 6633 /** 6634 * Prune any older {@link UriPermission} for the given UID until outstanding 6635 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6636 * 6637 * @return if any mutations occured that require persisting. 6638 */ 6639 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6640 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6641 if (perms == null) return false; 6642 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6643 6644 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6645 for (UriPermission perm : perms.values()) { 6646 if (perm.persistedModeFlags != 0) { 6647 persisted.add(perm); 6648 } 6649 } 6650 6651 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6652 if (trimCount <= 0) return false; 6653 6654 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6655 for (int i = 0; i < trimCount; i++) { 6656 final UriPermission perm = persisted.get(i); 6657 6658 if (DEBUG_URI_PERMISSION) { 6659 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6660 } 6661 6662 perm.releasePersistableModes(~0); 6663 removeUriPermissionIfNeededLocked(perm); 6664 } 6665 6666 return true; 6667 } 6668 6669 @Override 6670 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6671 String packageName, boolean incoming) { 6672 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6673 Preconditions.checkNotNull(packageName, "packageName"); 6674 6675 final int callingUid = Binder.getCallingUid(); 6676 final IPackageManager pm = AppGlobals.getPackageManager(); 6677 try { 6678 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6679 if (packageUid != callingUid) { 6680 throw new SecurityException( 6681 "Package " + packageName + " does not belong to calling UID " + callingUid); 6682 } 6683 } catch (RemoteException e) { 6684 throw new SecurityException("Failed to verify package name ownership"); 6685 } 6686 6687 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6688 synchronized (this) { 6689 if (incoming) { 6690 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6691 if (perms == null) { 6692 Slog.w(TAG, "No permission grants found for " + packageName); 6693 } else { 6694 final int size = perms.size(); 6695 for (int i = 0; i < size; i++) { 6696 final UriPermission perm = perms.valueAt(i); 6697 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6698 result.add(perm.buildPersistedPublicApiObject()); 6699 } 6700 } 6701 } 6702 } else { 6703 final int size = mGrantedUriPermissions.size(); 6704 for (int i = 0; i < size; i++) { 6705 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6706 final int permsSize = perms.size(); 6707 for (int j = 0; j < permsSize; j++) { 6708 final UriPermission perm = perms.valueAt(j); 6709 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6710 result.add(perm.buildPersistedPublicApiObject()); 6711 } 6712 } 6713 } 6714 } 6715 } 6716 return new ParceledListSlice<android.content.UriPermission>(result); 6717 } 6718 6719 @Override 6720 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6721 synchronized (this) { 6722 ProcessRecord app = 6723 who != null ? getRecordForAppLocked(who) : null; 6724 if (app == null) return; 6725 6726 Message msg = Message.obtain(); 6727 msg.what = WAIT_FOR_DEBUGGER_MSG; 6728 msg.obj = app; 6729 msg.arg1 = waiting ? 1 : 0; 6730 mHandler.sendMessage(msg); 6731 } 6732 } 6733 6734 @Override 6735 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6736 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6737 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6738 outInfo.availMem = Process.getFreeMemory(); 6739 outInfo.totalMem = Process.getTotalMemory(); 6740 outInfo.threshold = homeAppMem; 6741 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6742 outInfo.hiddenAppThreshold = cachedAppMem; 6743 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6744 ProcessList.SERVICE_ADJ); 6745 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6746 ProcessList.VISIBLE_APP_ADJ); 6747 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6748 ProcessList.FOREGROUND_APP_ADJ); 6749 } 6750 6751 // ========================================================= 6752 // TASK MANAGEMENT 6753 // ========================================================= 6754 6755 @Override 6756 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6757 IThumbnailReceiver receiver) { 6758 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6759 6760 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6761 ActivityRecord topRecord = null; 6762 6763 synchronized(this) { 6764 if (localLOGV) Slog.v( 6765 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6766 + ", receiver=" + receiver); 6767 6768 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6769 != PackageManager.PERMISSION_GRANTED) { 6770 if (receiver != null) { 6771 // If the caller wants to wait for pending thumbnails, 6772 // it ain't gonna get them. 6773 try { 6774 receiver.finished(); 6775 } catch (RemoteException ex) { 6776 } 6777 } 6778 String msg = "Permission Denial: getTasks() from pid=" 6779 + Binder.getCallingPid() 6780 + ", uid=" + Binder.getCallingUid() 6781 + " requires " + android.Manifest.permission.GET_TASKS; 6782 Slog.w(TAG, msg); 6783 throw new SecurityException(msg); 6784 } 6785 6786 // TODO: Improve with MRU list from all ActivityStacks. 6787 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6788 6789 if (!pending.pendingRecords.isEmpty()) { 6790 mPendingThumbnails.add(pending); 6791 } 6792 } 6793 6794 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6795 6796 if (topRecord != null) { 6797 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6798 try { 6799 IApplicationThread topThumbnail = topRecord.app.thread; 6800 topThumbnail.requestThumbnail(topRecord.appToken); 6801 } catch (Exception e) { 6802 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6803 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6804 } 6805 } 6806 6807 if (pending == null && receiver != null) { 6808 // In this case all thumbnails were available and the client 6809 // is being asked to be told when the remaining ones come in... 6810 // which is unusually, since the top-most currently running 6811 // activity should never have a canned thumbnail! Oh well. 6812 try { 6813 receiver.finished(); 6814 } catch (RemoteException ex) { 6815 } 6816 } 6817 6818 return list; 6819 } 6820 6821 TaskRecord getMostRecentTask() { 6822 return mRecentTasks.get(0); 6823 } 6824 6825 @Override 6826 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6827 int flags, int userId) { 6828 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6829 false, true, "getRecentTasks", null); 6830 6831 synchronized (this) { 6832 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6833 "getRecentTasks()"); 6834 final boolean detailed = checkCallingPermission( 6835 android.Manifest.permission.GET_DETAILED_TASKS) 6836 == PackageManager.PERMISSION_GRANTED; 6837 6838 IPackageManager pm = AppGlobals.getPackageManager(); 6839 6840 final int N = mRecentTasks.size(); 6841 ArrayList<ActivityManager.RecentTaskInfo> res 6842 = new ArrayList<ActivityManager.RecentTaskInfo>( 6843 maxNum < N ? maxNum : N); 6844 for (int i=0; i<N && maxNum > 0; i++) { 6845 TaskRecord tr = mRecentTasks.get(i); 6846 // Only add calling user's recent tasks 6847 if (tr.userId != userId) continue; 6848 // Return the entry if desired by the caller. We always return 6849 // the first entry, because callers always expect this to be the 6850 // foreground app. We may filter others if the caller has 6851 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6852 // we should exclude the entry. 6853 6854 if (i == 0 6855 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6856 || (tr.intent == null) 6857 || ((tr.intent.getFlags() 6858 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6859 ActivityManager.RecentTaskInfo rti 6860 = new ActivityManager.RecentTaskInfo(); 6861 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6862 rti.persistentId = tr.taskId; 6863 rti.baseIntent = new Intent( 6864 tr.intent != null ? tr.intent : tr.affinityIntent); 6865 if (!detailed) { 6866 rti.baseIntent.replaceExtras((Bundle)null); 6867 } 6868 rti.origActivity = tr.origActivity; 6869 rti.description = tr.lastDescription; 6870 rti.stackId = tr.stack.mStackId; 6871 6872 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6873 // Check whether this activity is currently available. 6874 try { 6875 if (rti.origActivity != null) { 6876 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6877 == null) { 6878 continue; 6879 } 6880 } else if (rti.baseIntent != null) { 6881 if (pm.queryIntentActivities(rti.baseIntent, 6882 null, 0, userId) == null) { 6883 continue; 6884 } 6885 } 6886 } catch (RemoteException e) { 6887 // Will never happen. 6888 } 6889 } 6890 6891 res.add(rti); 6892 maxNum--; 6893 } 6894 } 6895 return res; 6896 } 6897 } 6898 6899 private TaskRecord recentTaskForIdLocked(int id) { 6900 final int N = mRecentTasks.size(); 6901 for (int i=0; i<N; i++) { 6902 TaskRecord tr = mRecentTasks.get(i); 6903 if (tr.taskId == id) { 6904 return tr; 6905 } 6906 } 6907 return null; 6908 } 6909 6910 @Override 6911 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6912 synchronized (this) { 6913 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6914 "getTaskThumbnails()"); 6915 TaskRecord tr = recentTaskForIdLocked(id); 6916 if (tr != null) { 6917 return tr.getTaskThumbnailsLocked(); 6918 } 6919 } 6920 return null; 6921 } 6922 6923 @Override 6924 public Bitmap getTaskTopThumbnail(int id) { 6925 synchronized (this) { 6926 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6927 "getTaskTopThumbnail()"); 6928 TaskRecord tr = recentTaskForIdLocked(id); 6929 if (tr != null) { 6930 return tr.getTaskTopThumbnailLocked(); 6931 } 6932 } 6933 return null; 6934 } 6935 6936 @Override 6937 public boolean removeSubTask(int taskId, int subTaskIndex) { 6938 synchronized (this) { 6939 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6940 "removeSubTask()"); 6941 long ident = Binder.clearCallingIdentity(); 6942 try { 6943 TaskRecord tr = recentTaskForIdLocked(taskId); 6944 if (tr != null) { 6945 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6946 } 6947 return false; 6948 } finally { 6949 Binder.restoreCallingIdentity(ident); 6950 } 6951 } 6952 } 6953 6954 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6955 if (!pr.killedByAm) { 6956 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6957 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6958 pr.processName, pr.setAdj, reason); 6959 pr.killedByAm = true; 6960 Process.killProcessQuiet(pr.pid); 6961 } 6962 } 6963 6964 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6965 tr.disposeThumbnail(); 6966 mRecentTasks.remove(tr); 6967 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6968 Intent baseIntent = new Intent( 6969 tr.intent != null ? tr.intent : tr.affinityIntent); 6970 ComponentName component = baseIntent.getComponent(); 6971 if (component == null) { 6972 Slog.w(TAG, "Now component for base intent of task: " + tr); 6973 return; 6974 } 6975 6976 // Find any running services associated with this app. 6977 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 6978 6979 if (killProcesses) { 6980 // Find any running processes associated with this app. 6981 final String pkg = component.getPackageName(); 6982 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 6983 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 6984 for (int i=0; i<pmap.size(); i++) { 6985 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 6986 for (int j=0; j<uids.size(); j++) { 6987 ProcessRecord proc = uids.valueAt(j); 6988 if (proc.userId != tr.userId) { 6989 continue; 6990 } 6991 if (!proc.pkgList.containsKey(pkg)) { 6992 continue; 6993 } 6994 procs.add(proc); 6995 } 6996 } 6997 6998 // Kill the running processes. 6999 for (int i=0; i<procs.size(); i++) { 7000 ProcessRecord pr = procs.get(i); 7001 if (pr == mHomeProcess) { 7002 // Don't kill the home process along with tasks from the same package. 7003 continue; 7004 } 7005 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7006 killUnneededProcessLocked(pr, "remove task"); 7007 } else { 7008 pr.waitingToKill = "remove task"; 7009 } 7010 } 7011 } 7012 } 7013 7014 @Override 7015 public boolean removeTask(int taskId, int flags) { 7016 synchronized (this) { 7017 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7018 "removeTask()"); 7019 long ident = Binder.clearCallingIdentity(); 7020 try { 7021 TaskRecord tr = recentTaskForIdLocked(taskId); 7022 if (tr != null) { 7023 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7024 if (r != null) { 7025 cleanUpRemovedTaskLocked(tr, flags); 7026 return true; 7027 } 7028 if (tr.mActivities.size() == 0) { 7029 // Caller is just removing a recent task that is 7030 // not actively running. That is easy! 7031 cleanUpRemovedTaskLocked(tr, flags); 7032 return true; 7033 } 7034 Slog.w(TAG, "removeTask: task " + taskId 7035 + " does not have activities to remove, " 7036 + " but numActivities=" + tr.numActivities 7037 + ": " + tr); 7038 } 7039 } finally { 7040 Binder.restoreCallingIdentity(ident); 7041 } 7042 } 7043 return false; 7044 } 7045 7046 /** 7047 * TODO: Add mController hook 7048 */ 7049 @Override 7050 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7051 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7052 "moveTaskToFront()"); 7053 7054 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7055 synchronized(this) { 7056 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7057 Binder.getCallingUid(), "Task to front")) { 7058 ActivityOptions.abort(options); 7059 return; 7060 } 7061 final long origId = Binder.clearCallingIdentity(); 7062 try { 7063 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7064 if (task == null) { 7065 return; 7066 } 7067 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7068 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7069 return; 7070 } 7071 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7072 } finally { 7073 Binder.restoreCallingIdentity(origId); 7074 } 7075 ActivityOptions.abort(options); 7076 } 7077 } 7078 7079 @Override 7080 public void moveTaskToBack(int taskId) { 7081 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7082 "moveTaskToBack()"); 7083 7084 synchronized(this) { 7085 TaskRecord tr = recentTaskForIdLocked(taskId); 7086 if (tr != null) { 7087 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7088 ActivityStack stack = tr.stack; 7089 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7090 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7091 Binder.getCallingUid(), "Task to back")) { 7092 return; 7093 } 7094 } 7095 final long origId = Binder.clearCallingIdentity(); 7096 try { 7097 stack.moveTaskToBackLocked(taskId, null); 7098 } finally { 7099 Binder.restoreCallingIdentity(origId); 7100 } 7101 } 7102 } 7103 } 7104 7105 /** 7106 * Moves an activity, and all of the other activities within the same task, to the bottom 7107 * of the history stack. The activity's order within the task is unchanged. 7108 * 7109 * @param token A reference to the activity we wish to move 7110 * @param nonRoot If false then this only works if the activity is the root 7111 * of a task; if true it will work for any activity in a task. 7112 * @return Returns true if the move completed, false if not. 7113 */ 7114 @Override 7115 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7116 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7117 synchronized(this) { 7118 final long origId = Binder.clearCallingIdentity(); 7119 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7120 if (taskId >= 0) { 7121 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7122 } 7123 Binder.restoreCallingIdentity(origId); 7124 } 7125 return false; 7126 } 7127 7128 @Override 7129 public void moveTaskBackwards(int task) { 7130 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7131 "moveTaskBackwards()"); 7132 7133 synchronized(this) { 7134 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7135 Binder.getCallingUid(), "Task backwards")) { 7136 return; 7137 } 7138 final long origId = Binder.clearCallingIdentity(); 7139 moveTaskBackwardsLocked(task); 7140 Binder.restoreCallingIdentity(origId); 7141 } 7142 } 7143 7144 private final void moveTaskBackwardsLocked(int task) { 7145 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7146 } 7147 7148 @Override 7149 public IBinder getHomeActivityToken() throws RemoteException { 7150 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7151 "getHomeActivityToken()"); 7152 synchronized (this) { 7153 return mStackSupervisor.getHomeActivityToken(); 7154 } 7155 } 7156 7157 @Override 7158 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7159 IActivityContainerCallback callback) throws RemoteException { 7160 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7161 "createActivityContainer()"); 7162 synchronized (this) { 7163 if (parentActivityToken == null) { 7164 throw new IllegalArgumentException("parent token must not be null"); 7165 } 7166 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7167 if (r == null) { 7168 return null; 7169 } 7170 return mStackSupervisor.createActivityContainer(r, callback); 7171 } 7172 } 7173 7174 @Override 7175 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7176 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7177 "deleteActivityContainer()"); 7178 synchronized (this) { 7179 mStackSupervisor.deleteActivityContainer(container); 7180 } 7181 } 7182 7183 @Override 7184 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7185 throws RemoteException { 7186 synchronized (this) { 7187 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7188 if (stack != null) { 7189 return stack.mActivityContainer; 7190 } 7191 return null; 7192 } 7193 } 7194 7195 @Override 7196 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7197 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7198 "moveTaskToStack()"); 7199 if (stackId == HOME_STACK_ID) { 7200 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7201 new RuntimeException("here").fillInStackTrace()); 7202 } 7203 synchronized (this) { 7204 long ident = Binder.clearCallingIdentity(); 7205 try { 7206 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7207 + stackId + " toTop=" + toTop); 7208 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7209 } finally { 7210 Binder.restoreCallingIdentity(ident); 7211 } 7212 } 7213 } 7214 7215 @Override 7216 public void resizeStack(int stackBoxId, Rect bounds) { 7217 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7218 "resizeStackBox()"); 7219 long ident = Binder.clearCallingIdentity(); 7220 try { 7221 mWindowManager.resizeStack(stackBoxId, bounds); 7222 } finally { 7223 Binder.restoreCallingIdentity(ident); 7224 } 7225 } 7226 7227 @Override 7228 public List<StackInfo> getAllStackInfos() { 7229 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7230 "getAllStackInfos()"); 7231 long ident = Binder.clearCallingIdentity(); 7232 try { 7233 synchronized (this) { 7234 return mStackSupervisor.getAllStackInfosLocked(); 7235 } 7236 } finally { 7237 Binder.restoreCallingIdentity(ident); 7238 } 7239 } 7240 7241 @Override 7242 public StackInfo getStackInfo(int stackId) { 7243 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7244 "getStackInfo()"); 7245 long ident = Binder.clearCallingIdentity(); 7246 try { 7247 synchronized (this) { 7248 return mStackSupervisor.getStackInfoLocked(stackId); 7249 } 7250 } finally { 7251 Binder.restoreCallingIdentity(ident); 7252 } 7253 } 7254 7255 @Override 7256 public boolean isInHomeStack(int taskId) { 7257 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7258 "getStackInfo()"); 7259 long ident = Binder.clearCallingIdentity(); 7260 try { 7261 synchronized (this) { 7262 TaskRecord tr = recentTaskForIdLocked(taskId); 7263 if (tr != null) { 7264 return tr.stack.isHomeStack(); 7265 } 7266 } 7267 } finally { 7268 Binder.restoreCallingIdentity(ident); 7269 } 7270 return false; 7271 } 7272 7273 @Override 7274 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7275 synchronized(this) { 7276 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7277 } 7278 } 7279 7280 private boolean isLockTaskAuthorized(ComponentName name) { 7281// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7282// "startLockTaskMode()"); 7283// DevicePolicyManager dpm = (DevicePolicyManager) 7284// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7285// return dpm != null && dpm.isLockTaskPermitted(name); 7286 return true; 7287 } 7288 7289 private void startLockTaskMode(TaskRecord task) { 7290 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7291 return; 7292 } 7293 long ident = Binder.clearCallingIdentity(); 7294 try { 7295 synchronized (this) { 7296 // Since we lost lock on task, make sure it is still there. 7297 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7298 if (task != null) { 7299 mStackSupervisor.setLockTaskModeLocked(task); 7300 } 7301 } 7302 } finally { 7303 Binder.restoreCallingIdentity(ident); 7304 } 7305 } 7306 7307 @Override 7308 public void startLockTaskMode(int taskId) { 7309 long ident = Binder.clearCallingIdentity(); 7310 try { 7311 final TaskRecord task; 7312 synchronized (this) { 7313 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7314 } 7315 if (task != null) { 7316 startLockTaskMode(task); 7317 } 7318 } finally { 7319 Binder.restoreCallingIdentity(ident); 7320 } 7321 } 7322 7323 @Override 7324 public void startLockTaskMode(IBinder token) { 7325 long ident = Binder.clearCallingIdentity(); 7326 try { 7327 final TaskRecord task; 7328 synchronized (this) { 7329 final ActivityRecord r = ActivityRecord.forToken(token); 7330 if (r == null) { 7331 return; 7332 } 7333 task = r.task; 7334 } 7335 if (task != null) { 7336 startLockTaskMode(task); 7337 } 7338 } finally { 7339 Binder.restoreCallingIdentity(ident); 7340 } 7341 } 7342 7343 @Override 7344 public void stopLockTaskMode() { 7345// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7346// "stopLockTaskMode()"); 7347 synchronized (this) { 7348 mStackSupervisor.setLockTaskModeLocked(null); 7349 } 7350 } 7351 7352 @Override 7353 public boolean isInLockTaskMode() { 7354 synchronized (this) { 7355 return mStackSupervisor.isInLockTaskMode(); 7356 } 7357 } 7358 7359 // ========================================================= 7360 // THUMBNAILS 7361 // ========================================================= 7362 7363 public void reportThumbnail(IBinder token, 7364 Bitmap thumbnail, CharSequence description) { 7365 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7366 final long origId = Binder.clearCallingIdentity(); 7367 sendPendingThumbnail(null, token, thumbnail, description, true); 7368 Binder.restoreCallingIdentity(origId); 7369 } 7370 7371 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7372 Bitmap thumbnail, CharSequence description, boolean always) { 7373 TaskRecord task; 7374 ArrayList<PendingThumbnailsRecord> receivers = null; 7375 7376 //System.out.println("Send pending thumbnail: " + r); 7377 7378 synchronized(this) { 7379 if (r == null) { 7380 r = ActivityRecord.isInStackLocked(token); 7381 if (r == null) { 7382 return; 7383 } 7384 } 7385 if (thumbnail == null && r.thumbHolder != null) { 7386 thumbnail = r.thumbHolder.lastThumbnail; 7387 description = r.thumbHolder.lastDescription; 7388 } 7389 if (thumbnail == null && !always) { 7390 // If there is no thumbnail, and this entry is not actually 7391 // going away, then abort for now and pick up the next 7392 // thumbnail we get. 7393 return; 7394 } 7395 task = r.task; 7396 7397 int N = mPendingThumbnails.size(); 7398 int i=0; 7399 while (i<N) { 7400 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7401 //System.out.println("Looking in " + pr.pendingRecords); 7402 if (pr.pendingRecords.remove(r)) { 7403 if (receivers == null) { 7404 receivers = new ArrayList<PendingThumbnailsRecord>(); 7405 } 7406 receivers.add(pr); 7407 if (pr.pendingRecords.size() == 0) { 7408 pr.finished = true; 7409 mPendingThumbnails.remove(i); 7410 N--; 7411 continue; 7412 } 7413 } 7414 i++; 7415 } 7416 } 7417 7418 if (receivers != null) { 7419 final int N = receivers.size(); 7420 for (int i=0; i<N; i++) { 7421 try { 7422 PendingThumbnailsRecord pr = receivers.get(i); 7423 pr.receiver.newThumbnail( 7424 task != null ? task.taskId : -1, thumbnail, description); 7425 if (pr.finished) { 7426 pr.receiver.finished(); 7427 } 7428 } catch (Exception e) { 7429 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7430 } 7431 } 7432 } 7433 } 7434 7435 // ========================================================= 7436 // CONTENT PROVIDERS 7437 // ========================================================= 7438 7439 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7440 List<ProviderInfo> providers = null; 7441 try { 7442 providers = AppGlobals.getPackageManager(). 7443 queryContentProviders(app.processName, app.uid, 7444 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7445 } catch (RemoteException ex) { 7446 } 7447 if (DEBUG_MU) 7448 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7449 int userId = app.userId; 7450 if (providers != null) { 7451 int N = providers.size(); 7452 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7453 for (int i=0; i<N; i++) { 7454 ProviderInfo cpi = 7455 (ProviderInfo)providers.get(i); 7456 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7457 cpi.name, cpi.flags); 7458 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7459 // This is a singleton provider, but a user besides the 7460 // default user is asking to initialize a process it runs 7461 // in... well, no, it doesn't actually run in this process, 7462 // it runs in the process of the default user. Get rid of it. 7463 providers.remove(i); 7464 N--; 7465 i--; 7466 continue; 7467 } 7468 7469 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7470 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7471 if (cpr == null) { 7472 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7473 mProviderMap.putProviderByClass(comp, cpr); 7474 } 7475 if (DEBUG_MU) 7476 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7477 app.pubProviders.put(cpi.name, cpr); 7478 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7479 // Don't add this if it is a platform component that is marked 7480 // to run in multiple processes, because this is actually 7481 // part of the framework so doesn't make sense to track as a 7482 // separate apk in the process. 7483 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7484 } 7485 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7486 } 7487 } 7488 return providers; 7489 } 7490 7491 /** 7492 * Check if {@link ProcessRecord} has a possible chance at accessing the 7493 * given {@link ProviderInfo}. Final permission checking is always done 7494 * in {@link ContentProvider}. 7495 */ 7496 private final String checkContentProviderPermissionLocked( 7497 ProviderInfo cpi, ProcessRecord r) { 7498 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7499 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7500 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7501 cpi.applicationInfo.uid, cpi.exported) 7502 == PackageManager.PERMISSION_GRANTED) { 7503 return null; 7504 } 7505 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7506 cpi.applicationInfo.uid, cpi.exported) 7507 == PackageManager.PERMISSION_GRANTED) { 7508 return null; 7509 } 7510 7511 PathPermission[] pps = cpi.pathPermissions; 7512 if (pps != null) { 7513 int i = pps.length; 7514 while (i > 0) { 7515 i--; 7516 PathPermission pp = pps[i]; 7517 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7518 cpi.applicationInfo.uid, cpi.exported) 7519 == PackageManager.PERMISSION_GRANTED) { 7520 return null; 7521 } 7522 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7523 cpi.applicationInfo.uid, cpi.exported) 7524 == PackageManager.PERMISSION_GRANTED) { 7525 return null; 7526 } 7527 } 7528 } 7529 7530 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7531 if (perms != null) { 7532 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7533 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7534 return null; 7535 } 7536 } 7537 } 7538 7539 String msg; 7540 if (!cpi.exported) { 7541 msg = "Permission Denial: opening provider " + cpi.name 7542 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7543 + ", uid=" + callingUid + ") that is not exported from uid " 7544 + cpi.applicationInfo.uid; 7545 } else { 7546 msg = "Permission Denial: opening provider " + cpi.name 7547 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7548 + ", uid=" + callingUid + ") requires " 7549 + cpi.readPermission + " or " + cpi.writePermission; 7550 } 7551 Slog.w(TAG, msg); 7552 return msg; 7553 } 7554 7555 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7556 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7557 if (r != null) { 7558 for (int i=0; i<r.conProviders.size(); i++) { 7559 ContentProviderConnection conn = r.conProviders.get(i); 7560 if (conn.provider == cpr) { 7561 if (DEBUG_PROVIDER) Slog.v(TAG, 7562 "Adding provider requested by " 7563 + r.processName + " from process " 7564 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7565 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7566 if (stable) { 7567 conn.stableCount++; 7568 conn.numStableIncs++; 7569 } else { 7570 conn.unstableCount++; 7571 conn.numUnstableIncs++; 7572 } 7573 return conn; 7574 } 7575 } 7576 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7577 if (stable) { 7578 conn.stableCount = 1; 7579 conn.numStableIncs = 1; 7580 } else { 7581 conn.unstableCount = 1; 7582 conn.numUnstableIncs = 1; 7583 } 7584 cpr.connections.add(conn); 7585 r.conProviders.add(conn); 7586 return conn; 7587 } 7588 cpr.addExternalProcessHandleLocked(externalProcessToken); 7589 return null; 7590 } 7591 7592 boolean decProviderCountLocked(ContentProviderConnection conn, 7593 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7594 if (conn != null) { 7595 cpr = conn.provider; 7596 if (DEBUG_PROVIDER) Slog.v(TAG, 7597 "Removing provider requested by " 7598 + conn.client.processName + " from process " 7599 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7600 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7601 if (stable) { 7602 conn.stableCount--; 7603 } else { 7604 conn.unstableCount--; 7605 } 7606 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7607 cpr.connections.remove(conn); 7608 conn.client.conProviders.remove(conn); 7609 return true; 7610 } 7611 return false; 7612 } 7613 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7614 return false; 7615 } 7616 7617 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7618 String name, IBinder token, boolean stable, int userId) { 7619 ContentProviderRecord cpr; 7620 ContentProviderConnection conn = null; 7621 ProviderInfo cpi = null; 7622 7623 synchronized(this) { 7624 ProcessRecord r = null; 7625 if (caller != null) { 7626 r = getRecordForAppLocked(caller); 7627 if (r == null) { 7628 throw new SecurityException( 7629 "Unable to find app for caller " + caller 7630 + " (pid=" + Binder.getCallingPid() 7631 + ") when getting content provider " + name); 7632 } 7633 } 7634 7635 // First check if this content provider has been published... 7636 cpr = mProviderMap.getProviderByName(name, userId); 7637 boolean providerRunning = cpr != null; 7638 if (providerRunning) { 7639 cpi = cpr.info; 7640 String msg; 7641 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7642 throw new SecurityException(msg); 7643 } 7644 7645 if (r != null && cpr.canRunHere(r)) { 7646 // This provider has been published or is in the process 7647 // of being published... but it is also allowed to run 7648 // in the caller's process, so don't make a connection 7649 // and just let the caller instantiate its own instance. 7650 ContentProviderHolder holder = cpr.newHolder(null); 7651 // don't give caller the provider object, it needs 7652 // to make its own. 7653 holder.provider = null; 7654 return holder; 7655 } 7656 7657 final long origId = Binder.clearCallingIdentity(); 7658 7659 // In this case the provider instance already exists, so we can 7660 // return it right away. 7661 conn = incProviderCountLocked(r, cpr, token, stable); 7662 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7663 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7664 // If this is a perceptible app accessing the provider, 7665 // make sure to count it as being accessed and thus 7666 // back up on the LRU list. This is good because 7667 // content providers are often expensive to start. 7668 updateLruProcessLocked(cpr.proc, false, null); 7669 } 7670 } 7671 7672 if (cpr.proc != null) { 7673 if (false) { 7674 if (cpr.name.flattenToShortString().equals( 7675 "com.android.providers.calendar/.CalendarProvider2")) { 7676 Slog.v(TAG, "****************** KILLING " 7677 + cpr.name.flattenToShortString()); 7678 Process.killProcess(cpr.proc.pid); 7679 } 7680 } 7681 boolean success = updateOomAdjLocked(cpr.proc); 7682 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7683 // NOTE: there is still a race here where a signal could be 7684 // pending on the process even though we managed to update its 7685 // adj level. Not sure what to do about this, but at least 7686 // the race is now smaller. 7687 if (!success) { 7688 // Uh oh... it looks like the provider's process 7689 // has been killed on us. We need to wait for a new 7690 // process to be started, and make sure its death 7691 // doesn't kill our process. 7692 Slog.i(TAG, 7693 "Existing provider " + cpr.name.flattenToShortString() 7694 + " is crashing; detaching " + r); 7695 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7696 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7697 if (!lastRef) { 7698 // This wasn't the last ref our process had on 7699 // the provider... we have now been killed, bail. 7700 return null; 7701 } 7702 providerRunning = false; 7703 conn = null; 7704 } 7705 } 7706 7707 Binder.restoreCallingIdentity(origId); 7708 } 7709 7710 boolean singleton; 7711 if (!providerRunning) { 7712 try { 7713 cpi = AppGlobals.getPackageManager(). 7714 resolveContentProvider(name, 7715 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7716 } catch (RemoteException ex) { 7717 } 7718 if (cpi == null) { 7719 return null; 7720 } 7721 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7722 cpi.name, cpi.flags); 7723 if (singleton) { 7724 userId = 0; 7725 } 7726 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7727 7728 String msg; 7729 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7730 throw new SecurityException(msg); 7731 } 7732 7733 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7734 && !cpi.processName.equals("system")) { 7735 // If this content provider does not run in the system 7736 // process, and the system is not yet ready to run other 7737 // processes, then fail fast instead of hanging. 7738 throw new IllegalArgumentException( 7739 "Attempt to launch content provider before system ready"); 7740 } 7741 7742 // Make sure that the user who owns this provider is started. If not, 7743 // we don't want to allow it to run. 7744 if (mStartedUsers.get(userId) == null) { 7745 Slog.w(TAG, "Unable to launch app " 7746 + cpi.applicationInfo.packageName + "/" 7747 + cpi.applicationInfo.uid + " for provider " 7748 + name + ": user " + userId + " is stopped"); 7749 return null; 7750 } 7751 7752 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7753 cpr = mProviderMap.getProviderByClass(comp, userId); 7754 final boolean firstClass = cpr == null; 7755 if (firstClass) { 7756 try { 7757 ApplicationInfo ai = 7758 AppGlobals.getPackageManager(). 7759 getApplicationInfo( 7760 cpi.applicationInfo.packageName, 7761 STOCK_PM_FLAGS, userId); 7762 if (ai == null) { 7763 Slog.w(TAG, "No package info for content provider " 7764 + cpi.name); 7765 return null; 7766 } 7767 ai = getAppInfoForUser(ai, userId); 7768 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7769 } catch (RemoteException ex) { 7770 // pm is in same process, this will never happen. 7771 } 7772 } 7773 7774 if (r != null && cpr.canRunHere(r)) { 7775 // If this is a multiprocess provider, then just return its 7776 // info and allow the caller to instantiate it. Only do 7777 // this if the provider is the same user as the caller's 7778 // process, or can run as root (so can be in any process). 7779 return cpr.newHolder(null); 7780 } 7781 7782 if (DEBUG_PROVIDER) { 7783 RuntimeException e = new RuntimeException("here"); 7784 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7785 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7786 } 7787 7788 // This is single process, and our app is now connecting to it. 7789 // See if we are already in the process of launching this 7790 // provider. 7791 final int N = mLaunchingProviders.size(); 7792 int i; 7793 for (i=0; i<N; i++) { 7794 if (mLaunchingProviders.get(i) == cpr) { 7795 break; 7796 } 7797 } 7798 7799 // If the provider is not already being launched, then get it 7800 // started. 7801 if (i >= N) { 7802 final long origId = Binder.clearCallingIdentity(); 7803 7804 try { 7805 // Content provider is now in use, its package can't be stopped. 7806 try { 7807 AppGlobals.getPackageManager().setPackageStoppedState( 7808 cpr.appInfo.packageName, false, userId); 7809 } catch (RemoteException e) { 7810 } catch (IllegalArgumentException e) { 7811 Slog.w(TAG, "Failed trying to unstop package " 7812 + cpr.appInfo.packageName + ": " + e); 7813 } 7814 7815 // Use existing process if already started 7816 ProcessRecord proc = getProcessRecordLocked( 7817 cpi.processName, cpr.appInfo.uid, false); 7818 if (proc != null && proc.thread != null) { 7819 if (DEBUG_PROVIDER) { 7820 Slog.d(TAG, "Installing in existing process " + proc); 7821 } 7822 proc.pubProviders.put(cpi.name, cpr); 7823 try { 7824 proc.thread.scheduleInstallProvider(cpi); 7825 } catch (RemoteException e) { 7826 } 7827 } else { 7828 proc = startProcessLocked(cpi.processName, 7829 cpr.appInfo, false, 0, "content provider", 7830 new ComponentName(cpi.applicationInfo.packageName, 7831 cpi.name), false, false, false); 7832 if (proc == null) { 7833 Slog.w(TAG, "Unable to launch app " 7834 + cpi.applicationInfo.packageName + "/" 7835 + cpi.applicationInfo.uid + " for provider " 7836 + name + ": process is bad"); 7837 return null; 7838 } 7839 } 7840 cpr.launchingApp = proc; 7841 mLaunchingProviders.add(cpr); 7842 } finally { 7843 Binder.restoreCallingIdentity(origId); 7844 } 7845 } 7846 7847 // Make sure the provider is published (the same provider class 7848 // may be published under multiple names). 7849 if (firstClass) { 7850 mProviderMap.putProviderByClass(comp, cpr); 7851 } 7852 7853 mProviderMap.putProviderByName(name, cpr); 7854 conn = incProviderCountLocked(r, cpr, token, stable); 7855 if (conn != null) { 7856 conn.waiting = true; 7857 } 7858 } 7859 } 7860 7861 // Wait for the provider to be published... 7862 synchronized (cpr) { 7863 while (cpr.provider == null) { 7864 if (cpr.launchingApp == null) { 7865 Slog.w(TAG, "Unable to launch app " 7866 + cpi.applicationInfo.packageName + "/" 7867 + cpi.applicationInfo.uid + " for provider " 7868 + name + ": launching app became null"); 7869 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7870 UserHandle.getUserId(cpi.applicationInfo.uid), 7871 cpi.applicationInfo.packageName, 7872 cpi.applicationInfo.uid, name); 7873 return null; 7874 } 7875 try { 7876 if (DEBUG_MU) { 7877 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7878 + cpr.launchingApp); 7879 } 7880 if (conn != null) { 7881 conn.waiting = true; 7882 } 7883 cpr.wait(); 7884 } catch (InterruptedException ex) { 7885 } finally { 7886 if (conn != null) { 7887 conn.waiting = false; 7888 } 7889 } 7890 } 7891 } 7892 return cpr != null ? cpr.newHolder(conn) : null; 7893 } 7894 7895 public final ContentProviderHolder getContentProvider( 7896 IApplicationThread caller, String name, int userId, boolean stable) { 7897 enforceNotIsolatedCaller("getContentProvider"); 7898 if (caller == null) { 7899 String msg = "null IApplicationThread when getting content provider " 7900 + name; 7901 Slog.w(TAG, msg); 7902 throw new SecurityException(msg); 7903 } 7904 7905 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7906 false, true, "getContentProvider", null); 7907 return getContentProviderImpl(caller, name, null, stable, userId); 7908 } 7909 7910 public ContentProviderHolder getContentProviderExternal( 7911 String name, int userId, IBinder token) { 7912 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7913 "Do not have permission in call getContentProviderExternal()"); 7914 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7915 false, true, "getContentProvider", null); 7916 return getContentProviderExternalUnchecked(name, token, userId); 7917 } 7918 7919 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7920 IBinder token, int userId) { 7921 return getContentProviderImpl(null, name, token, true, userId); 7922 } 7923 7924 /** 7925 * Drop a content provider from a ProcessRecord's bookkeeping 7926 */ 7927 public void removeContentProvider(IBinder connection, boolean stable) { 7928 enforceNotIsolatedCaller("removeContentProvider"); 7929 long ident = Binder.clearCallingIdentity(); 7930 try { 7931 synchronized (this) { 7932 ContentProviderConnection conn; 7933 try { 7934 conn = (ContentProviderConnection)connection; 7935 } catch (ClassCastException e) { 7936 String msg ="removeContentProvider: " + connection 7937 + " not a ContentProviderConnection"; 7938 Slog.w(TAG, msg); 7939 throw new IllegalArgumentException(msg); 7940 } 7941 if (conn == null) { 7942 throw new NullPointerException("connection is null"); 7943 } 7944 if (decProviderCountLocked(conn, null, null, stable)) { 7945 updateOomAdjLocked(); 7946 } 7947 } 7948 } finally { 7949 Binder.restoreCallingIdentity(ident); 7950 } 7951 } 7952 7953 public void removeContentProviderExternal(String name, IBinder token) { 7954 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7955 "Do not have permission in call removeContentProviderExternal()"); 7956 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7957 } 7958 7959 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7960 synchronized (this) { 7961 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7962 if(cpr == null) { 7963 //remove from mProvidersByClass 7964 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7965 return; 7966 } 7967 7968 //update content provider record entry info 7969 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7970 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7971 if (localCpr.hasExternalProcessHandles()) { 7972 if (localCpr.removeExternalProcessHandleLocked(token)) { 7973 updateOomAdjLocked(); 7974 } else { 7975 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 7976 + " with no external reference for token: " 7977 + token + "."); 7978 } 7979 } else { 7980 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 7981 + " with no external references."); 7982 } 7983 } 7984 } 7985 7986 public final void publishContentProviders(IApplicationThread caller, 7987 List<ContentProviderHolder> providers) { 7988 if (providers == null) { 7989 return; 7990 } 7991 7992 enforceNotIsolatedCaller("publishContentProviders"); 7993 synchronized (this) { 7994 final ProcessRecord r = getRecordForAppLocked(caller); 7995 if (DEBUG_MU) 7996 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 7997 if (r == null) { 7998 throw new SecurityException( 7999 "Unable to find app for caller " + caller 8000 + " (pid=" + Binder.getCallingPid() 8001 + ") when publishing content providers"); 8002 } 8003 8004 final long origId = Binder.clearCallingIdentity(); 8005 8006 final int N = providers.size(); 8007 for (int i=0; i<N; i++) { 8008 ContentProviderHolder src = providers.get(i); 8009 if (src == null || src.info == null || src.provider == null) { 8010 continue; 8011 } 8012 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8013 if (DEBUG_MU) 8014 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8015 if (dst != null) { 8016 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8017 mProviderMap.putProviderByClass(comp, dst); 8018 String names[] = dst.info.authority.split(";"); 8019 for (int j = 0; j < names.length; j++) { 8020 mProviderMap.putProviderByName(names[j], dst); 8021 } 8022 8023 int NL = mLaunchingProviders.size(); 8024 int j; 8025 for (j=0; j<NL; j++) { 8026 if (mLaunchingProviders.get(j) == dst) { 8027 mLaunchingProviders.remove(j); 8028 j--; 8029 NL--; 8030 } 8031 } 8032 synchronized (dst) { 8033 dst.provider = src.provider; 8034 dst.proc = r; 8035 dst.notifyAll(); 8036 } 8037 updateOomAdjLocked(r); 8038 } 8039 } 8040 8041 Binder.restoreCallingIdentity(origId); 8042 } 8043 } 8044 8045 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8046 ContentProviderConnection conn; 8047 try { 8048 conn = (ContentProviderConnection)connection; 8049 } catch (ClassCastException e) { 8050 String msg ="refContentProvider: " + connection 8051 + " not a ContentProviderConnection"; 8052 Slog.w(TAG, msg); 8053 throw new IllegalArgumentException(msg); 8054 } 8055 if (conn == null) { 8056 throw new NullPointerException("connection is null"); 8057 } 8058 8059 synchronized (this) { 8060 if (stable > 0) { 8061 conn.numStableIncs += stable; 8062 } 8063 stable = conn.stableCount + stable; 8064 if (stable < 0) { 8065 throw new IllegalStateException("stableCount < 0: " + stable); 8066 } 8067 8068 if (unstable > 0) { 8069 conn.numUnstableIncs += unstable; 8070 } 8071 unstable = conn.unstableCount + unstable; 8072 if (unstable < 0) { 8073 throw new IllegalStateException("unstableCount < 0: " + unstable); 8074 } 8075 8076 if ((stable+unstable) <= 0) { 8077 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8078 + stable + " unstable=" + unstable); 8079 } 8080 conn.stableCount = stable; 8081 conn.unstableCount = unstable; 8082 return !conn.dead; 8083 } 8084 } 8085 8086 public void unstableProviderDied(IBinder connection) { 8087 ContentProviderConnection conn; 8088 try { 8089 conn = (ContentProviderConnection)connection; 8090 } catch (ClassCastException e) { 8091 String msg ="refContentProvider: " + connection 8092 + " not a ContentProviderConnection"; 8093 Slog.w(TAG, msg); 8094 throw new IllegalArgumentException(msg); 8095 } 8096 if (conn == null) { 8097 throw new NullPointerException("connection is null"); 8098 } 8099 8100 // Safely retrieve the content provider associated with the connection. 8101 IContentProvider provider; 8102 synchronized (this) { 8103 provider = conn.provider.provider; 8104 } 8105 8106 if (provider == null) { 8107 // Um, yeah, we're way ahead of you. 8108 return; 8109 } 8110 8111 // Make sure the caller is being honest with us. 8112 if (provider.asBinder().pingBinder()) { 8113 // Er, no, still looks good to us. 8114 synchronized (this) { 8115 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8116 + " says " + conn + " died, but we don't agree"); 8117 return; 8118 } 8119 } 8120 8121 // Well look at that! It's dead! 8122 synchronized (this) { 8123 if (conn.provider.provider != provider) { 8124 // But something changed... good enough. 8125 return; 8126 } 8127 8128 ProcessRecord proc = conn.provider.proc; 8129 if (proc == null || proc.thread == null) { 8130 // Seems like the process is already cleaned up. 8131 return; 8132 } 8133 8134 // As far as we're concerned, this is just like receiving a 8135 // death notification... just a bit prematurely. 8136 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8137 + ") early provider death"); 8138 final long ident = Binder.clearCallingIdentity(); 8139 try { 8140 appDiedLocked(proc, proc.pid, proc.thread); 8141 } finally { 8142 Binder.restoreCallingIdentity(ident); 8143 } 8144 } 8145 } 8146 8147 @Override 8148 public void appNotRespondingViaProvider(IBinder connection) { 8149 enforceCallingPermission( 8150 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8151 8152 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8153 if (conn == null) { 8154 Slog.w(TAG, "ContentProviderConnection is null"); 8155 return; 8156 } 8157 8158 final ProcessRecord host = conn.provider.proc; 8159 if (host == null) { 8160 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8161 return; 8162 } 8163 8164 final long token = Binder.clearCallingIdentity(); 8165 try { 8166 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8167 } finally { 8168 Binder.restoreCallingIdentity(token); 8169 } 8170 } 8171 8172 public final void installSystemProviders() { 8173 List<ProviderInfo> providers; 8174 synchronized (this) { 8175 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8176 providers = generateApplicationProvidersLocked(app); 8177 if (providers != null) { 8178 for (int i=providers.size()-1; i>=0; i--) { 8179 ProviderInfo pi = (ProviderInfo)providers.get(i); 8180 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8181 Slog.w(TAG, "Not installing system proc provider " + pi.name 8182 + ": not system .apk"); 8183 providers.remove(i); 8184 } 8185 } 8186 } 8187 } 8188 if (providers != null) { 8189 mSystemThread.installSystemProviders(providers); 8190 } 8191 8192 mCoreSettingsObserver = new CoreSettingsObserver(this); 8193 8194 mUsageStatsService.monitorPackages(); 8195 } 8196 8197 /** 8198 * Allows app to retrieve the MIME type of a URI without having permission 8199 * to access its content provider. 8200 * 8201 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8202 * 8203 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8204 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8205 */ 8206 public String getProviderMimeType(Uri uri, int userId) { 8207 enforceNotIsolatedCaller("getProviderMimeType"); 8208 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8209 userId, false, true, "getProviderMimeType", null); 8210 final String name = uri.getAuthority(); 8211 final long ident = Binder.clearCallingIdentity(); 8212 ContentProviderHolder holder = null; 8213 8214 try { 8215 holder = getContentProviderExternalUnchecked(name, null, userId); 8216 if (holder != null) { 8217 return holder.provider.getType(uri); 8218 } 8219 } catch (RemoteException e) { 8220 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8221 return null; 8222 } finally { 8223 if (holder != null) { 8224 removeContentProviderExternalUnchecked(name, null, userId); 8225 } 8226 Binder.restoreCallingIdentity(ident); 8227 } 8228 8229 return null; 8230 } 8231 8232 // ========================================================= 8233 // GLOBAL MANAGEMENT 8234 // ========================================================= 8235 8236 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8237 boolean isolated) { 8238 String proc = customProcess != null ? customProcess : info.processName; 8239 BatteryStatsImpl.Uid.Proc ps = null; 8240 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8241 int uid = info.uid; 8242 if (isolated) { 8243 int userId = UserHandle.getUserId(uid); 8244 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8245 while (true) { 8246 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8247 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8248 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8249 } 8250 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8251 mNextIsolatedProcessUid++; 8252 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8253 // No process for this uid, use it. 8254 break; 8255 } 8256 stepsLeft--; 8257 if (stepsLeft <= 0) { 8258 return null; 8259 } 8260 } 8261 } 8262 return new ProcessRecord(stats, info, proc, uid); 8263 } 8264 8265 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8266 ProcessRecord app; 8267 if (!isolated) { 8268 app = getProcessRecordLocked(info.processName, info.uid, true); 8269 } else { 8270 app = null; 8271 } 8272 8273 if (app == null) { 8274 app = newProcessRecordLocked(info, null, isolated); 8275 mProcessNames.put(info.processName, app.uid, app); 8276 if (isolated) { 8277 mIsolatedProcesses.put(app.uid, app); 8278 } 8279 updateLruProcessLocked(app, false, null); 8280 updateOomAdjLocked(); 8281 } 8282 8283 // This package really, really can not be stopped. 8284 try { 8285 AppGlobals.getPackageManager().setPackageStoppedState( 8286 info.packageName, false, UserHandle.getUserId(app.uid)); 8287 } catch (RemoteException e) { 8288 } catch (IllegalArgumentException e) { 8289 Slog.w(TAG, "Failed trying to unstop package " 8290 + info.packageName + ": " + e); 8291 } 8292 8293 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8294 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8295 app.persistent = true; 8296 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8297 } 8298 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8299 mPersistentStartingProcesses.add(app); 8300 startProcessLocked(app, "added application", app.processName); 8301 } 8302 8303 return app; 8304 } 8305 8306 public void unhandledBack() { 8307 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8308 "unhandledBack()"); 8309 8310 synchronized(this) { 8311 final long origId = Binder.clearCallingIdentity(); 8312 try { 8313 getFocusedStack().unhandledBackLocked(); 8314 } finally { 8315 Binder.restoreCallingIdentity(origId); 8316 } 8317 } 8318 } 8319 8320 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8321 enforceNotIsolatedCaller("openContentUri"); 8322 final int userId = UserHandle.getCallingUserId(); 8323 String name = uri.getAuthority(); 8324 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8325 ParcelFileDescriptor pfd = null; 8326 if (cph != null) { 8327 // We record the binder invoker's uid in thread-local storage before 8328 // going to the content provider to open the file. Later, in the code 8329 // that handles all permissions checks, we look for this uid and use 8330 // that rather than the Activity Manager's own uid. The effect is that 8331 // we do the check against the caller's permissions even though it looks 8332 // to the content provider like the Activity Manager itself is making 8333 // the request. 8334 sCallerIdentity.set(new Identity( 8335 Binder.getCallingPid(), Binder.getCallingUid())); 8336 try { 8337 pfd = cph.provider.openFile(null, uri, "r", null); 8338 } catch (FileNotFoundException e) { 8339 // do nothing; pfd will be returned null 8340 } finally { 8341 // Ensure that whatever happens, we clean up the identity state 8342 sCallerIdentity.remove(); 8343 } 8344 8345 // We've got the fd now, so we're done with the provider. 8346 removeContentProviderExternalUnchecked(name, null, userId); 8347 } else { 8348 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8349 } 8350 return pfd; 8351 } 8352 8353 // Actually is sleeping or shutting down or whatever else in the future 8354 // is an inactive state. 8355 public boolean isSleepingOrShuttingDown() { 8356 return mSleeping || mShuttingDown; 8357 } 8358 8359 public void goingToSleep() { 8360 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8361 != PackageManager.PERMISSION_GRANTED) { 8362 throw new SecurityException("Requires permission " 8363 + android.Manifest.permission.DEVICE_POWER); 8364 } 8365 8366 synchronized(this) { 8367 mWentToSleep = true; 8368 updateEventDispatchingLocked(); 8369 8370 if (!mSleeping) { 8371 mSleeping = true; 8372 mStackSupervisor.goingToSleepLocked(); 8373 8374 // Initialize the wake times of all processes. 8375 checkExcessivePowerUsageLocked(false); 8376 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8377 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8378 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8379 } 8380 } 8381 } 8382 8383 @Override 8384 public boolean shutdown(int timeout) { 8385 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8386 != PackageManager.PERMISSION_GRANTED) { 8387 throw new SecurityException("Requires permission " 8388 + android.Manifest.permission.SHUTDOWN); 8389 } 8390 8391 boolean timedout = false; 8392 8393 synchronized(this) { 8394 mShuttingDown = true; 8395 updateEventDispatchingLocked(); 8396 timedout = mStackSupervisor.shutdownLocked(timeout); 8397 } 8398 8399 mAppOpsService.shutdown(); 8400 mUsageStatsService.shutdown(); 8401 mBatteryStatsService.shutdown(); 8402 synchronized (this) { 8403 mProcessStats.shutdownLocked(); 8404 } 8405 8406 return timedout; 8407 } 8408 8409 public final void activitySlept(IBinder token) { 8410 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8411 8412 final long origId = Binder.clearCallingIdentity(); 8413 8414 synchronized (this) { 8415 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8416 if (r != null) { 8417 mStackSupervisor.activitySleptLocked(r); 8418 } 8419 } 8420 8421 Binder.restoreCallingIdentity(origId); 8422 } 8423 8424 void logLockScreen(String msg) { 8425 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8426 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8427 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8428 mStackSupervisor.mDismissKeyguardOnNextActivity); 8429 } 8430 8431 private void comeOutOfSleepIfNeededLocked() { 8432 if (!mWentToSleep && !mLockScreenShown) { 8433 if (mSleeping) { 8434 mSleeping = false; 8435 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8436 } 8437 } 8438 } 8439 8440 public void wakingUp() { 8441 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8442 != PackageManager.PERMISSION_GRANTED) { 8443 throw new SecurityException("Requires permission " 8444 + android.Manifest.permission.DEVICE_POWER); 8445 } 8446 8447 synchronized(this) { 8448 mWentToSleep = false; 8449 updateEventDispatchingLocked(); 8450 comeOutOfSleepIfNeededLocked(); 8451 } 8452 } 8453 8454 private void updateEventDispatchingLocked() { 8455 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8456 } 8457 8458 public void setLockScreenShown(boolean shown) { 8459 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8460 != PackageManager.PERMISSION_GRANTED) { 8461 throw new SecurityException("Requires permission " 8462 + android.Manifest.permission.DEVICE_POWER); 8463 } 8464 8465 synchronized(this) { 8466 long ident = Binder.clearCallingIdentity(); 8467 try { 8468 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8469 mLockScreenShown = shown; 8470 comeOutOfSleepIfNeededLocked(); 8471 } finally { 8472 Binder.restoreCallingIdentity(ident); 8473 } 8474 } 8475 } 8476 8477 public void stopAppSwitches() { 8478 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8479 != PackageManager.PERMISSION_GRANTED) { 8480 throw new SecurityException("Requires permission " 8481 + android.Manifest.permission.STOP_APP_SWITCHES); 8482 } 8483 8484 synchronized(this) { 8485 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8486 + APP_SWITCH_DELAY_TIME; 8487 mDidAppSwitch = false; 8488 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8489 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8490 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8491 } 8492 } 8493 8494 public void resumeAppSwitches() { 8495 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8496 != PackageManager.PERMISSION_GRANTED) { 8497 throw new SecurityException("Requires permission " 8498 + android.Manifest.permission.STOP_APP_SWITCHES); 8499 } 8500 8501 synchronized(this) { 8502 // Note that we don't execute any pending app switches... we will 8503 // let those wait until either the timeout, or the next start 8504 // activity request. 8505 mAppSwitchesAllowedTime = 0; 8506 } 8507 } 8508 8509 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8510 String name) { 8511 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8512 return true; 8513 } 8514 8515 final int perm = checkComponentPermission( 8516 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8517 callingUid, -1, true); 8518 if (perm == PackageManager.PERMISSION_GRANTED) { 8519 return true; 8520 } 8521 8522 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8523 return false; 8524 } 8525 8526 public void setDebugApp(String packageName, boolean waitForDebugger, 8527 boolean persistent) { 8528 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8529 "setDebugApp()"); 8530 8531 long ident = Binder.clearCallingIdentity(); 8532 try { 8533 // Note that this is not really thread safe if there are multiple 8534 // callers into it at the same time, but that's not a situation we 8535 // care about. 8536 if (persistent) { 8537 final ContentResolver resolver = mContext.getContentResolver(); 8538 Settings.Global.putString( 8539 resolver, Settings.Global.DEBUG_APP, 8540 packageName); 8541 Settings.Global.putInt( 8542 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8543 waitForDebugger ? 1 : 0); 8544 } 8545 8546 synchronized (this) { 8547 if (!persistent) { 8548 mOrigDebugApp = mDebugApp; 8549 mOrigWaitForDebugger = mWaitForDebugger; 8550 } 8551 mDebugApp = packageName; 8552 mWaitForDebugger = waitForDebugger; 8553 mDebugTransient = !persistent; 8554 if (packageName != null) { 8555 forceStopPackageLocked(packageName, -1, false, false, true, true, 8556 false, UserHandle.USER_ALL, "set debug app"); 8557 } 8558 } 8559 } finally { 8560 Binder.restoreCallingIdentity(ident); 8561 } 8562 } 8563 8564 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8565 synchronized (this) { 8566 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8567 if (!isDebuggable) { 8568 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8569 throw new SecurityException("Process not debuggable: " + app.packageName); 8570 } 8571 } 8572 8573 mOpenGlTraceApp = processName; 8574 } 8575 } 8576 8577 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8578 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8579 synchronized (this) { 8580 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8581 if (!isDebuggable) { 8582 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8583 throw new SecurityException("Process not debuggable: " + app.packageName); 8584 } 8585 } 8586 mProfileApp = processName; 8587 mProfileFile = profileFile; 8588 if (mProfileFd != null) { 8589 try { 8590 mProfileFd.close(); 8591 } catch (IOException e) { 8592 } 8593 mProfileFd = null; 8594 } 8595 mProfileFd = profileFd; 8596 mProfileType = 0; 8597 mAutoStopProfiler = autoStopProfiler; 8598 } 8599 } 8600 8601 @Override 8602 public void setAlwaysFinish(boolean enabled) { 8603 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8604 "setAlwaysFinish()"); 8605 8606 Settings.Global.putInt( 8607 mContext.getContentResolver(), 8608 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8609 8610 synchronized (this) { 8611 mAlwaysFinishActivities = enabled; 8612 } 8613 } 8614 8615 @Override 8616 public void setActivityController(IActivityController controller) { 8617 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8618 "setActivityController()"); 8619 synchronized (this) { 8620 mController = controller; 8621 Watchdog.getInstance().setActivityController(controller); 8622 } 8623 } 8624 8625 @Override 8626 public void setUserIsMonkey(boolean userIsMonkey) { 8627 synchronized (this) { 8628 synchronized (mPidsSelfLocked) { 8629 final int callingPid = Binder.getCallingPid(); 8630 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8631 if (precessRecord == null) { 8632 throw new SecurityException("Unknown process: " + callingPid); 8633 } 8634 if (precessRecord.instrumentationUiAutomationConnection == null) { 8635 throw new SecurityException("Only an instrumentation process " 8636 + "with a UiAutomation can call setUserIsMonkey"); 8637 } 8638 } 8639 mUserIsMonkey = userIsMonkey; 8640 } 8641 } 8642 8643 @Override 8644 public boolean isUserAMonkey() { 8645 synchronized (this) { 8646 // If there is a controller also implies the user is a monkey. 8647 return (mUserIsMonkey || mController != null); 8648 } 8649 } 8650 8651 public void requestBugReport() { 8652 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8653 SystemProperties.set("ctl.start", "bugreport"); 8654 } 8655 8656 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8657 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8658 } 8659 8660 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8661 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8662 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8663 } 8664 return KEY_DISPATCHING_TIMEOUT; 8665 } 8666 8667 @Override 8668 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8669 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8670 != PackageManager.PERMISSION_GRANTED) { 8671 throw new SecurityException("Requires permission " 8672 + android.Manifest.permission.FILTER_EVENTS); 8673 } 8674 ProcessRecord proc; 8675 long timeout; 8676 synchronized (this) { 8677 synchronized (mPidsSelfLocked) { 8678 proc = mPidsSelfLocked.get(pid); 8679 } 8680 timeout = getInputDispatchingTimeoutLocked(proc); 8681 } 8682 8683 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8684 return -1; 8685 } 8686 8687 return timeout; 8688 } 8689 8690 /** 8691 * Handle input dispatching timeouts. 8692 * Returns whether input dispatching should be aborted or not. 8693 */ 8694 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8695 final ActivityRecord activity, final ActivityRecord parent, 8696 final boolean aboveSystem, String reason) { 8697 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8698 != PackageManager.PERMISSION_GRANTED) { 8699 throw new SecurityException("Requires permission " 8700 + android.Manifest.permission.FILTER_EVENTS); 8701 } 8702 8703 final String annotation; 8704 if (reason == null) { 8705 annotation = "Input dispatching timed out"; 8706 } else { 8707 annotation = "Input dispatching timed out (" + reason + ")"; 8708 } 8709 8710 if (proc != null) { 8711 synchronized (this) { 8712 if (proc.debugging) { 8713 return false; 8714 } 8715 8716 if (mDidDexOpt) { 8717 // Give more time since we were dexopting. 8718 mDidDexOpt = false; 8719 return false; 8720 } 8721 8722 if (proc.instrumentationClass != null) { 8723 Bundle info = new Bundle(); 8724 info.putString("shortMsg", "keyDispatchingTimedOut"); 8725 info.putString("longMsg", annotation); 8726 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8727 return true; 8728 } 8729 } 8730 mHandler.post(new Runnable() { 8731 @Override 8732 public void run() { 8733 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8734 } 8735 }); 8736 } 8737 8738 return true; 8739 } 8740 8741 public Bundle getAssistContextExtras(int requestType) { 8742 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8743 "getAssistContextExtras()"); 8744 PendingAssistExtras pae; 8745 Bundle extras = new Bundle(); 8746 synchronized (this) { 8747 ActivityRecord activity = getFocusedStack().mResumedActivity; 8748 if (activity == null) { 8749 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8750 return null; 8751 } 8752 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8753 if (activity.app == null || activity.app.thread == null) { 8754 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8755 return extras; 8756 } 8757 if (activity.app.pid == Binder.getCallingPid()) { 8758 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8759 return extras; 8760 } 8761 pae = new PendingAssistExtras(activity); 8762 try { 8763 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8764 requestType); 8765 mPendingAssistExtras.add(pae); 8766 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8767 } catch (RemoteException e) { 8768 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8769 return extras; 8770 } 8771 } 8772 synchronized (pae) { 8773 while (!pae.haveResult) { 8774 try { 8775 pae.wait(); 8776 } catch (InterruptedException e) { 8777 } 8778 } 8779 if (pae.result != null) { 8780 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8781 } 8782 } 8783 synchronized (this) { 8784 mPendingAssistExtras.remove(pae); 8785 mHandler.removeCallbacks(pae); 8786 } 8787 return extras; 8788 } 8789 8790 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8791 PendingAssistExtras pae = (PendingAssistExtras)token; 8792 synchronized (pae) { 8793 pae.result = extras; 8794 pae.haveResult = true; 8795 pae.notifyAll(); 8796 } 8797 } 8798 8799 public void registerProcessObserver(IProcessObserver observer) { 8800 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8801 "registerProcessObserver()"); 8802 synchronized (this) { 8803 mProcessObservers.register(observer); 8804 } 8805 } 8806 8807 @Override 8808 public void unregisterProcessObserver(IProcessObserver observer) { 8809 synchronized (this) { 8810 mProcessObservers.unregister(observer); 8811 } 8812 } 8813 8814 @Override 8815 public boolean convertFromTranslucent(IBinder token) { 8816 final long origId = Binder.clearCallingIdentity(); 8817 try { 8818 synchronized (this) { 8819 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8820 if (r == null) { 8821 return false; 8822 } 8823 if (r.changeWindowTranslucency(true)) { 8824 mWindowManager.setAppFullscreen(token, true); 8825 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8826 return true; 8827 } 8828 return false; 8829 } 8830 } finally { 8831 Binder.restoreCallingIdentity(origId); 8832 } 8833 } 8834 8835 @Override 8836 public boolean convertToTranslucent(IBinder token) { 8837 final long origId = Binder.clearCallingIdentity(); 8838 try { 8839 synchronized (this) { 8840 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8841 if (r == null) { 8842 return false; 8843 } 8844 if (r.changeWindowTranslucency(false)) { 8845 r.task.stack.convertToTranslucent(r); 8846 mWindowManager.setAppFullscreen(token, false); 8847 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8848 return true; 8849 } 8850 return false; 8851 } 8852 } finally { 8853 Binder.restoreCallingIdentity(origId); 8854 } 8855 } 8856 8857 @Override 8858 public void setImmersive(IBinder token, boolean immersive) { 8859 synchronized(this) { 8860 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8861 if (r == null) { 8862 throw new IllegalArgumentException(); 8863 } 8864 r.immersive = immersive; 8865 8866 // update associated state if we're frontmost 8867 if (r == mFocusedActivity) { 8868 if (DEBUG_IMMERSIVE) { 8869 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8870 } 8871 applyUpdateLockStateLocked(r); 8872 } 8873 } 8874 } 8875 8876 @Override 8877 public boolean isImmersive(IBinder token) { 8878 synchronized (this) { 8879 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8880 if (r == null) { 8881 throw new IllegalArgumentException(); 8882 } 8883 return r.immersive; 8884 } 8885 } 8886 8887 public boolean isTopActivityImmersive() { 8888 enforceNotIsolatedCaller("startActivity"); 8889 synchronized (this) { 8890 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8891 return (r != null) ? r.immersive : false; 8892 } 8893 } 8894 8895 public final void enterSafeMode() { 8896 synchronized(this) { 8897 // It only makes sense to do this before the system is ready 8898 // and started launching other packages. 8899 if (!mSystemReady) { 8900 try { 8901 AppGlobals.getPackageManager().enterSafeMode(); 8902 } catch (RemoteException e) { 8903 } 8904 } 8905 } 8906 } 8907 8908 public final void showSafeModeOverlay() { 8909 View v = LayoutInflater.from(mContext).inflate( 8910 com.android.internal.R.layout.safe_mode, null); 8911 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8912 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8913 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8914 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8915 lp.gravity = Gravity.BOTTOM | Gravity.START; 8916 lp.format = v.getBackground().getOpacity(); 8917 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8918 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8919 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8920 ((WindowManager)mContext.getSystemService( 8921 Context.WINDOW_SERVICE)).addView(v, lp); 8922 } 8923 8924 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8925 if (!(sender instanceof PendingIntentRecord)) { 8926 return; 8927 } 8928 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8929 synchronized (stats) { 8930 if (mBatteryStatsService.isOnBattery()) { 8931 mBatteryStatsService.enforceCallingPermission(); 8932 PendingIntentRecord rec = (PendingIntentRecord)sender; 8933 int MY_UID = Binder.getCallingUid(); 8934 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8935 BatteryStatsImpl.Uid.Pkg pkg = 8936 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8937 sourcePkg != null ? sourcePkg : rec.key.packageName); 8938 pkg.incWakeupsLocked(); 8939 } 8940 } 8941 } 8942 8943 public boolean killPids(int[] pids, String pReason, boolean secure) { 8944 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8945 throw new SecurityException("killPids only available to the system"); 8946 } 8947 String reason = (pReason == null) ? "Unknown" : pReason; 8948 // XXX Note: don't acquire main activity lock here, because the window 8949 // manager calls in with its locks held. 8950 8951 boolean killed = false; 8952 synchronized (mPidsSelfLocked) { 8953 int[] types = new int[pids.length]; 8954 int worstType = 0; 8955 for (int i=0; i<pids.length; i++) { 8956 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8957 if (proc != null) { 8958 int type = proc.setAdj; 8959 types[i] = type; 8960 if (type > worstType) { 8961 worstType = type; 8962 } 8963 } 8964 } 8965 8966 // If the worst oom_adj is somewhere in the cached proc LRU range, 8967 // then constrain it so we will kill all cached procs. 8968 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8969 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8970 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8971 } 8972 8973 // If this is not a secure call, don't let it kill processes that 8974 // are important. 8975 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 8976 worstType = ProcessList.SERVICE_ADJ; 8977 } 8978 8979 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 8980 for (int i=0; i<pids.length; i++) { 8981 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8982 if (proc == null) { 8983 continue; 8984 } 8985 int adj = proc.setAdj; 8986 if (adj >= worstType && !proc.killedByAm) { 8987 killUnneededProcessLocked(proc, reason); 8988 killed = true; 8989 } 8990 } 8991 } 8992 return killed; 8993 } 8994 8995 @Override 8996 public void killUid(int uid, String reason) { 8997 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8998 throw new SecurityException("killUid only available to the system"); 8999 } 9000 synchronized (this) { 9001 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9002 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9003 reason != null ? reason : "kill uid"); 9004 } 9005 } 9006 9007 @Override 9008 public boolean killProcessesBelowForeground(String reason) { 9009 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9010 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9011 } 9012 9013 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9014 } 9015 9016 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9017 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9018 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9019 } 9020 9021 boolean killed = false; 9022 synchronized (mPidsSelfLocked) { 9023 final int size = mPidsSelfLocked.size(); 9024 for (int i = 0; i < size; i++) { 9025 final int pid = mPidsSelfLocked.keyAt(i); 9026 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9027 if (proc == null) continue; 9028 9029 final int adj = proc.setAdj; 9030 if (adj > belowAdj && !proc.killedByAm) { 9031 killUnneededProcessLocked(proc, reason); 9032 killed = true; 9033 } 9034 } 9035 } 9036 return killed; 9037 } 9038 9039 @Override 9040 public void hang(final IBinder who, boolean allowRestart) { 9041 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9042 != PackageManager.PERMISSION_GRANTED) { 9043 throw new SecurityException("Requires permission " 9044 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9045 } 9046 9047 final IBinder.DeathRecipient death = new DeathRecipient() { 9048 @Override 9049 public void binderDied() { 9050 synchronized (this) { 9051 notifyAll(); 9052 } 9053 } 9054 }; 9055 9056 try { 9057 who.linkToDeath(death, 0); 9058 } catch (RemoteException e) { 9059 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9060 return; 9061 } 9062 9063 synchronized (this) { 9064 Watchdog.getInstance().setAllowRestart(allowRestart); 9065 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9066 synchronized (death) { 9067 while (who.isBinderAlive()) { 9068 try { 9069 death.wait(); 9070 } catch (InterruptedException e) { 9071 } 9072 } 9073 } 9074 Watchdog.getInstance().setAllowRestart(true); 9075 } 9076 } 9077 9078 @Override 9079 public void restart() { 9080 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9081 != PackageManager.PERMISSION_GRANTED) { 9082 throw new SecurityException("Requires permission " 9083 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9084 } 9085 9086 Log.i(TAG, "Sending shutdown broadcast..."); 9087 9088 BroadcastReceiver br = new BroadcastReceiver() { 9089 @Override public void onReceive(Context context, Intent intent) { 9090 // Now the broadcast is done, finish up the low-level shutdown. 9091 Log.i(TAG, "Shutting down activity manager..."); 9092 shutdown(10000); 9093 Log.i(TAG, "Shutdown complete, restarting!"); 9094 Process.killProcess(Process.myPid()); 9095 System.exit(10); 9096 } 9097 }; 9098 9099 // First send the high-level shut down broadcast. 9100 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9101 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9102 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9103 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9104 mContext.sendOrderedBroadcastAsUser(intent, 9105 UserHandle.ALL, null, br, mHandler, 0, null, null); 9106 */ 9107 br.onReceive(mContext, intent); 9108 } 9109 9110 private long getLowRamTimeSinceIdle(long now) { 9111 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9112 } 9113 9114 @Override 9115 public void performIdleMaintenance() { 9116 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9117 != PackageManager.PERMISSION_GRANTED) { 9118 throw new SecurityException("Requires permission " 9119 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9120 } 9121 9122 synchronized (this) { 9123 final long now = SystemClock.uptimeMillis(); 9124 final long timeSinceLastIdle = now - mLastIdleTime; 9125 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9126 mLastIdleTime = now; 9127 mLowRamTimeSinceLastIdle = 0; 9128 if (mLowRamStartTime != 0) { 9129 mLowRamStartTime = now; 9130 } 9131 9132 StringBuilder sb = new StringBuilder(128); 9133 sb.append("Idle maintenance over "); 9134 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9135 sb.append(" low RAM for "); 9136 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9137 Slog.i(TAG, sb.toString()); 9138 9139 // If at least 1/3 of our time since the last idle period has been spent 9140 // with RAM low, then we want to kill processes. 9141 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9142 9143 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9144 ProcessRecord proc = mLruProcesses.get(i); 9145 if (proc.notCachedSinceIdle) { 9146 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9147 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9148 if (doKilling && proc.initialIdlePss != 0 9149 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9150 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9151 + " from " + proc.initialIdlePss + ")"); 9152 } 9153 } 9154 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9155 proc.notCachedSinceIdle = true; 9156 proc.initialIdlePss = 0; 9157 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9158 mSleeping, now); 9159 } 9160 } 9161 9162 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9163 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9164 } 9165 } 9166 9167 public final void startRunning(String pkg, String cls, String action, 9168 String data) { 9169 synchronized(this) { 9170 if (mStartRunning) { 9171 return; 9172 } 9173 mStartRunning = true; 9174 mTopComponent = pkg != null && cls != null 9175 ? new ComponentName(pkg, cls) : null; 9176 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9177 mTopData = data; 9178 if (!mSystemReady) { 9179 return; 9180 } 9181 } 9182 9183 systemReady(null); 9184 } 9185 9186 private void retrieveSettings() { 9187 final ContentResolver resolver = mContext.getContentResolver(); 9188 String debugApp = Settings.Global.getString( 9189 resolver, Settings.Global.DEBUG_APP); 9190 boolean waitForDebugger = Settings.Global.getInt( 9191 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9192 boolean alwaysFinishActivities = Settings.Global.getInt( 9193 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9194 boolean forceRtl = Settings.Global.getInt( 9195 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9196 // Transfer any global setting for forcing RTL layout, into a System Property 9197 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9198 9199 Configuration configuration = new Configuration(); 9200 Settings.System.getConfiguration(resolver, configuration); 9201 if (forceRtl) { 9202 // This will take care of setting the correct layout direction flags 9203 configuration.setLayoutDirection(configuration.locale); 9204 } 9205 9206 synchronized (this) { 9207 mDebugApp = mOrigDebugApp = debugApp; 9208 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9209 mAlwaysFinishActivities = alwaysFinishActivities; 9210 // This happens before any activities are started, so we can 9211 // change mConfiguration in-place. 9212 updateConfigurationLocked(configuration, null, false, true); 9213 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9214 } 9215 } 9216 9217 public boolean testIsSystemReady() { 9218 // no need to synchronize(this) just to read & return the value 9219 return mSystemReady; 9220 } 9221 9222 private static File getCalledPreBootReceiversFile() { 9223 File dataDir = Environment.getDataDirectory(); 9224 File systemDir = new File(dataDir, "system"); 9225 File fname = new File(systemDir, "called_pre_boots.dat"); 9226 return fname; 9227 } 9228 9229 static final int LAST_DONE_VERSION = 10000; 9230 9231 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9232 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9233 File file = getCalledPreBootReceiversFile(); 9234 FileInputStream fis = null; 9235 try { 9236 fis = new FileInputStream(file); 9237 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9238 int fvers = dis.readInt(); 9239 if (fvers == LAST_DONE_VERSION) { 9240 String vers = dis.readUTF(); 9241 String codename = dis.readUTF(); 9242 String build = dis.readUTF(); 9243 if (android.os.Build.VERSION.RELEASE.equals(vers) 9244 && android.os.Build.VERSION.CODENAME.equals(codename) 9245 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9246 int num = dis.readInt(); 9247 while (num > 0) { 9248 num--; 9249 String pkg = dis.readUTF(); 9250 String cls = dis.readUTF(); 9251 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9252 } 9253 } 9254 } 9255 } catch (FileNotFoundException e) { 9256 } catch (IOException e) { 9257 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9258 } finally { 9259 if (fis != null) { 9260 try { 9261 fis.close(); 9262 } catch (IOException e) { 9263 } 9264 } 9265 } 9266 return lastDoneReceivers; 9267 } 9268 9269 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9270 File file = getCalledPreBootReceiversFile(); 9271 FileOutputStream fos = null; 9272 DataOutputStream dos = null; 9273 try { 9274 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9275 fos = new FileOutputStream(file); 9276 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9277 dos.writeInt(LAST_DONE_VERSION); 9278 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9279 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9280 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9281 dos.writeInt(list.size()); 9282 for (int i=0; i<list.size(); i++) { 9283 dos.writeUTF(list.get(i).getPackageName()); 9284 dos.writeUTF(list.get(i).getClassName()); 9285 } 9286 } catch (IOException e) { 9287 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9288 file.delete(); 9289 } finally { 9290 FileUtils.sync(fos); 9291 if (dos != null) { 9292 try { 9293 dos.close(); 9294 } catch (IOException e) { 9295 // TODO Auto-generated catch block 9296 e.printStackTrace(); 9297 } 9298 } 9299 } 9300 } 9301 9302 public void systemReady(final Runnable goingCallback) { 9303 synchronized(this) { 9304 if (mSystemReady) { 9305 if (goingCallback != null) goingCallback.run(); 9306 return; 9307 } 9308 9309 // Check to see if there are any update receivers to run. 9310 if (!mDidUpdate) { 9311 if (mWaitingUpdate) { 9312 return; 9313 } 9314 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9315 List<ResolveInfo> ris = null; 9316 try { 9317 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9318 intent, null, 0, 0); 9319 } catch (RemoteException e) { 9320 } 9321 if (ris != null) { 9322 for (int i=ris.size()-1; i>=0; i--) { 9323 if ((ris.get(i).activityInfo.applicationInfo.flags 9324 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9325 ris.remove(i); 9326 } 9327 } 9328 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9329 9330 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9331 9332 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9333 for (int i=0; i<ris.size(); i++) { 9334 ActivityInfo ai = ris.get(i).activityInfo; 9335 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9336 if (lastDoneReceivers.contains(comp)) { 9337 // We already did the pre boot receiver for this app with the current 9338 // platform version, so don't do it again... 9339 ris.remove(i); 9340 i--; 9341 // ...however, do keep it as one that has been done, so we don't 9342 // forget about it when rewriting the file of last done receivers. 9343 doneReceivers.add(comp); 9344 } 9345 } 9346 9347 final int[] users = getUsersLocked(); 9348 for (int i=0; i<ris.size(); i++) { 9349 ActivityInfo ai = ris.get(i).activityInfo; 9350 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9351 doneReceivers.add(comp); 9352 intent.setComponent(comp); 9353 for (int j=0; j<users.length; j++) { 9354 IIntentReceiver finisher = null; 9355 if (i == ris.size()-1 && j == users.length-1) { 9356 finisher = new IIntentReceiver.Stub() { 9357 public void performReceive(Intent intent, int resultCode, 9358 String data, Bundle extras, boolean ordered, 9359 boolean sticky, int sendingUser) { 9360 // The raw IIntentReceiver interface is called 9361 // with the AM lock held, so redispatch to 9362 // execute our code without the lock. 9363 mHandler.post(new Runnable() { 9364 public void run() { 9365 synchronized (ActivityManagerService.this) { 9366 mDidUpdate = true; 9367 } 9368 writeLastDonePreBootReceivers(doneReceivers); 9369 showBootMessage(mContext.getText( 9370 R.string.android_upgrading_complete), 9371 false); 9372 systemReady(goingCallback); 9373 } 9374 }); 9375 } 9376 }; 9377 } 9378 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9379 + " for user " + users[j]); 9380 broadcastIntentLocked(null, null, intent, null, finisher, 9381 0, null, null, null, AppOpsManager.OP_NONE, 9382 true, false, MY_PID, Process.SYSTEM_UID, 9383 users[j]); 9384 if (finisher != null) { 9385 mWaitingUpdate = true; 9386 } 9387 } 9388 } 9389 } 9390 if (mWaitingUpdate) { 9391 return; 9392 } 9393 mDidUpdate = true; 9394 } 9395 9396 mAppOpsService.systemReady(); 9397 mSystemReady = true; 9398 if (!mStartRunning) { 9399 return; 9400 } 9401 } 9402 9403 ArrayList<ProcessRecord> procsToKill = null; 9404 synchronized(mPidsSelfLocked) { 9405 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9406 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9407 if (!isAllowedWhileBooting(proc.info)){ 9408 if (procsToKill == null) { 9409 procsToKill = new ArrayList<ProcessRecord>(); 9410 } 9411 procsToKill.add(proc); 9412 } 9413 } 9414 } 9415 9416 synchronized(this) { 9417 if (procsToKill != null) { 9418 for (int i=procsToKill.size()-1; i>=0; i--) { 9419 ProcessRecord proc = procsToKill.get(i); 9420 Slog.i(TAG, "Removing system update proc: " + proc); 9421 removeProcessLocked(proc, true, false, "system update done"); 9422 } 9423 } 9424 9425 // Now that we have cleaned up any update processes, we 9426 // are ready to start launching real processes and know that 9427 // we won't trample on them any more. 9428 mProcessesReady = true; 9429 } 9430 9431 Slog.i(TAG, "System now ready"); 9432 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9433 SystemClock.uptimeMillis()); 9434 9435 synchronized(this) { 9436 // Make sure we have no pre-ready processes sitting around. 9437 9438 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9439 ResolveInfo ri = mContext.getPackageManager() 9440 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9441 STOCK_PM_FLAGS); 9442 CharSequence errorMsg = null; 9443 if (ri != null) { 9444 ActivityInfo ai = ri.activityInfo; 9445 ApplicationInfo app = ai.applicationInfo; 9446 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9447 mTopAction = Intent.ACTION_FACTORY_TEST; 9448 mTopData = null; 9449 mTopComponent = new ComponentName(app.packageName, 9450 ai.name); 9451 } else { 9452 errorMsg = mContext.getResources().getText( 9453 com.android.internal.R.string.factorytest_not_system); 9454 } 9455 } else { 9456 errorMsg = mContext.getResources().getText( 9457 com.android.internal.R.string.factorytest_no_action); 9458 } 9459 if (errorMsg != null) { 9460 mTopAction = null; 9461 mTopData = null; 9462 mTopComponent = null; 9463 Message msg = Message.obtain(); 9464 msg.what = SHOW_FACTORY_ERROR_MSG; 9465 msg.getData().putCharSequence("msg", errorMsg); 9466 mHandler.sendMessage(msg); 9467 } 9468 } 9469 } 9470 9471 retrieveSettings(); 9472 9473 synchronized (this) { 9474 readGrantedUriPermissionsLocked(); 9475 } 9476 9477 if (goingCallback != null) goingCallback.run(); 9478 9479 synchronized (this) { 9480 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9481 try { 9482 List apps = AppGlobals.getPackageManager(). 9483 getPersistentApplications(STOCK_PM_FLAGS); 9484 if (apps != null) { 9485 int N = apps.size(); 9486 int i; 9487 for (i=0; i<N; i++) { 9488 ApplicationInfo info 9489 = (ApplicationInfo)apps.get(i); 9490 if (info != null && 9491 !info.packageName.equals("android")) { 9492 addAppLocked(info, false); 9493 } 9494 } 9495 } 9496 } catch (RemoteException ex) { 9497 // pm is in same process, this will never happen. 9498 } 9499 } 9500 9501 // Start up initial activity. 9502 mBooting = true; 9503 9504 try { 9505 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9506 Message msg = Message.obtain(); 9507 msg.what = SHOW_UID_ERROR_MSG; 9508 mHandler.sendMessage(msg); 9509 } 9510 } catch (RemoteException e) { 9511 } 9512 9513 long ident = Binder.clearCallingIdentity(); 9514 try { 9515 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9516 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9517 | Intent.FLAG_RECEIVER_FOREGROUND); 9518 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9519 broadcastIntentLocked(null, null, intent, 9520 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9521 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9522 intent = new Intent(Intent.ACTION_USER_STARTING); 9523 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9524 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9525 broadcastIntentLocked(null, null, intent, 9526 null, new IIntentReceiver.Stub() { 9527 @Override 9528 public void performReceive(Intent intent, int resultCode, String data, 9529 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9530 throws RemoteException { 9531 } 9532 }, 0, null, null, 9533 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9534 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9535 } finally { 9536 Binder.restoreCallingIdentity(ident); 9537 } 9538 mStackSupervisor.resumeTopActivitiesLocked(); 9539 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9540 } 9541 } 9542 9543 private boolean makeAppCrashingLocked(ProcessRecord app, 9544 String shortMsg, String longMsg, String stackTrace) { 9545 app.crashing = true; 9546 app.crashingReport = generateProcessError(app, 9547 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9548 startAppProblemLocked(app); 9549 app.stopFreezingAllLocked(); 9550 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9551 } 9552 9553 private void makeAppNotRespondingLocked(ProcessRecord app, 9554 String activity, String shortMsg, String longMsg) { 9555 app.notResponding = true; 9556 app.notRespondingReport = generateProcessError(app, 9557 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9558 activity, shortMsg, longMsg, null); 9559 startAppProblemLocked(app); 9560 app.stopFreezingAllLocked(); 9561 } 9562 9563 /** 9564 * Generate a process error record, suitable for attachment to a ProcessRecord. 9565 * 9566 * @param app The ProcessRecord in which the error occurred. 9567 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9568 * ActivityManager.AppErrorStateInfo 9569 * @param activity The activity associated with the crash, if known. 9570 * @param shortMsg Short message describing the crash. 9571 * @param longMsg Long message describing the crash. 9572 * @param stackTrace Full crash stack trace, may be null. 9573 * 9574 * @return Returns a fully-formed AppErrorStateInfo record. 9575 */ 9576 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9577 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9578 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9579 9580 report.condition = condition; 9581 report.processName = app.processName; 9582 report.pid = app.pid; 9583 report.uid = app.info.uid; 9584 report.tag = activity; 9585 report.shortMsg = shortMsg; 9586 report.longMsg = longMsg; 9587 report.stackTrace = stackTrace; 9588 9589 return report; 9590 } 9591 9592 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9593 synchronized (this) { 9594 app.crashing = false; 9595 app.crashingReport = null; 9596 app.notResponding = false; 9597 app.notRespondingReport = null; 9598 if (app.anrDialog == fromDialog) { 9599 app.anrDialog = null; 9600 } 9601 if (app.waitDialog == fromDialog) { 9602 app.waitDialog = null; 9603 } 9604 if (app.pid > 0 && app.pid != MY_PID) { 9605 handleAppCrashLocked(app, null, null, null); 9606 killUnneededProcessLocked(app, "user request after error"); 9607 } 9608 } 9609 } 9610 9611 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9612 String stackTrace) { 9613 long now = SystemClock.uptimeMillis(); 9614 9615 Long crashTime; 9616 if (!app.isolated) { 9617 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9618 } else { 9619 crashTime = null; 9620 } 9621 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9622 // This process loses! 9623 Slog.w(TAG, "Process " + app.info.processName 9624 + " has crashed too many times: killing!"); 9625 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9626 app.userId, app.info.processName, app.uid); 9627 mStackSupervisor.handleAppCrashLocked(app); 9628 if (!app.persistent) { 9629 // We don't want to start this process again until the user 9630 // explicitly does so... but for persistent process, we really 9631 // need to keep it running. If a persistent process is actually 9632 // repeatedly crashing, then badness for everyone. 9633 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9634 app.info.processName); 9635 if (!app.isolated) { 9636 // XXX We don't have a way to mark isolated processes 9637 // as bad, since they don't have a peristent identity. 9638 mBadProcesses.put(app.info.processName, app.uid, 9639 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9640 mProcessCrashTimes.remove(app.info.processName, app.uid); 9641 } 9642 app.bad = true; 9643 app.removed = true; 9644 // Don't let services in this process be restarted and potentially 9645 // annoy the user repeatedly. Unless it is persistent, since those 9646 // processes run critical code. 9647 removeProcessLocked(app, false, false, "crash"); 9648 mStackSupervisor.resumeTopActivitiesLocked(); 9649 return false; 9650 } 9651 mStackSupervisor.resumeTopActivitiesLocked(); 9652 } else { 9653 mStackSupervisor.finishTopRunningActivityLocked(app); 9654 } 9655 9656 // Bump up the crash count of any services currently running in the proc. 9657 for (int i=app.services.size()-1; i>=0; i--) { 9658 // Any services running in the application need to be placed 9659 // back in the pending list. 9660 ServiceRecord sr = app.services.valueAt(i); 9661 sr.crashCount++; 9662 } 9663 9664 // If the crashing process is what we consider to be the "home process" and it has been 9665 // replaced by a third-party app, clear the package preferred activities from packages 9666 // with a home activity running in the process to prevent a repeatedly crashing app 9667 // from blocking the user to manually clear the list. 9668 final ArrayList<ActivityRecord> activities = app.activities; 9669 if (app == mHomeProcess && activities.size() > 0 9670 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9671 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9672 final ActivityRecord r = activities.get(activityNdx); 9673 if (r.isHomeActivity()) { 9674 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9675 try { 9676 ActivityThread.getPackageManager() 9677 .clearPackagePreferredActivities(r.packageName); 9678 } catch (RemoteException c) { 9679 // pm is in same process, this will never happen. 9680 } 9681 } 9682 } 9683 } 9684 9685 if (!app.isolated) { 9686 // XXX Can't keep track of crash times for isolated processes, 9687 // because they don't have a perisistent identity. 9688 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9689 } 9690 9691 return true; 9692 } 9693 9694 void startAppProblemLocked(ProcessRecord app) { 9695 if (app.userId == mCurrentUserId) { 9696 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9697 mContext, app.info.packageName, app.info.flags); 9698 } else { 9699 // If this app is not running under the current user, then we 9700 // can't give it a report button because that would require 9701 // launching the report UI under a different user. 9702 app.errorReportReceiver = null; 9703 } 9704 skipCurrentReceiverLocked(app); 9705 } 9706 9707 void skipCurrentReceiverLocked(ProcessRecord app) { 9708 for (BroadcastQueue queue : mBroadcastQueues) { 9709 queue.skipCurrentReceiverLocked(app); 9710 } 9711 } 9712 9713 /** 9714 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9715 * The application process will exit immediately after this call returns. 9716 * @param app object of the crashing app, null for the system server 9717 * @param crashInfo describing the exception 9718 */ 9719 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9720 ProcessRecord r = findAppProcess(app, "Crash"); 9721 final String processName = app == null ? "system_server" 9722 : (r == null ? "unknown" : r.processName); 9723 9724 handleApplicationCrashInner("crash", r, processName, crashInfo); 9725 } 9726 9727 /* Native crash reporting uses this inner version because it needs to be somewhat 9728 * decoupled from the AM-managed cleanup lifecycle 9729 */ 9730 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9731 ApplicationErrorReport.CrashInfo crashInfo) { 9732 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9733 UserHandle.getUserId(Binder.getCallingUid()), processName, 9734 r == null ? -1 : r.info.flags, 9735 crashInfo.exceptionClassName, 9736 crashInfo.exceptionMessage, 9737 crashInfo.throwFileName, 9738 crashInfo.throwLineNumber); 9739 9740 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9741 9742 crashApplication(r, crashInfo); 9743 } 9744 9745 public void handleApplicationStrictModeViolation( 9746 IBinder app, 9747 int violationMask, 9748 StrictMode.ViolationInfo info) { 9749 ProcessRecord r = findAppProcess(app, "StrictMode"); 9750 if (r == null) { 9751 return; 9752 } 9753 9754 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9755 Integer stackFingerprint = info.hashCode(); 9756 boolean logIt = true; 9757 synchronized (mAlreadyLoggedViolatedStacks) { 9758 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9759 logIt = false; 9760 // TODO: sub-sample into EventLog for these, with 9761 // the info.durationMillis? Then we'd get 9762 // the relative pain numbers, without logging all 9763 // the stack traces repeatedly. We'd want to do 9764 // likewise in the client code, which also does 9765 // dup suppression, before the Binder call. 9766 } else { 9767 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9768 mAlreadyLoggedViolatedStacks.clear(); 9769 } 9770 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9771 } 9772 } 9773 if (logIt) { 9774 logStrictModeViolationToDropBox(r, info); 9775 } 9776 } 9777 9778 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9779 AppErrorResult result = new AppErrorResult(); 9780 synchronized (this) { 9781 final long origId = Binder.clearCallingIdentity(); 9782 9783 Message msg = Message.obtain(); 9784 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9785 HashMap<String, Object> data = new HashMap<String, Object>(); 9786 data.put("result", result); 9787 data.put("app", r); 9788 data.put("violationMask", violationMask); 9789 data.put("info", info); 9790 msg.obj = data; 9791 mHandler.sendMessage(msg); 9792 9793 Binder.restoreCallingIdentity(origId); 9794 } 9795 int res = result.get(); 9796 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9797 } 9798 } 9799 9800 // Depending on the policy in effect, there could be a bunch of 9801 // these in quick succession so we try to batch these together to 9802 // minimize disk writes, number of dropbox entries, and maximize 9803 // compression, by having more fewer, larger records. 9804 private void logStrictModeViolationToDropBox( 9805 ProcessRecord process, 9806 StrictMode.ViolationInfo info) { 9807 if (info == null) { 9808 return; 9809 } 9810 final boolean isSystemApp = process == null || 9811 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9812 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9813 final String processName = process == null ? "unknown" : process.processName; 9814 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9815 final DropBoxManager dbox = (DropBoxManager) 9816 mContext.getSystemService(Context.DROPBOX_SERVICE); 9817 9818 // Exit early if the dropbox isn't configured to accept this report type. 9819 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9820 9821 boolean bufferWasEmpty; 9822 boolean needsFlush; 9823 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9824 synchronized (sb) { 9825 bufferWasEmpty = sb.length() == 0; 9826 appendDropBoxProcessHeaders(process, processName, sb); 9827 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9828 sb.append("System-App: ").append(isSystemApp).append("\n"); 9829 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9830 if (info.violationNumThisLoop != 0) { 9831 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9832 } 9833 if (info.numAnimationsRunning != 0) { 9834 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9835 } 9836 if (info.broadcastIntentAction != null) { 9837 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9838 } 9839 if (info.durationMillis != -1) { 9840 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9841 } 9842 if (info.numInstances != -1) { 9843 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9844 } 9845 if (info.tags != null) { 9846 for (String tag : info.tags) { 9847 sb.append("Span-Tag: ").append(tag).append("\n"); 9848 } 9849 } 9850 sb.append("\n"); 9851 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9852 sb.append(info.crashInfo.stackTrace); 9853 } 9854 sb.append("\n"); 9855 9856 // Only buffer up to ~64k. Various logging bits truncate 9857 // things at 128k. 9858 needsFlush = (sb.length() > 64 * 1024); 9859 } 9860 9861 // Flush immediately if the buffer's grown too large, or this 9862 // is a non-system app. Non-system apps are isolated with a 9863 // different tag & policy and not batched. 9864 // 9865 // Batching is useful during internal testing with 9866 // StrictMode settings turned up high. Without batching, 9867 // thousands of separate files could be created on boot. 9868 if (!isSystemApp || needsFlush) { 9869 new Thread("Error dump: " + dropboxTag) { 9870 @Override 9871 public void run() { 9872 String report; 9873 synchronized (sb) { 9874 report = sb.toString(); 9875 sb.delete(0, sb.length()); 9876 sb.trimToSize(); 9877 } 9878 if (report.length() != 0) { 9879 dbox.addText(dropboxTag, report); 9880 } 9881 } 9882 }.start(); 9883 return; 9884 } 9885 9886 // System app batching: 9887 if (!bufferWasEmpty) { 9888 // An existing dropbox-writing thread is outstanding, so 9889 // we don't need to start it up. The existing thread will 9890 // catch the buffer appends we just did. 9891 return; 9892 } 9893 9894 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9895 // (After this point, we shouldn't access AMS internal data structures.) 9896 new Thread("Error dump: " + dropboxTag) { 9897 @Override 9898 public void run() { 9899 // 5 second sleep to let stacks arrive and be batched together 9900 try { 9901 Thread.sleep(5000); // 5 seconds 9902 } catch (InterruptedException e) {} 9903 9904 String errorReport; 9905 synchronized (mStrictModeBuffer) { 9906 errorReport = mStrictModeBuffer.toString(); 9907 if (errorReport.length() == 0) { 9908 return; 9909 } 9910 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9911 mStrictModeBuffer.trimToSize(); 9912 } 9913 dbox.addText(dropboxTag, errorReport); 9914 } 9915 }.start(); 9916 } 9917 9918 /** 9919 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9920 * @param app object of the crashing app, null for the system server 9921 * @param tag reported by the caller 9922 * @param crashInfo describing the context of the error 9923 * @return true if the process should exit immediately (WTF is fatal) 9924 */ 9925 public boolean handleApplicationWtf(IBinder app, String tag, 9926 ApplicationErrorReport.CrashInfo crashInfo) { 9927 ProcessRecord r = findAppProcess(app, "WTF"); 9928 final String processName = app == null ? "system_server" 9929 : (r == null ? "unknown" : r.processName); 9930 9931 EventLog.writeEvent(EventLogTags.AM_WTF, 9932 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9933 processName, 9934 r == null ? -1 : r.info.flags, 9935 tag, crashInfo.exceptionMessage); 9936 9937 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9938 9939 if (r != null && r.pid != Process.myPid() && 9940 Settings.Global.getInt(mContext.getContentResolver(), 9941 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9942 crashApplication(r, crashInfo); 9943 return true; 9944 } else { 9945 return false; 9946 } 9947 } 9948 9949 /** 9950 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9951 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9952 */ 9953 private ProcessRecord findAppProcess(IBinder app, String reason) { 9954 if (app == null) { 9955 return null; 9956 } 9957 9958 synchronized (this) { 9959 final int NP = mProcessNames.getMap().size(); 9960 for (int ip=0; ip<NP; ip++) { 9961 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9962 final int NA = apps.size(); 9963 for (int ia=0; ia<NA; ia++) { 9964 ProcessRecord p = apps.valueAt(ia); 9965 if (p.thread != null && p.thread.asBinder() == app) { 9966 return p; 9967 } 9968 } 9969 } 9970 9971 Slog.w(TAG, "Can't find mystery application for " + reason 9972 + " from pid=" + Binder.getCallingPid() 9973 + " uid=" + Binder.getCallingUid() + ": " + app); 9974 return null; 9975 } 9976 } 9977 9978 /** 9979 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 9980 * to append various headers to the dropbox log text. 9981 */ 9982 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 9983 StringBuilder sb) { 9984 // Watchdog thread ends up invoking this function (with 9985 // a null ProcessRecord) to add the stack file to dropbox. 9986 // Do not acquire a lock on this (am) in such cases, as it 9987 // could cause a potential deadlock, if and when watchdog 9988 // is invoked due to unavailability of lock on am and it 9989 // would prevent watchdog from killing system_server. 9990 if (process == null) { 9991 sb.append("Process: ").append(processName).append("\n"); 9992 return; 9993 } 9994 // Note: ProcessRecord 'process' is guarded by the service 9995 // instance. (notably process.pkgList, which could otherwise change 9996 // concurrently during execution of this method) 9997 synchronized (this) { 9998 sb.append("Process: ").append(processName).append("\n"); 9999 int flags = process.info.flags; 10000 IPackageManager pm = AppGlobals.getPackageManager(); 10001 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10002 for (int ip=0; ip<process.pkgList.size(); ip++) { 10003 String pkg = process.pkgList.keyAt(ip); 10004 sb.append("Package: ").append(pkg); 10005 try { 10006 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10007 if (pi != null) { 10008 sb.append(" v").append(pi.versionCode); 10009 if (pi.versionName != null) { 10010 sb.append(" (").append(pi.versionName).append(")"); 10011 } 10012 } 10013 } catch (RemoteException e) { 10014 Slog.e(TAG, "Error getting package info: " + pkg, e); 10015 } 10016 sb.append("\n"); 10017 } 10018 } 10019 } 10020 10021 private static String processClass(ProcessRecord process) { 10022 if (process == null || process.pid == MY_PID) { 10023 return "system_server"; 10024 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10025 return "system_app"; 10026 } else { 10027 return "data_app"; 10028 } 10029 } 10030 10031 /** 10032 * Write a description of an error (crash, WTF, ANR) to the drop box. 10033 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10034 * @param process which caused the error, null means the system server 10035 * @param activity which triggered the error, null if unknown 10036 * @param parent activity related to the error, null if unknown 10037 * @param subject line related to the error, null if absent 10038 * @param report in long form describing the error, null if absent 10039 * @param logFile to include in the report, null if none 10040 * @param crashInfo giving an application stack trace, null if absent 10041 */ 10042 public void addErrorToDropBox(String eventType, 10043 ProcessRecord process, String processName, ActivityRecord activity, 10044 ActivityRecord parent, String subject, 10045 final String report, final File logFile, 10046 final ApplicationErrorReport.CrashInfo crashInfo) { 10047 // NOTE -- this must never acquire the ActivityManagerService lock, 10048 // otherwise the watchdog may be prevented from resetting the system. 10049 10050 final String dropboxTag = processClass(process) + "_" + eventType; 10051 final DropBoxManager dbox = (DropBoxManager) 10052 mContext.getSystemService(Context.DROPBOX_SERVICE); 10053 10054 // Exit early if the dropbox isn't configured to accept this report type. 10055 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10056 10057 final StringBuilder sb = new StringBuilder(1024); 10058 appendDropBoxProcessHeaders(process, processName, sb); 10059 if (activity != null) { 10060 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10061 } 10062 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10063 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10064 } 10065 if (parent != null && parent != activity) { 10066 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10067 } 10068 if (subject != null) { 10069 sb.append("Subject: ").append(subject).append("\n"); 10070 } 10071 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10072 if (Debug.isDebuggerConnected()) { 10073 sb.append("Debugger: Connected\n"); 10074 } 10075 sb.append("\n"); 10076 10077 // Do the rest in a worker thread to avoid blocking the caller on I/O 10078 // (After this point, we shouldn't access AMS internal data structures.) 10079 Thread worker = new Thread("Error dump: " + dropboxTag) { 10080 @Override 10081 public void run() { 10082 if (report != null) { 10083 sb.append(report); 10084 } 10085 if (logFile != null) { 10086 try { 10087 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10088 "\n\n[[TRUNCATED]]")); 10089 } catch (IOException e) { 10090 Slog.e(TAG, "Error reading " + logFile, e); 10091 } 10092 } 10093 if (crashInfo != null && crashInfo.stackTrace != null) { 10094 sb.append(crashInfo.stackTrace); 10095 } 10096 10097 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10098 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10099 if (lines > 0) { 10100 sb.append("\n"); 10101 10102 // Merge several logcat streams, and take the last N lines 10103 InputStreamReader input = null; 10104 try { 10105 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10106 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10107 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10108 10109 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10110 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10111 input = new InputStreamReader(logcat.getInputStream()); 10112 10113 int num; 10114 char[] buf = new char[8192]; 10115 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10116 } catch (IOException e) { 10117 Slog.e(TAG, "Error running logcat", e); 10118 } finally { 10119 if (input != null) try { input.close(); } catch (IOException e) {} 10120 } 10121 } 10122 10123 dbox.addText(dropboxTag, sb.toString()); 10124 } 10125 }; 10126 10127 if (process == null) { 10128 // If process is null, we are being called from some internal code 10129 // and may be about to die -- run this synchronously. 10130 worker.run(); 10131 } else { 10132 worker.start(); 10133 } 10134 } 10135 10136 /** 10137 * Bring up the "unexpected error" dialog box for a crashing app. 10138 * Deal with edge cases (intercepts from instrumented applications, 10139 * ActivityController, error intent receivers, that sort of thing). 10140 * @param r the application crashing 10141 * @param crashInfo describing the failure 10142 */ 10143 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10144 long timeMillis = System.currentTimeMillis(); 10145 String shortMsg = crashInfo.exceptionClassName; 10146 String longMsg = crashInfo.exceptionMessage; 10147 String stackTrace = crashInfo.stackTrace; 10148 if (shortMsg != null && longMsg != null) { 10149 longMsg = shortMsg + ": " + longMsg; 10150 } else if (shortMsg != null) { 10151 longMsg = shortMsg; 10152 } 10153 10154 AppErrorResult result = new AppErrorResult(); 10155 synchronized (this) { 10156 if (mController != null) { 10157 try { 10158 String name = r != null ? r.processName : null; 10159 int pid = r != null ? r.pid : Binder.getCallingPid(); 10160 if (!mController.appCrashed(name, pid, 10161 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10162 Slog.w(TAG, "Force-killing crashed app " + name 10163 + " at watcher's request"); 10164 Process.killProcess(pid); 10165 return; 10166 } 10167 } catch (RemoteException e) { 10168 mController = null; 10169 Watchdog.getInstance().setActivityController(null); 10170 } 10171 } 10172 10173 final long origId = Binder.clearCallingIdentity(); 10174 10175 // If this process is running instrumentation, finish it. 10176 if (r != null && r.instrumentationClass != null) { 10177 Slog.w(TAG, "Error in app " + r.processName 10178 + " running instrumentation " + r.instrumentationClass + ":"); 10179 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10180 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10181 Bundle info = new Bundle(); 10182 info.putString("shortMsg", shortMsg); 10183 info.putString("longMsg", longMsg); 10184 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10185 Binder.restoreCallingIdentity(origId); 10186 return; 10187 } 10188 10189 // If we can't identify the process or it's already exceeded its crash quota, 10190 // quit right away without showing a crash dialog. 10191 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10192 Binder.restoreCallingIdentity(origId); 10193 return; 10194 } 10195 10196 Message msg = Message.obtain(); 10197 msg.what = SHOW_ERROR_MSG; 10198 HashMap data = new HashMap(); 10199 data.put("result", result); 10200 data.put("app", r); 10201 msg.obj = data; 10202 mHandler.sendMessage(msg); 10203 10204 Binder.restoreCallingIdentity(origId); 10205 } 10206 10207 int res = result.get(); 10208 10209 Intent appErrorIntent = null; 10210 synchronized (this) { 10211 if (r != null && !r.isolated) { 10212 // XXX Can't keep track of crash time for isolated processes, 10213 // since they don't have a persistent identity. 10214 mProcessCrashTimes.put(r.info.processName, r.uid, 10215 SystemClock.uptimeMillis()); 10216 } 10217 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10218 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10219 } 10220 } 10221 10222 if (appErrorIntent != null) { 10223 try { 10224 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10225 } catch (ActivityNotFoundException e) { 10226 Slog.w(TAG, "bug report receiver dissappeared", e); 10227 } 10228 } 10229 } 10230 10231 Intent createAppErrorIntentLocked(ProcessRecord r, 10232 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10233 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10234 if (report == null) { 10235 return null; 10236 } 10237 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10238 result.setComponent(r.errorReportReceiver); 10239 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10240 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10241 return result; 10242 } 10243 10244 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10245 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10246 if (r.errorReportReceiver == null) { 10247 return null; 10248 } 10249 10250 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10251 return null; 10252 } 10253 10254 ApplicationErrorReport report = new ApplicationErrorReport(); 10255 report.packageName = r.info.packageName; 10256 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10257 report.processName = r.processName; 10258 report.time = timeMillis; 10259 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10260 10261 if (r.crashing || r.forceCrashReport) { 10262 report.type = ApplicationErrorReport.TYPE_CRASH; 10263 report.crashInfo = crashInfo; 10264 } else if (r.notResponding) { 10265 report.type = ApplicationErrorReport.TYPE_ANR; 10266 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10267 10268 report.anrInfo.activity = r.notRespondingReport.tag; 10269 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10270 report.anrInfo.info = r.notRespondingReport.longMsg; 10271 } 10272 10273 return report; 10274 } 10275 10276 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10277 enforceNotIsolatedCaller("getProcessesInErrorState"); 10278 // assume our apps are happy - lazy create the list 10279 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10280 10281 final boolean allUsers = ActivityManager.checkUidPermission( 10282 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10283 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10284 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10285 10286 synchronized (this) { 10287 10288 // iterate across all processes 10289 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10290 ProcessRecord app = mLruProcesses.get(i); 10291 if (!allUsers && app.userId != userId) { 10292 continue; 10293 } 10294 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10295 // This one's in trouble, so we'll generate a report for it 10296 // crashes are higher priority (in case there's a crash *and* an anr) 10297 ActivityManager.ProcessErrorStateInfo report = null; 10298 if (app.crashing) { 10299 report = app.crashingReport; 10300 } else if (app.notResponding) { 10301 report = app.notRespondingReport; 10302 } 10303 10304 if (report != null) { 10305 if (errList == null) { 10306 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10307 } 10308 errList.add(report); 10309 } else { 10310 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10311 " crashing = " + app.crashing + 10312 " notResponding = " + app.notResponding); 10313 } 10314 } 10315 } 10316 } 10317 10318 return errList; 10319 } 10320 10321 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10322 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10323 if (currApp != null) { 10324 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10325 } 10326 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10327 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10328 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10329 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10330 if (currApp != null) { 10331 currApp.lru = 0; 10332 } 10333 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10334 } else if (adj >= ProcessList.SERVICE_ADJ) { 10335 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10336 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10337 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10338 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10339 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10340 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10341 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10342 } else { 10343 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10344 } 10345 } 10346 10347 private void fillInProcMemInfo(ProcessRecord app, 10348 ActivityManager.RunningAppProcessInfo outInfo) { 10349 outInfo.pid = app.pid; 10350 outInfo.uid = app.info.uid; 10351 if (mHeavyWeightProcess == app) { 10352 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10353 } 10354 if (app.persistent) { 10355 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10356 } 10357 if (app.activities.size() > 0) { 10358 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10359 } 10360 outInfo.lastTrimLevel = app.trimMemoryLevel; 10361 int adj = app.curAdj; 10362 outInfo.importance = oomAdjToImportance(adj, outInfo); 10363 outInfo.importanceReasonCode = app.adjTypeCode; 10364 } 10365 10366 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10367 enforceNotIsolatedCaller("getRunningAppProcesses"); 10368 // Lazy instantiation of list 10369 List<ActivityManager.RunningAppProcessInfo> runList = null; 10370 final boolean allUsers = ActivityManager.checkUidPermission( 10371 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10372 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10373 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10374 synchronized (this) { 10375 // Iterate across all processes 10376 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10377 ProcessRecord app = mLruProcesses.get(i); 10378 if (!allUsers && app.userId != userId) { 10379 continue; 10380 } 10381 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10382 // Generate process state info for running application 10383 ActivityManager.RunningAppProcessInfo currApp = 10384 new ActivityManager.RunningAppProcessInfo(app.processName, 10385 app.pid, app.getPackageList()); 10386 fillInProcMemInfo(app, currApp); 10387 if (app.adjSource instanceof ProcessRecord) { 10388 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10389 currApp.importanceReasonImportance = oomAdjToImportance( 10390 app.adjSourceOom, null); 10391 } else if (app.adjSource instanceof ActivityRecord) { 10392 ActivityRecord r = (ActivityRecord)app.adjSource; 10393 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10394 } 10395 if (app.adjTarget instanceof ComponentName) { 10396 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10397 } 10398 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10399 // + " lru=" + currApp.lru); 10400 if (runList == null) { 10401 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10402 } 10403 runList.add(currApp); 10404 } 10405 } 10406 } 10407 return runList; 10408 } 10409 10410 public List<ApplicationInfo> getRunningExternalApplications() { 10411 enforceNotIsolatedCaller("getRunningExternalApplications"); 10412 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10413 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10414 if (runningApps != null && runningApps.size() > 0) { 10415 Set<String> extList = new HashSet<String>(); 10416 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10417 if (app.pkgList != null) { 10418 for (String pkg : app.pkgList) { 10419 extList.add(pkg); 10420 } 10421 } 10422 } 10423 IPackageManager pm = AppGlobals.getPackageManager(); 10424 for (String pkg : extList) { 10425 try { 10426 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10427 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10428 retList.add(info); 10429 } 10430 } catch (RemoteException e) { 10431 } 10432 } 10433 } 10434 return retList; 10435 } 10436 10437 @Override 10438 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10439 enforceNotIsolatedCaller("getMyMemoryState"); 10440 synchronized (this) { 10441 ProcessRecord proc; 10442 synchronized (mPidsSelfLocked) { 10443 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10444 } 10445 fillInProcMemInfo(proc, outInfo); 10446 } 10447 } 10448 10449 @Override 10450 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10451 if (checkCallingPermission(android.Manifest.permission.DUMP) 10452 != PackageManager.PERMISSION_GRANTED) { 10453 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10454 + Binder.getCallingPid() 10455 + ", uid=" + Binder.getCallingUid() 10456 + " without permission " 10457 + android.Manifest.permission.DUMP); 10458 return; 10459 } 10460 10461 boolean dumpAll = false; 10462 boolean dumpClient = false; 10463 String dumpPackage = null; 10464 10465 int opti = 0; 10466 while (opti < args.length) { 10467 String opt = args[opti]; 10468 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10469 break; 10470 } 10471 opti++; 10472 if ("-a".equals(opt)) { 10473 dumpAll = true; 10474 } else if ("-c".equals(opt)) { 10475 dumpClient = true; 10476 } else if ("-h".equals(opt)) { 10477 pw.println("Activity manager dump options:"); 10478 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10479 pw.println(" cmd may be one of:"); 10480 pw.println(" a[ctivities]: activity stack state"); 10481 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10482 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10483 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10484 pw.println(" o[om]: out of memory management"); 10485 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10486 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10487 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10488 pw.println(" service [COMP_SPEC]: service client-side state"); 10489 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10490 pw.println(" all: dump all activities"); 10491 pw.println(" top: dump the top activity"); 10492 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10493 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10494 pw.println(" a partial substring in a component name, a"); 10495 pw.println(" hex object identifier."); 10496 pw.println(" -a: include all available server state."); 10497 pw.println(" -c: include client state."); 10498 return; 10499 } else { 10500 pw.println("Unknown argument: " + opt + "; use -h for help"); 10501 } 10502 } 10503 10504 long origId = Binder.clearCallingIdentity(); 10505 boolean more = false; 10506 // Is the caller requesting to dump a particular piece of data? 10507 if (opti < args.length) { 10508 String cmd = args[opti]; 10509 opti++; 10510 if ("activities".equals(cmd) || "a".equals(cmd)) { 10511 synchronized (this) { 10512 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10513 } 10514 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10515 String[] newArgs; 10516 String name; 10517 if (opti >= args.length) { 10518 name = null; 10519 newArgs = EMPTY_STRING_ARRAY; 10520 } else { 10521 name = args[opti]; 10522 opti++; 10523 newArgs = new String[args.length - opti]; 10524 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10525 args.length - opti); 10526 } 10527 synchronized (this) { 10528 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10529 } 10530 } else if ("intents".equals(cmd) || "i".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 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10545 } 10546 } else if ("processes".equals(cmd) || "p".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 dumpProcessesLocked(fd, pw, args, opti, true, name); 10561 } 10562 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10563 synchronized (this) { 10564 dumpOomLocked(fd, pw, args, opti, true); 10565 } 10566 } else if ("provider".equals(cmd)) { 10567 String[] newArgs; 10568 String name; 10569 if (opti >= args.length) { 10570 name = null; 10571 newArgs = EMPTY_STRING_ARRAY; 10572 } else { 10573 name = args[opti]; 10574 opti++; 10575 newArgs = new String[args.length - opti]; 10576 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10577 } 10578 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10579 pw.println("No providers match: " + name); 10580 pw.println("Use -h for help."); 10581 } 10582 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10583 synchronized (this) { 10584 dumpProvidersLocked(fd, pw, args, opti, true, null); 10585 } 10586 } else if ("service".equals(cmd)) { 10587 String[] newArgs; 10588 String name; 10589 if (opti >= args.length) { 10590 name = null; 10591 newArgs = EMPTY_STRING_ARRAY; 10592 } else { 10593 name = args[opti]; 10594 opti++; 10595 newArgs = new String[args.length - opti]; 10596 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10597 args.length - opti); 10598 } 10599 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10600 pw.println("No services match: " + name); 10601 pw.println("Use -h for help."); 10602 } 10603 } else if ("package".equals(cmd)) { 10604 String[] newArgs; 10605 if (opti >= args.length) { 10606 pw.println("package: no package name specified"); 10607 pw.println("Use -h for help."); 10608 } else { 10609 dumpPackage = 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 args = newArgs; 10615 opti = 0; 10616 more = true; 10617 } 10618 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10619 synchronized (this) { 10620 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10621 } 10622 } else { 10623 // Dumping a single activity? 10624 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10625 pw.println("Bad activity command, or no activities match: " + cmd); 10626 pw.println("Use -h for help."); 10627 } 10628 } 10629 if (!more) { 10630 Binder.restoreCallingIdentity(origId); 10631 return; 10632 } 10633 } 10634 10635 // No piece of data specified, dump everything. 10636 synchronized (this) { 10637 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10638 pw.println(); 10639 if (dumpAll) { 10640 pw.println("-------------------------------------------------------------------------------"); 10641 } 10642 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10643 pw.println(); 10644 if (dumpAll) { 10645 pw.println("-------------------------------------------------------------------------------"); 10646 } 10647 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10648 pw.println(); 10649 if (dumpAll) { 10650 pw.println("-------------------------------------------------------------------------------"); 10651 } 10652 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10653 pw.println(); 10654 if (dumpAll) { 10655 pw.println("-------------------------------------------------------------------------------"); 10656 } 10657 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10658 pw.println(); 10659 if (dumpAll) { 10660 pw.println("-------------------------------------------------------------------------------"); 10661 } 10662 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10663 } 10664 Binder.restoreCallingIdentity(origId); 10665 } 10666 10667 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10668 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10669 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10670 10671 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10672 dumpPackage); 10673 boolean needSep = printedAnything; 10674 10675 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10676 dumpPackage, needSep, " mFocusedActivity: "); 10677 if (printed) { 10678 printedAnything = true; 10679 needSep = false; 10680 } 10681 10682 if (dumpPackage == null) { 10683 if (needSep) { 10684 pw.println(); 10685 } 10686 needSep = true; 10687 printedAnything = true; 10688 mStackSupervisor.dump(pw, " "); 10689 } 10690 10691 if (mRecentTasks.size() > 0) { 10692 boolean printedHeader = false; 10693 10694 final int N = mRecentTasks.size(); 10695 for (int i=0; i<N; i++) { 10696 TaskRecord tr = mRecentTasks.get(i); 10697 if (dumpPackage != null) { 10698 if (tr.realActivity == null || 10699 !dumpPackage.equals(tr.realActivity)) { 10700 continue; 10701 } 10702 } 10703 if (!printedHeader) { 10704 if (needSep) { 10705 pw.println(); 10706 } 10707 pw.println(" Recent tasks:"); 10708 printedHeader = true; 10709 printedAnything = true; 10710 } 10711 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10712 pw.println(tr); 10713 if (dumpAll) { 10714 mRecentTasks.get(i).dump(pw, " "); 10715 } 10716 } 10717 } 10718 10719 if (!printedAnything) { 10720 pw.println(" (nothing)"); 10721 } 10722 } 10723 10724 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10725 int opti, boolean dumpAll, String dumpPackage) { 10726 boolean needSep = false; 10727 boolean printedAnything = false; 10728 int numPers = 0; 10729 10730 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10731 10732 if (dumpAll) { 10733 final int NP = mProcessNames.getMap().size(); 10734 for (int ip=0; ip<NP; ip++) { 10735 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10736 final int NA = procs.size(); 10737 for (int ia=0; ia<NA; ia++) { 10738 ProcessRecord r = procs.valueAt(ia); 10739 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10740 continue; 10741 } 10742 if (!needSep) { 10743 pw.println(" All known processes:"); 10744 needSep = true; 10745 printedAnything = true; 10746 } 10747 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10748 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10749 pw.print(" "); pw.println(r); 10750 r.dump(pw, " "); 10751 if (r.persistent) { 10752 numPers++; 10753 } 10754 } 10755 } 10756 } 10757 10758 if (mIsolatedProcesses.size() > 0) { 10759 boolean printed = false; 10760 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10761 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10762 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10763 continue; 10764 } 10765 if (!printed) { 10766 if (needSep) { 10767 pw.println(); 10768 } 10769 pw.println(" Isolated process list (sorted by uid):"); 10770 printedAnything = true; 10771 printed = true; 10772 needSep = true; 10773 } 10774 pw.println(String.format("%sIsolated #%2d: %s", 10775 " ", i, r.toString())); 10776 } 10777 } 10778 10779 if (mLruProcesses.size() > 0) { 10780 if (needSep) { 10781 pw.println(); 10782 } 10783 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10784 pw.print(" total, non-act at "); 10785 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10786 pw.print(", non-svc at "); 10787 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10788 pw.println("):"); 10789 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10790 needSep = true; 10791 printedAnything = true; 10792 } 10793 10794 if (dumpAll || dumpPackage != null) { 10795 synchronized (mPidsSelfLocked) { 10796 boolean printed = false; 10797 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10798 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10799 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10800 continue; 10801 } 10802 if (!printed) { 10803 if (needSep) pw.println(); 10804 needSep = true; 10805 pw.println(" PID mappings:"); 10806 printed = true; 10807 printedAnything = true; 10808 } 10809 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10810 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10811 } 10812 } 10813 } 10814 10815 if (mForegroundProcesses.size() > 0) { 10816 synchronized (mPidsSelfLocked) { 10817 boolean printed = false; 10818 for (int i=0; i<mForegroundProcesses.size(); i++) { 10819 ProcessRecord r = mPidsSelfLocked.get( 10820 mForegroundProcesses.valueAt(i).pid); 10821 if (dumpPackage != null && (r == null 10822 || !r.pkgList.containsKey(dumpPackage))) { 10823 continue; 10824 } 10825 if (!printed) { 10826 if (needSep) pw.println(); 10827 needSep = true; 10828 pw.println(" Foreground Processes:"); 10829 printed = true; 10830 printedAnything = true; 10831 } 10832 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10833 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10834 } 10835 } 10836 } 10837 10838 if (mPersistentStartingProcesses.size() > 0) { 10839 if (needSep) pw.println(); 10840 needSep = true; 10841 printedAnything = true; 10842 pw.println(" Persisent processes that are starting:"); 10843 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10844 "Starting Norm", "Restarting PERS", dumpPackage); 10845 } 10846 10847 if (mRemovedProcesses.size() > 0) { 10848 if (needSep) pw.println(); 10849 needSep = true; 10850 printedAnything = true; 10851 pw.println(" Processes that are being removed:"); 10852 dumpProcessList(pw, this, mRemovedProcesses, " ", 10853 "Removed Norm", "Removed PERS", dumpPackage); 10854 } 10855 10856 if (mProcessesOnHold.size() > 0) { 10857 if (needSep) pw.println(); 10858 needSep = true; 10859 printedAnything = true; 10860 pw.println(" Processes that are on old until the system is ready:"); 10861 dumpProcessList(pw, this, mProcessesOnHold, " ", 10862 "OnHold Norm", "OnHold PERS", dumpPackage); 10863 } 10864 10865 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10866 10867 if (mProcessCrashTimes.getMap().size() > 0) { 10868 boolean printed = false; 10869 long now = SystemClock.uptimeMillis(); 10870 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10871 final int NP = pmap.size(); 10872 for (int ip=0; ip<NP; ip++) { 10873 String pname = pmap.keyAt(ip); 10874 SparseArray<Long> uids = pmap.valueAt(ip); 10875 final int N = uids.size(); 10876 for (int i=0; i<N; i++) { 10877 int puid = uids.keyAt(i); 10878 ProcessRecord r = mProcessNames.get(pname, puid); 10879 if (dumpPackage != null && (r == null 10880 || !r.pkgList.containsKey(dumpPackage))) { 10881 continue; 10882 } 10883 if (!printed) { 10884 if (needSep) pw.println(); 10885 needSep = true; 10886 pw.println(" Time since processes crashed:"); 10887 printed = true; 10888 printedAnything = true; 10889 } 10890 pw.print(" Process "); pw.print(pname); 10891 pw.print(" uid "); pw.print(puid); 10892 pw.print(": last crashed "); 10893 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10894 pw.println(" ago"); 10895 } 10896 } 10897 } 10898 10899 if (mBadProcesses.getMap().size() > 0) { 10900 boolean printed = false; 10901 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10902 final int NP = pmap.size(); 10903 for (int ip=0; ip<NP; ip++) { 10904 String pname = pmap.keyAt(ip); 10905 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10906 final int N = uids.size(); 10907 for (int i=0; i<N; i++) { 10908 int puid = uids.keyAt(i); 10909 ProcessRecord r = mProcessNames.get(pname, puid); 10910 if (dumpPackage != null && (r == null 10911 || !r.pkgList.containsKey(dumpPackage))) { 10912 continue; 10913 } 10914 if (!printed) { 10915 if (needSep) pw.println(); 10916 needSep = true; 10917 pw.println(" Bad processes:"); 10918 printedAnything = true; 10919 } 10920 BadProcessInfo info = uids.valueAt(i); 10921 pw.print(" Bad process "); pw.print(pname); 10922 pw.print(" uid "); pw.print(puid); 10923 pw.print(": crashed at time "); pw.println(info.time); 10924 if (info.shortMsg != null) { 10925 pw.print(" Short msg: "); pw.println(info.shortMsg); 10926 } 10927 if (info.longMsg != null) { 10928 pw.print(" Long msg: "); pw.println(info.longMsg); 10929 } 10930 if (info.stack != null) { 10931 pw.println(" Stack:"); 10932 int lastPos = 0; 10933 for (int pos=0; pos<info.stack.length(); pos++) { 10934 if (info.stack.charAt(pos) == '\n') { 10935 pw.print(" "); 10936 pw.write(info.stack, lastPos, pos-lastPos); 10937 pw.println(); 10938 lastPos = pos+1; 10939 } 10940 } 10941 if (lastPos < info.stack.length()) { 10942 pw.print(" "); 10943 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10944 pw.println(); 10945 } 10946 } 10947 } 10948 } 10949 } 10950 10951 if (dumpPackage == null) { 10952 pw.println(); 10953 needSep = false; 10954 pw.println(" mStartedUsers:"); 10955 for (int i=0; i<mStartedUsers.size(); i++) { 10956 UserStartedState uss = mStartedUsers.valueAt(i); 10957 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10958 pw.print(": "); uss.dump("", pw); 10959 } 10960 pw.print(" mStartedUserArray: ["); 10961 for (int i=0; i<mStartedUserArray.length; i++) { 10962 if (i > 0) pw.print(", "); 10963 pw.print(mStartedUserArray[i]); 10964 } 10965 pw.println("]"); 10966 pw.print(" mUserLru: ["); 10967 for (int i=0; i<mUserLru.size(); i++) { 10968 if (i > 0) pw.print(", "); 10969 pw.print(mUserLru.get(i)); 10970 } 10971 pw.println("]"); 10972 if (dumpAll) { 10973 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10974 } 10975 } 10976 if (mHomeProcess != null && (dumpPackage == null 10977 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 10978 if (needSep) { 10979 pw.println(); 10980 needSep = false; 10981 } 10982 pw.println(" mHomeProcess: " + mHomeProcess); 10983 } 10984 if (mPreviousProcess != null && (dumpPackage == null 10985 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 10986 if (needSep) { 10987 pw.println(); 10988 needSep = false; 10989 } 10990 pw.println(" mPreviousProcess: " + mPreviousProcess); 10991 } 10992 if (dumpAll) { 10993 StringBuilder sb = new StringBuilder(128); 10994 sb.append(" mPreviousProcessVisibleTime: "); 10995 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 10996 pw.println(sb); 10997 } 10998 if (mHeavyWeightProcess != null && (dumpPackage == null 10999 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11000 if (needSep) { 11001 pw.println(); 11002 needSep = false; 11003 } 11004 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11005 } 11006 if (dumpPackage == null) { 11007 pw.println(" mConfiguration: " + mConfiguration); 11008 } 11009 if (dumpAll) { 11010 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11011 if (mCompatModePackages.getPackages().size() > 0) { 11012 boolean printed = false; 11013 for (Map.Entry<String, Integer> entry 11014 : mCompatModePackages.getPackages().entrySet()) { 11015 String pkg = entry.getKey(); 11016 int mode = entry.getValue(); 11017 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11018 continue; 11019 } 11020 if (!printed) { 11021 pw.println(" mScreenCompatPackages:"); 11022 printed = true; 11023 } 11024 pw.print(" "); pw.print(pkg); pw.print(": "); 11025 pw.print(mode); pw.println(); 11026 } 11027 } 11028 } 11029 if (dumpPackage == null) { 11030 if (mSleeping || mWentToSleep || mLockScreenShown) { 11031 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11032 + " mLockScreenShown " + mLockScreenShown); 11033 } 11034 if (mShuttingDown) { 11035 pw.println(" mShuttingDown=" + mShuttingDown); 11036 } 11037 } 11038 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11039 || mOrigWaitForDebugger) { 11040 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11041 || dumpPackage.equals(mOrigDebugApp)) { 11042 if (needSep) { 11043 pw.println(); 11044 needSep = false; 11045 } 11046 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11047 + " mDebugTransient=" + mDebugTransient 11048 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11049 } 11050 } 11051 if (mOpenGlTraceApp != null) { 11052 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11053 if (needSep) { 11054 pw.println(); 11055 needSep = false; 11056 } 11057 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11058 } 11059 } 11060 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11061 || mProfileFd != null) { 11062 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11063 if (needSep) { 11064 pw.println(); 11065 needSep = false; 11066 } 11067 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11068 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11069 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11070 + mAutoStopProfiler); 11071 } 11072 } 11073 if (dumpPackage == null) { 11074 if (mAlwaysFinishActivities || mController != null) { 11075 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11076 + " mController=" + mController); 11077 } 11078 if (dumpAll) { 11079 pw.println(" Total persistent processes: " + numPers); 11080 pw.println(" mStartRunning=" + mStartRunning 11081 + " mProcessesReady=" + mProcessesReady 11082 + " mSystemReady=" + mSystemReady); 11083 pw.println(" mBooting=" + mBooting 11084 + " mBooted=" + mBooted 11085 + " mFactoryTest=" + mFactoryTest); 11086 pw.print(" mLastPowerCheckRealtime="); 11087 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11088 pw.println(""); 11089 pw.print(" mLastPowerCheckUptime="); 11090 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11091 pw.println(""); 11092 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11093 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11094 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11095 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11096 + " (" + mLruProcesses.size() + " total)" 11097 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11098 + " mNumServiceProcs=" + mNumServiceProcs 11099 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11100 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11101 + " mLastMemoryLevel" + mLastMemoryLevel 11102 + " mLastNumProcesses" + mLastNumProcesses); 11103 long now = SystemClock.uptimeMillis(); 11104 pw.print(" mLastIdleTime="); 11105 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11106 pw.print(" mLowRamSinceLastIdle="); 11107 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11108 pw.println(); 11109 } 11110 } 11111 11112 if (!printedAnything) { 11113 pw.println(" (nothing)"); 11114 } 11115 } 11116 11117 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11118 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11119 if (mProcessesToGc.size() > 0) { 11120 boolean printed = false; 11121 long now = SystemClock.uptimeMillis(); 11122 for (int i=0; i<mProcessesToGc.size(); i++) { 11123 ProcessRecord proc = mProcessesToGc.get(i); 11124 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11125 continue; 11126 } 11127 if (!printed) { 11128 if (needSep) pw.println(); 11129 needSep = true; 11130 pw.println(" Processes that are waiting to GC:"); 11131 printed = true; 11132 } 11133 pw.print(" Process "); pw.println(proc); 11134 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11135 pw.print(", last gced="); 11136 pw.print(now-proc.lastRequestedGc); 11137 pw.print(" ms ago, last lowMem="); 11138 pw.print(now-proc.lastLowMemory); 11139 pw.println(" ms ago"); 11140 11141 } 11142 } 11143 return needSep; 11144 } 11145 11146 void printOomLevel(PrintWriter pw, String name, int adj) { 11147 pw.print(" "); 11148 if (adj >= 0) { 11149 pw.print(' '); 11150 if (adj < 10) pw.print(' '); 11151 } else { 11152 if (adj > -10) pw.print(' '); 11153 } 11154 pw.print(adj); 11155 pw.print(": "); 11156 pw.print(name); 11157 pw.print(" ("); 11158 pw.print(mProcessList.getMemLevel(adj)/1024); 11159 pw.println(" kB)"); 11160 } 11161 11162 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11163 int opti, boolean dumpAll) { 11164 boolean needSep = false; 11165 11166 if (mLruProcesses.size() > 0) { 11167 if (needSep) pw.println(); 11168 needSep = true; 11169 pw.println(" OOM levels:"); 11170 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11171 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11172 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11173 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11174 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11175 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11176 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11177 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11178 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11179 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11180 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11181 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11182 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11183 11184 if (needSep) pw.println(); 11185 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11186 pw.print(" total, non-act at "); 11187 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11188 pw.print(", non-svc at "); 11189 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11190 pw.println("):"); 11191 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11192 needSep = true; 11193 } 11194 11195 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11196 11197 pw.println(); 11198 pw.println(" mHomeProcess: " + mHomeProcess); 11199 pw.println(" mPreviousProcess: " + mPreviousProcess); 11200 if (mHeavyWeightProcess != null) { 11201 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11202 } 11203 11204 return true; 11205 } 11206 11207 /** 11208 * There are three ways to call this: 11209 * - no provider specified: dump all the providers 11210 * - a flattened component name that matched an existing provider was specified as the 11211 * first arg: dump that one provider 11212 * - the first arg isn't the flattened component name of an existing provider: 11213 * dump all providers whose component contains the first arg as a substring 11214 */ 11215 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11216 int opti, boolean dumpAll) { 11217 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11218 } 11219 11220 static class ItemMatcher { 11221 ArrayList<ComponentName> components; 11222 ArrayList<String> strings; 11223 ArrayList<Integer> objects; 11224 boolean all; 11225 11226 ItemMatcher() { 11227 all = true; 11228 } 11229 11230 void build(String name) { 11231 ComponentName componentName = ComponentName.unflattenFromString(name); 11232 if (componentName != null) { 11233 if (components == null) { 11234 components = new ArrayList<ComponentName>(); 11235 } 11236 components.add(componentName); 11237 all = false; 11238 } else { 11239 int objectId = 0; 11240 // Not a '/' separated full component name; maybe an object ID? 11241 try { 11242 objectId = Integer.parseInt(name, 16); 11243 if (objects == null) { 11244 objects = new ArrayList<Integer>(); 11245 } 11246 objects.add(objectId); 11247 all = false; 11248 } catch (RuntimeException e) { 11249 // Not an integer; just do string match. 11250 if (strings == null) { 11251 strings = new ArrayList<String>(); 11252 } 11253 strings.add(name); 11254 all = false; 11255 } 11256 } 11257 } 11258 11259 int build(String[] args, int opti) { 11260 for (; opti<args.length; opti++) { 11261 String name = args[opti]; 11262 if ("--".equals(name)) { 11263 return opti+1; 11264 } 11265 build(name); 11266 } 11267 return opti; 11268 } 11269 11270 boolean match(Object object, ComponentName comp) { 11271 if (all) { 11272 return true; 11273 } 11274 if (components != null) { 11275 for (int i=0; i<components.size(); i++) { 11276 if (components.get(i).equals(comp)) { 11277 return true; 11278 } 11279 } 11280 } 11281 if (objects != null) { 11282 for (int i=0; i<objects.size(); i++) { 11283 if (System.identityHashCode(object) == objects.get(i)) { 11284 return true; 11285 } 11286 } 11287 } 11288 if (strings != null) { 11289 String flat = comp.flattenToString(); 11290 for (int i=0; i<strings.size(); i++) { 11291 if (flat.contains(strings.get(i))) { 11292 return true; 11293 } 11294 } 11295 } 11296 return false; 11297 } 11298 } 11299 11300 /** 11301 * There are three things that cmd can be: 11302 * - a flattened component name that matches an existing activity 11303 * - the cmd arg isn't the flattened component name of an existing activity: 11304 * dump all activity whose component contains the cmd as a substring 11305 * - A hex number of the ActivityRecord object instance. 11306 */ 11307 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11308 int opti, boolean dumpAll) { 11309 ArrayList<ActivityRecord> activities; 11310 11311 synchronized (this) { 11312 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11313 } 11314 11315 if (activities.size() <= 0) { 11316 return false; 11317 } 11318 11319 String[] newArgs = new String[args.length - opti]; 11320 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11321 11322 TaskRecord lastTask = null; 11323 boolean needSep = false; 11324 for (int i=activities.size()-1; i>=0; i--) { 11325 ActivityRecord r = activities.get(i); 11326 if (needSep) { 11327 pw.println(); 11328 } 11329 needSep = true; 11330 synchronized (this) { 11331 if (lastTask != r.task) { 11332 lastTask = r.task; 11333 pw.print("TASK "); pw.print(lastTask.affinity); 11334 pw.print(" id="); pw.println(lastTask.taskId); 11335 if (dumpAll) { 11336 lastTask.dump(pw, " "); 11337 } 11338 } 11339 } 11340 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11341 } 11342 return true; 11343 } 11344 11345 /** 11346 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11347 * there is a thread associated with the activity. 11348 */ 11349 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11350 final ActivityRecord r, String[] args, boolean dumpAll) { 11351 String innerPrefix = prefix + " "; 11352 synchronized (this) { 11353 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11354 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11355 pw.print(" pid="); 11356 if (r.app != null) pw.println(r.app.pid); 11357 else pw.println("(not running)"); 11358 if (dumpAll) { 11359 r.dump(pw, innerPrefix); 11360 } 11361 } 11362 if (r.app != null && r.app.thread != null) { 11363 // flush anything that is already in the PrintWriter since the thread is going 11364 // to write to the file descriptor directly 11365 pw.flush(); 11366 try { 11367 TransferPipe tp = new TransferPipe(); 11368 try { 11369 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11370 r.appToken, innerPrefix, args); 11371 tp.go(fd); 11372 } finally { 11373 tp.kill(); 11374 } 11375 } catch (IOException e) { 11376 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11377 } catch (RemoteException e) { 11378 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11379 } 11380 } 11381 } 11382 11383 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11384 int opti, boolean dumpAll, String dumpPackage) { 11385 boolean needSep = false; 11386 boolean onlyHistory = false; 11387 boolean printedAnything = false; 11388 11389 if ("history".equals(dumpPackage)) { 11390 if (opti < args.length && "-s".equals(args[opti])) { 11391 dumpAll = false; 11392 } 11393 onlyHistory = true; 11394 dumpPackage = null; 11395 } 11396 11397 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11398 if (!onlyHistory && dumpAll) { 11399 if (mRegisteredReceivers.size() > 0) { 11400 boolean printed = false; 11401 Iterator it = mRegisteredReceivers.values().iterator(); 11402 while (it.hasNext()) { 11403 ReceiverList r = (ReceiverList)it.next(); 11404 if (dumpPackage != null && (r.app == null || 11405 !dumpPackage.equals(r.app.info.packageName))) { 11406 continue; 11407 } 11408 if (!printed) { 11409 pw.println(" Registered Receivers:"); 11410 needSep = true; 11411 printed = true; 11412 printedAnything = true; 11413 } 11414 pw.print(" * "); pw.println(r); 11415 r.dump(pw, " "); 11416 } 11417 } 11418 11419 if (mReceiverResolver.dump(pw, needSep ? 11420 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11421 " ", dumpPackage, false)) { 11422 needSep = true; 11423 printedAnything = true; 11424 } 11425 } 11426 11427 for (BroadcastQueue q : mBroadcastQueues) { 11428 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11429 printedAnything |= needSep; 11430 } 11431 11432 needSep = true; 11433 11434 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11435 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11436 if (needSep) { 11437 pw.println(); 11438 } 11439 needSep = true; 11440 printedAnything = true; 11441 pw.print(" Sticky broadcasts for user "); 11442 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11443 StringBuilder sb = new StringBuilder(128); 11444 for (Map.Entry<String, ArrayList<Intent>> ent 11445 : mStickyBroadcasts.valueAt(user).entrySet()) { 11446 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11447 if (dumpAll) { 11448 pw.println(":"); 11449 ArrayList<Intent> intents = ent.getValue(); 11450 final int N = intents.size(); 11451 for (int i=0; i<N; i++) { 11452 sb.setLength(0); 11453 sb.append(" Intent: "); 11454 intents.get(i).toShortString(sb, false, true, false, false); 11455 pw.println(sb.toString()); 11456 Bundle bundle = intents.get(i).getExtras(); 11457 if (bundle != null) { 11458 pw.print(" "); 11459 pw.println(bundle.toString()); 11460 } 11461 } 11462 } else { 11463 pw.println(""); 11464 } 11465 } 11466 } 11467 } 11468 11469 if (!onlyHistory && dumpAll) { 11470 pw.println(); 11471 for (BroadcastQueue queue : mBroadcastQueues) { 11472 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11473 + queue.mBroadcastsScheduled); 11474 } 11475 pw.println(" mHandler:"); 11476 mHandler.dump(new PrintWriterPrinter(pw), " "); 11477 needSep = true; 11478 printedAnything = true; 11479 } 11480 11481 if (!printedAnything) { 11482 pw.println(" (nothing)"); 11483 } 11484 } 11485 11486 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11487 int opti, boolean dumpAll, String dumpPackage) { 11488 boolean needSep; 11489 boolean printedAnything = false; 11490 11491 ItemMatcher matcher = new ItemMatcher(); 11492 matcher.build(args, opti); 11493 11494 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11495 11496 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11497 printedAnything |= needSep; 11498 11499 if (mLaunchingProviders.size() > 0) { 11500 boolean printed = false; 11501 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11502 ContentProviderRecord r = mLaunchingProviders.get(i); 11503 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11504 continue; 11505 } 11506 if (!printed) { 11507 if (needSep) pw.println(); 11508 needSep = true; 11509 pw.println(" Launching content providers:"); 11510 printed = true; 11511 printedAnything = true; 11512 } 11513 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11514 pw.println(r); 11515 } 11516 } 11517 11518 if (mGrantedUriPermissions.size() > 0) { 11519 boolean printed = false; 11520 int dumpUid = -2; 11521 if (dumpPackage != null) { 11522 try { 11523 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11524 } catch (NameNotFoundException e) { 11525 dumpUid = -1; 11526 } 11527 } 11528 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11529 int uid = mGrantedUriPermissions.keyAt(i); 11530 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11531 continue; 11532 } 11533 ArrayMap<Uri, UriPermission> perms 11534 = mGrantedUriPermissions.valueAt(i); 11535 if (!printed) { 11536 if (needSep) pw.println(); 11537 needSep = true; 11538 pw.println(" Granted Uri Permissions:"); 11539 printed = true; 11540 printedAnything = true; 11541 } 11542 pw.print(" * UID "); pw.print(uid); 11543 pw.println(" holds:"); 11544 for (UriPermission perm : perms.values()) { 11545 pw.print(" "); pw.println(perm); 11546 if (dumpAll) { 11547 perm.dump(pw, " "); 11548 } 11549 } 11550 } 11551 } 11552 11553 if (!printedAnything) { 11554 pw.println(" (nothing)"); 11555 } 11556 } 11557 11558 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11559 int opti, boolean dumpAll, String dumpPackage) { 11560 boolean printed = false; 11561 11562 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11563 11564 if (mIntentSenderRecords.size() > 0) { 11565 Iterator<WeakReference<PendingIntentRecord>> it 11566 = mIntentSenderRecords.values().iterator(); 11567 while (it.hasNext()) { 11568 WeakReference<PendingIntentRecord> ref = it.next(); 11569 PendingIntentRecord rec = ref != null ? ref.get(): null; 11570 if (dumpPackage != null && (rec == null 11571 || !dumpPackage.equals(rec.key.packageName))) { 11572 continue; 11573 } 11574 printed = true; 11575 if (rec != null) { 11576 pw.print(" * "); pw.println(rec); 11577 if (dumpAll) { 11578 rec.dump(pw, " "); 11579 } 11580 } else { 11581 pw.print(" * "); pw.println(ref); 11582 } 11583 } 11584 } 11585 11586 if (!printed) { 11587 pw.println(" (nothing)"); 11588 } 11589 } 11590 11591 private static final int dumpProcessList(PrintWriter pw, 11592 ActivityManagerService service, List list, 11593 String prefix, String normalLabel, String persistentLabel, 11594 String dumpPackage) { 11595 int numPers = 0; 11596 final int N = list.size()-1; 11597 for (int i=N; i>=0; i--) { 11598 ProcessRecord r = (ProcessRecord)list.get(i); 11599 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11600 continue; 11601 } 11602 pw.println(String.format("%s%s #%2d: %s", 11603 prefix, (r.persistent ? persistentLabel : normalLabel), 11604 i, r.toString())); 11605 if (r.persistent) { 11606 numPers++; 11607 } 11608 } 11609 return numPers; 11610 } 11611 11612 private static final boolean dumpProcessOomList(PrintWriter pw, 11613 ActivityManagerService service, List<ProcessRecord> origList, 11614 String prefix, String normalLabel, String persistentLabel, 11615 boolean inclDetails, String dumpPackage) { 11616 11617 ArrayList<Pair<ProcessRecord, Integer>> list 11618 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11619 for (int i=0; i<origList.size(); i++) { 11620 ProcessRecord r = origList.get(i); 11621 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11622 continue; 11623 } 11624 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11625 } 11626 11627 if (list.size() <= 0) { 11628 return false; 11629 } 11630 11631 Comparator<Pair<ProcessRecord, Integer>> comparator 11632 = new Comparator<Pair<ProcessRecord, Integer>>() { 11633 @Override 11634 public int compare(Pair<ProcessRecord, Integer> object1, 11635 Pair<ProcessRecord, Integer> object2) { 11636 if (object1.first.setAdj != object2.first.setAdj) { 11637 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11638 } 11639 if (object1.second.intValue() != object2.second.intValue()) { 11640 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11641 } 11642 return 0; 11643 } 11644 }; 11645 11646 Collections.sort(list, comparator); 11647 11648 final long curRealtime = SystemClock.elapsedRealtime(); 11649 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11650 final long curUptime = SystemClock.uptimeMillis(); 11651 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11652 11653 for (int i=list.size()-1; i>=0; i--) { 11654 ProcessRecord r = list.get(i).first; 11655 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11656 char schedGroup; 11657 switch (r.setSchedGroup) { 11658 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11659 schedGroup = 'B'; 11660 break; 11661 case Process.THREAD_GROUP_DEFAULT: 11662 schedGroup = 'F'; 11663 break; 11664 default: 11665 schedGroup = '?'; 11666 break; 11667 } 11668 char foreground; 11669 if (r.foregroundActivities) { 11670 foreground = 'A'; 11671 } else if (r.foregroundServices) { 11672 foreground = 'S'; 11673 } else { 11674 foreground = ' '; 11675 } 11676 String procState = ProcessList.makeProcStateString(r.curProcState); 11677 pw.print(prefix); 11678 pw.print(r.persistent ? persistentLabel : normalLabel); 11679 pw.print(" #"); 11680 int num = (origList.size()-1)-list.get(i).second; 11681 if (num < 10) pw.print(' '); 11682 pw.print(num); 11683 pw.print(": "); 11684 pw.print(oomAdj); 11685 pw.print(' '); 11686 pw.print(schedGroup); 11687 pw.print('/'); 11688 pw.print(foreground); 11689 pw.print('/'); 11690 pw.print(procState); 11691 pw.print(" trm:"); 11692 if (r.trimMemoryLevel < 10) pw.print(' '); 11693 pw.print(r.trimMemoryLevel); 11694 pw.print(' '); 11695 pw.print(r.toShortString()); 11696 pw.print(" ("); 11697 pw.print(r.adjType); 11698 pw.println(')'); 11699 if (r.adjSource != null || r.adjTarget != null) { 11700 pw.print(prefix); 11701 pw.print(" "); 11702 if (r.adjTarget instanceof ComponentName) { 11703 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11704 } else if (r.adjTarget != null) { 11705 pw.print(r.adjTarget.toString()); 11706 } else { 11707 pw.print("{null}"); 11708 } 11709 pw.print("<="); 11710 if (r.adjSource instanceof ProcessRecord) { 11711 pw.print("Proc{"); 11712 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11713 pw.println("}"); 11714 } else if (r.adjSource != null) { 11715 pw.println(r.adjSource.toString()); 11716 } else { 11717 pw.println("{null}"); 11718 } 11719 } 11720 if (inclDetails) { 11721 pw.print(prefix); 11722 pw.print(" "); 11723 pw.print("oom: max="); pw.print(r.maxAdj); 11724 pw.print(" curRaw="); pw.print(r.curRawAdj); 11725 pw.print(" setRaw="); pw.print(r.setRawAdj); 11726 pw.print(" cur="); pw.print(r.curAdj); 11727 pw.print(" set="); pw.println(r.setAdj); 11728 pw.print(prefix); 11729 pw.print(" "); 11730 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11731 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11732 pw.print(" lastPss="); pw.print(r.lastPss); 11733 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11734 pw.print(prefix); 11735 pw.print(" "); 11736 pw.print("keeping="); pw.print(r.keeping); 11737 pw.print(" cached="); pw.print(r.cached); 11738 pw.print(" empty="); pw.print(r.empty); 11739 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11740 11741 if (!r.keeping) { 11742 if (r.lastWakeTime != 0) { 11743 long wtime; 11744 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11745 synchronized (stats) { 11746 wtime = stats.getProcessWakeTime(r.info.uid, 11747 r.pid, curRealtime); 11748 } 11749 long timeUsed = wtime - r.lastWakeTime; 11750 pw.print(prefix); 11751 pw.print(" "); 11752 pw.print("keep awake over "); 11753 TimeUtils.formatDuration(realtimeSince, pw); 11754 pw.print(" used "); 11755 TimeUtils.formatDuration(timeUsed, pw); 11756 pw.print(" ("); 11757 pw.print((timeUsed*100)/realtimeSince); 11758 pw.println("%)"); 11759 } 11760 if (r.lastCpuTime != 0) { 11761 long timeUsed = r.curCpuTime - r.lastCpuTime; 11762 pw.print(prefix); 11763 pw.print(" "); 11764 pw.print("run cpu over "); 11765 TimeUtils.formatDuration(uptimeSince, pw); 11766 pw.print(" used "); 11767 TimeUtils.formatDuration(timeUsed, pw); 11768 pw.print(" ("); 11769 pw.print((timeUsed*100)/uptimeSince); 11770 pw.println("%)"); 11771 } 11772 } 11773 } 11774 } 11775 return true; 11776 } 11777 11778 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11779 ArrayList<ProcessRecord> procs; 11780 synchronized (this) { 11781 if (args != null && args.length > start 11782 && args[start].charAt(0) != '-') { 11783 procs = new ArrayList<ProcessRecord>(); 11784 int pid = -1; 11785 try { 11786 pid = Integer.parseInt(args[start]); 11787 } catch (NumberFormatException e) { 11788 } 11789 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11790 ProcessRecord proc = mLruProcesses.get(i); 11791 if (proc.pid == pid) { 11792 procs.add(proc); 11793 } else if (proc.processName.equals(args[start])) { 11794 procs.add(proc); 11795 } 11796 } 11797 if (procs.size() <= 0) { 11798 return null; 11799 } 11800 } else { 11801 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11802 } 11803 } 11804 return procs; 11805 } 11806 11807 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11808 PrintWriter pw, String[] args) { 11809 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11810 if (procs == null) { 11811 pw.println("No process found for: " + args[0]); 11812 return; 11813 } 11814 11815 long uptime = SystemClock.uptimeMillis(); 11816 long realtime = SystemClock.elapsedRealtime(); 11817 pw.println("Applications Graphics Acceleration Info:"); 11818 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11819 11820 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11821 ProcessRecord r = procs.get(i); 11822 if (r.thread != null) { 11823 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11824 pw.flush(); 11825 try { 11826 TransferPipe tp = new TransferPipe(); 11827 try { 11828 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11829 tp.go(fd); 11830 } finally { 11831 tp.kill(); 11832 } 11833 } catch (IOException e) { 11834 pw.println("Failure while dumping the app: " + r); 11835 pw.flush(); 11836 } catch (RemoteException e) { 11837 pw.println("Got a RemoteException while dumping the app " + r); 11838 pw.flush(); 11839 } 11840 } 11841 } 11842 } 11843 11844 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11845 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11846 if (procs == null) { 11847 pw.println("No process found for: " + args[0]); 11848 return; 11849 } 11850 11851 pw.println("Applications Database Info:"); 11852 11853 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11854 ProcessRecord r = procs.get(i); 11855 if (r.thread != null) { 11856 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11857 pw.flush(); 11858 try { 11859 TransferPipe tp = new TransferPipe(); 11860 try { 11861 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11862 tp.go(fd); 11863 } finally { 11864 tp.kill(); 11865 } 11866 } catch (IOException e) { 11867 pw.println("Failure while dumping the app: " + r); 11868 pw.flush(); 11869 } catch (RemoteException e) { 11870 pw.println("Got a RemoteException while dumping the app " + r); 11871 pw.flush(); 11872 } 11873 } 11874 } 11875 } 11876 11877 final static class MemItem { 11878 final boolean isProc; 11879 final String label; 11880 final String shortLabel; 11881 final long pss; 11882 final int id; 11883 final boolean hasActivities; 11884 ArrayList<MemItem> subitems; 11885 11886 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11887 boolean _hasActivities) { 11888 isProc = true; 11889 label = _label; 11890 shortLabel = _shortLabel; 11891 pss = _pss; 11892 id = _id; 11893 hasActivities = _hasActivities; 11894 } 11895 11896 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11897 isProc = false; 11898 label = _label; 11899 shortLabel = _shortLabel; 11900 pss = _pss; 11901 id = _id; 11902 hasActivities = false; 11903 } 11904 } 11905 11906 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11907 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11908 if (sort && !isCompact) { 11909 Collections.sort(items, new Comparator<MemItem>() { 11910 @Override 11911 public int compare(MemItem lhs, MemItem rhs) { 11912 if (lhs.pss < rhs.pss) { 11913 return 1; 11914 } else if (lhs.pss > rhs.pss) { 11915 return -1; 11916 } 11917 return 0; 11918 } 11919 }); 11920 } 11921 11922 for (int i=0; i<items.size(); i++) { 11923 MemItem mi = items.get(i); 11924 if (!isCompact) { 11925 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11926 } else if (mi.isProc) { 11927 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11928 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11929 pw.println(mi.hasActivities ? ",a" : ",e"); 11930 } else { 11931 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11932 pw.println(mi.pss); 11933 } 11934 if (mi.subitems != null) { 11935 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11936 true, isCompact); 11937 } 11938 } 11939 } 11940 11941 // These are in KB. 11942 static final long[] DUMP_MEM_BUCKETS = new long[] { 11943 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11944 120*1024, 160*1024, 200*1024, 11945 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11946 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11947 }; 11948 11949 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11950 boolean stackLike) { 11951 int start = label.lastIndexOf('.'); 11952 if (start >= 0) start++; 11953 else start = 0; 11954 int end = label.length(); 11955 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11956 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11957 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11958 out.append(bucket); 11959 out.append(stackLike ? "MB." : "MB "); 11960 out.append(label, start, end); 11961 return; 11962 } 11963 } 11964 out.append(memKB/1024); 11965 out.append(stackLike ? "MB." : "MB "); 11966 out.append(label, start, end); 11967 } 11968 11969 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11970 ProcessList.NATIVE_ADJ, 11971 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11972 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11973 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11974 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 11975 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 11976 }; 11977 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 11978 "Native", 11979 "System", "Persistent", "Foreground", 11980 "Visible", "Perceptible", 11981 "Heavy Weight", "Backup", 11982 "A Services", "Home", 11983 "Previous", "B Services", "Cached" 11984 }; 11985 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 11986 "native", 11987 "sys", "pers", "fore", 11988 "vis", "percept", 11989 "heavy", "backup", 11990 "servicea", "home", 11991 "prev", "serviceb", "cached" 11992 }; 11993 11994 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 11995 long realtime, boolean isCheckinRequest, boolean isCompact) { 11996 if (isCheckinRequest || isCompact) { 11997 // short checkin version 11998 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 11999 } else { 12000 pw.println("Applications Memory Usage (kB):"); 12001 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12002 } 12003 } 12004 12005 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12006 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12007 boolean dumpDetails = false; 12008 boolean dumpFullDetails = false; 12009 boolean dumpDalvik = false; 12010 boolean oomOnly = false; 12011 boolean isCompact = false; 12012 boolean localOnly = false; 12013 12014 int opti = 0; 12015 while (opti < args.length) { 12016 String opt = args[opti]; 12017 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12018 break; 12019 } 12020 opti++; 12021 if ("-a".equals(opt)) { 12022 dumpDetails = true; 12023 dumpFullDetails = true; 12024 dumpDalvik = true; 12025 } else if ("-d".equals(opt)) { 12026 dumpDalvik = true; 12027 } else if ("-c".equals(opt)) { 12028 isCompact = true; 12029 } else if ("--oom".equals(opt)) { 12030 oomOnly = true; 12031 } else if ("--local".equals(opt)) { 12032 localOnly = true; 12033 } else if ("-h".equals(opt)) { 12034 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12035 pw.println(" -a: include all available information for each process."); 12036 pw.println(" -d: include dalvik details when dumping process details."); 12037 pw.println(" -c: dump in a compact machine-parseable representation."); 12038 pw.println(" --oom: only show processes organized by oom adj."); 12039 pw.println(" --local: only collect details locally, don't call process."); 12040 pw.println("If [process] is specified it can be the name or "); 12041 pw.println("pid of a specific process to dump."); 12042 return; 12043 } else { 12044 pw.println("Unknown argument: " + opt + "; use -h for help"); 12045 } 12046 } 12047 12048 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12049 long uptime = SystemClock.uptimeMillis(); 12050 long realtime = SystemClock.elapsedRealtime(); 12051 final long[] tmpLong = new long[1]; 12052 12053 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12054 if (procs == null) { 12055 // No Java processes. Maybe they want to print a native process. 12056 if (args != null && args.length > opti 12057 && args[opti].charAt(0) != '-') { 12058 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12059 = new ArrayList<ProcessCpuTracker.Stats>(); 12060 updateCpuStatsNow(); 12061 int findPid = -1; 12062 try { 12063 findPid = Integer.parseInt(args[opti]); 12064 } catch (NumberFormatException e) { 12065 } 12066 synchronized (mProcessCpuThread) { 12067 final int N = mProcessCpuTracker.countStats(); 12068 for (int i=0; i<N; i++) { 12069 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12070 if (st.pid == findPid || (st.baseName != null 12071 && st.baseName.equals(args[opti]))) { 12072 nativeProcs.add(st); 12073 } 12074 } 12075 } 12076 if (nativeProcs.size() > 0) { 12077 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12078 isCompact); 12079 Debug.MemoryInfo mi = null; 12080 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12081 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12082 final int pid = r.pid; 12083 if (!isCheckinRequest && dumpDetails) { 12084 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12085 } 12086 if (mi == null) { 12087 mi = new Debug.MemoryInfo(); 12088 } 12089 if (dumpDetails || (!brief && !oomOnly)) { 12090 Debug.getMemoryInfo(pid, mi); 12091 } else { 12092 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12093 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12094 } 12095 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12096 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12097 if (isCheckinRequest) { 12098 pw.println(); 12099 } 12100 } 12101 return; 12102 } 12103 } 12104 pw.println("No process found for: " + args[opti]); 12105 return; 12106 } 12107 12108 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12109 dumpDetails = true; 12110 } 12111 12112 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12113 12114 String[] innerArgs = new String[args.length-opti]; 12115 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12116 12117 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12118 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12119 long nativePss=0, dalvikPss=0, otherPss=0; 12120 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12121 12122 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12123 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12124 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12125 12126 long totalPss = 0; 12127 long cachedPss = 0; 12128 12129 Debug.MemoryInfo mi = null; 12130 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12131 final ProcessRecord r = procs.get(i); 12132 final IApplicationThread thread; 12133 final int pid; 12134 final int oomAdj; 12135 final boolean hasActivities; 12136 synchronized (this) { 12137 thread = r.thread; 12138 pid = r.pid; 12139 oomAdj = r.getSetAdjWithServices(); 12140 hasActivities = r.activities.size() > 0; 12141 } 12142 if (thread != null) { 12143 if (!isCheckinRequest && dumpDetails) { 12144 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12145 } 12146 if (mi == null) { 12147 mi = new Debug.MemoryInfo(); 12148 } 12149 if (dumpDetails || (!brief && !oomOnly)) { 12150 Debug.getMemoryInfo(pid, mi); 12151 } else { 12152 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12153 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12154 } 12155 if (dumpDetails) { 12156 if (localOnly) { 12157 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12158 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12159 if (isCheckinRequest) { 12160 pw.println(); 12161 } 12162 } else { 12163 try { 12164 pw.flush(); 12165 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12166 dumpDalvik, innerArgs); 12167 } catch (RemoteException e) { 12168 if (!isCheckinRequest) { 12169 pw.println("Got RemoteException!"); 12170 pw.flush(); 12171 } 12172 } 12173 } 12174 } 12175 12176 final long myTotalPss = mi.getTotalPss(); 12177 final long myTotalUss = mi.getTotalUss(); 12178 12179 synchronized (this) { 12180 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12181 // Record this for posterity if the process has been stable. 12182 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12183 } 12184 } 12185 12186 if (!isCheckinRequest && mi != null) { 12187 totalPss += myTotalPss; 12188 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12189 (hasActivities ? " / activities)" : ")"), 12190 r.processName, myTotalPss, pid, hasActivities); 12191 procMems.add(pssItem); 12192 procMemsMap.put(pid, pssItem); 12193 12194 nativePss += mi.nativePss; 12195 dalvikPss += mi.dalvikPss; 12196 otherPss += mi.otherPss; 12197 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12198 long mem = mi.getOtherPss(j); 12199 miscPss[j] += mem; 12200 otherPss -= mem; 12201 } 12202 12203 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12204 cachedPss += myTotalPss; 12205 } 12206 12207 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12208 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12209 || oomIndex == (oomPss.length-1)) { 12210 oomPss[oomIndex] += myTotalPss; 12211 if (oomProcs[oomIndex] == null) { 12212 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12213 } 12214 oomProcs[oomIndex].add(pssItem); 12215 break; 12216 } 12217 } 12218 } 12219 } 12220 } 12221 12222 if (!isCheckinRequest && procs.size() > 1) { 12223 // If we are showing aggregations, also look for native processes to 12224 // include so that our aggregations are more accurate. 12225 updateCpuStatsNow(); 12226 synchronized (mProcessCpuThread) { 12227 final int N = mProcessCpuTracker.countStats(); 12228 for (int i=0; i<N; i++) { 12229 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12230 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12231 if (mi == null) { 12232 mi = new Debug.MemoryInfo(); 12233 } 12234 if (!brief && !oomOnly) { 12235 Debug.getMemoryInfo(st.pid, mi); 12236 } else { 12237 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12238 mi.nativePrivateDirty = (int)tmpLong[0]; 12239 } 12240 12241 final long myTotalPss = mi.getTotalPss(); 12242 totalPss += myTotalPss; 12243 12244 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12245 st.name, myTotalPss, st.pid, false); 12246 procMems.add(pssItem); 12247 12248 nativePss += mi.nativePss; 12249 dalvikPss += mi.dalvikPss; 12250 otherPss += mi.otherPss; 12251 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12252 long mem = mi.getOtherPss(j); 12253 miscPss[j] += mem; 12254 otherPss -= mem; 12255 } 12256 oomPss[0] += myTotalPss; 12257 if (oomProcs[0] == null) { 12258 oomProcs[0] = new ArrayList<MemItem>(); 12259 } 12260 oomProcs[0].add(pssItem); 12261 } 12262 } 12263 } 12264 12265 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12266 12267 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12268 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12269 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12270 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12271 String label = Debug.MemoryInfo.getOtherLabel(j); 12272 catMems.add(new MemItem(label, label, miscPss[j], j)); 12273 } 12274 12275 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12276 for (int j=0; j<oomPss.length; j++) { 12277 if (oomPss[j] != 0) { 12278 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12279 : DUMP_MEM_OOM_LABEL[j]; 12280 MemItem item = new MemItem(label, label, oomPss[j], 12281 DUMP_MEM_OOM_ADJ[j]); 12282 item.subitems = oomProcs[j]; 12283 oomMems.add(item); 12284 } 12285 } 12286 12287 if (!brief && !oomOnly && !isCompact) { 12288 pw.println(); 12289 pw.println("Total PSS by process:"); 12290 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12291 pw.println(); 12292 } 12293 if (!isCompact) { 12294 pw.println("Total PSS by OOM adjustment:"); 12295 } 12296 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12297 if (!brief && !oomOnly) { 12298 PrintWriter out = categoryPw != null ? categoryPw : pw; 12299 if (!isCompact) { 12300 out.println(); 12301 out.println("Total PSS by category:"); 12302 } 12303 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12304 } 12305 if (!isCompact) { 12306 pw.println(); 12307 } 12308 MemInfoReader memInfo = new MemInfoReader(); 12309 memInfo.readMemInfo(); 12310 if (!brief) { 12311 if (!isCompact) { 12312 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12313 pw.print(" kB (status "); 12314 switch (mLastMemoryLevel) { 12315 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12316 pw.println("normal)"); 12317 break; 12318 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12319 pw.println("moderate)"); 12320 break; 12321 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12322 pw.println("low)"); 12323 break; 12324 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12325 pw.println("critical)"); 12326 break; 12327 default: 12328 pw.print(mLastMemoryLevel); 12329 pw.println(")"); 12330 break; 12331 } 12332 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12333 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12334 pw.print(cachedPss); pw.print(" cached pss + "); 12335 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12336 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12337 } else { 12338 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12339 pw.print(cachedPss + memInfo.getCachedSizeKb() 12340 + memInfo.getFreeSizeKb()); pw.print(","); 12341 pw.println(totalPss - cachedPss); 12342 } 12343 } 12344 if (!isCompact) { 12345 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12346 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12347 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12348 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12349 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12350 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12351 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12352 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12353 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12354 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12355 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12356 } 12357 if (!brief) { 12358 if (memInfo.getZramTotalSizeKb() != 0) { 12359 if (!isCompact) { 12360 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12361 pw.print(" kB physical used for "); 12362 pw.print(memInfo.getSwapTotalSizeKb() 12363 - memInfo.getSwapFreeSizeKb()); 12364 pw.print(" kB in swap ("); 12365 pw.print(memInfo.getSwapTotalSizeKb()); 12366 pw.println(" kB total swap)"); 12367 } else { 12368 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12369 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12370 pw.println(memInfo.getSwapFreeSizeKb()); 12371 } 12372 } 12373 final int[] SINGLE_LONG_FORMAT = new int[] { 12374 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12375 }; 12376 long[] longOut = new long[1]; 12377 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12378 SINGLE_LONG_FORMAT, null, longOut, null); 12379 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12380 longOut[0] = 0; 12381 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12382 SINGLE_LONG_FORMAT, null, longOut, null); 12383 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12384 longOut[0] = 0; 12385 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12386 SINGLE_LONG_FORMAT, null, longOut, null); 12387 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12388 longOut[0] = 0; 12389 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12390 SINGLE_LONG_FORMAT, null, longOut, null); 12391 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12392 if (!isCompact) { 12393 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12394 pw.print(" KSM: "); pw.print(sharing); 12395 pw.print(" kB saved from shared "); 12396 pw.print(shared); pw.println(" kB"); 12397 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12398 pw.print(voltile); pw.println(" kB volatile"); 12399 } 12400 pw.print(" Tuning: "); 12401 pw.print(ActivityManager.staticGetMemoryClass()); 12402 pw.print(" (large "); 12403 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12404 pw.print("), oom "); 12405 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12406 pw.print(" kB"); 12407 pw.print(", restore limit "); 12408 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12409 pw.print(" kB"); 12410 if (ActivityManager.isLowRamDeviceStatic()) { 12411 pw.print(" (low-ram)"); 12412 } 12413 if (ActivityManager.isHighEndGfx()) { 12414 pw.print(" (high-end-gfx)"); 12415 } 12416 pw.println(); 12417 } else { 12418 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12419 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12420 pw.println(voltile); 12421 pw.print("tuning,"); 12422 pw.print(ActivityManager.staticGetMemoryClass()); 12423 pw.print(','); 12424 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12425 pw.print(','); 12426 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12427 if (ActivityManager.isLowRamDeviceStatic()) { 12428 pw.print(",low-ram"); 12429 } 12430 if (ActivityManager.isHighEndGfx()) { 12431 pw.print(",high-end-gfx"); 12432 } 12433 pw.println(); 12434 } 12435 } 12436 } 12437 } 12438 12439 /** 12440 * Searches array of arguments for the specified string 12441 * @param args array of argument strings 12442 * @param value value to search for 12443 * @return true if the value is contained in the array 12444 */ 12445 private static boolean scanArgs(String[] args, String value) { 12446 if (args != null) { 12447 for (String arg : args) { 12448 if (value.equals(arg)) { 12449 return true; 12450 } 12451 } 12452 } 12453 return false; 12454 } 12455 12456 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12457 ContentProviderRecord cpr, boolean always) { 12458 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12459 12460 if (!inLaunching || always) { 12461 synchronized (cpr) { 12462 cpr.launchingApp = null; 12463 cpr.notifyAll(); 12464 } 12465 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12466 String names[] = cpr.info.authority.split(";"); 12467 for (int j = 0; j < names.length; j++) { 12468 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12469 } 12470 } 12471 12472 for (int i=0; i<cpr.connections.size(); i++) { 12473 ContentProviderConnection conn = cpr.connections.get(i); 12474 if (conn.waiting) { 12475 // If this connection is waiting for the provider, then we don't 12476 // need to mess with its process unless we are always removing 12477 // or for some reason the provider is not currently launching. 12478 if (inLaunching && !always) { 12479 continue; 12480 } 12481 } 12482 ProcessRecord capp = conn.client; 12483 conn.dead = true; 12484 if (conn.stableCount > 0) { 12485 if (!capp.persistent && capp.thread != null 12486 && capp.pid != 0 12487 && capp.pid != MY_PID) { 12488 killUnneededProcessLocked(capp, "depends on provider " 12489 + cpr.name.flattenToShortString() 12490 + " in dying proc " + (proc != null ? proc.processName : "??")); 12491 } 12492 } else if (capp.thread != null && conn.provider.provider != null) { 12493 try { 12494 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12495 } catch (RemoteException e) { 12496 } 12497 // In the protocol here, we don't expect the client to correctly 12498 // clean up this connection, we'll just remove it. 12499 cpr.connections.remove(i); 12500 conn.client.conProviders.remove(conn); 12501 } 12502 } 12503 12504 if (inLaunching && always) { 12505 mLaunchingProviders.remove(cpr); 12506 } 12507 return inLaunching; 12508 } 12509 12510 /** 12511 * Main code for cleaning up a process when it has gone away. This is 12512 * called both as a result of the process dying, or directly when stopping 12513 * a process when running in single process mode. 12514 */ 12515 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12516 boolean restarting, boolean allowRestart, int index) { 12517 if (index >= 0) { 12518 removeLruProcessLocked(app); 12519 ProcessList.remove(app.pid); 12520 } 12521 12522 mProcessesToGc.remove(app); 12523 mPendingPssProcesses.remove(app); 12524 12525 // Dismiss any open dialogs. 12526 if (app.crashDialog != null && !app.forceCrashReport) { 12527 app.crashDialog.dismiss(); 12528 app.crashDialog = null; 12529 } 12530 if (app.anrDialog != null) { 12531 app.anrDialog.dismiss(); 12532 app.anrDialog = null; 12533 } 12534 if (app.waitDialog != null) { 12535 app.waitDialog.dismiss(); 12536 app.waitDialog = null; 12537 } 12538 12539 app.crashing = false; 12540 app.notResponding = false; 12541 12542 app.resetPackageList(mProcessStats); 12543 app.unlinkDeathRecipient(); 12544 app.makeInactive(mProcessStats); 12545 app.forcingToForeground = null; 12546 updateProcessForegroundLocked(app, false, false); 12547 app.foregroundActivities = false; 12548 app.hasShownUi = false; 12549 app.hasAboveClient = false; 12550 12551 mServices.killServicesLocked(app, allowRestart); 12552 12553 boolean restart = false; 12554 12555 // Remove published content providers. 12556 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12557 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12558 final boolean always = app.bad || !allowRestart; 12559 if (removeDyingProviderLocked(app, cpr, always) || always) { 12560 // We left the provider in the launching list, need to 12561 // restart it. 12562 restart = true; 12563 } 12564 12565 cpr.provider = null; 12566 cpr.proc = null; 12567 } 12568 app.pubProviders.clear(); 12569 12570 // Take care of any launching providers waiting for this process. 12571 if (checkAppInLaunchingProvidersLocked(app, false)) { 12572 restart = true; 12573 } 12574 12575 // Unregister from connected content providers. 12576 if (!app.conProviders.isEmpty()) { 12577 for (int i=0; i<app.conProviders.size(); i++) { 12578 ContentProviderConnection conn = app.conProviders.get(i); 12579 conn.provider.connections.remove(conn); 12580 } 12581 app.conProviders.clear(); 12582 } 12583 12584 // At this point there may be remaining entries in mLaunchingProviders 12585 // where we were the only one waiting, so they are no longer of use. 12586 // Look for these and clean up if found. 12587 // XXX Commented out for now. Trying to figure out a way to reproduce 12588 // the actual situation to identify what is actually going on. 12589 if (false) { 12590 for (int i=0; i<mLaunchingProviders.size(); i++) { 12591 ContentProviderRecord cpr = (ContentProviderRecord) 12592 mLaunchingProviders.get(i); 12593 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12594 synchronized (cpr) { 12595 cpr.launchingApp = null; 12596 cpr.notifyAll(); 12597 } 12598 } 12599 } 12600 } 12601 12602 skipCurrentReceiverLocked(app); 12603 12604 // Unregister any receivers. 12605 for (int i=app.receivers.size()-1; i>=0; i--) { 12606 removeReceiverLocked(app.receivers.valueAt(i)); 12607 } 12608 app.receivers.clear(); 12609 12610 // If the app is undergoing backup, tell the backup manager about it 12611 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12612 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12613 + mBackupTarget.appInfo + " died during backup"); 12614 try { 12615 IBackupManager bm = IBackupManager.Stub.asInterface( 12616 ServiceManager.getService(Context.BACKUP_SERVICE)); 12617 bm.agentDisconnected(app.info.packageName); 12618 } catch (RemoteException e) { 12619 // can't happen; backup manager is local 12620 } 12621 } 12622 12623 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12624 ProcessChangeItem item = mPendingProcessChanges.get(i); 12625 if (item.pid == app.pid) { 12626 mPendingProcessChanges.remove(i); 12627 mAvailProcessChanges.add(item); 12628 } 12629 } 12630 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12631 12632 // If the caller is restarting this app, then leave it in its 12633 // current lists and let the caller take care of it. 12634 if (restarting) { 12635 return; 12636 } 12637 12638 if (!app.persistent || app.isolated) { 12639 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12640 "Removing non-persistent process during cleanup: " + app); 12641 mProcessNames.remove(app.processName, app.uid); 12642 mIsolatedProcesses.remove(app.uid); 12643 if (mHeavyWeightProcess == app) { 12644 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12645 mHeavyWeightProcess.userId, 0)); 12646 mHeavyWeightProcess = null; 12647 } 12648 } else if (!app.removed) { 12649 // This app is persistent, so we need to keep its record around. 12650 // If it is not already on the pending app list, add it there 12651 // and start a new process for it. 12652 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12653 mPersistentStartingProcesses.add(app); 12654 restart = true; 12655 } 12656 } 12657 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12658 "Clean-up removing on hold: " + app); 12659 mProcessesOnHold.remove(app); 12660 12661 if (app == mHomeProcess) { 12662 mHomeProcess = null; 12663 } 12664 if (app == mPreviousProcess) { 12665 mPreviousProcess = null; 12666 } 12667 12668 if (restart && !app.isolated) { 12669 // We have components that still need to be running in the 12670 // process, so re-launch it. 12671 mProcessNames.put(app.processName, app.uid, app); 12672 startProcessLocked(app, "restart", app.processName); 12673 } else if (app.pid > 0 && app.pid != MY_PID) { 12674 // Goodbye! 12675 boolean removed; 12676 synchronized (mPidsSelfLocked) { 12677 mPidsSelfLocked.remove(app.pid); 12678 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12679 } 12680 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12681 app.processName, app.info.uid); 12682 if (app.isolated) { 12683 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12684 } 12685 app.setPid(0); 12686 } 12687 } 12688 12689 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12690 // Look through the content providers we are waiting to have launched, 12691 // and if any run in this process then either schedule a restart of 12692 // the process or kill the client waiting for it if this process has 12693 // gone bad. 12694 int NL = mLaunchingProviders.size(); 12695 boolean restart = false; 12696 for (int i=0; i<NL; i++) { 12697 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12698 if (cpr.launchingApp == app) { 12699 if (!alwaysBad && !app.bad) { 12700 restart = true; 12701 } else { 12702 removeDyingProviderLocked(app, cpr, true); 12703 // cpr should have been removed from mLaunchingProviders 12704 NL = mLaunchingProviders.size(); 12705 i--; 12706 } 12707 } 12708 } 12709 return restart; 12710 } 12711 12712 // ========================================================= 12713 // SERVICES 12714 // ========================================================= 12715 12716 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12717 int flags) { 12718 enforceNotIsolatedCaller("getServices"); 12719 synchronized (this) { 12720 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12721 } 12722 } 12723 12724 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12725 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12726 synchronized (this) { 12727 return mServices.getRunningServiceControlPanelLocked(name); 12728 } 12729 } 12730 12731 public ComponentName startService(IApplicationThread caller, Intent service, 12732 String resolvedType, int userId) { 12733 enforceNotIsolatedCaller("startService"); 12734 // Refuse possible leaked file descriptors 12735 if (service != null && service.hasFileDescriptors() == true) { 12736 throw new IllegalArgumentException("File descriptors passed in Intent"); 12737 } 12738 12739 if (DEBUG_SERVICE) 12740 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12741 synchronized(this) { 12742 final int callingPid = Binder.getCallingPid(); 12743 final int callingUid = Binder.getCallingUid(); 12744 final long origId = Binder.clearCallingIdentity(); 12745 ComponentName res = mServices.startServiceLocked(caller, service, 12746 resolvedType, callingPid, callingUid, userId); 12747 Binder.restoreCallingIdentity(origId); 12748 return res; 12749 } 12750 } 12751 12752 ComponentName startServiceInPackage(int uid, 12753 Intent service, String resolvedType, int userId) { 12754 synchronized(this) { 12755 if (DEBUG_SERVICE) 12756 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12757 final long origId = Binder.clearCallingIdentity(); 12758 ComponentName res = mServices.startServiceLocked(null, service, 12759 resolvedType, -1, uid, userId); 12760 Binder.restoreCallingIdentity(origId); 12761 return res; 12762 } 12763 } 12764 12765 public int stopService(IApplicationThread caller, Intent service, 12766 String resolvedType, int userId) { 12767 enforceNotIsolatedCaller("stopService"); 12768 // Refuse possible leaked file descriptors 12769 if (service != null && service.hasFileDescriptors() == true) { 12770 throw new IllegalArgumentException("File descriptors passed in Intent"); 12771 } 12772 12773 synchronized(this) { 12774 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12775 } 12776 } 12777 12778 public IBinder peekService(Intent service, String resolvedType) { 12779 enforceNotIsolatedCaller("peekService"); 12780 // Refuse possible leaked file descriptors 12781 if (service != null && service.hasFileDescriptors() == true) { 12782 throw new IllegalArgumentException("File descriptors passed in Intent"); 12783 } 12784 synchronized(this) { 12785 return mServices.peekServiceLocked(service, resolvedType); 12786 } 12787 } 12788 12789 public boolean stopServiceToken(ComponentName className, IBinder token, 12790 int startId) { 12791 synchronized(this) { 12792 return mServices.stopServiceTokenLocked(className, token, startId); 12793 } 12794 } 12795 12796 public void setServiceForeground(ComponentName className, IBinder token, 12797 int id, Notification notification, boolean removeNotification) { 12798 synchronized(this) { 12799 mServices.setServiceForegroundLocked(className, token, id, notification, 12800 removeNotification); 12801 } 12802 } 12803 12804 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12805 boolean requireFull, String name, String callerPackage) { 12806 final int callingUserId = UserHandle.getUserId(callingUid); 12807 if (callingUserId != userId) { 12808 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12809 if ((requireFull || checkComponentPermission( 12810 android.Manifest.permission.INTERACT_ACROSS_USERS, 12811 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12812 && checkComponentPermission( 12813 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12814 callingPid, callingUid, -1, true) 12815 != PackageManager.PERMISSION_GRANTED) { 12816 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12817 // In this case, they would like to just execute as their 12818 // owner user instead of failing. 12819 userId = callingUserId; 12820 } else { 12821 StringBuilder builder = new StringBuilder(128); 12822 builder.append("Permission Denial: "); 12823 builder.append(name); 12824 if (callerPackage != null) { 12825 builder.append(" from "); 12826 builder.append(callerPackage); 12827 } 12828 builder.append(" asks to run as user "); 12829 builder.append(userId); 12830 builder.append(" but is calling from user "); 12831 builder.append(UserHandle.getUserId(callingUid)); 12832 builder.append("; this requires "); 12833 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12834 if (!requireFull) { 12835 builder.append(" or "); 12836 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12837 } 12838 String msg = builder.toString(); 12839 Slog.w(TAG, msg); 12840 throw new SecurityException(msg); 12841 } 12842 } 12843 } 12844 if (userId == UserHandle.USER_CURRENT 12845 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12846 // Note that we may be accessing this outside of a lock... 12847 // shouldn't be a big deal, if this is being called outside 12848 // of a locked context there is intrinsically a race with 12849 // the value the caller will receive and someone else changing it. 12850 userId = mCurrentUserId; 12851 } 12852 if (!allowAll && userId < 0) { 12853 throw new IllegalArgumentException( 12854 "Call does not support special user #" + userId); 12855 } 12856 } 12857 return userId; 12858 } 12859 12860 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12861 String className, int flags) { 12862 boolean result = false; 12863 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12864 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12865 if (ActivityManager.checkUidPermission( 12866 android.Manifest.permission.INTERACT_ACROSS_USERS, 12867 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12868 ComponentName comp = new ComponentName(aInfo.packageName, className); 12869 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12870 + " requests FLAG_SINGLE_USER, but app does not hold " 12871 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12872 Slog.w(TAG, msg); 12873 throw new SecurityException(msg); 12874 } 12875 result = true; 12876 } 12877 } else if (componentProcessName == aInfo.packageName) { 12878 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12879 } else if ("system".equals(componentProcessName)) { 12880 result = true; 12881 } 12882 if (DEBUG_MU) { 12883 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12884 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12885 } 12886 return result; 12887 } 12888 12889 public int bindService(IApplicationThread caller, IBinder token, 12890 Intent service, String resolvedType, 12891 IServiceConnection connection, int flags, int userId) { 12892 enforceNotIsolatedCaller("bindService"); 12893 // Refuse possible leaked file descriptors 12894 if (service != null && service.hasFileDescriptors() == true) { 12895 throw new IllegalArgumentException("File descriptors passed in Intent"); 12896 } 12897 12898 synchronized(this) { 12899 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12900 connection, flags, userId); 12901 } 12902 } 12903 12904 public boolean unbindService(IServiceConnection connection) { 12905 synchronized (this) { 12906 return mServices.unbindServiceLocked(connection); 12907 } 12908 } 12909 12910 public void publishService(IBinder token, Intent intent, IBinder service) { 12911 // Refuse possible leaked file descriptors 12912 if (intent != null && intent.hasFileDescriptors() == true) { 12913 throw new IllegalArgumentException("File descriptors passed in Intent"); 12914 } 12915 12916 synchronized(this) { 12917 if (!(token instanceof ServiceRecord)) { 12918 throw new IllegalArgumentException("Invalid service token"); 12919 } 12920 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12921 } 12922 } 12923 12924 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12925 // Refuse possible leaked file descriptors 12926 if (intent != null && intent.hasFileDescriptors() == true) { 12927 throw new IllegalArgumentException("File descriptors passed in Intent"); 12928 } 12929 12930 synchronized(this) { 12931 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12932 } 12933 } 12934 12935 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12936 synchronized(this) { 12937 if (!(token instanceof ServiceRecord)) { 12938 throw new IllegalArgumentException("Invalid service token"); 12939 } 12940 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12941 } 12942 } 12943 12944 // ========================================================= 12945 // BACKUP AND RESTORE 12946 // ========================================================= 12947 12948 // Cause the target app to be launched if necessary and its backup agent 12949 // instantiated. The backup agent will invoke backupAgentCreated() on the 12950 // activity manager to announce its creation. 12951 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12952 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12953 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12954 12955 synchronized(this) { 12956 // !!! TODO: currently no check here that we're already bound 12957 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12958 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12959 synchronized (stats) { 12960 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12961 } 12962 12963 // Backup agent is now in use, its package can't be stopped. 12964 try { 12965 AppGlobals.getPackageManager().setPackageStoppedState( 12966 app.packageName, false, UserHandle.getUserId(app.uid)); 12967 } catch (RemoteException e) { 12968 } catch (IllegalArgumentException e) { 12969 Slog.w(TAG, "Failed trying to unstop package " 12970 + app.packageName + ": " + e); 12971 } 12972 12973 BackupRecord r = new BackupRecord(ss, app, backupMode); 12974 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 12975 ? new ComponentName(app.packageName, app.backupAgentName) 12976 : new ComponentName("android", "FullBackupAgent"); 12977 // startProcessLocked() returns existing proc's record if it's already running 12978 ProcessRecord proc = startProcessLocked(app.processName, app, 12979 false, 0, "backup", hostingName, false, false, false); 12980 if (proc == null) { 12981 Slog.e(TAG, "Unable to start backup agent process " + r); 12982 return false; 12983 } 12984 12985 r.app = proc; 12986 mBackupTarget = r; 12987 mBackupAppName = app.packageName; 12988 12989 // Try not to kill the process during backup 12990 updateOomAdjLocked(proc); 12991 12992 // If the process is already attached, schedule the creation of the backup agent now. 12993 // If it is not yet live, this will be done when it attaches to the framework. 12994 if (proc.thread != null) { 12995 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 12996 try { 12997 proc.thread.scheduleCreateBackupAgent(app, 12998 compatibilityInfoForPackageLocked(app), backupMode); 12999 } catch (RemoteException e) { 13000 // Will time out on the backup manager side 13001 } 13002 } else { 13003 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13004 } 13005 // Invariants: at this point, the target app process exists and the application 13006 // is either already running or in the process of coming up. mBackupTarget and 13007 // mBackupAppName describe the app, so that when it binds back to the AM we 13008 // know that it's scheduled for a backup-agent operation. 13009 } 13010 13011 return true; 13012 } 13013 13014 @Override 13015 public void clearPendingBackup() { 13016 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13017 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13018 13019 synchronized (this) { 13020 mBackupTarget = null; 13021 mBackupAppName = null; 13022 } 13023 } 13024 13025 // A backup agent has just come up 13026 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13027 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13028 + " = " + agent); 13029 13030 synchronized(this) { 13031 if (!agentPackageName.equals(mBackupAppName)) { 13032 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13033 return; 13034 } 13035 } 13036 13037 long oldIdent = Binder.clearCallingIdentity(); 13038 try { 13039 IBackupManager bm = IBackupManager.Stub.asInterface( 13040 ServiceManager.getService(Context.BACKUP_SERVICE)); 13041 bm.agentConnected(agentPackageName, agent); 13042 } catch (RemoteException e) { 13043 // can't happen; the backup manager service is local 13044 } catch (Exception e) { 13045 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13046 e.printStackTrace(); 13047 } finally { 13048 Binder.restoreCallingIdentity(oldIdent); 13049 } 13050 } 13051 13052 // done with this agent 13053 public void unbindBackupAgent(ApplicationInfo appInfo) { 13054 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13055 if (appInfo == null) { 13056 Slog.w(TAG, "unbind backup agent for null app"); 13057 return; 13058 } 13059 13060 synchronized(this) { 13061 try { 13062 if (mBackupAppName == null) { 13063 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13064 return; 13065 } 13066 13067 if (!mBackupAppName.equals(appInfo.packageName)) { 13068 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13069 return; 13070 } 13071 13072 // Not backing this app up any more; reset its OOM adjustment 13073 final ProcessRecord proc = mBackupTarget.app; 13074 updateOomAdjLocked(proc); 13075 13076 // If the app crashed during backup, 'thread' will be null here 13077 if (proc.thread != null) { 13078 try { 13079 proc.thread.scheduleDestroyBackupAgent(appInfo, 13080 compatibilityInfoForPackageLocked(appInfo)); 13081 } catch (Exception e) { 13082 Slog.e(TAG, "Exception when unbinding backup agent:"); 13083 e.printStackTrace(); 13084 } 13085 } 13086 } finally { 13087 mBackupTarget = null; 13088 mBackupAppName = null; 13089 } 13090 } 13091 } 13092 // ========================================================= 13093 // BROADCASTS 13094 // ========================================================= 13095 13096 private final List getStickiesLocked(String action, IntentFilter filter, 13097 List cur, int userId) { 13098 final ContentResolver resolver = mContext.getContentResolver(); 13099 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13100 if (stickies == null) { 13101 return cur; 13102 } 13103 final ArrayList<Intent> list = stickies.get(action); 13104 if (list == null) { 13105 return cur; 13106 } 13107 int N = list.size(); 13108 for (int i=0; i<N; i++) { 13109 Intent intent = list.get(i); 13110 if (filter.match(resolver, intent, true, TAG) >= 0) { 13111 if (cur == null) { 13112 cur = new ArrayList<Intent>(); 13113 } 13114 cur.add(intent); 13115 } 13116 } 13117 return cur; 13118 } 13119 13120 boolean isPendingBroadcastProcessLocked(int pid) { 13121 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13122 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13123 } 13124 13125 void skipPendingBroadcastLocked(int pid) { 13126 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13127 for (BroadcastQueue queue : mBroadcastQueues) { 13128 queue.skipPendingBroadcastLocked(pid); 13129 } 13130 } 13131 13132 // The app just attached; send any pending broadcasts that it should receive 13133 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13134 boolean didSomething = false; 13135 for (BroadcastQueue queue : mBroadcastQueues) { 13136 didSomething |= queue.sendPendingBroadcastsLocked(app); 13137 } 13138 return didSomething; 13139 } 13140 13141 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13142 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13143 enforceNotIsolatedCaller("registerReceiver"); 13144 int callingUid; 13145 int callingPid; 13146 synchronized(this) { 13147 ProcessRecord callerApp = null; 13148 if (caller != null) { 13149 callerApp = getRecordForAppLocked(caller); 13150 if (callerApp == null) { 13151 throw new SecurityException( 13152 "Unable to find app for caller " + caller 13153 + " (pid=" + Binder.getCallingPid() 13154 + ") when registering receiver " + receiver); 13155 } 13156 if (callerApp.info.uid != Process.SYSTEM_UID && 13157 !callerApp.pkgList.containsKey(callerPackage) && 13158 !"android".equals(callerPackage)) { 13159 throw new SecurityException("Given caller package " + callerPackage 13160 + " is not running in process " + callerApp); 13161 } 13162 callingUid = callerApp.info.uid; 13163 callingPid = callerApp.pid; 13164 } else { 13165 callerPackage = null; 13166 callingUid = Binder.getCallingUid(); 13167 callingPid = Binder.getCallingPid(); 13168 } 13169 13170 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13171 true, true, "registerReceiver", callerPackage); 13172 13173 List allSticky = null; 13174 13175 // Look for any matching sticky broadcasts... 13176 Iterator actions = filter.actionsIterator(); 13177 if (actions != null) { 13178 while (actions.hasNext()) { 13179 String action = (String)actions.next(); 13180 allSticky = getStickiesLocked(action, filter, allSticky, 13181 UserHandle.USER_ALL); 13182 allSticky = getStickiesLocked(action, filter, allSticky, 13183 UserHandle.getUserId(callingUid)); 13184 } 13185 } else { 13186 allSticky = getStickiesLocked(null, filter, allSticky, 13187 UserHandle.USER_ALL); 13188 allSticky = getStickiesLocked(null, filter, allSticky, 13189 UserHandle.getUserId(callingUid)); 13190 } 13191 13192 // The first sticky in the list is returned directly back to 13193 // the client. 13194 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13195 13196 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13197 + ": " + sticky); 13198 13199 if (receiver == null) { 13200 return sticky; 13201 } 13202 13203 ReceiverList rl 13204 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13205 if (rl == null) { 13206 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13207 userId, receiver); 13208 if (rl.app != null) { 13209 rl.app.receivers.add(rl); 13210 } else { 13211 try { 13212 receiver.asBinder().linkToDeath(rl, 0); 13213 } catch (RemoteException e) { 13214 return sticky; 13215 } 13216 rl.linkedToDeath = true; 13217 } 13218 mRegisteredReceivers.put(receiver.asBinder(), rl); 13219 } else if (rl.uid != callingUid) { 13220 throw new IllegalArgumentException( 13221 "Receiver requested to register for uid " + callingUid 13222 + " was previously registered for uid " + rl.uid); 13223 } else if (rl.pid != callingPid) { 13224 throw new IllegalArgumentException( 13225 "Receiver requested to register for pid " + callingPid 13226 + " was previously registered for pid " + rl.pid); 13227 } else if (rl.userId != userId) { 13228 throw new IllegalArgumentException( 13229 "Receiver requested to register for user " + userId 13230 + " was previously registered for user " + rl.userId); 13231 } 13232 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13233 permission, callingUid, userId); 13234 rl.add(bf); 13235 if (!bf.debugCheck()) { 13236 Slog.w(TAG, "==> For Dynamic broadast"); 13237 } 13238 mReceiverResolver.addFilter(bf); 13239 13240 // Enqueue broadcasts for all existing stickies that match 13241 // this filter. 13242 if (allSticky != null) { 13243 ArrayList receivers = new ArrayList(); 13244 receivers.add(bf); 13245 13246 int N = allSticky.size(); 13247 for (int i=0; i<N; i++) { 13248 Intent intent = (Intent)allSticky.get(i); 13249 BroadcastQueue queue = broadcastQueueForIntent(intent); 13250 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13251 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13252 null, null, false, true, true, -1); 13253 queue.enqueueParallelBroadcastLocked(r); 13254 queue.scheduleBroadcastsLocked(); 13255 } 13256 } 13257 13258 return sticky; 13259 } 13260 } 13261 13262 public void unregisterReceiver(IIntentReceiver receiver) { 13263 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13264 13265 final long origId = Binder.clearCallingIdentity(); 13266 try { 13267 boolean doTrim = false; 13268 13269 synchronized(this) { 13270 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13271 if (rl != null) { 13272 if (rl.curBroadcast != null) { 13273 BroadcastRecord r = rl.curBroadcast; 13274 final boolean doNext = finishReceiverLocked( 13275 receiver.asBinder(), r.resultCode, r.resultData, 13276 r.resultExtras, r.resultAbort); 13277 if (doNext) { 13278 doTrim = true; 13279 r.queue.processNextBroadcast(false); 13280 } 13281 } 13282 13283 if (rl.app != null) { 13284 rl.app.receivers.remove(rl); 13285 } 13286 removeReceiverLocked(rl); 13287 if (rl.linkedToDeath) { 13288 rl.linkedToDeath = false; 13289 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13290 } 13291 } 13292 } 13293 13294 // If we actually concluded any broadcasts, we might now be able 13295 // to trim the recipients' apps from our working set 13296 if (doTrim) { 13297 trimApplications(); 13298 return; 13299 } 13300 13301 } finally { 13302 Binder.restoreCallingIdentity(origId); 13303 } 13304 } 13305 13306 void removeReceiverLocked(ReceiverList rl) { 13307 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13308 int N = rl.size(); 13309 for (int i=0; i<N; i++) { 13310 mReceiverResolver.removeFilter(rl.get(i)); 13311 } 13312 } 13313 13314 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13315 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13316 ProcessRecord r = mLruProcesses.get(i); 13317 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13318 try { 13319 r.thread.dispatchPackageBroadcast(cmd, packages); 13320 } catch (RemoteException ex) { 13321 } 13322 } 13323 } 13324 } 13325 13326 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13327 int[] users) { 13328 List<ResolveInfo> receivers = null; 13329 try { 13330 HashSet<ComponentName> singleUserReceivers = null; 13331 boolean scannedFirstReceivers = false; 13332 for (int user : users) { 13333 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13334 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13335 if (user != 0 && newReceivers != null) { 13336 // If this is not the primary user, we need to check for 13337 // any receivers that should be filtered out. 13338 for (int i=0; i<newReceivers.size(); i++) { 13339 ResolveInfo ri = newReceivers.get(i); 13340 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13341 newReceivers.remove(i); 13342 i--; 13343 } 13344 } 13345 } 13346 if (newReceivers != null && newReceivers.size() == 0) { 13347 newReceivers = null; 13348 } 13349 if (receivers == null) { 13350 receivers = newReceivers; 13351 } else if (newReceivers != null) { 13352 // We need to concatenate the additional receivers 13353 // found with what we have do far. This would be easy, 13354 // but we also need to de-dup any receivers that are 13355 // singleUser. 13356 if (!scannedFirstReceivers) { 13357 // Collect any single user receivers we had already retrieved. 13358 scannedFirstReceivers = true; 13359 for (int i=0; i<receivers.size(); i++) { 13360 ResolveInfo ri = receivers.get(i); 13361 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13362 ComponentName cn = new ComponentName( 13363 ri.activityInfo.packageName, ri.activityInfo.name); 13364 if (singleUserReceivers == null) { 13365 singleUserReceivers = new HashSet<ComponentName>(); 13366 } 13367 singleUserReceivers.add(cn); 13368 } 13369 } 13370 } 13371 // Add the new results to the existing results, tracking 13372 // and de-dupping single user receivers. 13373 for (int i=0; i<newReceivers.size(); i++) { 13374 ResolveInfo ri = newReceivers.get(i); 13375 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13376 ComponentName cn = new ComponentName( 13377 ri.activityInfo.packageName, ri.activityInfo.name); 13378 if (singleUserReceivers == null) { 13379 singleUserReceivers = new HashSet<ComponentName>(); 13380 } 13381 if (!singleUserReceivers.contains(cn)) { 13382 singleUserReceivers.add(cn); 13383 receivers.add(ri); 13384 } 13385 } else { 13386 receivers.add(ri); 13387 } 13388 } 13389 } 13390 } 13391 } catch (RemoteException ex) { 13392 // pm is in same process, this will never happen. 13393 } 13394 return receivers; 13395 } 13396 13397 private final int broadcastIntentLocked(ProcessRecord callerApp, 13398 String callerPackage, Intent intent, String resolvedType, 13399 IIntentReceiver resultTo, int resultCode, String resultData, 13400 Bundle map, String requiredPermission, int appOp, 13401 boolean ordered, boolean sticky, int callingPid, int callingUid, 13402 int userId) { 13403 intent = new Intent(intent); 13404 13405 // By default broadcasts do not go to stopped apps. 13406 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13407 13408 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13409 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13410 + " ordered=" + ordered + " userid=" + userId); 13411 if ((resultTo != null) && !ordered) { 13412 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13413 } 13414 13415 userId = handleIncomingUser(callingPid, callingUid, userId, 13416 true, false, "broadcast", callerPackage); 13417 13418 // Make sure that the user who is receiving this broadcast is started. 13419 // If not, we will just skip it. 13420 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13421 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13422 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13423 Slog.w(TAG, "Skipping broadcast of " + intent 13424 + ": user " + userId + " is stopped"); 13425 return ActivityManager.BROADCAST_SUCCESS; 13426 } 13427 } 13428 13429 /* 13430 * Prevent non-system code (defined here to be non-persistent 13431 * processes) from sending protected broadcasts. 13432 */ 13433 int callingAppId = UserHandle.getAppId(callingUid); 13434 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13435 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13436 callingUid == 0) { 13437 // Always okay. 13438 } else if (callerApp == null || !callerApp.persistent) { 13439 try { 13440 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13441 intent.getAction())) { 13442 String msg = "Permission Denial: not allowed to send broadcast " 13443 + intent.getAction() + " from pid=" 13444 + callingPid + ", uid=" + callingUid; 13445 Slog.w(TAG, msg); 13446 throw new SecurityException(msg); 13447 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13448 // Special case for compatibility: we don't want apps to send this, 13449 // but historically it has not been protected and apps may be using it 13450 // to poke their own app widget. So, instead of making it protected, 13451 // just limit it to the caller. 13452 if (callerApp == null) { 13453 String msg = "Permission Denial: not allowed to send broadcast " 13454 + intent.getAction() + " from unknown caller."; 13455 Slog.w(TAG, msg); 13456 throw new SecurityException(msg); 13457 } else if (intent.getComponent() != null) { 13458 // They are good enough to send to an explicit component... verify 13459 // it is being sent to the calling app. 13460 if (!intent.getComponent().getPackageName().equals( 13461 callerApp.info.packageName)) { 13462 String msg = "Permission Denial: not allowed to send broadcast " 13463 + intent.getAction() + " to " 13464 + intent.getComponent().getPackageName() + " from " 13465 + callerApp.info.packageName; 13466 Slog.w(TAG, msg); 13467 throw new SecurityException(msg); 13468 } 13469 } else { 13470 // Limit broadcast to their own package. 13471 intent.setPackage(callerApp.info.packageName); 13472 } 13473 } 13474 } catch (RemoteException e) { 13475 Slog.w(TAG, "Remote exception", e); 13476 return ActivityManager.BROADCAST_SUCCESS; 13477 } 13478 } 13479 13480 // Handle special intents: if this broadcast is from the package 13481 // manager about a package being removed, we need to remove all of 13482 // its activities from the history stack. 13483 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13484 intent.getAction()); 13485 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13486 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13487 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13488 || uidRemoved) { 13489 if (checkComponentPermission( 13490 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13491 callingPid, callingUid, -1, true) 13492 == PackageManager.PERMISSION_GRANTED) { 13493 if (uidRemoved) { 13494 final Bundle intentExtras = intent.getExtras(); 13495 final int uid = intentExtras != null 13496 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13497 if (uid >= 0) { 13498 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13499 synchronized (bs) { 13500 bs.removeUidStatsLocked(uid); 13501 } 13502 mAppOpsService.uidRemoved(uid); 13503 } 13504 } else { 13505 // If resources are unavailable just force stop all 13506 // those packages and flush the attribute cache as well. 13507 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13508 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13509 if (list != null && (list.length > 0)) { 13510 for (String pkg : list) { 13511 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13512 "storage unmount"); 13513 } 13514 sendPackageBroadcastLocked( 13515 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13516 } 13517 } else { 13518 Uri data = intent.getData(); 13519 String ssp; 13520 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13521 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13522 intent.getAction()); 13523 boolean fullUninstall = removed && 13524 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13525 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13526 forceStopPackageLocked(ssp, UserHandle.getAppId( 13527 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13528 false, fullUninstall, userId, 13529 removed ? "pkg removed" : "pkg changed"); 13530 } 13531 if (removed) { 13532 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13533 new String[] {ssp}, userId); 13534 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13535 mAppOpsService.packageRemoved( 13536 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13537 13538 // Remove all permissions granted from/to this package 13539 removeUriPermissionsForPackageLocked(ssp, userId, true); 13540 } 13541 } 13542 } 13543 } 13544 } 13545 } else { 13546 String msg = "Permission Denial: " + intent.getAction() 13547 + " broadcast from " + callerPackage + " (pid=" + callingPid 13548 + ", uid=" + callingUid + ")" 13549 + " requires " 13550 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13551 Slog.w(TAG, msg); 13552 throw new SecurityException(msg); 13553 } 13554 13555 // Special case for adding a package: by default turn on compatibility 13556 // mode. 13557 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13558 Uri data = intent.getData(); 13559 String ssp; 13560 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13561 mCompatModePackages.handlePackageAddedLocked(ssp, 13562 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13563 } 13564 } 13565 13566 /* 13567 * If this is the time zone changed action, queue up a message that will reset the timezone 13568 * of all currently running processes. This message will get queued up before the broadcast 13569 * happens. 13570 */ 13571 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13572 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13573 } 13574 13575 /* 13576 * If the user set the time, let all running processes know. 13577 */ 13578 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13579 final int is24Hour = intent.getBooleanExtra( 13580 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13581 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13582 } 13583 13584 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13585 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13586 } 13587 13588 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13589 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13590 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13591 } 13592 13593 // Add to the sticky list if requested. 13594 if (sticky) { 13595 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13596 callingPid, callingUid) 13597 != PackageManager.PERMISSION_GRANTED) { 13598 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13599 + callingPid + ", uid=" + callingUid 13600 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13601 Slog.w(TAG, msg); 13602 throw new SecurityException(msg); 13603 } 13604 if (requiredPermission != null) { 13605 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13606 + " and enforce permission " + requiredPermission); 13607 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13608 } 13609 if (intent.getComponent() != null) { 13610 throw new SecurityException( 13611 "Sticky broadcasts can't target a specific component"); 13612 } 13613 // We use userId directly here, since the "all" target is maintained 13614 // as a separate set of sticky broadcasts. 13615 if (userId != UserHandle.USER_ALL) { 13616 // But first, if this is not a broadcast to all users, then 13617 // make sure it doesn't conflict with an existing broadcast to 13618 // all users. 13619 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13620 UserHandle.USER_ALL); 13621 if (stickies != null) { 13622 ArrayList<Intent> list = stickies.get(intent.getAction()); 13623 if (list != null) { 13624 int N = list.size(); 13625 int i; 13626 for (i=0; i<N; i++) { 13627 if (intent.filterEquals(list.get(i))) { 13628 throw new IllegalArgumentException( 13629 "Sticky broadcast " + intent + " for user " 13630 + userId + " conflicts with existing global broadcast"); 13631 } 13632 } 13633 } 13634 } 13635 } 13636 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13637 if (stickies == null) { 13638 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13639 mStickyBroadcasts.put(userId, stickies); 13640 } 13641 ArrayList<Intent> list = stickies.get(intent.getAction()); 13642 if (list == null) { 13643 list = new ArrayList<Intent>(); 13644 stickies.put(intent.getAction(), list); 13645 } 13646 int N = list.size(); 13647 int i; 13648 for (i=0; i<N; i++) { 13649 if (intent.filterEquals(list.get(i))) { 13650 // This sticky already exists, replace it. 13651 list.set(i, new Intent(intent)); 13652 break; 13653 } 13654 } 13655 if (i >= N) { 13656 list.add(new Intent(intent)); 13657 } 13658 } 13659 13660 int[] users; 13661 if (userId == UserHandle.USER_ALL) { 13662 // Caller wants broadcast to go to all started users. 13663 users = mStartedUserArray; 13664 } else { 13665 // Caller wants broadcast to go to one specific user. 13666 users = new int[] {userId}; 13667 } 13668 13669 // Figure out who all will receive this broadcast. 13670 List receivers = null; 13671 List<BroadcastFilter> registeredReceivers = null; 13672 // Need to resolve the intent to interested receivers... 13673 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13674 == 0) { 13675 receivers = collectReceiverComponents(intent, resolvedType, users); 13676 } 13677 if (intent.getComponent() == null) { 13678 registeredReceivers = mReceiverResolver.queryIntent(intent, 13679 resolvedType, false, userId); 13680 } 13681 13682 final boolean replacePending = 13683 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13684 13685 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13686 + " replacePending=" + replacePending); 13687 13688 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13689 if (!ordered && NR > 0) { 13690 // If we are not serializing this broadcast, then send the 13691 // registered receivers separately so they don't wait for the 13692 // components to be launched. 13693 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13694 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13695 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13696 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13697 ordered, sticky, false, userId); 13698 if (DEBUG_BROADCAST) Slog.v( 13699 TAG, "Enqueueing parallel broadcast " + r); 13700 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13701 if (!replaced) { 13702 queue.enqueueParallelBroadcastLocked(r); 13703 queue.scheduleBroadcastsLocked(); 13704 } 13705 registeredReceivers = null; 13706 NR = 0; 13707 } 13708 13709 // Merge into one list. 13710 int ir = 0; 13711 if (receivers != null) { 13712 // A special case for PACKAGE_ADDED: do not allow the package 13713 // being added to see this broadcast. This prevents them from 13714 // using this as a back door to get run as soon as they are 13715 // installed. Maybe in the future we want to have a special install 13716 // broadcast or such for apps, but we'd like to deliberately make 13717 // this decision. 13718 String skipPackages[] = null; 13719 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13720 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13721 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13722 Uri data = intent.getData(); 13723 if (data != null) { 13724 String pkgName = data.getSchemeSpecificPart(); 13725 if (pkgName != null) { 13726 skipPackages = new String[] { pkgName }; 13727 } 13728 } 13729 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13730 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13731 } 13732 if (skipPackages != null && (skipPackages.length > 0)) { 13733 for (String skipPackage : skipPackages) { 13734 if (skipPackage != null) { 13735 int NT = receivers.size(); 13736 for (int it=0; it<NT; it++) { 13737 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13738 if (curt.activityInfo.packageName.equals(skipPackage)) { 13739 receivers.remove(it); 13740 it--; 13741 NT--; 13742 } 13743 } 13744 } 13745 } 13746 } 13747 13748 int NT = receivers != null ? receivers.size() : 0; 13749 int it = 0; 13750 ResolveInfo curt = null; 13751 BroadcastFilter curr = null; 13752 while (it < NT && ir < NR) { 13753 if (curt == null) { 13754 curt = (ResolveInfo)receivers.get(it); 13755 } 13756 if (curr == null) { 13757 curr = registeredReceivers.get(ir); 13758 } 13759 if (curr.getPriority() >= curt.priority) { 13760 // Insert this broadcast record into the final list. 13761 receivers.add(it, curr); 13762 ir++; 13763 curr = null; 13764 it++; 13765 NT++; 13766 } else { 13767 // Skip to the next ResolveInfo in the final list. 13768 it++; 13769 curt = null; 13770 } 13771 } 13772 } 13773 while (ir < NR) { 13774 if (receivers == null) { 13775 receivers = new ArrayList(); 13776 } 13777 receivers.add(registeredReceivers.get(ir)); 13778 ir++; 13779 } 13780 13781 if ((receivers != null && receivers.size() > 0) 13782 || resultTo != null) { 13783 BroadcastQueue queue = broadcastQueueForIntent(intent); 13784 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13785 callerPackage, callingPid, callingUid, resolvedType, 13786 requiredPermission, appOp, receivers, resultTo, resultCode, 13787 resultData, map, ordered, sticky, false, userId); 13788 if (DEBUG_BROADCAST) Slog.v( 13789 TAG, "Enqueueing ordered broadcast " + r 13790 + ": prev had " + queue.mOrderedBroadcasts.size()); 13791 if (DEBUG_BROADCAST) { 13792 int seq = r.intent.getIntExtra("seq", -1); 13793 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13794 } 13795 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13796 if (!replaced) { 13797 queue.enqueueOrderedBroadcastLocked(r); 13798 queue.scheduleBroadcastsLocked(); 13799 } 13800 } 13801 13802 return ActivityManager.BROADCAST_SUCCESS; 13803 } 13804 13805 final Intent verifyBroadcastLocked(Intent intent) { 13806 // Refuse possible leaked file descriptors 13807 if (intent != null && intent.hasFileDescriptors() == true) { 13808 throw new IllegalArgumentException("File descriptors passed in Intent"); 13809 } 13810 13811 int flags = intent.getFlags(); 13812 13813 if (!mProcessesReady) { 13814 // if the caller really truly claims to know what they're doing, go 13815 // ahead and allow the broadcast without launching any receivers 13816 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13817 intent = new Intent(intent); 13818 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13819 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13820 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13821 + " before boot completion"); 13822 throw new IllegalStateException("Cannot broadcast before boot completed"); 13823 } 13824 } 13825 13826 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13827 throw new IllegalArgumentException( 13828 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13829 } 13830 13831 return intent; 13832 } 13833 13834 public final int broadcastIntent(IApplicationThread caller, 13835 Intent intent, String resolvedType, IIntentReceiver resultTo, 13836 int resultCode, String resultData, Bundle map, 13837 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13838 enforceNotIsolatedCaller("broadcastIntent"); 13839 synchronized(this) { 13840 intent = verifyBroadcastLocked(intent); 13841 13842 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13843 final int callingPid = Binder.getCallingPid(); 13844 final int callingUid = Binder.getCallingUid(); 13845 final long origId = Binder.clearCallingIdentity(); 13846 int res = broadcastIntentLocked(callerApp, 13847 callerApp != null ? callerApp.info.packageName : null, 13848 intent, resolvedType, resultTo, 13849 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13850 callingPid, callingUid, userId); 13851 Binder.restoreCallingIdentity(origId); 13852 return res; 13853 } 13854 } 13855 13856 int broadcastIntentInPackage(String packageName, int uid, 13857 Intent intent, String resolvedType, IIntentReceiver resultTo, 13858 int resultCode, String resultData, Bundle map, 13859 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13860 synchronized(this) { 13861 intent = verifyBroadcastLocked(intent); 13862 13863 final long origId = Binder.clearCallingIdentity(); 13864 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13865 resultTo, resultCode, resultData, map, requiredPermission, 13866 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13867 Binder.restoreCallingIdentity(origId); 13868 return res; 13869 } 13870 } 13871 13872 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13873 // Refuse possible leaked file descriptors 13874 if (intent != null && intent.hasFileDescriptors() == true) { 13875 throw new IllegalArgumentException("File descriptors passed in Intent"); 13876 } 13877 13878 userId = handleIncomingUser(Binder.getCallingPid(), 13879 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13880 13881 synchronized(this) { 13882 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13883 != PackageManager.PERMISSION_GRANTED) { 13884 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13885 + Binder.getCallingPid() 13886 + ", uid=" + Binder.getCallingUid() 13887 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13888 Slog.w(TAG, msg); 13889 throw new SecurityException(msg); 13890 } 13891 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13892 if (stickies != null) { 13893 ArrayList<Intent> list = stickies.get(intent.getAction()); 13894 if (list != null) { 13895 int N = list.size(); 13896 int i; 13897 for (i=0; i<N; i++) { 13898 if (intent.filterEquals(list.get(i))) { 13899 list.remove(i); 13900 break; 13901 } 13902 } 13903 if (list.size() <= 0) { 13904 stickies.remove(intent.getAction()); 13905 } 13906 } 13907 if (stickies.size() <= 0) { 13908 mStickyBroadcasts.remove(userId); 13909 } 13910 } 13911 } 13912 } 13913 13914 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13915 String resultData, Bundle resultExtras, boolean resultAbort) { 13916 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13917 if (r == null) { 13918 Slog.w(TAG, "finishReceiver called but not found on queue"); 13919 return false; 13920 } 13921 13922 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13923 } 13924 13925 void backgroundServicesFinishedLocked(int userId) { 13926 for (BroadcastQueue queue : mBroadcastQueues) { 13927 queue.backgroundServicesFinishedLocked(userId); 13928 } 13929 } 13930 13931 public void finishReceiver(IBinder who, int resultCode, String resultData, 13932 Bundle resultExtras, boolean resultAbort) { 13933 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13934 13935 // Refuse possible leaked file descriptors 13936 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13937 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13938 } 13939 13940 final long origId = Binder.clearCallingIdentity(); 13941 try { 13942 boolean doNext = false; 13943 BroadcastRecord r; 13944 13945 synchronized(this) { 13946 r = broadcastRecordForReceiverLocked(who); 13947 if (r != null) { 13948 doNext = r.queue.finishReceiverLocked(r, resultCode, 13949 resultData, resultExtras, resultAbort, true); 13950 } 13951 } 13952 13953 if (doNext) { 13954 r.queue.processNextBroadcast(false); 13955 } 13956 trimApplications(); 13957 } finally { 13958 Binder.restoreCallingIdentity(origId); 13959 } 13960 } 13961 13962 // ========================================================= 13963 // INSTRUMENTATION 13964 // ========================================================= 13965 13966 public boolean startInstrumentation(ComponentName className, 13967 String profileFile, int flags, Bundle arguments, 13968 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13969 int userId) { 13970 enforceNotIsolatedCaller("startInstrumentation"); 13971 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13972 userId, false, true, "startInstrumentation", null); 13973 // Refuse possible leaked file descriptors 13974 if (arguments != null && arguments.hasFileDescriptors()) { 13975 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13976 } 13977 13978 synchronized(this) { 13979 InstrumentationInfo ii = null; 13980 ApplicationInfo ai = null; 13981 try { 13982 ii = mContext.getPackageManager().getInstrumentationInfo( 13983 className, STOCK_PM_FLAGS); 13984 ai = AppGlobals.getPackageManager().getApplicationInfo( 13985 ii.targetPackage, STOCK_PM_FLAGS, userId); 13986 } catch (PackageManager.NameNotFoundException e) { 13987 } catch (RemoteException e) { 13988 } 13989 if (ii == null) { 13990 reportStartInstrumentationFailure(watcher, className, 13991 "Unable to find instrumentation info for: " + className); 13992 return false; 13993 } 13994 if (ai == null) { 13995 reportStartInstrumentationFailure(watcher, className, 13996 "Unable to find instrumentation target package: " + ii.targetPackage); 13997 return false; 13998 } 13999 14000 int match = mContext.getPackageManager().checkSignatures( 14001 ii.targetPackage, ii.packageName); 14002 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14003 String msg = "Permission Denial: starting instrumentation " 14004 + className + " from pid=" 14005 + Binder.getCallingPid() 14006 + ", uid=" + Binder.getCallingPid() 14007 + " not allowed because package " + ii.packageName 14008 + " does not have a signature matching the target " 14009 + ii.targetPackage; 14010 reportStartInstrumentationFailure(watcher, className, msg); 14011 throw new SecurityException(msg); 14012 } 14013 14014 final long origId = Binder.clearCallingIdentity(); 14015 // Instrumentation can kill and relaunch even persistent processes 14016 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14017 "start instr"); 14018 ProcessRecord app = addAppLocked(ai, false); 14019 app.instrumentationClass = className; 14020 app.instrumentationInfo = ai; 14021 app.instrumentationProfileFile = profileFile; 14022 app.instrumentationArguments = arguments; 14023 app.instrumentationWatcher = watcher; 14024 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14025 app.instrumentationResultClass = className; 14026 Binder.restoreCallingIdentity(origId); 14027 } 14028 14029 return true; 14030 } 14031 14032 /** 14033 * Report errors that occur while attempting to start Instrumentation. Always writes the 14034 * error to the logs, but if somebody is watching, send the report there too. This enables 14035 * the "am" command to report errors with more information. 14036 * 14037 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14038 * @param cn The component name of the instrumentation. 14039 * @param report The error report. 14040 */ 14041 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14042 ComponentName cn, String report) { 14043 Slog.w(TAG, report); 14044 try { 14045 if (watcher != null) { 14046 Bundle results = new Bundle(); 14047 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14048 results.putString("Error", report); 14049 watcher.instrumentationStatus(cn, -1, results); 14050 } 14051 } catch (RemoteException e) { 14052 Slog.w(TAG, e); 14053 } 14054 } 14055 14056 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14057 if (app.instrumentationWatcher != null) { 14058 try { 14059 // NOTE: IInstrumentationWatcher *must* be oneway here 14060 app.instrumentationWatcher.instrumentationFinished( 14061 app.instrumentationClass, 14062 resultCode, 14063 results); 14064 } catch (RemoteException e) { 14065 } 14066 } 14067 if (app.instrumentationUiAutomationConnection != null) { 14068 try { 14069 app.instrumentationUiAutomationConnection.shutdown(); 14070 } catch (RemoteException re) { 14071 /* ignore */ 14072 } 14073 // Only a UiAutomation can set this flag and now that 14074 // it is finished we make sure it is reset to its default. 14075 mUserIsMonkey = false; 14076 } 14077 app.instrumentationWatcher = null; 14078 app.instrumentationUiAutomationConnection = null; 14079 app.instrumentationClass = null; 14080 app.instrumentationInfo = null; 14081 app.instrumentationProfileFile = null; 14082 app.instrumentationArguments = null; 14083 14084 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14085 "finished inst"); 14086 } 14087 14088 public void finishInstrumentation(IApplicationThread target, 14089 int resultCode, Bundle results) { 14090 int userId = UserHandle.getCallingUserId(); 14091 // Refuse possible leaked file descriptors 14092 if (results != null && results.hasFileDescriptors()) { 14093 throw new IllegalArgumentException("File descriptors passed in Intent"); 14094 } 14095 14096 synchronized(this) { 14097 ProcessRecord app = getRecordForAppLocked(target); 14098 if (app == null) { 14099 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14100 return; 14101 } 14102 final long origId = Binder.clearCallingIdentity(); 14103 finishInstrumentationLocked(app, resultCode, results); 14104 Binder.restoreCallingIdentity(origId); 14105 } 14106 } 14107 14108 // ========================================================= 14109 // CONFIGURATION 14110 // ========================================================= 14111 14112 public ConfigurationInfo getDeviceConfigurationInfo() { 14113 ConfigurationInfo config = new ConfigurationInfo(); 14114 synchronized (this) { 14115 config.reqTouchScreen = mConfiguration.touchscreen; 14116 config.reqKeyboardType = mConfiguration.keyboard; 14117 config.reqNavigation = mConfiguration.navigation; 14118 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14119 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14120 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14121 } 14122 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14123 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14124 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14125 } 14126 config.reqGlEsVersion = GL_ES_VERSION; 14127 } 14128 return config; 14129 } 14130 14131 ActivityStack getFocusedStack() { 14132 return mStackSupervisor.getFocusedStack(); 14133 } 14134 14135 public Configuration getConfiguration() { 14136 Configuration ci; 14137 synchronized(this) { 14138 ci = new Configuration(mConfiguration); 14139 } 14140 return ci; 14141 } 14142 14143 public void updatePersistentConfiguration(Configuration values) { 14144 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14145 "updateConfiguration()"); 14146 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14147 "updateConfiguration()"); 14148 if (values == null) { 14149 throw new NullPointerException("Configuration must not be null"); 14150 } 14151 14152 synchronized(this) { 14153 final long origId = Binder.clearCallingIdentity(); 14154 updateConfigurationLocked(values, null, true, false); 14155 Binder.restoreCallingIdentity(origId); 14156 } 14157 } 14158 14159 public void updateConfiguration(Configuration values) { 14160 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14161 "updateConfiguration()"); 14162 14163 synchronized(this) { 14164 if (values == null && mWindowManager != null) { 14165 // sentinel: fetch the current configuration from the window manager 14166 values = mWindowManager.computeNewConfiguration(); 14167 } 14168 14169 if (mWindowManager != null) { 14170 mProcessList.applyDisplaySize(mWindowManager); 14171 } 14172 14173 final long origId = Binder.clearCallingIdentity(); 14174 if (values != null) { 14175 Settings.System.clearConfiguration(values); 14176 } 14177 updateConfigurationLocked(values, null, false, false); 14178 Binder.restoreCallingIdentity(origId); 14179 } 14180 } 14181 14182 /** 14183 * Do either or both things: (1) change the current configuration, and (2) 14184 * make sure the given activity is running with the (now) current 14185 * configuration. Returns true if the activity has been left running, or 14186 * false if <var>starting</var> is being destroyed to match the new 14187 * configuration. 14188 * @param persistent TODO 14189 */ 14190 boolean updateConfigurationLocked(Configuration values, 14191 ActivityRecord starting, boolean persistent, boolean initLocale) { 14192 int changes = 0; 14193 14194 if (values != null) { 14195 Configuration newConfig = new Configuration(mConfiguration); 14196 changes = newConfig.updateFrom(values); 14197 if (changes != 0) { 14198 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14199 Slog.i(TAG, "Updating configuration to: " + values); 14200 } 14201 14202 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14203 14204 if (values.locale != null && !initLocale) { 14205 saveLocaleLocked(values.locale, 14206 !values.locale.equals(mConfiguration.locale), 14207 values.userSetLocale); 14208 } 14209 14210 mConfigurationSeq++; 14211 if (mConfigurationSeq <= 0) { 14212 mConfigurationSeq = 1; 14213 } 14214 newConfig.seq = mConfigurationSeq; 14215 mConfiguration = newConfig; 14216 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14217 14218 final Configuration configCopy = new Configuration(mConfiguration); 14219 14220 // TODO: If our config changes, should we auto dismiss any currently 14221 // showing dialogs? 14222 mShowDialogs = shouldShowDialogs(newConfig); 14223 14224 AttributeCache ac = AttributeCache.instance(); 14225 if (ac != null) { 14226 ac.updateConfiguration(configCopy); 14227 } 14228 14229 // Make sure all resources in our process are updated 14230 // right now, so that anyone who is going to retrieve 14231 // resource values after we return will be sure to get 14232 // the new ones. This is especially important during 14233 // boot, where the first config change needs to guarantee 14234 // all resources have that config before following boot 14235 // code is executed. 14236 mSystemThread.applyConfigurationToResources(configCopy); 14237 14238 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14239 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14240 msg.obj = new Configuration(configCopy); 14241 mHandler.sendMessage(msg); 14242 } 14243 14244 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14245 ProcessRecord app = mLruProcesses.get(i); 14246 try { 14247 if (app.thread != null) { 14248 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14249 + app.processName + " new config " + mConfiguration); 14250 app.thread.scheduleConfigurationChanged(configCopy); 14251 } 14252 } catch (Exception e) { 14253 } 14254 } 14255 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14256 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14257 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14258 | Intent.FLAG_RECEIVER_FOREGROUND); 14259 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14260 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14261 Process.SYSTEM_UID, UserHandle.USER_ALL); 14262 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14263 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14264 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14265 broadcastIntentLocked(null, null, intent, 14266 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14267 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14268 } 14269 } 14270 } 14271 14272 boolean kept = true; 14273 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14274 // mainStack is null during startup. 14275 if (mainStack != null) { 14276 if (changes != 0 && starting == null) { 14277 // If the configuration changed, and the caller is not already 14278 // in the process of starting an activity, then find the top 14279 // activity to check if its configuration needs to change. 14280 starting = mainStack.topRunningActivityLocked(null); 14281 } 14282 14283 if (starting != null) { 14284 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14285 // And we need to make sure at this point that all other activities 14286 // are made visible with the correct configuration. 14287 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14288 } 14289 } 14290 14291 if (values != null && mWindowManager != null) { 14292 mWindowManager.setNewConfiguration(mConfiguration); 14293 } 14294 14295 return kept; 14296 } 14297 14298 /** 14299 * Decide based on the configuration whether we should shouw the ANR, 14300 * crash, etc dialogs. The idea is that if there is no affordnace to 14301 * press the on-screen buttons, we shouldn't show the dialog. 14302 * 14303 * A thought: SystemUI might also want to get told about this, the Power 14304 * dialog / global actions also might want different behaviors. 14305 */ 14306 private static final boolean shouldShowDialogs(Configuration config) { 14307 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14308 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14309 } 14310 14311 /** 14312 * Save the locale. You must be inside a synchronized (this) block. 14313 */ 14314 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14315 if(isDiff) { 14316 SystemProperties.set("user.language", l.getLanguage()); 14317 SystemProperties.set("user.region", l.getCountry()); 14318 } 14319 14320 if(isPersist) { 14321 SystemProperties.set("persist.sys.language", l.getLanguage()); 14322 SystemProperties.set("persist.sys.country", l.getCountry()); 14323 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14324 } 14325 } 14326 14327 @Override 14328 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14329 ActivityRecord srec = ActivityRecord.forToken(token); 14330 return srec != null && srec.task.affinity != null && 14331 srec.task.affinity.equals(destAffinity); 14332 } 14333 14334 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14335 Intent resultData) { 14336 14337 synchronized (this) { 14338 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14339 if (stack != null) { 14340 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14341 } 14342 return false; 14343 } 14344 } 14345 14346 public int getLaunchedFromUid(IBinder activityToken) { 14347 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14348 if (srec == null) { 14349 return -1; 14350 } 14351 return srec.launchedFromUid; 14352 } 14353 14354 public String getLaunchedFromPackage(IBinder activityToken) { 14355 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14356 if (srec == null) { 14357 return null; 14358 } 14359 return srec.launchedFromPackage; 14360 } 14361 14362 // ========================================================= 14363 // LIFETIME MANAGEMENT 14364 // ========================================================= 14365 14366 // Returns which broadcast queue the app is the current [or imminent] receiver 14367 // on, or 'null' if the app is not an active broadcast recipient. 14368 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14369 BroadcastRecord r = app.curReceiver; 14370 if (r != null) { 14371 return r.queue; 14372 } 14373 14374 // It's not the current receiver, but it might be starting up to become one 14375 synchronized (this) { 14376 for (BroadcastQueue queue : mBroadcastQueues) { 14377 r = queue.mPendingBroadcast; 14378 if (r != null && r.curApp == app) { 14379 // found it; report which queue it's in 14380 return queue; 14381 } 14382 } 14383 } 14384 14385 return null; 14386 } 14387 14388 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14389 boolean doingAll, long now) { 14390 if (mAdjSeq == app.adjSeq) { 14391 // This adjustment has already been computed. 14392 return app.curRawAdj; 14393 } 14394 14395 if (app.thread == null) { 14396 app.adjSeq = mAdjSeq; 14397 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14398 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14399 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14400 } 14401 14402 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14403 app.adjSource = null; 14404 app.adjTarget = null; 14405 app.empty = false; 14406 app.cached = false; 14407 14408 final int activitiesSize = app.activities.size(); 14409 14410 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14411 // The max adjustment doesn't allow this app to be anything 14412 // below foreground, so it is not worth doing work for it. 14413 app.adjType = "fixed"; 14414 app.adjSeq = mAdjSeq; 14415 app.curRawAdj = app.maxAdj; 14416 app.foregroundActivities = false; 14417 app.keeping = true; 14418 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14419 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14420 // System process can do UI, and when they do we want to have 14421 // them trim their memory after the user leaves the UI. To 14422 // facilitate this, here we need to determine whether or not it 14423 // is currently showing UI. 14424 app.systemNoUi = true; 14425 if (app == TOP_APP) { 14426 app.systemNoUi = false; 14427 } else if (activitiesSize > 0) { 14428 for (int j = 0; j < activitiesSize; j++) { 14429 final ActivityRecord r = app.activities.get(j); 14430 if (r.visible) { 14431 app.systemNoUi = false; 14432 } 14433 } 14434 } 14435 if (!app.systemNoUi) { 14436 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14437 } 14438 return (app.curAdj=app.maxAdj); 14439 } 14440 14441 app.keeping = false; 14442 app.systemNoUi = false; 14443 14444 // Determine the importance of the process, starting with most 14445 // important to least, and assign an appropriate OOM adjustment. 14446 int adj; 14447 int schedGroup; 14448 int procState; 14449 boolean foregroundActivities = false; 14450 boolean interesting = false; 14451 BroadcastQueue queue; 14452 if (app == TOP_APP) { 14453 // The last app on the list is the foreground app. 14454 adj = ProcessList.FOREGROUND_APP_ADJ; 14455 schedGroup = Process.THREAD_GROUP_DEFAULT; 14456 app.adjType = "top-activity"; 14457 foregroundActivities = true; 14458 interesting = true; 14459 procState = ActivityManager.PROCESS_STATE_TOP; 14460 } else if (app.instrumentationClass != null) { 14461 // Don't want to kill running instrumentation. 14462 adj = ProcessList.FOREGROUND_APP_ADJ; 14463 schedGroup = Process.THREAD_GROUP_DEFAULT; 14464 app.adjType = "instrumentation"; 14465 interesting = true; 14466 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14467 } else if ((queue = isReceivingBroadcast(app)) != null) { 14468 // An app that is currently receiving a broadcast also 14469 // counts as being in the foreground for OOM killer purposes. 14470 // It's placed in a sched group based on the nature of the 14471 // broadcast as reflected by which queue it's active in. 14472 adj = ProcessList.FOREGROUND_APP_ADJ; 14473 schedGroup = (queue == mFgBroadcastQueue) 14474 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14475 app.adjType = "broadcast"; 14476 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14477 } else if (app.executingServices.size() > 0) { 14478 // An app that is currently executing a service callback also 14479 // counts as being in the foreground. 14480 adj = ProcessList.FOREGROUND_APP_ADJ; 14481 schedGroup = app.execServicesFg ? 14482 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14483 app.adjType = "exec-service"; 14484 procState = ActivityManager.PROCESS_STATE_SERVICE; 14485 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14486 } else { 14487 // As far as we know the process is empty. We may change our mind later. 14488 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14489 // At this point we don't actually know the adjustment. Use the cached adj 14490 // value that the caller wants us to. 14491 adj = cachedAdj; 14492 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14493 app.cached = true; 14494 app.empty = true; 14495 app.adjType = "cch-empty"; 14496 } 14497 14498 // Examine all activities if not already foreground. 14499 if (!foregroundActivities && activitiesSize > 0) { 14500 for (int j = 0; j < activitiesSize; j++) { 14501 final ActivityRecord r = app.activities.get(j); 14502 if (r.app != app) { 14503 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14504 + app + "?!?"); 14505 continue; 14506 } 14507 if (r.visible) { 14508 // App has a visible activity; only upgrade adjustment. 14509 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14510 adj = ProcessList.VISIBLE_APP_ADJ; 14511 app.adjType = "visible"; 14512 } 14513 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14514 procState = ActivityManager.PROCESS_STATE_TOP; 14515 } 14516 schedGroup = Process.THREAD_GROUP_DEFAULT; 14517 app.cached = false; 14518 app.empty = false; 14519 foregroundActivities = true; 14520 break; 14521 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14522 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14523 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14524 app.adjType = "pausing"; 14525 } 14526 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14527 procState = ActivityManager.PROCESS_STATE_TOP; 14528 } 14529 schedGroup = Process.THREAD_GROUP_DEFAULT; 14530 app.cached = false; 14531 app.empty = false; 14532 foregroundActivities = true; 14533 } else if (r.state == ActivityState.STOPPING) { 14534 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14535 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14536 app.adjType = "stopping"; 14537 } 14538 // For the process state, we will at this point consider the 14539 // process to be cached. It will be cached either as an activity 14540 // or empty depending on whether the activity is finishing. We do 14541 // this so that we can treat the process as cached for purposes of 14542 // memory trimming (determing current memory level, trim command to 14543 // send to process) since there can be an arbitrary number of stopping 14544 // processes and they should soon all go into the cached state. 14545 if (!r.finishing) { 14546 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14547 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14548 } 14549 } 14550 app.cached = false; 14551 app.empty = false; 14552 foregroundActivities = true; 14553 } else { 14554 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14555 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14556 app.adjType = "cch-act"; 14557 } 14558 } 14559 } 14560 } 14561 14562 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14563 if (app.foregroundServices) { 14564 // The user is aware of this app, so make it visible. 14565 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14566 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14567 app.cached = false; 14568 app.adjType = "fg-service"; 14569 schedGroup = Process.THREAD_GROUP_DEFAULT; 14570 } else if (app.forcingToForeground != null) { 14571 // The user is aware of this app, so make it visible. 14572 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14573 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14574 app.cached = false; 14575 app.adjType = "force-fg"; 14576 app.adjSource = app.forcingToForeground; 14577 schedGroup = Process.THREAD_GROUP_DEFAULT; 14578 } 14579 } 14580 14581 if (app.foregroundServices) { 14582 interesting = true; 14583 } 14584 14585 if (app == mHeavyWeightProcess) { 14586 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14587 // We don't want to kill the current heavy-weight process. 14588 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14589 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14590 app.cached = false; 14591 app.adjType = "heavy"; 14592 } 14593 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14594 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14595 } 14596 } 14597 14598 if (app == mHomeProcess) { 14599 if (adj > ProcessList.HOME_APP_ADJ) { 14600 // This process is hosting what we currently consider to be the 14601 // home app, so we don't want to let it go into the background. 14602 adj = ProcessList.HOME_APP_ADJ; 14603 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14604 app.cached = false; 14605 app.adjType = "home"; 14606 } 14607 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14608 procState = ActivityManager.PROCESS_STATE_HOME; 14609 } 14610 } 14611 14612 if (app == mPreviousProcess && app.activities.size() > 0) { 14613 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14614 // This was the previous process that showed UI to the user. 14615 // We want to try to keep it around more aggressively, to give 14616 // a good experience around switching between two apps. 14617 adj = ProcessList.PREVIOUS_APP_ADJ; 14618 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14619 app.cached = false; 14620 app.adjType = "previous"; 14621 } 14622 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14623 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14624 } 14625 } 14626 14627 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14628 + " reason=" + app.adjType); 14629 14630 // By default, we use the computed adjustment. It may be changed if 14631 // there are applications dependent on our services or providers, but 14632 // this gives us a baseline and makes sure we don't get into an 14633 // infinite recursion. 14634 app.adjSeq = mAdjSeq; 14635 app.curRawAdj = adj; 14636 app.hasStartedServices = false; 14637 14638 if (mBackupTarget != null && app == mBackupTarget.app) { 14639 // If possible we want to avoid killing apps while they're being backed up 14640 if (adj > ProcessList.BACKUP_APP_ADJ) { 14641 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14642 adj = ProcessList.BACKUP_APP_ADJ; 14643 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14644 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14645 } 14646 app.adjType = "backup"; 14647 app.cached = false; 14648 } 14649 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14650 procState = ActivityManager.PROCESS_STATE_BACKUP; 14651 } 14652 } 14653 14654 boolean mayBeTop = false; 14655 14656 for (int is = app.services.size()-1; 14657 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14658 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14659 || procState > ActivityManager.PROCESS_STATE_TOP); 14660 is--) { 14661 ServiceRecord s = app.services.valueAt(is); 14662 if (s.startRequested) { 14663 app.hasStartedServices = true; 14664 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14665 procState = ActivityManager.PROCESS_STATE_SERVICE; 14666 } 14667 if (app.hasShownUi && app != mHomeProcess) { 14668 // If this process has shown some UI, let it immediately 14669 // go to the LRU list because it may be pretty heavy with 14670 // UI stuff. We'll tag it with a label just to help 14671 // debug and understand what is going on. 14672 if (adj > ProcessList.SERVICE_ADJ) { 14673 app.adjType = "cch-started-ui-services"; 14674 } 14675 } else { 14676 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14677 // This service has seen some activity within 14678 // recent memory, so we will keep its process ahead 14679 // of the background processes. 14680 if (adj > ProcessList.SERVICE_ADJ) { 14681 adj = ProcessList.SERVICE_ADJ; 14682 app.adjType = "started-services"; 14683 app.cached = false; 14684 } 14685 } 14686 // If we have let the service slide into the background 14687 // state, still have some text describing what it is doing 14688 // even though the service no longer has an impact. 14689 if (adj > ProcessList.SERVICE_ADJ) { 14690 app.adjType = "cch-started-services"; 14691 } 14692 } 14693 // Don't kill this process because it is doing work; it 14694 // has said it is doing work. 14695 app.keeping = true; 14696 } 14697 for (int conni = s.connections.size()-1; 14698 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14699 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14700 || procState > ActivityManager.PROCESS_STATE_TOP); 14701 conni--) { 14702 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14703 for (int i = 0; 14704 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14705 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14706 || procState > ActivityManager.PROCESS_STATE_TOP); 14707 i++) { 14708 // XXX should compute this based on the max of 14709 // all connected clients. 14710 ConnectionRecord cr = clist.get(i); 14711 if (cr.binding.client == app) { 14712 // Binding to ourself is not interesting. 14713 continue; 14714 } 14715 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14716 ProcessRecord client = cr.binding.client; 14717 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14718 TOP_APP, doingAll, now); 14719 int clientProcState = client.curProcState; 14720 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14721 // If the other app is cached for any reason, for purposes here 14722 // we are going to consider it empty. The specific cached state 14723 // doesn't propagate except under certain conditions. 14724 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14725 } 14726 String adjType = null; 14727 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14728 // Not doing bind OOM management, so treat 14729 // this guy more like a started service. 14730 if (app.hasShownUi && app != mHomeProcess) { 14731 // If this process has shown some UI, let it immediately 14732 // go to the LRU list because it may be pretty heavy with 14733 // UI stuff. We'll tag it with a label just to help 14734 // debug and understand what is going on. 14735 if (adj > clientAdj) { 14736 adjType = "cch-bound-ui-services"; 14737 } 14738 app.cached = false; 14739 clientAdj = adj; 14740 clientProcState = procState; 14741 } else { 14742 if (now >= (s.lastActivity 14743 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14744 // This service has not seen activity within 14745 // recent memory, so allow it to drop to the 14746 // LRU list if there is no other reason to keep 14747 // it around. We'll also tag it with a label just 14748 // to help debug and undertand what is going on. 14749 if (adj > clientAdj) { 14750 adjType = "cch-bound-services"; 14751 } 14752 clientAdj = adj; 14753 } 14754 } 14755 } 14756 if (adj > clientAdj) { 14757 // If this process has recently shown UI, and 14758 // the process that is binding to it is less 14759 // important than being visible, then we don't 14760 // care about the binding as much as we care 14761 // about letting this process get into the LRU 14762 // list to be killed and restarted if needed for 14763 // memory. 14764 if (app.hasShownUi && app != mHomeProcess 14765 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14766 adjType = "cch-bound-ui-services"; 14767 } else { 14768 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14769 |Context.BIND_IMPORTANT)) != 0) { 14770 adj = clientAdj; 14771 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14772 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14773 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14774 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14775 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14776 adj = clientAdj; 14777 } else { 14778 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14779 adj = ProcessList.VISIBLE_APP_ADJ; 14780 } 14781 } 14782 if (!client.cached) { 14783 app.cached = false; 14784 } 14785 if (client.keeping) { 14786 app.keeping = true; 14787 } 14788 adjType = "service"; 14789 } 14790 } 14791 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14792 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14793 schedGroup = Process.THREAD_GROUP_DEFAULT; 14794 } 14795 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14796 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14797 // Special handling of clients who are in the top state. 14798 // We *may* want to consider this process to be in the 14799 // top state as well, but only if there is not another 14800 // reason for it to be running. Being on the top is a 14801 // special state, meaning you are specifically running 14802 // for the current top app. If the process is already 14803 // running in the background for some other reason, it 14804 // is more important to continue considering it to be 14805 // in the background state. 14806 mayBeTop = true; 14807 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14808 } else { 14809 // Special handling for above-top states (persistent 14810 // processes). These should not bring the current process 14811 // into the top state, since they are not on top. Instead 14812 // give them the best state after that. 14813 clientProcState = 14814 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14815 } 14816 } 14817 } else { 14818 if (clientProcState < 14819 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14820 clientProcState = 14821 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14822 } 14823 } 14824 if (procState > clientProcState) { 14825 procState = clientProcState; 14826 } 14827 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14828 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14829 app.pendingUiClean = true; 14830 } 14831 if (adjType != null) { 14832 app.adjType = adjType; 14833 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14834 .REASON_SERVICE_IN_USE; 14835 app.adjSource = cr.binding.client; 14836 app.adjSourceOom = clientAdj; 14837 app.adjTarget = s.name; 14838 } 14839 } 14840 final ActivityRecord a = cr.activity; 14841 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14842 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14843 (a.visible || a.state == ActivityState.RESUMED 14844 || a.state == ActivityState.PAUSING)) { 14845 adj = ProcessList.FOREGROUND_APP_ADJ; 14846 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14847 schedGroup = Process.THREAD_GROUP_DEFAULT; 14848 } 14849 app.cached = false; 14850 app.adjType = "service"; 14851 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14852 .REASON_SERVICE_IN_USE; 14853 app.adjSource = a; 14854 app.adjSourceOom = adj; 14855 app.adjTarget = s.name; 14856 } 14857 } 14858 } 14859 } 14860 } 14861 14862 for (int provi = app.pubProviders.size()-1; 14863 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14864 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14865 || procState > ActivityManager.PROCESS_STATE_TOP); 14866 provi--) { 14867 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14868 for (int i = cpr.connections.size()-1; 14869 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14870 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14871 || procState > ActivityManager.PROCESS_STATE_TOP); 14872 i--) { 14873 ContentProviderConnection conn = cpr.connections.get(i); 14874 ProcessRecord client = conn.client; 14875 if (client == app) { 14876 // Being our own client is not interesting. 14877 continue; 14878 } 14879 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14880 int clientProcState = client.curProcState; 14881 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14882 // If the other app is cached for any reason, for purposes here 14883 // we are going to consider it empty. 14884 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14885 } 14886 if (adj > clientAdj) { 14887 if (app.hasShownUi && app != mHomeProcess 14888 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14889 app.adjType = "cch-ui-provider"; 14890 } else { 14891 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14892 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14893 app.adjType = "provider"; 14894 } 14895 app.cached &= client.cached; 14896 app.keeping |= client.keeping; 14897 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14898 .REASON_PROVIDER_IN_USE; 14899 app.adjSource = client; 14900 app.adjSourceOom = clientAdj; 14901 app.adjTarget = cpr.name; 14902 } 14903 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14904 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14905 // Special handling of clients who are in the top state. 14906 // We *may* want to consider this process to be in the 14907 // top state as well, but only if there is not another 14908 // reason for it to be running. Being on the top is a 14909 // special state, meaning you are specifically running 14910 // for the current top app. If the process is already 14911 // running in the background for some other reason, it 14912 // is more important to continue considering it to be 14913 // in the background state. 14914 mayBeTop = true; 14915 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14916 } else { 14917 // Special handling for above-top states (persistent 14918 // processes). These should not bring the current process 14919 // into the top state, since they are not on top. Instead 14920 // give them the best state after that. 14921 clientProcState = 14922 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14923 } 14924 } 14925 if (procState > clientProcState) { 14926 procState = clientProcState; 14927 } 14928 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14929 schedGroup = Process.THREAD_GROUP_DEFAULT; 14930 } 14931 } 14932 // If the provider has external (non-framework) process 14933 // dependencies, ensure that its adjustment is at least 14934 // FOREGROUND_APP_ADJ. 14935 if (cpr.hasExternalProcessHandles()) { 14936 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14937 adj = ProcessList.FOREGROUND_APP_ADJ; 14938 schedGroup = Process.THREAD_GROUP_DEFAULT; 14939 app.cached = false; 14940 app.keeping = true; 14941 app.adjType = "provider"; 14942 app.adjTarget = cpr.name; 14943 } 14944 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14945 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14946 } 14947 } 14948 } 14949 14950 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14951 // A client of one of our services or providers is in the top state. We 14952 // *may* want to be in the top state, but not if we are already running in 14953 // the background for some other reason. For the decision here, we are going 14954 // to pick out a few specific states that we want to remain in when a client 14955 // is top (states that tend to be longer-term) and otherwise allow it to go 14956 // to the top state. 14957 switch (procState) { 14958 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14959 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14960 case ActivityManager.PROCESS_STATE_SERVICE: 14961 // These all are longer-term states, so pull them up to the top 14962 // of the background states, but not all the way to the top state. 14963 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14964 break; 14965 default: 14966 // Otherwise, top is a better choice, so take it. 14967 procState = ActivityManager.PROCESS_STATE_TOP; 14968 break; 14969 } 14970 } 14971 14972 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14973 // This is a cached process, but with client activities. Mark it so. 14974 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 14975 app.adjType = "cch-client-act"; 14976 } 14977 14978 if (adj == ProcessList.SERVICE_ADJ) { 14979 if (doingAll) { 14980 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 14981 mNewNumServiceProcs++; 14982 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 14983 if (!app.serviceb) { 14984 // This service isn't far enough down on the LRU list to 14985 // normally be a B service, but if we are low on RAM and it 14986 // is large we want to force it down since we would prefer to 14987 // keep launcher over it. 14988 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 14989 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 14990 app.serviceHighRam = true; 14991 app.serviceb = true; 14992 //Slog.i(TAG, "ADJ " + app + " high ram!"); 14993 } else { 14994 mNewNumAServiceProcs++; 14995 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 14996 } 14997 } else { 14998 app.serviceHighRam = false; 14999 } 15000 } 15001 if (app.serviceb) { 15002 adj = ProcessList.SERVICE_B_ADJ; 15003 } 15004 } 15005 15006 app.curRawAdj = adj; 15007 15008 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15009 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15010 if (adj > app.maxAdj) { 15011 adj = app.maxAdj; 15012 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15013 schedGroup = Process.THREAD_GROUP_DEFAULT; 15014 } 15015 } 15016 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15017 app.keeping = true; 15018 } 15019 15020 // Do final modification to adj. Everything we do between here and applying 15021 // the final setAdj must be done in this function, because we will also use 15022 // it when computing the final cached adj later. Note that we don't need to 15023 // worry about this for max adj above, since max adj will always be used to 15024 // keep it out of the cached vaues. 15025 adj = app.modifyRawOomAdj(adj); 15026 15027 app.curProcState = procState; 15028 15029 int importance = app.memImportance; 15030 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15031 app.curAdj = adj; 15032 app.curSchedGroup = schedGroup; 15033 if (!interesting) { 15034 // For this reporting, if there is not something explicitly 15035 // interesting in this process then we will push it to the 15036 // background importance. 15037 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15038 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15039 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15040 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15041 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15042 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15043 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15044 } else if (adj >= ProcessList.SERVICE_ADJ) { 15045 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15046 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15047 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15048 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15049 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15050 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15051 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15052 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15053 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15054 } else { 15055 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15056 } 15057 } 15058 15059 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15060 if (foregroundActivities != app.foregroundActivities) { 15061 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15062 } 15063 if (changes != 0) { 15064 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15065 app.memImportance = importance; 15066 app.foregroundActivities = foregroundActivities; 15067 int i = mPendingProcessChanges.size()-1; 15068 ProcessChangeItem item = null; 15069 while (i >= 0) { 15070 item = mPendingProcessChanges.get(i); 15071 if (item.pid == app.pid) { 15072 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15073 break; 15074 } 15075 i--; 15076 } 15077 if (i < 0) { 15078 // No existing item in pending changes; need a new one. 15079 final int NA = mAvailProcessChanges.size(); 15080 if (NA > 0) { 15081 item = mAvailProcessChanges.remove(NA-1); 15082 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15083 } else { 15084 item = new ProcessChangeItem(); 15085 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15086 } 15087 item.changes = 0; 15088 item.pid = app.pid; 15089 item.uid = app.info.uid; 15090 if (mPendingProcessChanges.size() == 0) { 15091 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15092 "*** Enqueueing dispatch processes changed!"); 15093 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15094 } 15095 mPendingProcessChanges.add(item); 15096 } 15097 item.changes |= changes; 15098 item.importance = importance; 15099 item.foregroundActivities = foregroundActivities; 15100 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15101 + Integer.toHexString(System.identityHashCode(item)) 15102 + " " + app.toShortString() + ": changes=" + item.changes 15103 + " importance=" + item.importance 15104 + " foreground=" + item.foregroundActivities 15105 + " type=" + app.adjType + " source=" + app.adjSource 15106 + " target=" + app.adjTarget); 15107 } 15108 15109 return app.curRawAdj; 15110 } 15111 15112 /** 15113 * Schedule PSS collection of a process. 15114 */ 15115 void requestPssLocked(ProcessRecord proc, int procState) { 15116 if (mPendingPssProcesses.contains(proc)) { 15117 return; 15118 } 15119 if (mPendingPssProcesses.size() == 0) { 15120 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15121 } 15122 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15123 proc.pssProcState = procState; 15124 mPendingPssProcesses.add(proc); 15125 } 15126 15127 /** 15128 * Schedule PSS collection of all processes. 15129 */ 15130 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15131 if (!always) { 15132 if (now < (mLastFullPssTime + 15133 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15134 return; 15135 } 15136 } 15137 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15138 mLastFullPssTime = now; 15139 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15140 mPendingPssProcesses.clear(); 15141 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15142 ProcessRecord app = mLruProcesses.get(i); 15143 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15144 app.pssProcState = app.setProcState; 15145 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15146 mSleeping, now); 15147 mPendingPssProcesses.add(app); 15148 } 15149 } 15150 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15151 } 15152 15153 /** 15154 * Ask a given process to GC right now. 15155 */ 15156 final void performAppGcLocked(ProcessRecord app) { 15157 try { 15158 app.lastRequestedGc = SystemClock.uptimeMillis(); 15159 if (app.thread != null) { 15160 if (app.reportLowMemory) { 15161 app.reportLowMemory = false; 15162 app.thread.scheduleLowMemory(); 15163 } else { 15164 app.thread.processInBackground(); 15165 } 15166 } 15167 } catch (Exception e) { 15168 // whatever. 15169 } 15170 } 15171 15172 /** 15173 * Returns true if things are idle enough to perform GCs. 15174 */ 15175 private final boolean canGcNowLocked() { 15176 boolean processingBroadcasts = false; 15177 for (BroadcastQueue q : mBroadcastQueues) { 15178 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15179 processingBroadcasts = true; 15180 } 15181 } 15182 return !processingBroadcasts 15183 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15184 } 15185 15186 /** 15187 * Perform GCs on all processes that are waiting for it, but only 15188 * if things are idle. 15189 */ 15190 final void performAppGcsLocked() { 15191 final int N = mProcessesToGc.size(); 15192 if (N <= 0) { 15193 return; 15194 } 15195 if (canGcNowLocked()) { 15196 while (mProcessesToGc.size() > 0) { 15197 ProcessRecord proc = mProcessesToGc.remove(0); 15198 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15199 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15200 <= SystemClock.uptimeMillis()) { 15201 // To avoid spamming the system, we will GC processes one 15202 // at a time, waiting a few seconds between each. 15203 performAppGcLocked(proc); 15204 scheduleAppGcsLocked(); 15205 return; 15206 } else { 15207 // It hasn't been long enough since we last GCed this 15208 // process... put it in the list to wait for its time. 15209 addProcessToGcListLocked(proc); 15210 break; 15211 } 15212 } 15213 } 15214 15215 scheduleAppGcsLocked(); 15216 } 15217 } 15218 15219 /** 15220 * If all looks good, perform GCs on all processes waiting for them. 15221 */ 15222 final void performAppGcsIfAppropriateLocked() { 15223 if (canGcNowLocked()) { 15224 performAppGcsLocked(); 15225 return; 15226 } 15227 // Still not idle, wait some more. 15228 scheduleAppGcsLocked(); 15229 } 15230 15231 /** 15232 * Schedule the execution of all pending app GCs. 15233 */ 15234 final void scheduleAppGcsLocked() { 15235 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15236 15237 if (mProcessesToGc.size() > 0) { 15238 // Schedule a GC for the time to the next process. 15239 ProcessRecord proc = mProcessesToGc.get(0); 15240 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15241 15242 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15243 long now = SystemClock.uptimeMillis(); 15244 if (when < (now+GC_TIMEOUT)) { 15245 when = now + GC_TIMEOUT; 15246 } 15247 mHandler.sendMessageAtTime(msg, when); 15248 } 15249 } 15250 15251 /** 15252 * Add a process to the array of processes waiting to be GCed. Keeps the 15253 * list in sorted order by the last GC time. The process can't already be 15254 * on the list. 15255 */ 15256 final void addProcessToGcListLocked(ProcessRecord proc) { 15257 boolean added = false; 15258 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15259 if (mProcessesToGc.get(i).lastRequestedGc < 15260 proc.lastRequestedGc) { 15261 added = true; 15262 mProcessesToGc.add(i+1, proc); 15263 break; 15264 } 15265 } 15266 if (!added) { 15267 mProcessesToGc.add(0, proc); 15268 } 15269 } 15270 15271 /** 15272 * Set up to ask a process to GC itself. This will either do it 15273 * immediately, or put it on the list of processes to gc the next 15274 * time things are idle. 15275 */ 15276 final void scheduleAppGcLocked(ProcessRecord app) { 15277 long now = SystemClock.uptimeMillis(); 15278 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15279 return; 15280 } 15281 if (!mProcessesToGc.contains(app)) { 15282 addProcessToGcListLocked(app); 15283 scheduleAppGcsLocked(); 15284 } 15285 } 15286 15287 final void checkExcessivePowerUsageLocked(boolean doKills) { 15288 updateCpuStatsNow(); 15289 15290 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15291 boolean doWakeKills = doKills; 15292 boolean doCpuKills = doKills; 15293 if (mLastPowerCheckRealtime == 0) { 15294 doWakeKills = false; 15295 } 15296 if (mLastPowerCheckUptime == 0) { 15297 doCpuKills = false; 15298 } 15299 if (stats.isScreenOn()) { 15300 doWakeKills = false; 15301 } 15302 final long curRealtime = SystemClock.elapsedRealtime(); 15303 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15304 final long curUptime = SystemClock.uptimeMillis(); 15305 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15306 mLastPowerCheckRealtime = curRealtime; 15307 mLastPowerCheckUptime = curUptime; 15308 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15309 doWakeKills = false; 15310 } 15311 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15312 doCpuKills = false; 15313 } 15314 int i = mLruProcesses.size(); 15315 while (i > 0) { 15316 i--; 15317 ProcessRecord app = mLruProcesses.get(i); 15318 if (!app.keeping) { 15319 long wtime; 15320 synchronized (stats) { 15321 wtime = stats.getProcessWakeTime(app.info.uid, 15322 app.pid, curRealtime); 15323 } 15324 long wtimeUsed = wtime - app.lastWakeTime; 15325 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15326 if (DEBUG_POWER) { 15327 StringBuilder sb = new StringBuilder(128); 15328 sb.append("Wake for "); 15329 app.toShortString(sb); 15330 sb.append(": over "); 15331 TimeUtils.formatDuration(realtimeSince, sb); 15332 sb.append(" used "); 15333 TimeUtils.formatDuration(wtimeUsed, sb); 15334 sb.append(" ("); 15335 sb.append((wtimeUsed*100)/realtimeSince); 15336 sb.append("%)"); 15337 Slog.i(TAG, sb.toString()); 15338 sb.setLength(0); 15339 sb.append("CPU for "); 15340 app.toShortString(sb); 15341 sb.append(": over "); 15342 TimeUtils.formatDuration(uptimeSince, sb); 15343 sb.append(" used "); 15344 TimeUtils.formatDuration(cputimeUsed, sb); 15345 sb.append(" ("); 15346 sb.append((cputimeUsed*100)/uptimeSince); 15347 sb.append("%)"); 15348 Slog.i(TAG, sb.toString()); 15349 } 15350 // If a process has held a wake lock for more 15351 // than 50% of the time during this period, 15352 // that sounds bad. Kill! 15353 if (doWakeKills && realtimeSince > 0 15354 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15355 synchronized (stats) { 15356 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15357 realtimeSince, wtimeUsed); 15358 } 15359 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15360 + " during " + realtimeSince); 15361 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15362 } else if (doCpuKills && uptimeSince > 0 15363 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15364 synchronized (stats) { 15365 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15366 uptimeSince, cputimeUsed); 15367 } 15368 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15369 + " during " + uptimeSince); 15370 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15371 } else { 15372 app.lastWakeTime = wtime; 15373 app.lastCpuTime = app.curCpuTime; 15374 } 15375 } 15376 } 15377 } 15378 15379 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15380 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15381 boolean success = true; 15382 15383 if (app.curRawAdj != app.setRawAdj) { 15384 if (wasKeeping && !app.keeping) { 15385 // This app is no longer something we want to keep. Note 15386 // its current wake lock time to later know to kill it if 15387 // it is not behaving well. 15388 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15389 synchronized (stats) { 15390 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15391 app.pid, SystemClock.elapsedRealtime()); 15392 } 15393 app.lastCpuTime = app.curCpuTime; 15394 } 15395 15396 app.setRawAdj = app.curRawAdj; 15397 } 15398 15399 if (app.curAdj != app.setAdj) { 15400 ProcessList.setOomAdj(app.pid, app.curAdj); 15401 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15402 TAG, "Set " + app.pid + " " + app.processName + 15403 " adj " + app.curAdj + ": " + app.adjType); 15404 app.setAdj = app.curAdj; 15405 } 15406 15407 if (app.setSchedGroup != app.curSchedGroup) { 15408 app.setSchedGroup = app.curSchedGroup; 15409 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15410 "Setting process group of " + app.processName 15411 + " to " + app.curSchedGroup); 15412 if (app.waitingToKill != null && 15413 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15414 killUnneededProcessLocked(app, app.waitingToKill); 15415 success = false; 15416 } else { 15417 if (true) { 15418 long oldId = Binder.clearCallingIdentity(); 15419 try { 15420 Process.setProcessGroup(app.pid, app.curSchedGroup); 15421 } catch (Exception e) { 15422 Slog.w(TAG, "Failed setting process group of " + app.pid 15423 + " to " + app.curSchedGroup); 15424 e.printStackTrace(); 15425 } finally { 15426 Binder.restoreCallingIdentity(oldId); 15427 } 15428 } else { 15429 if (app.thread != null) { 15430 try { 15431 app.thread.setSchedulingGroup(app.curSchedGroup); 15432 } catch (RemoteException e) { 15433 } 15434 } 15435 } 15436 Process.setSwappiness(app.pid, 15437 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15438 } 15439 } 15440 if (app.repProcState != app.curProcState) { 15441 app.repProcState = app.curProcState; 15442 if (!reportingProcessState && app.thread != null) { 15443 try { 15444 if (false) { 15445 //RuntimeException h = new RuntimeException("here"); 15446 Slog.i(TAG, "Sending new process state " + app.repProcState 15447 + " to " + app /*, h*/); 15448 } 15449 app.thread.setProcessState(app.repProcState); 15450 } catch (RemoteException e) { 15451 } 15452 } 15453 } 15454 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15455 app.setProcState)) { 15456 app.lastStateTime = now; 15457 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15458 mSleeping, now); 15459 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15460 + ProcessList.makeProcStateString(app.setProcState) + " to " 15461 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15462 + (app.nextPssTime-now) + ": " + app); 15463 } else { 15464 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15465 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15466 requestPssLocked(app, app.setProcState); 15467 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15468 mSleeping, now); 15469 } else if (false && DEBUG_PSS) { 15470 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15471 } 15472 } 15473 if (app.setProcState != app.curProcState) { 15474 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15475 "Proc state change of " + app.processName 15476 + " to " + app.curProcState); 15477 app.setProcState = app.curProcState; 15478 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15479 app.notCachedSinceIdle = false; 15480 } 15481 if (!doingAll) { 15482 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15483 } else { 15484 app.procStateChanged = true; 15485 } 15486 } 15487 return success; 15488 } 15489 15490 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15491 if (proc.thread != null && proc.baseProcessTracker != null) { 15492 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15493 } 15494 } 15495 15496 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15497 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15498 if (app.thread == null) { 15499 return false; 15500 } 15501 15502 final boolean wasKeeping = app.keeping; 15503 15504 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15505 15506 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15507 reportingProcessState, now); 15508 } 15509 15510 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15511 boolean oomAdj) { 15512 if (isForeground != proc.foregroundServices) { 15513 proc.foregroundServices = isForeground; 15514 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15515 proc.info.uid); 15516 if (isForeground) { 15517 if (curProcs == null) { 15518 curProcs = new ArrayList<ProcessRecord>(); 15519 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15520 } 15521 if (!curProcs.contains(proc)) { 15522 curProcs.add(proc); 15523 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15524 proc.info.packageName, proc.info.uid); 15525 } 15526 } else { 15527 if (curProcs != null) { 15528 if (curProcs.remove(proc)) { 15529 mBatteryStatsService.noteEvent( 15530 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15531 proc.info.packageName, proc.info.uid); 15532 if (curProcs.size() <= 0) { 15533 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15534 } 15535 } 15536 } 15537 } 15538 if (oomAdj) { 15539 updateOomAdjLocked(); 15540 } 15541 } 15542 } 15543 15544 private final ActivityRecord resumedAppLocked() { 15545 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15546 String pkg; 15547 int uid; 15548 if (act != null) { 15549 pkg = act.packageName; 15550 uid = act.info.applicationInfo.uid; 15551 } else { 15552 pkg = null; 15553 uid = -1; 15554 } 15555 // Has the UID or resumed package name changed? 15556 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15557 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15558 if (mCurResumedPackage != null) { 15559 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15560 mCurResumedPackage, mCurResumedUid); 15561 } 15562 mCurResumedPackage = pkg; 15563 mCurResumedUid = uid; 15564 if (mCurResumedPackage != null) { 15565 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15566 mCurResumedPackage, mCurResumedUid); 15567 } 15568 } 15569 return act; 15570 } 15571 15572 final boolean updateOomAdjLocked(ProcessRecord app) { 15573 return updateOomAdjLocked(app, false); 15574 } 15575 15576 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15577 final ActivityRecord TOP_ACT = resumedAppLocked(); 15578 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15579 final boolean wasCached = app.cached; 15580 15581 mAdjSeq++; 15582 15583 // This is the desired cached adjusment we want to tell it to use. 15584 // If our app is currently cached, we know it, and that is it. Otherwise, 15585 // we don't know it yet, and it needs to now be cached we will then 15586 // need to do a complete oom adj. 15587 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15588 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15589 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15590 SystemClock.uptimeMillis()); 15591 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15592 // Changed to/from cached state, so apps after it in the LRU 15593 // list may also be changed. 15594 updateOomAdjLocked(); 15595 } 15596 return success; 15597 } 15598 15599 final void updateOomAdjLocked() { 15600 final ActivityRecord TOP_ACT = resumedAppLocked(); 15601 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15602 final long now = SystemClock.uptimeMillis(); 15603 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15604 final int N = mLruProcesses.size(); 15605 15606 if (false) { 15607 RuntimeException e = new RuntimeException(); 15608 e.fillInStackTrace(); 15609 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15610 } 15611 15612 mAdjSeq++; 15613 mNewNumServiceProcs = 0; 15614 mNewNumAServiceProcs = 0; 15615 15616 final int emptyProcessLimit; 15617 final int cachedProcessLimit; 15618 if (mProcessLimit <= 0) { 15619 emptyProcessLimit = cachedProcessLimit = 0; 15620 } else if (mProcessLimit == 1) { 15621 emptyProcessLimit = 1; 15622 cachedProcessLimit = 0; 15623 } else { 15624 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15625 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15626 } 15627 15628 // Let's determine how many processes we have running vs. 15629 // how many slots we have for background processes; we may want 15630 // to put multiple processes in a slot of there are enough of 15631 // them. 15632 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15633 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15634 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15635 if (numEmptyProcs > cachedProcessLimit) { 15636 // If there are more empty processes than our limit on cached 15637 // processes, then use the cached process limit for the factor. 15638 // This ensures that the really old empty processes get pushed 15639 // down to the bottom, so if we are running low on memory we will 15640 // have a better chance at keeping around more cached processes 15641 // instead of a gazillion empty processes. 15642 numEmptyProcs = cachedProcessLimit; 15643 } 15644 int emptyFactor = numEmptyProcs/numSlots; 15645 if (emptyFactor < 1) emptyFactor = 1; 15646 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15647 if (cachedFactor < 1) cachedFactor = 1; 15648 int stepCached = 0; 15649 int stepEmpty = 0; 15650 int numCached = 0; 15651 int numEmpty = 0; 15652 int numTrimming = 0; 15653 15654 mNumNonCachedProcs = 0; 15655 mNumCachedHiddenProcs = 0; 15656 15657 // First update the OOM adjustment for each of the 15658 // application processes based on their current state. 15659 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15660 int nextCachedAdj = curCachedAdj+1; 15661 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15662 int nextEmptyAdj = curEmptyAdj+2; 15663 for (int i=N-1; i>=0; i--) { 15664 ProcessRecord app = mLruProcesses.get(i); 15665 if (!app.killedByAm && app.thread != null) { 15666 app.procStateChanged = false; 15667 final boolean wasKeeping = app.keeping; 15668 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15669 15670 // If we haven't yet assigned the final cached adj 15671 // to the process, do that now. 15672 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15673 switch (app.curProcState) { 15674 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15675 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15676 // This process is a cached process holding activities... 15677 // assign it the next cached value for that type, and then 15678 // step that cached level. 15679 app.curRawAdj = curCachedAdj; 15680 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15681 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15682 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15683 + ")"); 15684 if (curCachedAdj != nextCachedAdj) { 15685 stepCached++; 15686 if (stepCached >= cachedFactor) { 15687 stepCached = 0; 15688 curCachedAdj = nextCachedAdj; 15689 nextCachedAdj += 2; 15690 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15691 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15692 } 15693 } 15694 } 15695 break; 15696 default: 15697 // For everything else, assign next empty cached process 15698 // level and bump that up. Note that this means that 15699 // long-running services that have dropped down to the 15700 // cached level will be treated as empty (since their process 15701 // state is still as a service), which is what we want. 15702 app.curRawAdj = curEmptyAdj; 15703 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15704 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15705 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15706 + ")"); 15707 if (curEmptyAdj != nextEmptyAdj) { 15708 stepEmpty++; 15709 if (stepEmpty >= emptyFactor) { 15710 stepEmpty = 0; 15711 curEmptyAdj = nextEmptyAdj; 15712 nextEmptyAdj += 2; 15713 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15714 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15715 } 15716 } 15717 } 15718 break; 15719 } 15720 } 15721 15722 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15723 15724 // Count the number of process types. 15725 switch (app.curProcState) { 15726 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15727 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15728 mNumCachedHiddenProcs++; 15729 numCached++; 15730 if (numCached > cachedProcessLimit) { 15731 killUnneededProcessLocked(app, "cached #" + numCached); 15732 } 15733 break; 15734 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15735 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15736 && app.lastActivityTime < oldTime) { 15737 killUnneededProcessLocked(app, "empty for " 15738 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15739 / 1000) + "s"); 15740 } else { 15741 numEmpty++; 15742 if (numEmpty > emptyProcessLimit) { 15743 killUnneededProcessLocked(app, "empty #" + numEmpty); 15744 } 15745 } 15746 break; 15747 default: 15748 mNumNonCachedProcs++; 15749 break; 15750 } 15751 15752 if (app.isolated && app.services.size() <= 0) { 15753 // If this is an isolated process, and there are no 15754 // services running in it, then the process is no longer 15755 // needed. We agressively kill these because we can by 15756 // definition not re-use the same process again, and it is 15757 // good to avoid having whatever code was running in them 15758 // left sitting around after no longer needed. 15759 killUnneededProcessLocked(app, "isolated not needed"); 15760 } 15761 15762 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15763 && !app.killedByAm) { 15764 numTrimming++; 15765 } 15766 } 15767 } 15768 15769 mNumServiceProcs = mNewNumServiceProcs; 15770 15771 // Now determine the memory trimming level of background processes. 15772 // Unfortunately we need to start at the back of the list to do this 15773 // properly. We only do this if the number of background apps we 15774 // are managing to keep around is less than half the maximum we desire; 15775 // if we are keeping a good number around, we'll let them use whatever 15776 // memory they want. 15777 final int numCachedAndEmpty = numCached + numEmpty; 15778 int memFactor; 15779 if (numCached <= ProcessList.TRIM_CACHED_APPS 15780 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15781 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15782 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15783 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15784 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15785 } else { 15786 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15787 } 15788 } else { 15789 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15790 } 15791 // We always allow the memory level to go up (better). We only allow it to go 15792 // down if we are in a state where that is allowed, *and* the total number of processes 15793 // has gone down since last time. 15794 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15795 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15796 + " last=" + mLastNumProcesses); 15797 if (memFactor > mLastMemoryLevel) { 15798 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15799 memFactor = mLastMemoryLevel; 15800 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15801 } 15802 } 15803 mLastMemoryLevel = memFactor; 15804 mLastNumProcesses = mLruProcesses.size(); 15805 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15806 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15807 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15808 if (mLowRamStartTime == 0) { 15809 mLowRamStartTime = now; 15810 } 15811 int step = 0; 15812 int fgTrimLevel; 15813 switch (memFactor) { 15814 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15815 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15816 break; 15817 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15818 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15819 break; 15820 default: 15821 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15822 break; 15823 } 15824 int factor = numTrimming/3; 15825 int minFactor = 2; 15826 if (mHomeProcess != null) minFactor++; 15827 if (mPreviousProcess != null) minFactor++; 15828 if (factor < minFactor) factor = minFactor; 15829 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15830 for (int i=N-1; i>=0; i--) { 15831 ProcessRecord app = mLruProcesses.get(i); 15832 if (allChanged || app.procStateChanged) { 15833 setProcessTrackerState(app, trackerMemFactor, now); 15834 app.procStateChanged = false; 15835 } 15836 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15837 && !app.killedByAm) { 15838 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15839 try { 15840 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15841 "Trimming memory of " + app.processName 15842 + " to " + curLevel); 15843 app.thread.scheduleTrimMemory(curLevel); 15844 } catch (RemoteException e) { 15845 } 15846 if (false) { 15847 // For now we won't do this; our memory trimming seems 15848 // to be good enough at this point that destroying 15849 // activities causes more harm than good. 15850 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15851 && app != mHomeProcess && app != mPreviousProcess) { 15852 // Need to do this on its own message because the stack may not 15853 // be in a consistent state at this point. 15854 // For these apps we will also finish their activities 15855 // to help them free memory. 15856 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15857 } 15858 } 15859 } 15860 app.trimMemoryLevel = curLevel; 15861 step++; 15862 if (step >= factor) { 15863 step = 0; 15864 switch (curLevel) { 15865 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15866 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15867 break; 15868 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15869 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15870 break; 15871 } 15872 } 15873 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15874 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15875 && app.thread != null) { 15876 try { 15877 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15878 "Trimming memory of heavy-weight " + app.processName 15879 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15880 app.thread.scheduleTrimMemory( 15881 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15882 } catch (RemoteException e) { 15883 } 15884 } 15885 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15886 } else { 15887 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15888 || app.systemNoUi) && app.pendingUiClean) { 15889 // If this application is now in the background and it 15890 // had done UI, then give it the special trim level to 15891 // have it free UI resources. 15892 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15893 if (app.trimMemoryLevel < level && app.thread != null) { 15894 try { 15895 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15896 "Trimming memory of bg-ui " + app.processName 15897 + " to " + level); 15898 app.thread.scheduleTrimMemory(level); 15899 } catch (RemoteException e) { 15900 } 15901 } 15902 app.pendingUiClean = false; 15903 } 15904 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15905 try { 15906 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15907 "Trimming memory of fg " + app.processName 15908 + " to " + fgTrimLevel); 15909 app.thread.scheduleTrimMemory(fgTrimLevel); 15910 } catch (RemoteException e) { 15911 } 15912 } 15913 app.trimMemoryLevel = fgTrimLevel; 15914 } 15915 } 15916 } else { 15917 if (mLowRamStartTime != 0) { 15918 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15919 mLowRamStartTime = 0; 15920 } 15921 for (int i=N-1; i>=0; i--) { 15922 ProcessRecord app = mLruProcesses.get(i); 15923 if (allChanged || app.procStateChanged) { 15924 setProcessTrackerState(app, trackerMemFactor, now); 15925 app.procStateChanged = false; 15926 } 15927 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15928 || app.systemNoUi) && app.pendingUiClean) { 15929 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15930 && app.thread != null) { 15931 try { 15932 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15933 "Trimming memory of ui hidden " + app.processName 15934 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15935 app.thread.scheduleTrimMemory( 15936 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15937 } catch (RemoteException e) { 15938 } 15939 } 15940 app.pendingUiClean = false; 15941 } 15942 app.trimMemoryLevel = 0; 15943 } 15944 } 15945 15946 if (mAlwaysFinishActivities) { 15947 // Need to do this on its own message because the stack may not 15948 // be in a consistent state at this point. 15949 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15950 } 15951 15952 if (allChanged) { 15953 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15954 } 15955 15956 if (mProcessStats.shouldWriteNowLocked(now)) { 15957 mHandler.post(new Runnable() { 15958 @Override public void run() { 15959 synchronized (ActivityManagerService.this) { 15960 mProcessStats.writeStateAsyncLocked(); 15961 } 15962 } 15963 }); 15964 } 15965 15966 if (DEBUG_OOM_ADJ) { 15967 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15968 } 15969 } 15970 15971 final void trimApplications() { 15972 synchronized (this) { 15973 int i; 15974 15975 // First remove any unused application processes whose package 15976 // has been removed. 15977 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 15978 final ProcessRecord app = mRemovedProcesses.get(i); 15979 if (app.activities.size() == 0 15980 && app.curReceiver == null && app.services.size() == 0) { 15981 Slog.i( 15982 TAG, "Exiting empty application process " 15983 + app.processName + " (" 15984 + (app.thread != null ? app.thread.asBinder() : null) 15985 + ")\n"); 15986 if (app.pid > 0 && app.pid != MY_PID) { 15987 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 15988 app.processName, app.setAdj, "empty"); 15989 app.killedByAm = true; 15990 Process.killProcessQuiet(app.pid); 15991 } else { 15992 try { 15993 app.thread.scheduleExit(); 15994 } catch (Exception e) { 15995 // Ignore exceptions. 15996 } 15997 } 15998 cleanUpApplicationRecordLocked(app, false, true, -1); 15999 mRemovedProcesses.remove(i); 16000 16001 if (app.persistent) { 16002 if (app.persistent) { 16003 addAppLocked(app.info, false); 16004 } 16005 } 16006 } 16007 } 16008 16009 // Now update the oom adj for all processes. 16010 updateOomAdjLocked(); 16011 } 16012 } 16013 16014 /** This method sends the specified signal to each of the persistent apps */ 16015 public void signalPersistentProcesses(int sig) throws RemoteException { 16016 if (sig != Process.SIGNAL_USR1) { 16017 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16018 } 16019 16020 synchronized (this) { 16021 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16022 != PackageManager.PERMISSION_GRANTED) { 16023 throw new SecurityException("Requires permission " 16024 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16025 } 16026 16027 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16028 ProcessRecord r = mLruProcesses.get(i); 16029 if (r.thread != null && r.persistent) { 16030 Process.sendSignal(r.pid, sig); 16031 } 16032 } 16033 } 16034 } 16035 16036 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16037 if (proc == null || proc == mProfileProc) { 16038 proc = mProfileProc; 16039 path = mProfileFile; 16040 profileType = mProfileType; 16041 clearProfilerLocked(); 16042 } 16043 if (proc == null) { 16044 return; 16045 } 16046 try { 16047 proc.thread.profilerControl(false, path, null, profileType); 16048 } catch (RemoteException e) { 16049 throw new IllegalStateException("Process disappeared"); 16050 } 16051 } 16052 16053 private void clearProfilerLocked() { 16054 if (mProfileFd != null) { 16055 try { 16056 mProfileFd.close(); 16057 } catch (IOException e) { 16058 } 16059 } 16060 mProfileApp = null; 16061 mProfileProc = null; 16062 mProfileFile = null; 16063 mProfileType = 0; 16064 mAutoStopProfiler = false; 16065 } 16066 16067 public boolean profileControl(String process, int userId, boolean start, 16068 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16069 16070 try { 16071 synchronized (this) { 16072 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16073 // its own permission. 16074 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16075 != PackageManager.PERMISSION_GRANTED) { 16076 throw new SecurityException("Requires permission " 16077 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16078 } 16079 16080 if (start && fd == null) { 16081 throw new IllegalArgumentException("null fd"); 16082 } 16083 16084 ProcessRecord proc = null; 16085 if (process != null) { 16086 proc = findProcessLocked(process, userId, "profileControl"); 16087 } 16088 16089 if (start && (proc == null || proc.thread == null)) { 16090 throw new IllegalArgumentException("Unknown process: " + process); 16091 } 16092 16093 if (start) { 16094 stopProfilerLocked(null, null, 0); 16095 setProfileApp(proc.info, proc.processName, path, fd, false); 16096 mProfileProc = proc; 16097 mProfileType = profileType; 16098 try { 16099 fd = fd.dup(); 16100 } catch (IOException e) { 16101 fd = null; 16102 } 16103 proc.thread.profilerControl(start, path, fd, profileType); 16104 fd = null; 16105 mProfileFd = null; 16106 } else { 16107 stopProfilerLocked(proc, path, profileType); 16108 if (fd != null) { 16109 try { 16110 fd.close(); 16111 } catch (IOException e) { 16112 } 16113 } 16114 } 16115 16116 return true; 16117 } 16118 } catch (RemoteException e) { 16119 throw new IllegalStateException("Process disappeared"); 16120 } finally { 16121 if (fd != null) { 16122 try { 16123 fd.close(); 16124 } catch (IOException e) { 16125 } 16126 } 16127 } 16128 } 16129 16130 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16131 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16132 userId, true, true, callName, null); 16133 ProcessRecord proc = null; 16134 try { 16135 int pid = Integer.parseInt(process); 16136 synchronized (mPidsSelfLocked) { 16137 proc = mPidsSelfLocked.get(pid); 16138 } 16139 } catch (NumberFormatException e) { 16140 } 16141 16142 if (proc == null) { 16143 ArrayMap<String, SparseArray<ProcessRecord>> all 16144 = mProcessNames.getMap(); 16145 SparseArray<ProcessRecord> procs = all.get(process); 16146 if (procs != null && procs.size() > 0) { 16147 proc = procs.valueAt(0); 16148 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16149 for (int i=1; i<procs.size(); i++) { 16150 ProcessRecord thisProc = procs.valueAt(i); 16151 if (thisProc.userId == userId) { 16152 proc = thisProc; 16153 break; 16154 } 16155 } 16156 } 16157 } 16158 } 16159 16160 return proc; 16161 } 16162 16163 public boolean dumpHeap(String process, int userId, boolean managed, 16164 String path, ParcelFileDescriptor fd) throws RemoteException { 16165 16166 try { 16167 synchronized (this) { 16168 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16169 // its own permission (same as profileControl). 16170 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16171 != PackageManager.PERMISSION_GRANTED) { 16172 throw new SecurityException("Requires permission " 16173 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16174 } 16175 16176 if (fd == null) { 16177 throw new IllegalArgumentException("null fd"); 16178 } 16179 16180 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16181 if (proc == null || proc.thread == null) { 16182 throw new IllegalArgumentException("Unknown process: " + process); 16183 } 16184 16185 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16186 if (!isDebuggable) { 16187 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16188 throw new SecurityException("Process not debuggable: " + proc); 16189 } 16190 } 16191 16192 proc.thread.dumpHeap(managed, path, fd); 16193 fd = null; 16194 return true; 16195 } 16196 } catch (RemoteException e) { 16197 throw new IllegalStateException("Process disappeared"); 16198 } finally { 16199 if (fd != null) { 16200 try { 16201 fd.close(); 16202 } catch (IOException e) { 16203 } 16204 } 16205 } 16206 } 16207 16208 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16209 public void monitor() { 16210 synchronized (this) { } 16211 } 16212 16213 void onCoreSettingsChange(Bundle settings) { 16214 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16215 ProcessRecord processRecord = mLruProcesses.get(i); 16216 try { 16217 if (processRecord.thread != null) { 16218 processRecord.thread.setCoreSettings(settings); 16219 } 16220 } catch (RemoteException re) { 16221 /* ignore */ 16222 } 16223 } 16224 } 16225 16226 // Multi-user methods 16227 16228 /** 16229 * Start user, if its not already running, but don't bring it to foreground. 16230 */ 16231 @Override 16232 public boolean startUserInBackground(final int userId) { 16233 return startUser(userId, /* foreground */ false); 16234 } 16235 16236 /** 16237 * Refreshes the list of users related to the current user when either a 16238 * user switch happens or when a new related user is started in the 16239 * background. 16240 */ 16241 private void updateRelatedUserIdsLocked() { 16242 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16243 int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null 16244 for (int i = 0; i < relatedUserIds.length; i++) { 16245 relatedUserIds[i] = relatedUsers.get(i).id; 16246 } 16247 mRelatedUserIds = relatedUserIds; 16248 } 16249 16250 @Override 16251 public boolean switchUser(final int userId) { 16252 return startUser(userId, /* foregound */ true); 16253 } 16254 16255 private boolean startUser(final int userId, boolean foreground) { 16256 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16257 != PackageManager.PERMISSION_GRANTED) { 16258 String msg = "Permission Denial: switchUser() from pid=" 16259 + Binder.getCallingPid() 16260 + ", uid=" + Binder.getCallingUid() 16261 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16262 Slog.w(TAG, msg); 16263 throw new SecurityException(msg); 16264 } 16265 16266 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16267 16268 final long ident = Binder.clearCallingIdentity(); 16269 try { 16270 synchronized (this) { 16271 final int oldUserId = mCurrentUserId; 16272 if (oldUserId == userId) { 16273 return true; 16274 } 16275 16276 mStackSupervisor.setLockTaskModeLocked(null); 16277 16278 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16279 if (userInfo == null) { 16280 Slog.w(TAG, "No user info for user #" + userId); 16281 return false; 16282 } 16283 16284 if (foreground) { 16285 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16286 R.anim.screen_user_enter); 16287 } 16288 16289 boolean needStart = false; 16290 16291 // If the user we are switching to is not currently started, then 16292 // we need to start it now. 16293 if (mStartedUsers.get(userId) == null) { 16294 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16295 updateStartedUserArrayLocked(); 16296 needStart = true; 16297 } 16298 16299 final Integer userIdInt = Integer.valueOf(userId); 16300 mUserLru.remove(userIdInt); 16301 mUserLru.add(userIdInt); 16302 16303 if (foreground) { 16304 mCurrentUserId = userId; 16305 updateRelatedUserIdsLocked(); 16306 mWindowManager.setCurrentUser(userId, mRelatedUserIds); 16307 // Once the internal notion of the active user has switched, we lock the device 16308 // with the option to show the user switcher on the keyguard. 16309 mWindowManager.lockNow(null); 16310 } else { 16311 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16312 updateRelatedUserIdsLocked(); 16313 mWindowManager.updateRelatedUserIds(mRelatedUserIds); 16314 mUserLru.remove(currentUserIdInt); 16315 mUserLru.add(currentUserIdInt); 16316 } 16317 16318 final UserStartedState uss = mStartedUsers.get(userId); 16319 16320 // Make sure user is in the started state. If it is currently 16321 // stopping, we need to knock that off. 16322 if (uss.mState == UserStartedState.STATE_STOPPING) { 16323 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16324 // so we can just fairly silently bring the user back from 16325 // the almost-dead. 16326 uss.mState = UserStartedState.STATE_RUNNING; 16327 updateStartedUserArrayLocked(); 16328 needStart = true; 16329 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16330 // This means ACTION_SHUTDOWN has been sent, so we will 16331 // need to treat this as a new boot of the user. 16332 uss.mState = UserStartedState.STATE_BOOTING; 16333 updateStartedUserArrayLocked(); 16334 needStart = true; 16335 } 16336 16337 if (foreground) { 16338 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16339 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16340 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16341 oldUserId, userId, uss)); 16342 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16343 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16344 } 16345 16346 if (needStart) { 16347 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16348 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16349 | Intent.FLAG_RECEIVER_FOREGROUND); 16350 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16351 broadcastIntentLocked(null, null, intent, 16352 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16353 false, false, MY_PID, Process.SYSTEM_UID, userId); 16354 } 16355 16356 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16357 if (userId != 0) { 16358 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16359 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16360 broadcastIntentLocked(null, null, intent, null, 16361 new IIntentReceiver.Stub() { 16362 public void performReceive(Intent intent, int resultCode, 16363 String data, Bundle extras, boolean ordered, 16364 boolean sticky, int sendingUser) { 16365 userInitialized(uss, userId); 16366 } 16367 }, 0, null, null, null, AppOpsManager.OP_NONE, 16368 true, false, MY_PID, Process.SYSTEM_UID, 16369 userId); 16370 uss.initializing = true; 16371 } else { 16372 getUserManagerLocked().makeInitialized(userInfo.id); 16373 } 16374 } 16375 16376 if (foreground) { 16377 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16378 if (homeInFront) { 16379 startHomeActivityLocked(userId); 16380 } else { 16381 mStackSupervisor.resumeTopActivitiesLocked(); 16382 } 16383 EventLogTags.writeAmSwitchUser(userId); 16384 getUserManagerLocked().userForeground(userId); 16385 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16386 } 16387 16388 if (needStart) { 16389 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16390 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16391 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16392 broadcastIntentLocked(null, null, intent, 16393 null, new IIntentReceiver.Stub() { 16394 @Override 16395 public void performReceive(Intent intent, int resultCode, String data, 16396 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16397 throws RemoteException { 16398 } 16399 }, 0, null, null, 16400 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16401 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16402 } 16403 } 16404 } finally { 16405 Binder.restoreCallingIdentity(ident); 16406 } 16407 16408 return true; 16409 } 16410 16411 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16412 long ident = Binder.clearCallingIdentity(); 16413 try { 16414 Intent intent; 16415 if (oldUserId >= 0) { 16416 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16417 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16418 | Intent.FLAG_RECEIVER_FOREGROUND); 16419 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16420 broadcastIntentLocked(null, null, intent, 16421 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16422 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16423 } 16424 if (newUserId >= 0) { 16425 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16426 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16427 | Intent.FLAG_RECEIVER_FOREGROUND); 16428 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16429 broadcastIntentLocked(null, null, intent, 16430 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16431 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16432 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16433 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16434 | Intent.FLAG_RECEIVER_FOREGROUND); 16435 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16436 broadcastIntentLocked(null, null, intent, 16437 null, null, 0, null, null, 16438 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16439 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16440 } 16441 } finally { 16442 Binder.restoreCallingIdentity(ident); 16443 } 16444 } 16445 16446 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16447 final int newUserId) { 16448 final int N = mUserSwitchObservers.beginBroadcast(); 16449 if (N > 0) { 16450 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16451 int mCount = 0; 16452 @Override 16453 public void sendResult(Bundle data) throws RemoteException { 16454 synchronized (ActivityManagerService.this) { 16455 if (mCurUserSwitchCallback == this) { 16456 mCount++; 16457 if (mCount == N) { 16458 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16459 } 16460 } 16461 } 16462 } 16463 }; 16464 synchronized (this) { 16465 uss.switching = true; 16466 mCurUserSwitchCallback = callback; 16467 } 16468 for (int i=0; i<N; i++) { 16469 try { 16470 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16471 newUserId, callback); 16472 } catch (RemoteException e) { 16473 } 16474 } 16475 } else { 16476 synchronized (this) { 16477 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16478 } 16479 } 16480 mUserSwitchObservers.finishBroadcast(); 16481 } 16482 16483 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16484 synchronized (this) { 16485 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16486 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16487 } 16488 } 16489 16490 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16491 mCurUserSwitchCallback = null; 16492 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16493 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16494 oldUserId, newUserId, uss)); 16495 } 16496 16497 void userInitialized(UserStartedState uss, int newUserId) { 16498 completeSwitchAndInitalize(uss, newUserId, true, false); 16499 } 16500 16501 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16502 completeSwitchAndInitalize(uss, newUserId, false, true); 16503 } 16504 16505 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16506 boolean clearInitializing, boolean clearSwitching) { 16507 boolean unfrozen = false; 16508 synchronized (this) { 16509 if (clearInitializing) { 16510 uss.initializing = false; 16511 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16512 } 16513 if (clearSwitching) { 16514 uss.switching = false; 16515 } 16516 if (!uss.switching && !uss.initializing) { 16517 mWindowManager.stopFreezingScreen(); 16518 unfrozen = true; 16519 } 16520 } 16521 if (unfrozen) { 16522 final int N = mUserSwitchObservers.beginBroadcast(); 16523 for (int i=0; i<N; i++) { 16524 try { 16525 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16526 } catch (RemoteException e) { 16527 } 16528 } 16529 mUserSwitchObservers.finishBroadcast(); 16530 } 16531 } 16532 16533 void scheduleStartRelatedUsersLocked() { 16534 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16535 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16536 DateUtils.SECOND_IN_MILLIS); 16537 } 16538 } 16539 16540 void startRelatedUsersLocked() { 16541 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16542 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16543 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16544 for (UserInfo relatedUser : relatedUsers) { 16545 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16546 toStart.add(relatedUser); 16547 } 16548 } 16549 final int n = toStart.size(); 16550 int i = 0; 16551 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16552 startUserInBackground(toStart.get(i).id); 16553 } 16554 if (i < n) { 16555 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16556 } 16557 } 16558 16559 void finishUserSwitch(UserStartedState uss) { 16560 synchronized (this) { 16561 if (uss.mState == UserStartedState.STATE_BOOTING 16562 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16563 uss.mState = UserStartedState.STATE_RUNNING; 16564 final int userId = uss.mHandle.getIdentifier(); 16565 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16566 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16567 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16568 broadcastIntentLocked(null, null, intent, 16569 null, null, 0, null, null, 16570 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16571 true, false, MY_PID, Process.SYSTEM_UID, userId); 16572 } 16573 16574 startRelatedUsersLocked(); 16575 16576 int num = mUserLru.size(); 16577 int i = 0; 16578 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16579 Integer oldUserId = mUserLru.get(i); 16580 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16581 if (oldUss == null) { 16582 // Shouldn't happen, but be sane if it does. 16583 mUserLru.remove(i); 16584 num--; 16585 continue; 16586 } 16587 if (oldUss.mState == UserStartedState.STATE_STOPPING 16588 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16589 // This user is already stopping, doesn't count. 16590 num--; 16591 i++; 16592 continue; 16593 } 16594 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16595 // Owner and current can't be stopped, but count as running. 16596 i++; 16597 continue; 16598 } 16599 // This is a user to be stopped. 16600 stopUserLocked(oldUserId, null); 16601 num--; 16602 i++; 16603 } 16604 } 16605 } 16606 16607 @Override 16608 public int stopUser(final int userId, final IStopUserCallback callback) { 16609 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16610 != PackageManager.PERMISSION_GRANTED) { 16611 String msg = "Permission Denial: switchUser() from pid=" 16612 + Binder.getCallingPid() 16613 + ", uid=" + Binder.getCallingUid() 16614 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16615 Slog.w(TAG, msg); 16616 throw new SecurityException(msg); 16617 } 16618 if (userId <= 0) { 16619 throw new IllegalArgumentException("Can't stop primary user " + userId); 16620 } 16621 synchronized (this) { 16622 return stopUserLocked(userId, callback); 16623 } 16624 } 16625 16626 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16627 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16628 if (mCurrentUserId == userId) { 16629 return ActivityManager.USER_OP_IS_CURRENT; 16630 } 16631 16632 final UserStartedState uss = mStartedUsers.get(userId); 16633 if (uss == null) { 16634 // User is not started, nothing to do... but we do need to 16635 // callback if requested. 16636 if (callback != null) { 16637 mHandler.post(new Runnable() { 16638 @Override 16639 public void run() { 16640 try { 16641 callback.userStopped(userId); 16642 } catch (RemoteException e) { 16643 } 16644 } 16645 }); 16646 } 16647 return ActivityManager.USER_OP_SUCCESS; 16648 } 16649 16650 if (callback != null) { 16651 uss.mStopCallbacks.add(callback); 16652 } 16653 16654 if (uss.mState != UserStartedState.STATE_STOPPING 16655 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16656 uss.mState = UserStartedState.STATE_STOPPING; 16657 updateStartedUserArrayLocked(); 16658 16659 long ident = Binder.clearCallingIdentity(); 16660 try { 16661 // We are going to broadcast ACTION_USER_STOPPING and then 16662 // once that is done send a final ACTION_SHUTDOWN and then 16663 // stop the user. 16664 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16665 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16666 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16667 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16668 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16669 // This is the result receiver for the final shutdown broadcast. 16670 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16671 @Override 16672 public void performReceive(Intent intent, int resultCode, String data, 16673 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16674 finishUserStop(uss); 16675 } 16676 }; 16677 // This is the result receiver for the initial stopping broadcast. 16678 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16679 @Override 16680 public void performReceive(Intent intent, int resultCode, String data, 16681 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16682 // On to the next. 16683 synchronized (ActivityManagerService.this) { 16684 if (uss.mState != UserStartedState.STATE_STOPPING) { 16685 // Whoops, we are being started back up. Abort, abort! 16686 return; 16687 } 16688 uss.mState = UserStartedState.STATE_SHUTDOWN; 16689 } 16690 broadcastIntentLocked(null, null, shutdownIntent, 16691 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16692 true, false, MY_PID, Process.SYSTEM_UID, userId); 16693 } 16694 }; 16695 // Kick things off. 16696 broadcastIntentLocked(null, null, stoppingIntent, 16697 null, stoppingReceiver, 0, null, null, 16698 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16699 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16700 } finally { 16701 Binder.restoreCallingIdentity(ident); 16702 } 16703 } 16704 16705 return ActivityManager.USER_OP_SUCCESS; 16706 } 16707 16708 void finishUserStop(UserStartedState uss) { 16709 final int userId = uss.mHandle.getIdentifier(); 16710 boolean stopped; 16711 ArrayList<IStopUserCallback> callbacks; 16712 synchronized (this) { 16713 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16714 if (mStartedUsers.get(userId) != uss) { 16715 stopped = false; 16716 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16717 stopped = false; 16718 } else { 16719 stopped = true; 16720 // User can no longer run. 16721 mStartedUsers.remove(userId); 16722 mUserLru.remove(Integer.valueOf(userId)); 16723 updateStartedUserArrayLocked(); 16724 16725 // Clean up all state and processes associated with the user. 16726 // Kill all the processes for the user. 16727 forceStopUserLocked(userId, "finish user"); 16728 } 16729 } 16730 16731 for (int i=0; i<callbacks.size(); i++) { 16732 try { 16733 if (stopped) callbacks.get(i).userStopped(userId); 16734 else callbacks.get(i).userStopAborted(userId); 16735 } catch (RemoteException e) { 16736 } 16737 } 16738 16739 mStackSupervisor.removeUserLocked(userId); 16740 } 16741 16742 @Override 16743 public UserInfo getCurrentUser() { 16744 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16745 != PackageManager.PERMISSION_GRANTED) && ( 16746 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16747 != PackageManager.PERMISSION_GRANTED)) { 16748 String msg = "Permission Denial: getCurrentUser() from pid=" 16749 + Binder.getCallingPid() 16750 + ", uid=" + Binder.getCallingUid() 16751 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16752 Slog.w(TAG, msg); 16753 throw new SecurityException(msg); 16754 } 16755 synchronized (this) { 16756 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16757 } 16758 } 16759 16760 int getCurrentUserIdLocked() { 16761 return mCurrentUserId; 16762 } 16763 16764 @Override 16765 public boolean isUserRunning(int userId, boolean orStopped) { 16766 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16767 != PackageManager.PERMISSION_GRANTED) { 16768 String msg = "Permission Denial: isUserRunning() from pid=" 16769 + Binder.getCallingPid() 16770 + ", uid=" + Binder.getCallingUid() 16771 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16772 Slog.w(TAG, msg); 16773 throw new SecurityException(msg); 16774 } 16775 synchronized (this) { 16776 return isUserRunningLocked(userId, orStopped); 16777 } 16778 } 16779 16780 boolean isUserRunningLocked(int userId, boolean orStopped) { 16781 UserStartedState state = mStartedUsers.get(userId); 16782 if (state == null) { 16783 return false; 16784 } 16785 if (orStopped) { 16786 return true; 16787 } 16788 return state.mState != UserStartedState.STATE_STOPPING 16789 && state.mState != UserStartedState.STATE_SHUTDOWN; 16790 } 16791 16792 @Override 16793 public int[] getRunningUserIds() { 16794 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16795 != PackageManager.PERMISSION_GRANTED) { 16796 String msg = "Permission Denial: isUserRunning() from pid=" 16797 + Binder.getCallingPid() 16798 + ", uid=" + Binder.getCallingUid() 16799 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16800 Slog.w(TAG, msg); 16801 throw new SecurityException(msg); 16802 } 16803 synchronized (this) { 16804 return mStartedUserArray; 16805 } 16806 } 16807 16808 private void updateStartedUserArrayLocked() { 16809 int num = 0; 16810 for (int i=0; i<mStartedUsers.size(); i++) { 16811 UserStartedState uss = mStartedUsers.valueAt(i); 16812 // This list does not include stopping users. 16813 if (uss.mState != UserStartedState.STATE_STOPPING 16814 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16815 num++; 16816 } 16817 } 16818 mStartedUserArray = new int[num]; 16819 num = 0; 16820 for (int i=0; i<mStartedUsers.size(); i++) { 16821 UserStartedState uss = mStartedUsers.valueAt(i); 16822 if (uss.mState != UserStartedState.STATE_STOPPING 16823 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16824 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16825 num++; 16826 } 16827 } 16828 } 16829 16830 @Override 16831 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16832 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16833 != PackageManager.PERMISSION_GRANTED) { 16834 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16835 + Binder.getCallingPid() 16836 + ", uid=" + Binder.getCallingUid() 16837 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16838 Slog.w(TAG, msg); 16839 throw new SecurityException(msg); 16840 } 16841 16842 mUserSwitchObservers.register(observer); 16843 } 16844 16845 @Override 16846 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16847 mUserSwitchObservers.unregister(observer); 16848 } 16849 16850 private boolean userExists(int userId) { 16851 if (userId == 0) { 16852 return true; 16853 } 16854 UserManagerService ums = getUserManagerLocked(); 16855 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16856 } 16857 16858 int[] getUsersLocked() { 16859 UserManagerService ums = getUserManagerLocked(); 16860 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16861 } 16862 16863 UserManagerService getUserManagerLocked() { 16864 if (mUserManager == null) { 16865 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16866 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16867 } 16868 return mUserManager; 16869 } 16870 16871 private int applyUserId(int uid, int userId) { 16872 return UserHandle.getUid(userId, uid); 16873 } 16874 16875 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16876 if (info == null) return null; 16877 ApplicationInfo newInfo = new ApplicationInfo(info); 16878 newInfo.uid = applyUserId(info.uid, userId); 16879 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16880 + info.packageName; 16881 return newInfo; 16882 } 16883 16884 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16885 if (aInfo == null 16886 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16887 return aInfo; 16888 } 16889 16890 ActivityInfo info = new ActivityInfo(aInfo); 16891 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16892 return info; 16893 } 16894} 16895