ActivityManagerService.java revision 4590e52f3d0558e01322fe4dd55bb612afdfb079
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack 1019 private UserManagerService mUserManager; 1020 1021 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1022 final ProcessRecord mApp; 1023 final int mPid; 1024 final IApplicationThread mAppThread; 1025 1026 AppDeathRecipient(ProcessRecord app, int pid, 1027 IApplicationThread thread) { 1028 if (localLOGV) Slog.v( 1029 TAG, "New death recipient " + this 1030 + " for thread " + thread.asBinder()); 1031 mApp = app; 1032 mPid = pid; 1033 mAppThread = thread; 1034 } 1035 1036 @Override 1037 public void binderDied() { 1038 if (localLOGV) Slog.v( 1039 TAG, "Death received in " + this 1040 + " for thread " + mAppThread.asBinder()); 1041 synchronized(ActivityManagerService.this) { 1042 appDiedLocked(mApp, mPid, mAppThread); 1043 } 1044 } 1045 } 1046 1047 static final int SHOW_ERROR_MSG = 1; 1048 static final int SHOW_NOT_RESPONDING_MSG = 2; 1049 static final int SHOW_FACTORY_ERROR_MSG = 3; 1050 static final int UPDATE_CONFIGURATION_MSG = 4; 1051 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1052 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1053 static final int SERVICE_TIMEOUT_MSG = 12; 1054 static final int UPDATE_TIME_ZONE = 13; 1055 static final int SHOW_UID_ERROR_MSG = 14; 1056 static final int IM_FEELING_LUCKY_MSG = 15; 1057 static final int PROC_START_TIMEOUT_MSG = 20; 1058 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1059 static final int KILL_APPLICATION_MSG = 22; 1060 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1061 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1062 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1063 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1064 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1065 static final int CLEAR_DNS_CACHE_MSG = 28; 1066 static final int UPDATE_HTTP_PROXY_MSG = 29; 1067 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1068 static final int DISPATCH_PROCESSES_CHANGED = 31; 1069 static final int DISPATCH_PROCESS_DIED = 32; 1070 static final int REPORT_MEM_USAGE_MSG = 33; 1071 static final int REPORT_USER_SWITCH_MSG = 34; 1072 static final int CONTINUE_USER_SWITCH_MSG = 35; 1073 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1074 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1075 static final int PERSIST_URI_GRANTS_MSG = 38; 1076 static final int REQUEST_ALL_PSS_MSG = 39; 1077 static final int START_RELATED_USERS_MSG = 40; 1078 static final int UPDATE_TIME = 41; 1079 1080 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1081 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1082 static final int FIRST_COMPAT_MODE_MSG = 300; 1083 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1084 1085 AlertDialog mUidAlert; 1086 CompatModeDialog mCompatModeDialog; 1087 long mLastMemUsageReportTime = 0; 1088 1089 /** 1090 * Flag whether the current user is a "monkey", i.e. whether 1091 * the UI is driven by a UI automation tool. 1092 */ 1093 private boolean mUserIsMonkey; 1094 1095 final ServiceThread mHandlerThread; 1096 final MainHandler mHandler; 1097 1098 final class MainHandler extends Handler { 1099 public MainHandler(Looper looper) { 1100 super(looper, null, true); 1101 } 1102 1103 @Override 1104 public void handleMessage(Message msg) { 1105 switch (msg.what) { 1106 case SHOW_ERROR_MSG: { 1107 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1108 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1109 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1110 synchronized (ActivityManagerService.this) { 1111 ProcessRecord proc = (ProcessRecord)data.get("app"); 1112 AppErrorResult res = (AppErrorResult) data.get("result"); 1113 if (proc != null && proc.crashDialog != null) { 1114 Slog.e(TAG, "App already has crash dialog: " + proc); 1115 if (res != null) { 1116 res.set(0); 1117 } 1118 return; 1119 } 1120 if (!showBackground && UserHandle.getAppId(proc.uid) 1121 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1122 && proc.pid != MY_PID) { 1123 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1124 if (res != null) { 1125 res.set(0); 1126 } 1127 return; 1128 } 1129 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1130 Dialog d = new AppErrorDialog(mContext, 1131 ActivityManagerService.this, res, proc); 1132 d.show(); 1133 proc.crashDialog = d; 1134 } else { 1135 // The device is asleep, so just pretend that the user 1136 // saw a crash dialog and hit "force quit". 1137 if (res != null) { 1138 res.set(0); 1139 } 1140 } 1141 } 1142 1143 ensureBootCompleted(); 1144 } break; 1145 case SHOW_NOT_RESPONDING_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1148 ProcessRecord proc = (ProcessRecord)data.get("app"); 1149 if (proc != null && proc.anrDialog != null) { 1150 Slog.e(TAG, "App already has anr dialog: " + proc); 1151 return; 1152 } 1153 1154 Intent intent = new Intent("android.intent.action.ANR"); 1155 if (!mProcessesReady) { 1156 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1157 | Intent.FLAG_RECEIVER_FOREGROUND); 1158 } 1159 broadcastIntentLocked(null, null, intent, 1160 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1161 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1162 1163 if (mShowDialogs) { 1164 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1165 mContext, proc, (ActivityRecord)data.get("activity"), 1166 msg.arg1 != 0); 1167 d.show(); 1168 proc.anrDialog = d; 1169 } else { 1170 // Just kill the app if there is no dialog to be shown. 1171 killAppAtUsersRequest(proc, null); 1172 } 1173 } 1174 1175 ensureBootCompleted(); 1176 } break; 1177 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1178 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1179 synchronized (ActivityManagerService.this) { 1180 ProcessRecord proc = (ProcessRecord) data.get("app"); 1181 if (proc == null) { 1182 Slog.e(TAG, "App not found when showing strict mode dialog."); 1183 break; 1184 } 1185 if (proc.crashDialog != null) { 1186 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1187 return; 1188 } 1189 AppErrorResult res = (AppErrorResult) data.get("result"); 1190 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1191 Dialog d = new StrictModeViolationDialog(mContext, 1192 ActivityManagerService.this, res, proc); 1193 d.show(); 1194 proc.crashDialog = d; 1195 } else { 1196 // The device is asleep, so just pretend that the user 1197 // saw a crash dialog and hit "force quit". 1198 res.set(0); 1199 } 1200 } 1201 ensureBootCompleted(); 1202 } break; 1203 case SHOW_FACTORY_ERROR_MSG: { 1204 Dialog d = new FactoryErrorDialog( 1205 mContext, msg.getData().getCharSequence("msg")); 1206 d.show(); 1207 ensureBootCompleted(); 1208 } break; 1209 case UPDATE_CONFIGURATION_MSG: { 1210 final ContentResolver resolver = mContext.getContentResolver(); 1211 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1212 } break; 1213 case GC_BACKGROUND_PROCESSES_MSG: { 1214 synchronized (ActivityManagerService.this) { 1215 performAppGcsIfAppropriateLocked(); 1216 } 1217 } break; 1218 case WAIT_FOR_DEBUGGER_MSG: { 1219 synchronized (ActivityManagerService.this) { 1220 ProcessRecord app = (ProcessRecord)msg.obj; 1221 if (msg.arg1 != 0) { 1222 if (!app.waitedForDebugger) { 1223 Dialog d = new AppWaitingForDebuggerDialog( 1224 ActivityManagerService.this, 1225 mContext, app); 1226 app.waitDialog = d; 1227 app.waitedForDebugger = true; 1228 d.show(); 1229 } 1230 } else { 1231 if (app.waitDialog != null) { 1232 app.waitDialog.dismiss(); 1233 app.waitDialog = null; 1234 } 1235 } 1236 } 1237 } break; 1238 case SERVICE_TIMEOUT_MSG: { 1239 if (mDidDexOpt) { 1240 mDidDexOpt = false; 1241 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1242 nmsg.obj = msg.obj; 1243 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1244 return; 1245 } 1246 mServices.serviceTimeout((ProcessRecord)msg.obj); 1247 } break; 1248 case UPDATE_TIME_ZONE: { 1249 synchronized (ActivityManagerService.this) { 1250 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1251 ProcessRecord r = mLruProcesses.get(i); 1252 if (r.thread != null) { 1253 try { 1254 r.thread.updateTimeZone(); 1255 } catch (RemoteException ex) { 1256 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1257 } 1258 } 1259 } 1260 } 1261 } break; 1262 case CLEAR_DNS_CACHE_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1265 ProcessRecord r = mLruProcesses.get(i); 1266 if (r.thread != null) { 1267 try { 1268 r.thread.clearDnsCache(); 1269 } catch (RemoteException ex) { 1270 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1271 } 1272 } 1273 } 1274 } 1275 } break; 1276 case UPDATE_HTTP_PROXY_MSG: { 1277 ProxyProperties proxy = (ProxyProperties)msg.obj; 1278 String host = ""; 1279 String port = ""; 1280 String exclList = ""; 1281 String pacFileUrl = null; 1282 if (proxy != null) { 1283 host = proxy.getHost(); 1284 port = Integer.toString(proxy.getPort()); 1285 exclList = proxy.getExclusionList(); 1286 pacFileUrl = proxy.getPacFileUrl(); 1287 } 1288 synchronized (ActivityManagerService.this) { 1289 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1290 ProcessRecord r = mLruProcesses.get(i); 1291 if (r.thread != null) { 1292 try { 1293 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1294 } catch (RemoteException ex) { 1295 Slog.w(TAG, "Failed to update http proxy for: " + 1296 r.info.processName); 1297 } 1298 } 1299 } 1300 } 1301 } break; 1302 case SHOW_UID_ERROR_MSG: { 1303 String title = "System UIDs Inconsistent"; 1304 String text = "UIDs on the system are inconsistent, you need to wipe your" 1305 + " data partition or your device will be unstable."; 1306 Log.e(TAG, title + ": " + text); 1307 if (mShowDialogs) { 1308 // XXX This is a temporary dialog, no need to localize. 1309 AlertDialog d = new BaseErrorDialog(mContext); 1310 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1311 d.setCancelable(false); 1312 d.setTitle(title); 1313 d.setMessage(text); 1314 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1315 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1316 mUidAlert = d; 1317 d.show(); 1318 } 1319 } break; 1320 case IM_FEELING_LUCKY_MSG: { 1321 if (mUidAlert != null) { 1322 mUidAlert.dismiss(); 1323 mUidAlert = null; 1324 } 1325 } break; 1326 case PROC_START_TIMEOUT_MSG: { 1327 if (mDidDexOpt) { 1328 mDidDexOpt = false; 1329 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1330 nmsg.obj = msg.obj; 1331 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1332 return; 1333 } 1334 ProcessRecord app = (ProcessRecord)msg.obj; 1335 synchronized (ActivityManagerService.this) { 1336 processStartTimedOutLocked(app); 1337 } 1338 } break; 1339 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1340 synchronized (ActivityManagerService.this) { 1341 doPendingActivityLaunchesLocked(true); 1342 } 1343 } break; 1344 case KILL_APPLICATION_MSG: { 1345 synchronized (ActivityManagerService.this) { 1346 int appid = msg.arg1; 1347 boolean restart = (msg.arg2 == 1); 1348 Bundle bundle = (Bundle)msg.obj; 1349 String pkg = bundle.getString("pkg"); 1350 String reason = bundle.getString("reason"); 1351 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1352 false, UserHandle.USER_ALL, reason); 1353 } 1354 } break; 1355 case FINALIZE_PENDING_INTENT_MSG: { 1356 ((PendingIntentRecord)msg.obj).completeFinalize(); 1357 } break; 1358 case POST_HEAVY_NOTIFICATION_MSG: { 1359 INotificationManager inm = NotificationManager.getService(); 1360 if (inm == null) { 1361 return; 1362 } 1363 1364 ActivityRecord root = (ActivityRecord)msg.obj; 1365 ProcessRecord process = root.app; 1366 if (process == null) { 1367 return; 1368 } 1369 1370 try { 1371 Context context = mContext.createPackageContext(process.info.packageName, 0); 1372 String text = mContext.getString(R.string.heavy_weight_notification, 1373 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1374 Notification notification = new Notification(); 1375 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1376 notification.when = 0; 1377 notification.flags = Notification.FLAG_ONGOING_EVENT; 1378 notification.tickerText = text; 1379 notification.defaults = 0; // please be quiet 1380 notification.sound = null; 1381 notification.vibrate = null; 1382 notification.setLatestEventInfo(context, text, 1383 mContext.getText(R.string.heavy_weight_notification_detail), 1384 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1385 PendingIntent.FLAG_CANCEL_CURRENT, null, 1386 new UserHandle(root.userId))); 1387 1388 try { 1389 int[] outId = new int[1]; 1390 inm.enqueueNotificationWithTag("android", "android", null, 1391 R.string.heavy_weight_notification, 1392 notification, outId, root.userId); 1393 } catch (RuntimeException e) { 1394 Slog.w(ActivityManagerService.TAG, 1395 "Error showing notification for heavy-weight app", e); 1396 } catch (RemoteException e) { 1397 } 1398 } catch (NameNotFoundException e) { 1399 Slog.w(TAG, "Unable to create context for heavy notification", e); 1400 } 1401 } break; 1402 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1403 INotificationManager inm = NotificationManager.getService(); 1404 if (inm == null) { 1405 return; 1406 } 1407 try { 1408 inm.cancelNotificationWithTag("android", null, 1409 R.string.heavy_weight_notification, msg.arg1); 1410 } catch (RuntimeException e) { 1411 Slog.w(ActivityManagerService.TAG, 1412 "Error canceling notification for service", e); 1413 } catch (RemoteException e) { 1414 } 1415 } break; 1416 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1417 synchronized (ActivityManagerService.this) { 1418 checkExcessivePowerUsageLocked(true); 1419 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1420 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1421 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1422 } 1423 } break; 1424 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 ActivityRecord ar = (ActivityRecord)msg.obj; 1427 if (mCompatModeDialog != null) { 1428 if (mCompatModeDialog.mAppInfo.packageName.equals( 1429 ar.info.applicationInfo.packageName)) { 1430 return; 1431 } 1432 mCompatModeDialog.dismiss(); 1433 mCompatModeDialog = null; 1434 } 1435 if (ar != null && false) { 1436 if (mCompatModePackages.getPackageAskCompatModeLocked( 1437 ar.packageName)) { 1438 int mode = mCompatModePackages.computeCompatModeLocked( 1439 ar.info.applicationInfo); 1440 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1441 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1442 mCompatModeDialog = new CompatModeDialog( 1443 ActivityManagerService.this, mContext, 1444 ar.info.applicationInfo); 1445 mCompatModeDialog.show(); 1446 } 1447 } 1448 } 1449 } 1450 break; 1451 } 1452 case DISPATCH_PROCESSES_CHANGED: { 1453 dispatchProcessesChanged(); 1454 break; 1455 } 1456 case DISPATCH_PROCESS_DIED: { 1457 final int pid = msg.arg1; 1458 final int uid = msg.arg2; 1459 dispatchProcessDied(pid, uid); 1460 break; 1461 } 1462 case REPORT_MEM_USAGE_MSG: { 1463 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1464 Thread thread = new Thread() { 1465 @Override public void run() { 1466 final SparseArray<ProcessMemInfo> infoMap 1467 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1468 for (int i=0, N=memInfos.size(); i<N; i++) { 1469 ProcessMemInfo mi = memInfos.get(i); 1470 infoMap.put(mi.pid, mi); 1471 } 1472 updateCpuStatsNow(); 1473 synchronized (mProcessCpuThread) { 1474 final int N = mProcessCpuTracker.countStats(); 1475 for (int i=0; i<N; i++) { 1476 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1477 if (st.vsize > 0) { 1478 long pss = Debug.getPss(st.pid, null); 1479 if (pss > 0) { 1480 if (infoMap.indexOfKey(st.pid) < 0) { 1481 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1482 ProcessList.NATIVE_ADJ, -1, "native", null); 1483 mi.pss = pss; 1484 memInfos.add(mi); 1485 } 1486 } 1487 } 1488 } 1489 } 1490 1491 long totalPss = 0; 1492 for (int i=0, N=memInfos.size(); i<N; i++) { 1493 ProcessMemInfo mi = memInfos.get(i); 1494 if (mi.pss == 0) { 1495 mi.pss = Debug.getPss(mi.pid, null); 1496 } 1497 totalPss += mi.pss; 1498 } 1499 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1500 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1501 if (lhs.oomAdj != rhs.oomAdj) { 1502 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1503 } 1504 if (lhs.pss != rhs.pss) { 1505 return lhs.pss < rhs.pss ? 1 : -1; 1506 } 1507 return 0; 1508 } 1509 }); 1510 1511 StringBuilder tag = new StringBuilder(128); 1512 StringBuilder stack = new StringBuilder(128); 1513 tag.append("Low on memory -- "); 1514 appendMemBucket(tag, totalPss, "total", false); 1515 appendMemBucket(stack, totalPss, "total", true); 1516 1517 StringBuilder logBuilder = new StringBuilder(1024); 1518 logBuilder.append("Low on memory:\n"); 1519 1520 boolean firstLine = true; 1521 int lastOomAdj = Integer.MIN_VALUE; 1522 for (int i=0, N=memInfos.size(); i<N; i++) { 1523 ProcessMemInfo mi = memInfos.get(i); 1524 1525 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1526 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1527 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1528 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1529 if (lastOomAdj != mi.oomAdj) { 1530 lastOomAdj = mi.oomAdj; 1531 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1532 tag.append(" / "); 1533 } 1534 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1535 if (firstLine) { 1536 stack.append(":"); 1537 firstLine = false; 1538 } 1539 stack.append("\n\t at "); 1540 } else { 1541 stack.append("$"); 1542 } 1543 } else { 1544 tag.append(" "); 1545 stack.append("$"); 1546 } 1547 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1548 appendMemBucket(tag, mi.pss, mi.name, false); 1549 } 1550 appendMemBucket(stack, mi.pss, mi.name, true); 1551 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1552 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1553 stack.append("("); 1554 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1555 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1556 stack.append(DUMP_MEM_OOM_LABEL[k]); 1557 stack.append(":"); 1558 stack.append(DUMP_MEM_OOM_ADJ[k]); 1559 } 1560 } 1561 stack.append(")"); 1562 } 1563 } 1564 1565 logBuilder.append(" "); 1566 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1567 logBuilder.append(' '); 1568 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1569 logBuilder.append(' '); 1570 ProcessList.appendRamKb(logBuilder, mi.pss); 1571 logBuilder.append(" kB: "); 1572 logBuilder.append(mi.name); 1573 logBuilder.append(" ("); 1574 logBuilder.append(mi.pid); 1575 logBuilder.append(") "); 1576 logBuilder.append(mi.adjType); 1577 logBuilder.append('\n'); 1578 if (mi.adjReason != null) { 1579 logBuilder.append(" "); 1580 logBuilder.append(mi.adjReason); 1581 logBuilder.append('\n'); 1582 } 1583 } 1584 1585 logBuilder.append(" "); 1586 ProcessList.appendRamKb(logBuilder, totalPss); 1587 logBuilder.append(" kB: TOTAL\n"); 1588 1589 long[] infos = new long[Debug.MEMINFO_COUNT]; 1590 Debug.getMemInfo(infos); 1591 logBuilder.append(" MemInfo: "); 1592 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1593 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1594 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1595 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1596 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1597 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1598 logBuilder.append(" ZRAM: "); 1599 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1600 logBuilder.append(" kB RAM, "); 1601 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1602 logBuilder.append(" kB swap total, "); 1603 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1604 logBuilder.append(" kB swap free\n"); 1605 } 1606 Slog.i(TAG, logBuilder.toString()); 1607 1608 StringBuilder dropBuilder = new StringBuilder(1024); 1609 /* 1610 StringWriter oomSw = new StringWriter(); 1611 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1612 StringWriter catSw = new StringWriter(); 1613 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1614 String[] emptyArgs = new String[] { }; 1615 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1616 oomPw.flush(); 1617 String oomString = oomSw.toString(); 1618 */ 1619 dropBuilder.append(stack); 1620 dropBuilder.append('\n'); 1621 dropBuilder.append('\n'); 1622 dropBuilder.append(logBuilder); 1623 dropBuilder.append('\n'); 1624 /* 1625 dropBuilder.append(oomString); 1626 dropBuilder.append('\n'); 1627 */ 1628 StringWriter catSw = new StringWriter(); 1629 synchronized (ActivityManagerService.this) { 1630 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1631 String[] emptyArgs = new String[] { }; 1632 catPw.println(); 1633 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1634 catPw.println(); 1635 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1636 false, false, null); 1637 catPw.println(); 1638 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1639 catPw.flush(); 1640 } 1641 dropBuilder.append(catSw.toString()); 1642 addErrorToDropBox("lowmem", null, "system_server", null, 1643 null, tag.toString(), dropBuilder.toString(), null, null); 1644 //Slog.i(TAG, "Sent to dropbox:"); 1645 //Slog.i(TAG, dropBuilder.toString()); 1646 synchronized (ActivityManagerService.this) { 1647 long now = SystemClock.uptimeMillis(); 1648 if (mLastMemUsageReportTime < now) { 1649 mLastMemUsageReportTime = now; 1650 } 1651 } 1652 } 1653 }; 1654 thread.start(); 1655 break; 1656 } 1657 case REPORT_USER_SWITCH_MSG: { 1658 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1659 break; 1660 } 1661 case CONTINUE_USER_SWITCH_MSG: { 1662 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1663 break; 1664 } 1665 case USER_SWITCH_TIMEOUT_MSG: { 1666 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1667 break; 1668 } 1669 case IMMERSIVE_MODE_LOCK_MSG: { 1670 final boolean nextState = (msg.arg1 != 0); 1671 if (mUpdateLock.isHeld() != nextState) { 1672 if (DEBUG_IMMERSIVE) { 1673 final ActivityRecord r = (ActivityRecord) msg.obj; 1674 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1675 } 1676 if (nextState) { 1677 mUpdateLock.acquire(); 1678 } else { 1679 mUpdateLock.release(); 1680 } 1681 } 1682 break; 1683 } 1684 case PERSIST_URI_GRANTS_MSG: { 1685 writeGrantedUriPermissions(); 1686 break; 1687 } 1688 case REQUEST_ALL_PSS_MSG: { 1689 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1690 break; 1691 } 1692 case START_RELATED_USERS_MSG: { 1693 synchronized (ActivityManagerService.this) { 1694 startRelatedUsersLocked(); 1695 } 1696 break; 1697 } 1698 case UPDATE_TIME: { 1699 synchronized (ActivityManagerService.this) { 1700 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1701 ProcessRecord r = mLruProcesses.get(i); 1702 if (r.thread != null) { 1703 try { 1704 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1705 } catch (RemoteException ex) { 1706 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1707 } 1708 } 1709 } 1710 } 1711 break; 1712 } 1713 } 1714 } 1715 }; 1716 1717 static final int COLLECT_PSS_BG_MSG = 1; 1718 1719 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1720 @Override 1721 public void handleMessage(Message msg) { 1722 switch (msg.what) { 1723 case COLLECT_PSS_BG_MSG: { 1724 int i=0, num=0; 1725 long start = SystemClock.uptimeMillis(); 1726 long[] tmp = new long[1]; 1727 do { 1728 ProcessRecord proc; 1729 int procState; 1730 int pid; 1731 synchronized (ActivityManagerService.this) { 1732 if (i >= mPendingPssProcesses.size()) { 1733 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1734 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1735 mPendingPssProcesses.clear(); 1736 return; 1737 } 1738 proc = mPendingPssProcesses.get(i); 1739 procState = proc.pssProcState; 1740 if (proc.thread != null && procState == proc.setProcState) { 1741 pid = proc.pid; 1742 } else { 1743 proc = null; 1744 pid = 0; 1745 } 1746 i++; 1747 } 1748 if (proc != null) { 1749 long pss = Debug.getPss(pid, tmp); 1750 synchronized (ActivityManagerService.this) { 1751 if (proc.thread != null && proc.setProcState == procState 1752 && proc.pid == pid) { 1753 num++; 1754 proc.lastPssTime = SystemClock.uptimeMillis(); 1755 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1756 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1757 + ": " + pss + " lastPss=" + proc.lastPss 1758 + " state=" + ProcessList.makeProcStateString(procState)); 1759 if (proc.initialIdlePss == 0) { 1760 proc.initialIdlePss = pss; 1761 } 1762 proc.lastPss = pss; 1763 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1764 proc.lastCachedPss = pss; 1765 } 1766 } 1767 } 1768 } 1769 } while (true); 1770 } 1771 } 1772 } 1773 }; 1774 1775 public void setSystemProcess() { 1776 try { 1777 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1778 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1779 ServiceManager.addService("meminfo", new MemBinder(this)); 1780 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1781 ServiceManager.addService("dbinfo", new DbBinder(this)); 1782 if (MONITOR_CPU_USAGE) { 1783 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1784 } 1785 ServiceManager.addService("permission", new PermissionController(this)); 1786 1787 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1788 "android", STOCK_PM_FLAGS); 1789 mSystemThread.installSystemApplicationInfo(info); 1790 1791 synchronized (this) { 1792 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1793 app.persistent = true; 1794 app.pid = MY_PID; 1795 app.maxAdj = ProcessList.SYSTEM_ADJ; 1796 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1797 mProcessNames.put(app.processName, app.uid, app); 1798 synchronized (mPidsSelfLocked) { 1799 mPidsSelfLocked.put(app.pid, app); 1800 } 1801 updateLruProcessLocked(app, false, null); 1802 updateOomAdjLocked(); 1803 } 1804 } catch (PackageManager.NameNotFoundException e) { 1805 throw new RuntimeException( 1806 "Unable to find android system package", e); 1807 } 1808 } 1809 1810 public void setWindowManager(WindowManagerService wm) { 1811 mWindowManager = wm; 1812 mStackSupervisor.setWindowManager(wm); 1813 } 1814 1815 public void startObservingNativeCrashes() { 1816 final NativeCrashListener ncl = new NativeCrashListener(this); 1817 ncl.start(); 1818 } 1819 1820 public IAppOpsService getAppOpsService() { 1821 return mAppOpsService; 1822 } 1823 1824 static class MemBinder extends Binder { 1825 ActivityManagerService mActivityManagerService; 1826 MemBinder(ActivityManagerService activityManagerService) { 1827 mActivityManagerService = activityManagerService; 1828 } 1829 1830 @Override 1831 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1832 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1833 != PackageManager.PERMISSION_GRANTED) { 1834 pw.println("Permission Denial: can't dump meminfo from from pid=" 1835 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1836 + " without permission " + android.Manifest.permission.DUMP); 1837 return; 1838 } 1839 1840 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1841 } 1842 } 1843 1844 static class GraphicsBinder extends Binder { 1845 ActivityManagerService mActivityManagerService; 1846 GraphicsBinder(ActivityManagerService activityManagerService) { 1847 mActivityManagerService = activityManagerService; 1848 } 1849 1850 @Override 1851 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1852 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1853 != PackageManager.PERMISSION_GRANTED) { 1854 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1855 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1856 + " without permission " + android.Manifest.permission.DUMP); 1857 return; 1858 } 1859 1860 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1861 } 1862 } 1863 1864 static class DbBinder extends Binder { 1865 ActivityManagerService mActivityManagerService; 1866 DbBinder(ActivityManagerService activityManagerService) { 1867 mActivityManagerService = activityManagerService; 1868 } 1869 1870 @Override 1871 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1872 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1873 != PackageManager.PERMISSION_GRANTED) { 1874 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1875 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1876 + " without permission " + android.Manifest.permission.DUMP); 1877 return; 1878 } 1879 1880 mActivityManagerService.dumpDbInfo(fd, pw, args); 1881 } 1882 } 1883 1884 static class CpuBinder extends Binder { 1885 ActivityManagerService mActivityManagerService; 1886 CpuBinder(ActivityManagerService activityManagerService) { 1887 mActivityManagerService = activityManagerService; 1888 } 1889 1890 @Override 1891 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1892 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1893 != PackageManager.PERMISSION_GRANTED) { 1894 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1895 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1896 + " without permission " + android.Manifest.permission.DUMP); 1897 return; 1898 } 1899 1900 synchronized (mActivityManagerService.mProcessCpuThread) { 1901 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1902 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1903 SystemClock.uptimeMillis())); 1904 } 1905 } 1906 } 1907 1908 public static final class Lifecycle extends SystemService { 1909 private final ActivityManagerService mService; 1910 1911 public Lifecycle(Context context) { 1912 super(context); 1913 mService = new ActivityManagerService(context); 1914 } 1915 1916 @Override 1917 public void onStart() { 1918 mService.start(); 1919 } 1920 1921 public ActivityManagerService getService() { 1922 return mService; 1923 } 1924 } 1925 1926 // Note: This method is invoked on the main thread but may need to attach various 1927 // handlers to other threads. So take care to be explicit about the looper. 1928 public ActivityManagerService(Context systemContext) { 1929 mContext = systemContext; 1930 mFactoryTest = FactoryTest.getMode(); 1931 mSystemThread = ActivityThread.currentActivityThread(); 1932 1933 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1934 1935 mHandlerThread = new ServiceThread(TAG, 1936 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1937 mHandlerThread.start(); 1938 mHandler = new MainHandler(mHandlerThread.getLooper()); 1939 1940 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1941 "foreground", BROADCAST_FG_TIMEOUT, false); 1942 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1943 "background", BROADCAST_BG_TIMEOUT, true); 1944 mBroadcastQueues[0] = mFgBroadcastQueue; 1945 mBroadcastQueues[1] = mBgBroadcastQueue; 1946 1947 mServices = new ActiveServices(this); 1948 mProviderMap = new ProviderMap(this); 1949 1950 // TODO: Move creation of battery stats service outside of activity manager service. 1951 File dataDir = Environment.getDataDirectory(); 1952 File systemDir = new File(dataDir, "system"); 1953 systemDir.mkdirs(); 1954 mBatteryStatsService = new BatteryStatsService(new File( 1955 systemDir, "batterystats.bin").toString(), mHandler); 1956 mBatteryStatsService.getActiveStatistics().readLocked(); 1957 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1958 mOnBattery = DEBUG_POWER ? true 1959 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1960 mBatteryStatsService.getActiveStatistics().setCallback(this); 1961 1962 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1963 1964 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1965 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1966 1967 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1968 1969 // User 0 is the first and only user that runs at boot. 1970 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1971 mUserLru.add(Integer.valueOf(0)); 1972 updateStartedUserArrayLocked(); 1973 1974 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1975 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1976 1977 mConfiguration.setToDefaults(); 1978 mConfiguration.setLocale(Locale.getDefault()); 1979 1980 mConfigurationSeq = mConfiguration.seq = 1; 1981 mProcessCpuTracker.init(); 1982 1983 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1984 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1985 mStackSupervisor = new ActivityStackSupervisor(this); 1986 1987 mProcessCpuThread = new Thread("CpuTracker") { 1988 @Override 1989 public void run() { 1990 while (true) { 1991 try { 1992 try { 1993 synchronized(this) { 1994 final long now = SystemClock.uptimeMillis(); 1995 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1996 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1997 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1998 // + ", write delay=" + nextWriteDelay); 1999 if (nextWriteDelay < nextCpuDelay) { 2000 nextCpuDelay = nextWriteDelay; 2001 } 2002 if (nextCpuDelay > 0) { 2003 mProcessCpuMutexFree.set(true); 2004 this.wait(nextCpuDelay); 2005 } 2006 } 2007 } catch (InterruptedException e) { 2008 } 2009 updateCpuStatsNow(); 2010 } catch (Exception e) { 2011 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2012 } 2013 } 2014 } 2015 }; 2016 2017 Watchdog.getInstance().addMonitor(this); 2018 Watchdog.getInstance().addThread(mHandler); 2019 } 2020 2021 private void start() { 2022 mProcessCpuThread.start(); 2023 2024 mBatteryStatsService.publish(mContext); 2025 mUsageStatsService.publish(mContext); 2026 mAppOpsService.publish(mContext); 2027 startRunning(null, null, null, null); 2028 } 2029 2030 @Override 2031 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2032 throws RemoteException { 2033 if (code == SYSPROPS_TRANSACTION) { 2034 // We need to tell all apps about the system property change. 2035 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2036 synchronized(this) { 2037 final int NP = mProcessNames.getMap().size(); 2038 for (int ip=0; ip<NP; ip++) { 2039 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2040 final int NA = apps.size(); 2041 for (int ia=0; ia<NA; ia++) { 2042 ProcessRecord app = apps.valueAt(ia); 2043 if (app.thread != null) { 2044 procs.add(app.thread.asBinder()); 2045 } 2046 } 2047 } 2048 } 2049 2050 int N = procs.size(); 2051 for (int i=0; i<N; i++) { 2052 Parcel data2 = Parcel.obtain(); 2053 try { 2054 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2055 } catch (RemoteException e) { 2056 } 2057 data2.recycle(); 2058 } 2059 } 2060 try { 2061 return super.onTransact(code, data, reply, flags); 2062 } catch (RuntimeException e) { 2063 // The activity manager only throws security exceptions, so let's 2064 // log all others. 2065 if (!(e instanceof SecurityException)) { 2066 Slog.wtf(TAG, "Activity Manager Crash", e); 2067 } 2068 throw e; 2069 } 2070 } 2071 2072 void updateCpuStats() { 2073 final long now = SystemClock.uptimeMillis(); 2074 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2075 return; 2076 } 2077 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2078 synchronized (mProcessCpuThread) { 2079 mProcessCpuThread.notify(); 2080 } 2081 } 2082 } 2083 2084 void updateCpuStatsNow() { 2085 synchronized (mProcessCpuThread) { 2086 mProcessCpuMutexFree.set(false); 2087 final long now = SystemClock.uptimeMillis(); 2088 boolean haveNewCpuStats = false; 2089 2090 if (MONITOR_CPU_USAGE && 2091 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2092 mLastCpuTime.set(now); 2093 haveNewCpuStats = true; 2094 mProcessCpuTracker.update(); 2095 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2096 //Slog.i(TAG, "Total CPU usage: " 2097 // + mProcessCpu.getTotalCpuPercent() + "%"); 2098 2099 // Slog the cpu usage if the property is set. 2100 if ("true".equals(SystemProperties.get("events.cpu"))) { 2101 int user = mProcessCpuTracker.getLastUserTime(); 2102 int system = mProcessCpuTracker.getLastSystemTime(); 2103 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2104 int irq = mProcessCpuTracker.getLastIrqTime(); 2105 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2106 int idle = mProcessCpuTracker.getLastIdleTime(); 2107 2108 int total = user + system + iowait + irq + softIrq + idle; 2109 if (total == 0) total = 1; 2110 2111 EventLog.writeEvent(EventLogTags.CPU, 2112 ((user+system+iowait+irq+softIrq) * 100) / total, 2113 (user * 100) / total, 2114 (system * 100) / total, 2115 (iowait * 100) / total, 2116 (irq * 100) / total, 2117 (softIrq * 100) / total); 2118 } 2119 } 2120 2121 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2122 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2123 synchronized(bstats) { 2124 synchronized(mPidsSelfLocked) { 2125 if (haveNewCpuStats) { 2126 if (mOnBattery) { 2127 int perc = bstats.startAddingCpuLocked(); 2128 int totalUTime = 0; 2129 int totalSTime = 0; 2130 final int N = mProcessCpuTracker.countStats(); 2131 for (int i=0; i<N; i++) { 2132 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2133 if (!st.working) { 2134 continue; 2135 } 2136 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2137 int otherUTime = (st.rel_utime*perc)/100; 2138 int otherSTime = (st.rel_stime*perc)/100; 2139 totalUTime += otherUTime; 2140 totalSTime += otherSTime; 2141 if (pr != null) { 2142 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2143 if (ps == null || !ps.isActive()) { 2144 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2145 pr.info.uid, pr.processName); 2146 } 2147 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2148 st.rel_stime-otherSTime); 2149 ps.addSpeedStepTimes(cpuSpeedTimes); 2150 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2151 } else { 2152 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2153 if (ps == null || !ps.isActive()) { 2154 st.batteryStats = ps = bstats.getProcessStatsLocked( 2155 bstats.mapUid(st.uid), st.name); 2156 } 2157 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2158 st.rel_stime-otherSTime); 2159 ps.addSpeedStepTimes(cpuSpeedTimes); 2160 } 2161 } 2162 bstats.finishAddingCpuLocked(perc, totalUTime, 2163 totalSTime, cpuSpeedTimes); 2164 } 2165 } 2166 } 2167 2168 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2169 mLastWriteTime = now; 2170 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2171 } 2172 } 2173 } 2174 } 2175 2176 @Override 2177 public void batteryNeedsCpuUpdate() { 2178 updateCpuStatsNow(); 2179 } 2180 2181 @Override 2182 public void batteryPowerChanged(boolean onBattery) { 2183 // When plugging in, update the CPU stats first before changing 2184 // the plug state. 2185 updateCpuStatsNow(); 2186 synchronized (this) { 2187 synchronized(mPidsSelfLocked) { 2188 mOnBattery = DEBUG_POWER ? true : onBattery; 2189 } 2190 } 2191 } 2192 2193 /** 2194 * Initialize the application bind args. These are passed to each 2195 * process when the bindApplication() IPC is sent to the process. They're 2196 * lazily setup to make sure the services are running when they're asked for. 2197 */ 2198 private HashMap<String, IBinder> getCommonServicesLocked() { 2199 if (mAppBindArgs == null) { 2200 mAppBindArgs = new HashMap<String, IBinder>(); 2201 2202 // Setup the application init args 2203 mAppBindArgs.put("package", ServiceManager.getService("package")); 2204 mAppBindArgs.put("window", ServiceManager.getService("window")); 2205 mAppBindArgs.put(Context.ALARM_SERVICE, 2206 ServiceManager.getService(Context.ALARM_SERVICE)); 2207 } 2208 return mAppBindArgs; 2209 } 2210 2211 final void setFocusedActivityLocked(ActivityRecord r) { 2212 if (mFocusedActivity != r) { 2213 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2214 mFocusedActivity = r; 2215 mStackSupervisor.setFocusedStack(r); 2216 if (r != null) { 2217 mWindowManager.setFocusedApp(r.appToken, true); 2218 } 2219 applyUpdateLockStateLocked(r); 2220 } 2221 } 2222 2223 @Override 2224 public void setFocusedStack(int stackId) { 2225 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2226 synchronized (ActivityManagerService.this) { 2227 ActivityStack stack = mStackSupervisor.getStack(stackId); 2228 if (stack != null) { 2229 ActivityRecord r = stack.topRunningActivityLocked(null); 2230 if (r != null) { 2231 setFocusedActivityLocked(r); 2232 } 2233 } 2234 } 2235 } 2236 2237 @Override 2238 public void notifyActivityDrawn(IBinder token) { 2239 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2240 synchronized (this) { 2241 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2242 if (r != null) { 2243 r.task.stack.notifyActivityDrawnLocked(r); 2244 } 2245 } 2246 } 2247 2248 final void applyUpdateLockStateLocked(ActivityRecord r) { 2249 // Modifications to the UpdateLock state are done on our handler, outside 2250 // the activity manager's locks. The new state is determined based on the 2251 // state *now* of the relevant activity record. The object is passed to 2252 // the handler solely for logging detail, not to be consulted/modified. 2253 final boolean nextState = r != null && r.immersive; 2254 mHandler.sendMessage( 2255 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2256 } 2257 2258 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2259 Message msg = Message.obtain(); 2260 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2261 msg.obj = r.task.askedCompatMode ? null : r; 2262 mHandler.sendMessage(msg); 2263 } 2264 2265 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2266 String what, Object obj, ProcessRecord srcApp) { 2267 app.lastActivityTime = now; 2268 2269 if (app.activities.size() > 0) { 2270 // Don't want to touch dependent processes that are hosting activities. 2271 return index; 2272 } 2273 2274 int lrui = mLruProcesses.lastIndexOf(app); 2275 if (lrui < 0) { 2276 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2277 + what + " " + obj + " from " + srcApp); 2278 return index; 2279 } 2280 2281 if (lrui >= index) { 2282 // Don't want to cause this to move dependent processes *back* in the 2283 // list as if they were less frequently used. 2284 return index; 2285 } 2286 2287 if (lrui >= mLruProcessActivityStart) { 2288 // Don't want to touch dependent processes that are hosting activities. 2289 return index; 2290 } 2291 2292 mLruProcesses.remove(lrui); 2293 if (index > 0) { 2294 index--; 2295 } 2296 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2297 + " in LRU list: " + app); 2298 mLruProcesses.add(index, app); 2299 return index; 2300 } 2301 2302 final void removeLruProcessLocked(ProcessRecord app) { 2303 int lrui = mLruProcesses.lastIndexOf(app); 2304 if (lrui >= 0) { 2305 if (lrui <= mLruProcessActivityStart) { 2306 mLruProcessActivityStart--; 2307 } 2308 if (lrui <= mLruProcessServiceStart) { 2309 mLruProcessServiceStart--; 2310 } 2311 mLruProcesses.remove(lrui); 2312 } 2313 } 2314 2315 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2316 ProcessRecord client) { 2317 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2318 || app.treatLikeActivity; 2319 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2320 if (!activityChange && hasActivity) { 2321 // The process has activities, so we are only allowing activity-based adjustments 2322 // to move it. It should be kept in the front of the list with other 2323 // processes that have activities, and we don't want those to change their 2324 // order except due to activity operations. 2325 return; 2326 } 2327 2328 mLruSeq++; 2329 final long now = SystemClock.uptimeMillis(); 2330 app.lastActivityTime = now; 2331 2332 // First a quick reject: if the app is already at the position we will 2333 // put it, then there is nothing to do. 2334 if (hasActivity) { 2335 final int N = mLruProcesses.size(); 2336 if (N > 0 && mLruProcesses.get(N-1) == app) { 2337 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2338 return; 2339 } 2340 } else { 2341 if (mLruProcessServiceStart > 0 2342 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2343 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2344 return; 2345 } 2346 } 2347 2348 int lrui = mLruProcesses.lastIndexOf(app); 2349 2350 if (app.persistent && lrui >= 0) { 2351 // We don't care about the position of persistent processes, as long as 2352 // they are in the list. 2353 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2354 return; 2355 } 2356 2357 /* In progress: compute new position first, so we can avoid doing work 2358 if the process is not actually going to move. Not yet working. 2359 int addIndex; 2360 int nextIndex; 2361 boolean inActivity = false, inService = false; 2362 if (hasActivity) { 2363 // Process has activities, put it at the very tipsy-top. 2364 addIndex = mLruProcesses.size(); 2365 nextIndex = mLruProcessServiceStart; 2366 inActivity = true; 2367 } else if (hasService) { 2368 // Process has services, put it at the top of the service list. 2369 addIndex = mLruProcessActivityStart; 2370 nextIndex = mLruProcessServiceStart; 2371 inActivity = true; 2372 inService = true; 2373 } else { 2374 // Process not otherwise of interest, it goes to the top of the non-service area. 2375 addIndex = mLruProcessServiceStart; 2376 if (client != null) { 2377 int clientIndex = mLruProcesses.lastIndexOf(client); 2378 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2379 + app); 2380 if (clientIndex >= 0 && addIndex > clientIndex) { 2381 addIndex = clientIndex; 2382 } 2383 } 2384 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2385 } 2386 2387 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2388 + mLruProcessActivityStart + "): " + app); 2389 */ 2390 2391 if (lrui >= 0) { 2392 if (lrui < mLruProcessActivityStart) { 2393 mLruProcessActivityStart--; 2394 } 2395 if (lrui < mLruProcessServiceStart) { 2396 mLruProcessServiceStart--; 2397 } 2398 /* 2399 if (addIndex > lrui) { 2400 addIndex--; 2401 } 2402 if (nextIndex > lrui) { 2403 nextIndex--; 2404 } 2405 */ 2406 mLruProcesses.remove(lrui); 2407 } 2408 2409 /* 2410 mLruProcesses.add(addIndex, app); 2411 if (inActivity) { 2412 mLruProcessActivityStart++; 2413 } 2414 if (inService) { 2415 mLruProcessActivityStart++; 2416 } 2417 */ 2418 2419 int nextIndex; 2420 if (hasActivity) { 2421 final int N = mLruProcesses.size(); 2422 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2423 // Process doesn't have activities, but has clients with 2424 // activities... move it up, but one below the top (the top 2425 // should always have a real activity). 2426 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2427 mLruProcesses.add(N-1, app); 2428 // To keep it from spamming the LRU list (by making a bunch of clients), 2429 // we will push down any other entries owned by the app. 2430 final int uid = app.info.uid; 2431 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2432 ProcessRecord subProc = mLruProcesses.get(i); 2433 if (subProc.info.uid == uid) { 2434 // We want to push this one down the list. If the process after 2435 // it is for the same uid, however, don't do so, because we don't 2436 // want them internally to be re-ordered. 2437 if (mLruProcesses.get(i-1).info.uid != uid) { 2438 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2439 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2440 ProcessRecord tmp = mLruProcesses.get(i); 2441 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2442 mLruProcesses.set(i-1, tmp); 2443 i--; 2444 } 2445 } else { 2446 // A gap, we can stop here. 2447 break; 2448 } 2449 } 2450 } else { 2451 // Process has activities, put it at the very tipsy-top. 2452 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2453 mLruProcesses.add(app); 2454 } 2455 nextIndex = mLruProcessServiceStart; 2456 } else if (hasService) { 2457 // Process has services, put it at the top of the service list. 2458 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2459 mLruProcesses.add(mLruProcessActivityStart, app); 2460 nextIndex = mLruProcessServiceStart; 2461 mLruProcessActivityStart++; 2462 } else { 2463 // Process not otherwise of interest, it goes to the top of the non-service area. 2464 int index = mLruProcessServiceStart; 2465 if (client != null) { 2466 // If there is a client, don't allow the process to be moved up higher 2467 // in the list than that client. 2468 int clientIndex = mLruProcesses.lastIndexOf(client); 2469 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2470 + " when updating " + app); 2471 if (clientIndex <= lrui) { 2472 // Don't allow the client index restriction to push it down farther in the 2473 // list than it already is. 2474 clientIndex = lrui; 2475 } 2476 if (clientIndex >= 0 && index > clientIndex) { 2477 index = clientIndex; 2478 } 2479 } 2480 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2481 mLruProcesses.add(index, app); 2482 nextIndex = index-1; 2483 mLruProcessActivityStart++; 2484 mLruProcessServiceStart++; 2485 } 2486 2487 // If the app is currently using a content provider or service, 2488 // bump those processes as well. 2489 for (int j=app.connections.size()-1; j>=0; j--) { 2490 ConnectionRecord cr = app.connections.valueAt(j); 2491 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2492 && cr.binding.service.app != null 2493 && cr.binding.service.app.lruSeq != mLruSeq 2494 && !cr.binding.service.app.persistent) { 2495 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2496 "service connection", cr, app); 2497 } 2498 } 2499 for (int j=app.conProviders.size()-1; j>=0; j--) { 2500 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2501 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2502 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2503 "provider reference", cpr, app); 2504 } 2505 } 2506 } 2507 2508 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2509 if (uid == Process.SYSTEM_UID) { 2510 // The system gets to run in any process. If there are multiple 2511 // processes with the same uid, just pick the first (this 2512 // should never happen). 2513 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2514 if (procs == null) return null; 2515 final int N = procs.size(); 2516 for (int i = 0; i < N; i++) { 2517 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2518 } 2519 } 2520 ProcessRecord proc = mProcessNames.get(processName, uid); 2521 if (false && proc != null && !keepIfLarge 2522 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2523 && proc.lastCachedPss >= 4000) { 2524 // Turn this condition on to cause killing to happen regularly, for testing. 2525 if (proc.baseProcessTracker != null) { 2526 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2527 } 2528 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2529 + "k from cached"); 2530 } else if (proc != null && !keepIfLarge 2531 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2532 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2533 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2534 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2535 if (proc.baseProcessTracker != null) { 2536 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2537 } 2538 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2539 + "k from cached"); 2540 } 2541 } 2542 return proc; 2543 } 2544 2545 void ensurePackageDexOpt(String packageName) { 2546 IPackageManager pm = AppGlobals.getPackageManager(); 2547 try { 2548 if (pm.performDexOpt(packageName)) { 2549 mDidDexOpt = true; 2550 } 2551 } catch (RemoteException e) { 2552 } 2553 } 2554 2555 boolean isNextTransitionForward() { 2556 int transit = mWindowManager.getPendingAppTransition(); 2557 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2558 || transit == AppTransition.TRANSIT_TASK_OPEN 2559 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2560 } 2561 2562 final ProcessRecord startProcessLocked(String processName, 2563 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2564 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2565 boolean isolated, boolean keepIfLarge) { 2566 ProcessRecord app; 2567 if (!isolated) { 2568 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2569 } else { 2570 // If this is an isolated process, it can't re-use an existing process. 2571 app = null; 2572 } 2573 // We don't have to do anything more if: 2574 // (1) There is an existing application record; and 2575 // (2) The caller doesn't think it is dead, OR there is no thread 2576 // object attached to it so we know it couldn't have crashed; and 2577 // (3) There is a pid assigned to it, so it is either starting or 2578 // already running. 2579 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2580 + " app=" + app + " knownToBeDead=" + knownToBeDead 2581 + " thread=" + (app != null ? app.thread : null) 2582 + " pid=" + (app != null ? app.pid : -1)); 2583 if (app != null && app.pid > 0) { 2584 if (!knownToBeDead || app.thread == null) { 2585 // We already have the app running, or are waiting for it to 2586 // come up (we have a pid but not yet its thread), so keep it. 2587 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2588 // If this is a new package in the process, add the package to the list 2589 app.addPackage(info.packageName, mProcessStats); 2590 return app; 2591 } 2592 2593 // An application record is attached to a previous process, 2594 // clean it up now. 2595 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2596 handleAppDiedLocked(app, true, true); 2597 } 2598 2599 String hostingNameStr = hostingName != null 2600 ? hostingName.flattenToShortString() : null; 2601 2602 if (!isolated) { 2603 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2604 // If we are in the background, then check to see if this process 2605 // is bad. If so, we will just silently fail. 2606 if (mBadProcesses.get(info.processName, info.uid) != null) { 2607 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2608 + "/" + info.processName); 2609 return null; 2610 } 2611 } else { 2612 // When the user is explicitly starting a process, then clear its 2613 // crash count so that we won't make it bad until they see at 2614 // least one crash dialog again, and make the process good again 2615 // if it had been bad. 2616 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2617 + "/" + info.processName); 2618 mProcessCrashTimes.remove(info.processName, info.uid); 2619 if (mBadProcesses.get(info.processName, info.uid) != null) { 2620 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2621 UserHandle.getUserId(info.uid), info.uid, 2622 info.processName); 2623 mBadProcesses.remove(info.processName, info.uid); 2624 if (app != null) { 2625 app.bad = false; 2626 } 2627 } 2628 } 2629 } 2630 2631 if (app == null) { 2632 app = newProcessRecordLocked(info, processName, isolated); 2633 if (app == null) { 2634 Slog.w(TAG, "Failed making new process record for " 2635 + processName + "/" + info.uid + " isolated=" + isolated); 2636 return null; 2637 } 2638 mProcessNames.put(processName, app.uid, app); 2639 if (isolated) { 2640 mIsolatedProcesses.put(app.uid, app); 2641 } 2642 } else { 2643 // If this is a new package in the process, add the package to the list 2644 app.addPackage(info.packageName, mProcessStats); 2645 } 2646 2647 // If the system is not ready yet, then hold off on starting this 2648 // process until it is. 2649 if (!mProcessesReady 2650 && !isAllowedWhileBooting(info) 2651 && !allowWhileBooting) { 2652 if (!mProcessesOnHold.contains(app)) { 2653 mProcessesOnHold.add(app); 2654 } 2655 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2656 return app; 2657 } 2658 2659 startProcessLocked(app, hostingType, hostingNameStr); 2660 return (app.pid != 0) ? app : null; 2661 } 2662 2663 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2664 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2665 } 2666 2667 private final void startProcessLocked(ProcessRecord app, 2668 String hostingType, String hostingNameStr) { 2669 if (app.pid > 0 && app.pid != MY_PID) { 2670 synchronized (mPidsSelfLocked) { 2671 mPidsSelfLocked.remove(app.pid); 2672 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2673 } 2674 app.setPid(0); 2675 } 2676 2677 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2678 "startProcessLocked removing on hold: " + app); 2679 mProcessesOnHold.remove(app); 2680 2681 updateCpuStats(); 2682 2683 try { 2684 int uid = app.uid; 2685 2686 int[] gids = null; 2687 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2688 if (!app.isolated) { 2689 int[] permGids = null; 2690 try { 2691 final PackageManager pm = mContext.getPackageManager(); 2692 permGids = pm.getPackageGids(app.info.packageName); 2693 2694 if (Environment.isExternalStorageEmulated()) { 2695 if (pm.checkPermission( 2696 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2697 app.info.packageName) == PERMISSION_GRANTED) { 2698 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2699 } else { 2700 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2701 } 2702 } 2703 } catch (PackageManager.NameNotFoundException e) { 2704 Slog.w(TAG, "Unable to retrieve gids", e); 2705 } 2706 2707 /* 2708 * Add shared application GID so applications can share some 2709 * resources like shared libraries 2710 */ 2711 if (permGids == null) { 2712 gids = new int[1]; 2713 } else { 2714 gids = new int[permGids.length + 1]; 2715 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2716 } 2717 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2718 } 2719 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2720 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2721 && mTopComponent != null 2722 && app.processName.equals(mTopComponent.getPackageName())) { 2723 uid = 0; 2724 } 2725 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2726 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2727 uid = 0; 2728 } 2729 } 2730 int debugFlags = 0; 2731 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2732 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2733 // Also turn on CheckJNI for debuggable apps. It's quite 2734 // awkward to turn on otherwise. 2735 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2736 } 2737 // Run the app in safe mode if its manifest requests so or the 2738 // system is booted in safe mode. 2739 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2740 Zygote.systemInSafeMode == true) { 2741 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2742 } 2743 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2744 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2745 } 2746 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2747 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2748 } 2749 if ("1".equals(SystemProperties.get("debug.assert"))) { 2750 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2751 } 2752 2753 // Start the process. It will either succeed and return a result containing 2754 // the PID of the new process, or else throw a RuntimeException. 2755 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2756 app.processName, uid, uid, gids, debugFlags, mountExternal, 2757 app.info.targetSdkVersion, app.info.seinfo, null); 2758 2759 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2760 synchronized (bs) { 2761 if (bs.isOnBattery()) { 2762 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2763 } 2764 } 2765 2766 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2767 UserHandle.getUserId(uid), startResult.pid, uid, 2768 app.processName, hostingType, 2769 hostingNameStr != null ? hostingNameStr : ""); 2770 2771 if (app.persistent) { 2772 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2773 } 2774 2775 StringBuilder buf = mStringBuilder; 2776 buf.setLength(0); 2777 buf.append("Start proc "); 2778 buf.append(app.processName); 2779 buf.append(" for "); 2780 buf.append(hostingType); 2781 if (hostingNameStr != null) { 2782 buf.append(" "); 2783 buf.append(hostingNameStr); 2784 } 2785 buf.append(": pid="); 2786 buf.append(startResult.pid); 2787 buf.append(" uid="); 2788 buf.append(uid); 2789 buf.append(" gids={"); 2790 if (gids != null) { 2791 for (int gi=0; gi<gids.length; gi++) { 2792 if (gi != 0) buf.append(", "); 2793 buf.append(gids[gi]); 2794 2795 } 2796 } 2797 buf.append("}"); 2798 Slog.i(TAG, buf.toString()); 2799 app.setPid(startResult.pid); 2800 app.usingWrapper = startResult.usingWrapper; 2801 app.removed = false; 2802 synchronized (mPidsSelfLocked) { 2803 this.mPidsSelfLocked.put(startResult.pid, app); 2804 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2805 msg.obj = app; 2806 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2807 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2808 } 2809 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2810 app.processName, app.info.uid); 2811 if (app.isolated) { 2812 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2813 } 2814 } catch (RuntimeException e) { 2815 // XXX do better error recovery. 2816 app.setPid(0); 2817 Slog.e(TAG, "Failure starting process " + app.processName, e); 2818 } 2819 } 2820 2821 void updateUsageStats(ActivityRecord component, boolean resumed) { 2822 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2823 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2824 if (resumed) { 2825 mUsageStatsService.noteResumeComponent(component.realActivity); 2826 synchronized (stats) { 2827 stats.noteActivityResumedLocked(component.app.uid); 2828 } 2829 } else { 2830 mUsageStatsService.notePauseComponent(component.realActivity); 2831 synchronized (stats) { 2832 stats.noteActivityPausedLocked(component.app.uid); 2833 } 2834 } 2835 } 2836 2837 Intent getHomeIntent() { 2838 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2839 intent.setComponent(mTopComponent); 2840 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2841 intent.addCategory(Intent.CATEGORY_HOME); 2842 } 2843 return intent; 2844 } 2845 2846 boolean startHomeActivityLocked(int userId) { 2847 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2848 && mTopAction == null) { 2849 // We are running in factory test mode, but unable to find 2850 // the factory test app, so just sit around displaying the 2851 // error message and don't try to start anything. 2852 return false; 2853 } 2854 Intent intent = getHomeIntent(); 2855 ActivityInfo aInfo = 2856 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2857 if (aInfo != null) { 2858 intent.setComponent(new ComponentName( 2859 aInfo.applicationInfo.packageName, aInfo.name)); 2860 // Don't do this if the home app is currently being 2861 // instrumented. 2862 aInfo = new ActivityInfo(aInfo); 2863 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2864 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2865 aInfo.applicationInfo.uid, true); 2866 if (app == null || app.instrumentationClass == null) { 2867 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2868 mStackSupervisor.startHomeActivity(intent, aInfo); 2869 } 2870 } 2871 2872 return true; 2873 } 2874 2875 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2876 ActivityInfo ai = null; 2877 ComponentName comp = intent.getComponent(); 2878 try { 2879 if (comp != null) { 2880 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2881 } else { 2882 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2883 intent, 2884 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2885 flags, userId); 2886 2887 if (info != null) { 2888 ai = info.activityInfo; 2889 } 2890 } 2891 } catch (RemoteException e) { 2892 // ignore 2893 } 2894 2895 return ai; 2896 } 2897 2898 /** 2899 * Starts the "new version setup screen" if appropriate. 2900 */ 2901 void startSetupActivityLocked() { 2902 // Only do this once per boot. 2903 if (mCheckedForSetup) { 2904 return; 2905 } 2906 2907 // We will show this screen if the current one is a different 2908 // version than the last one shown, and we are not running in 2909 // low-level factory test mode. 2910 final ContentResolver resolver = mContext.getContentResolver(); 2911 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2912 Settings.Global.getInt(resolver, 2913 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2914 mCheckedForSetup = true; 2915 2916 // See if we should be showing the platform update setup UI. 2917 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2918 List<ResolveInfo> ris = mContext.getPackageManager() 2919 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2920 2921 // We don't allow third party apps to replace this. 2922 ResolveInfo ri = null; 2923 for (int i=0; ris != null && i<ris.size(); i++) { 2924 if ((ris.get(i).activityInfo.applicationInfo.flags 2925 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2926 ri = ris.get(i); 2927 break; 2928 } 2929 } 2930 2931 if (ri != null) { 2932 String vers = ri.activityInfo.metaData != null 2933 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2934 : null; 2935 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2936 vers = ri.activityInfo.applicationInfo.metaData.getString( 2937 Intent.METADATA_SETUP_VERSION); 2938 } 2939 String lastVers = Settings.Secure.getString( 2940 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2941 if (vers != null && !vers.equals(lastVers)) { 2942 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2943 intent.setComponent(new ComponentName( 2944 ri.activityInfo.packageName, ri.activityInfo.name)); 2945 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2946 null, null, 0, 0, 0, null, 0, null, false, null, null); 2947 } 2948 } 2949 } 2950 } 2951 2952 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2953 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2954 } 2955 2956 void enforceNotIsolatedCaller(String caller) { 2957 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2958 throw new SecurityException("Isolated process not allowed to call " + caller); 2959 } 2960 } 2961 2962 @Override 2963 public int getFrontActivityScreenCompatMode() { 2964 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2965 synchronized (this) { 2966 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2967 } 2968 } 2969 2970 @Override 2971 public void setFrontActivityScreenCompatMode(int mode) { 2972 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2973 "setFrontActivityScreenCompatMode"); 2974 synchronized (this) { 2975 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2976 } 2977 } 2978 2979 @Override 2980 public int getPackageScreenCompatMode(String packageName) { 2981 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2982 synchronized (this) { 2983 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2984 } 2985 } 2986 2987 @Override 2988 public void setPackageScreenCompatMode(String packageName, int mode) { 2989 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2990 "setPackageScreenCompatMode"); 2991 synchronized (this) { 2992 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2993 } 2994 } 2995 2996 @Override 2997 public boolean getPackageAskScreenCompat(String packageName) { 2998 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2999 synchronized (this) { 3000 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3001 } 3002 } 3003 3004 @Override 3005 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3006 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3007 "setPackageAskScreenCompat"); 3008 synchronized (this) { 3009 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3010 } 3011 } 3012 3013 private void dispatchProcessesChanged() { 3014 int N; 3015 synchronized (this) { 3016 N = mPendingProcessChanges.size(); 3017 if (mActiveProcessChanges.length < N) { 3018 mActiveProcessChanges = new ProcessChangeItem[N]; 3019 } 3020 mPendingProcessChanges.toArray(mActiveProcessChanges); 3021 mAvailProcessChanges.addAll(mPendingProcessChanges); 3022 mPendingProcessChanges.clear(); 3023 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3024 } 3025 3026 int i = mProcessObservers.beginBroadcast(); 3027 while (i > 0) { 3028 i--; 3029 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3030 if (observer != null) { 3031 try { 3032 for (int j=0; j<N; j++) { 3033 ProcessChangeItem item = mActiveProcessChanges[j]; 3034 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3035 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3036 + item.pid + " uid=" + item.uid + ": " 3037 + item.foregroundActivities); 3038 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3039 item.foregroundActivities); 3040 } 3041 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3042 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3043 + item.pid + " uid=" + item.uid + ": " + item.importance); 3044 observer.onImportanceChanged(item.pid, item.uid, 3045 item.importance); 3046 } 3047 } 3048 } catch (RemoteException e) { 3049 } 3050 } 3051 } 3052 mProcessObservers.finishBroadcast(); 3053 } 3054 3055 private void dispatchProcessDied(int pid, int uid) { 3056 int i = mProcessObservers.beginBroadcast(); 3057 while (i > 0) { 3058 i--; 3059 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3060 if (observer != null) { 3061 try { 3062 observer.onProcessDied(pid, uid); 3063 } catch (RemoteException e) { 3064 } 3065 } 3066 } 3067 mProcessObservers.finishBroadcast(); 3068 } 3069 3070 final void doPendingActivityLaunchesLocked(boolean doResume) { 3071 final int N = mPendingActivityLaunches.size(); 3072 if (N <= 0) { 3073 return; 3074 } 3075 for (int i=0; i<N; i++) { 3076 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3077 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3078 doResume && i == (N-1), null); 3079 } 3080 mPendingActivityLaunches.clear(); 3081 } 3082 3083 @Override 3084 public final int startActivity(IApplicationThread caller, String callingPackage, 3085 Intent intent, String resolvedType, IBinder resultTo, 3086 String resultWho, int requestCode, int startFlags, 3087 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3088 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3089 resultWho, requestCode, 3090 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3091 } 3092 3093 @Override 3094 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3095 Intent intent, String resolvedType, IBinder resultTo, 3096 String resultWho, int requestCode, int startFlags, 3097 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3098 enforceNotIsolatedCaller("startActivity"); 3099 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3100 false, true, "startActivity", null); 3101 // TODO: Switch to user app stacks here. 3102 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3103 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3104 null, null, options, userId, null); 3105 } 3106 3107 @Override 3108 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3109 Intent intent, String resolvedType, IBinder resultTo, 3110 String resultWho, int requestCode, int startFlags, String profileFile, 3111 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3112 enforceNotIsolatedCaller("startActivityAndWait"); 3113 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3114 false, true, "startActivityAndWait", null); 3115 WaitResult res = new WaitResult(); 3116 // TODO: Switch to user app stacks here. 3117 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3118 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3119 res, null, options, UserHandle.getCallingUserId(), null); 3120 return res; 3121 } 3122 3123 @Override 3124 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3125 Intent intent, String resolvedType, IBinder resultTo, 3126 String resultWho, int requestCode, int startFlags, Configuration config, 3127 Bundle options, int userId) { 3128 enforceNotIsolatedCaller("startActivityWithConfig"); 3129 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3130 false, true, "startActivityWithConfig", null); 3131 // TODO: Switch to user app stacks here. 3132 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3133 resolvedType, resultTo, resultWho, requestCode, startFlags, 3134 null, null, null, config, options, userId, null); 3135 return ret; 3136 } 3137 3138 @Override 3139 public int startActivityIntentSender(IApplicationThread caller, 3140 IntentSender intent, Intent fillInIntent, String resolvedType, 3141 IBinder resultTo, String resultWho, int requestCode, 3142 int flagsMask, int flagsValues, Bundle options) { 3143 enforceNotIsolatedCaller("startActivityIntentSender"); 3144 // Refuse possible leaked file descriptors 3145 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3146 throw new IllegalArgumentException("File descriptors passed in Intent"); 3147 } 3148 3149 IIntentSender sender = intent.getTarget(); 3150 if (!(sender instanceof PendingIntentRecord)) { 3151 throw new IllegalArgumentException("Bad PendingIntent object"); 3152 } 3153 3154 PendingIntentRecord pir = (PendingIntentRecord)sender; 3155 3156 synchronized (this) { 3157 // If this is coming from the currently resumed activity, it is 3158 // effectively saying that app switches are allowed at this point. 3159 final ActivityStack stack = getFocusedStack(); 3160 if (stack.mResumedActivity != null && 3161 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3162 mAppSwitchesAllowedTime = 0; 3163 } 3164 } 3165 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3166 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3167 return ret; 3168 } 3169 3170 @Override 3171 public boolean startNextMatchingActivity(IBinder callingActivity, 3172 Intent intent, Bundle options) { 3173 // Refuse possible leaked file descriptors 3174 if (intent != null && intent.hasFileDescriptors() == true) { 3175 throw new IllegalArgumentException("File descriptors passed in Intent"); 3176 } 3177 3178 synchronized (this) { 3179 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3180 if (r == null) { 3181 ActivityOptions.abort(options); 3182 return false; 3183 } 3184 if (r.app == null || r.app.thread == null) { 3185 // The caller is not running... d'oh! 3186 ActivityOptions.abort(options); 3187 return false; 3188 } 3189 intent = new Intent(intent); 3190 // The caller is not allowed to change the data. 3191 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3192 // And we are resetting to find the next component... 3193 intent.setComponent(null); 3194 3195 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3196 3197 ActivityInfo aInfo = null; 3198 try { 3199 List<ResolveInfo> resolves = 3200 AppGlobals.getPackageManager().queryIntentActivities( 3201 intent, r.resolvedType, 3202 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3203 UserHandle.getCallingUserId()); 3204 3205 // Look for the original activity in the list... 3206 final int N = resolves != null ? resolves.size() : 0; 3207 for (int i=0; i<N; i++) { 3208 ResolveInfo rInfo = resolves.get(i); 3209 if (rInfo.activityInfo.packageName.equals(r.packageName) 3210 && rInfo.activityInfo.name.equals(r.info.name)) { 3211 // We found the current one... the next matching is 3212 // after it. 3213 i++; 3214 if (i<N) { 3215 aInfo = resolves.get(i).activityInfo; 3216 } 3217 if (debug) { 3218 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3219 + "/" + r.info.name); 3220 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3221 + "/" + aInfo.name); 3222 } 3223 break; 3224 } 3225 } 3226 } catch (RemoteException e) { 3227 } 3228 3229 if (aInfo == null) { 3230 // Nobody who is next! 3231 ActivityOptions.abort(options); 3232 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3233 return false; 3234 } 3235 3236 intent.setComponent(new ComponentName( 3237 aInfo.applicationInfo.packageName, aInfo.name)); 3238 intent.setFlags(intent.getFlags()&~( 3239 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3240 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3241 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3242 Intent.FLAG_ACTIVITY_NEW_TASK)); 3243 3244 // Okay now we need to start the new activity, replacing the 3245 // currently running activity. This is a little tricky because 3246 // we want to start the new one as if the current one is finished, 3247 // but not finish the current one first so that there is no flicker. 3248 // And thus... 3249 final boolean wasFinishing = r.finishing; 3250 r.finishing = true; 3251 3252 // Propagate reply information over to the new activity. 3253 final ActivityRecord resultTo = r.resultTo; 3254 final String resultWho = r.resultWho; 3255 final int requestCode = r.requestCode; 3256 r.resultTo = null; 3257 if (resultTo != null) { 3258 resultTo.removeResultsLocked(r, resultWho, requestCode); 3259 } 3260 3261 final long origId = Binder.clearCallingIdentity(); 3262 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3263 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3264 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3265 options, false, null, null); 3266 Binder.restoreCallingIdentity(origId); 3267 3268 r.finishing = wasFinishing; 3269 if (res != ActivityManager.START_SUCCESS) { 3270 return false; 3271 } 3272 return true; 3273 } 3274 } 3275 3276 final int startActivityInPackage(int uid, String callingPackage, 3277 Intent intent, String resolvedType, IBinder resultTo, 3278 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3279 IActivityContainer container) { 3280 3281 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3282 false, true, "startActivityInPackage", null); 3283 3284 // TODO: Switch to user app stacks here. 3285 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3286 resultTo, resultWho, requestCode, startFlags, 3287 null, null, null, null, options, userId, container); 3288 return ret; 3289 } 3290 3291 @Override 3292 public final int startActivities(IApplicationThread caller, String callingPackage, 3293 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3294 int userId) { 3295 enforceNotIsolatedCaller("startActivities"); 3296 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3297 false, true, "startActivity", null); 3298 // TODO: Switch to user app stacks here. 3299 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3300 resolvedTypes, resultTo, options, userId); 3301 return ret; 3302 } 3303 3304 final int startActivitiesInPackage(int uid, String callingPackage, 3305 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3306 Bundle options, int userId) { 3307 3308 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3309 false, true, "startActivityInPackage", null); 3310 // TODO: Switch to user app stacks here. 3311 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3312 resultTo, options, userId); 3313 return ret; 3314 } 3315 3316 final void addRecentTaskLocked(TaskRecord task) { 3317 int N = mRecentTasks.size(); 3318 // Quick case: check if the top-most recent task is the same. 3319 if (N > 0 && mRecentTasks.get(0) == task) { 3320 return; 3321 } 3322 // Remove any existing entries that are the same kind of task. 3323 final Intent intent = task.intent; 3324 final boolean document = intent != null && intent.isDocument(); 3325 for (int i=0; i<N; i++) { 3326 TaskRecord tr = mRecentTasks.get(i); 3327 if (task != tr) { 3328 if (task.userId != tr.userId) { 3329 continue; 3330 } 3331 final Intent trIntent = tr.intent; 3332 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3333 (intent == null || !intent.filterEquals(trIntent))) { 3334 continue; 3335 } 3336 if (document || trIntent != null && trIntent.isDocument()) { 3337 // Document tasks do not match other tasks. 3338 continue; 3339 } 3340 } 3341 3342 // Either task and tr are the same or, their affinities match or their intents match 3343 // and neither of them is a document. 3344 tr.disposeThumbnail(); 3345 mRecentTasks.remove(i); 3346 i--; 3347 N--; 3348 if (task.intent == null) { 3349 // If the new recent task we are adding is not fully 3350 // specified, then replace it with the existing recent task. 3351 task = tr; 3352 } 3353 } 3354 if (N >= MAX_RECENT_TASKS) { 3355 mRecentTasks.remove(N-1).disposeThumbnail(); 3356 } 3357 mRecentTasks.add(0, task); 3358 } 3359 3360 @Override 3361 public void reportActivityFullyDrawn(IBinder token) { 3362 synchronized (this) { 3363 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3364 if (r == null) { 3365 return; 3366 } 3367 r.reportFullyDrawnLocked(); 3368 } 3369 } 3370 3371 @Override 3372 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3373 synchronized (this) { 3374 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3375 if (r == null) { 3376 return; 3377 } 3378 final long origId = Binder.clearCallingIdentity(); 3379 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3380 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3381 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3382 if (config != null) { 3383 r.frozenBeforeDestroy = true; 3384 if (!updateConfigurationLocked(config, r, false, false)) { 3385 mStackSupervisor.resumeTopActivitiesLocked(); 3386 } 3387 } 3388 Binder.restoreCallingIdentity(origId); 3389 } 3390 } 3391 3392 @Override 3393 public int getRequestedOrientation(IBinder token) { 3394 synchronized (this) { 3395 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3396 if (r == null) { 3397 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3398 } 3399 return mWindowManager.getAppOrientation(r.appToken); 3400 } 3401 } 3402 3403 /** 3404 * This is the internal entry point for handling Activity.finish(). 3405 * 3406 * @param token The Binder token referencing the Activity we want to finish. 3407 * @param resultCode Result code, if any, from this Activity. 3408 * @param resultData Result data (Intent), if any, from this Activity. 3409 * 3410 * @return Returns true if the activity successfully finished, or false if it is still running. 3411 */ 3412 @Override 3413 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3414 // Refuse possible leaked file descriptors 3415 if (resultData != null && resultData.hasFileDescriptors() == true) { 3416 throw new IllegalArgumentException("File descriptors passed in Intent"); 3417 } 3418 3419 synchronized(this) { 3420 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3421 if (r == null) { 3422 return true; 3423 } 3424 if (mController != null) { 3425 // Find the first activity that is not finishing. 3426 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3427 if (next != null) { 3428 // ask watcher if this is allowed 3429 boolean resumeOK = true; 3430 try { 3431 resumeOK = mController.activityResuming(next.packageName); 3432 } catch (RemoteException e) { 3433 mController = null; 3434 Watchdog.getInstance().setActivityController(null); 3435 } 3436 3437 if (!resumeOK) { 3438 return false; 3439 } 3440 } 3441 } 3442 final long origId = Binder.clearCallingIdentity(); 3443 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3444 resultData, "app-request", true); 3445 Binder.restoreCallingIdentity(origId); 3446 return res; 3447 } 3448 } 3449 3450 @Override 3451 public final void finishHeavyWeightApp() { 3452 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3453 != PackageManager.PERMISSION_GRANTED) { 3454 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3455 + Binder.getCallingPid() 3456 + ", uid=" + Binder.getCallingUid() 3457 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3458 Slog.w(TAG, msg); 3459 throw new SecurityException(msg); 3460 } 3461 3462 synchronized(this) { 3463 if (mHeavyWeightProcess == null) { 3464 return; 3465 } 3466 3467 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3468 mHeavyWeightProcess.activities); 3469 for (int i=0; i<activities.size(); i++) { 3470 ActivityRecord r = activities.get(i); 3471 if (!r.finishing) { 3472 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3473 null, "finish-heavy", true); 3474 } 3475 } 3476 3477 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3478 mHeavyWeightProcess.userId, 0)); 3479 mHeavyWeightProcess = null; 3480 } 3481 } 3482 3483 @Override 3484 public void crashApplication(int uid, int initialPid, String packageName, 3485 String message) { 3486 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3487 != PackageManager.PERMISSION_GRANTED) { 3488 String msg = "Permission Denial: crashApplication() from pid=" 3489 + Binder.getCallingPid() 3490 + ", uid=" + Binder.getCallingUid() 3491 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3492 Slog.w(TAG, msg); 3493 throw new SecurityException(msg); 3494 } 3495 3496 synchronized(this) { 3497 ProcessRecord proc = null; 3498 3499 // Figure out which process to kill. We don't trust that initialPid 3500 // still has any relation to current pids, so must scan through the 3501 // list. 3502 synchronized (mPidsSelfLocked) { 3503 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3504 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3505 if (p.uid != uid) { 3506 continue; 3507 } 3508 if (p.pid == initialPid) { 3509 proc = p; 3510 break; 3511 } 3512 if (p.pkgList.containsKey(packageName)) { 3513 proc = p; 3514 } 3515 } 3516 } 3517 3518 if (proc == null) { 3519 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3520 + " initialPid=" + initialPid 3521 + " packageName=" + packageName); 3522 return; 3523 } 3524 3525 if (proc.thread != null) { 3526 if (proc.pid == Process.myPid()) { 3527 Log.w(TAG, "crashApplication: trying to crash self!"); 3528 return; 3529 } 3530 long ident = Binder.clearCallingIdentity(); 3531 try { 3532 proc.thread.scheduleCrash(message); 3533 } catch (RemoteException e) { 3534 } 3535 Binder.restoreCallingIdentity(ident); 3536 } 3537 } 3538 } 3539 3540 @Override 3541 public final void finishSubActivity(IBinder token, String resultWho, 3542 int requestCode) { 3543 synchronized(this) { 3544 final long origId = Binder.clearCallingIdentity(); 3545 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3546 if (r != null) { 3547 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3548 } 3549 Binder.restoreCallingIdentity(origId); 3550 } 3551 } 3552 3553 @Override 3554 public boolean finishActivityAffinity(IBinder token) { 3555 synchronized(this) { 3556 final long origId = Binder.clearCallingIdentity(); 3557 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3558 boolean res = false; 3559 if (r != null) { 3560 res = r.task.stack.finishActivityAffinityLocked(r); 3561 } 3562 Binder.restoreCallingIdentity(origId); 3563 return res; 3564 } 3565 } 3566 3567 @Override 3568 public boolean willActivityBeVisible(IBinder token) { 3569 synchronized(this) { 3570 ActivityStack stack = ActivityRecord.getStackLocked(token); 3571 if (stack != null) { 3572 return stack.willActivityBeVisibleLocked(token); 3573 } 3574 return false; 3575 } 3576 } 3577 3578 @Override 3579 public void overridePendingTransition(IBinder token, String packageName, 3580 int enterAnim, int exitAnim) { 3581 synchronized(this) { 3582 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3583 if (self == null) { 3584 return; 3585 } 3586 3587 final long origId = Binder.clearCallingIdentity(); 3588 3589 if (self.state == ActivityState.RESUMED 3590 || self.state == ActivityState.PAUSING) { 3591 mWindowManager.overridePendingAppTransition(packageName, 3592 enterAnim, exitAnim, null); 3593 } 3594 3595 Binder.restoreCallingIdentity(origId); 3596 } 3597 } 3598 3599 /** 3600 * Main function for removing an existing process from the activity manager 3601 * as a result of that process going away. Clears out all connections 3602 * to the process. 3603 */ 3604 private final void handleAppDiedLocked(ProcessRecord app, 3605 boolean restarting, boolean allowRestart) { 3606 int pid = app.pid; 3607 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3608 if (!restarting) { 3609 removeLruProcessLocked(app); 3610 if (pid > 0) { 3611 ProcessList.remove(pid); 3612 } 3613 } 3614 3615 if (mProfileProc == app) { 3616 clearProfilerLocked(); 3617 } 3618 3619 // Remove this application's activities from active lists. 3620 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3621 3622 app.activities.clear(); 3623 3624 if (app.instrumentationClass != null) { 3625 Slog.w(TAG, "Crash of app " + app.processName 3626 + " running instrumentation " + app.instrumentationClass); 3627 Bundle info = new Bundle(); 3628 info.putString("shortMsg", "Process crashed."); 3629 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3630 } 3631 3632 if (!restarting) { 3633 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3634 // If there was nothing to resume, and we are not already 3635 // restarting this process, but there is a visible activity that 3636 // is hosted by the process... then make sure all visible 3637 // activities are running, taking care of restarting this 3638 // process. 3639 if (hasVisibleActivities) { 3640 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3641 } 3642 } 3643 } 3644 } 3645 3646 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3647 IBinder threadBinder = thread.asBinder(); 3648 // Find the application record. 3649 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3650 ProcessRecord rec = mLruProcesses.get(i); 3651 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3652 return i; 3653 } 3654 } 3655 return -1; 3656 } 3657 3658 final ProcessRecord getRecordForAppLocked( 3659 IApplicationThread thread) { 3660 if (thread == null) { 3661 return null; 3662 } 3663 3664 int appIndex = getLRURecordIndexForAppLocked(thread); 3665 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3666 } 3667 3668 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3669 // If there are no longer any background processes running, 3670 // and the app that died was not running instrumentation, 3671 // then tell everyone we are now low on memory. 3672 boolean haveBg = false; 3673 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3674 ProcessRecord rec = mLruProcesses.get(i); 3675 if (rec.thread != null 3676 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3677 haveBg = true; 3678 break; 3679 } 3680 } 3681 3682 if (!haveBg) { 3683 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3684 if (doReport) { 3685 long now = SystemClock.uptimeMillis(); 3686 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3687 doReport = false; 3688 } else { 3689 mLastMemUsageReportTime = now; 3690 } 3691 } 3692 final ArrayList<ProcessMemInfo> memInfos 3693 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3694 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3695 long now = SystemClock.uptimeMillis(); 3696 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3697 ProcessRecord rec = mLruProcesses.get(i); 3698 if (rec == dyingProc || rec.thread == null) { 3699 continue; 3700 } 3701 if (doReport) { 3702 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3703 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3704 } 3705 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3706 // The low memory report is overriding any current 3707 // state for a GC request. Make sure to do 3708 // heavy/important/visible/foreground processes first. 3709 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3710 rec.lastRequestedGc = 0; 3711 } else { 3712 rec.lastRequestedGc = rec.lastLowMemory; 3713 } 3714 rec.reportLowMemory = true; 3715 rec.lastLowMemory = now; 3716 mProcessesToGc.remove(rec); 3717 addProcessToGcListLocked(rec); 3718 } 3719 } 3720 if (doReport) { 3721 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3722 mHandler.sendMessage(msg); 3723 } 3724 scheduleAppGcsLocked(); 3725 } 3726 } 3727 3728 final void appDiedLocked(ProcessRecord app, int pid, 3729 IApplicationThread thread) { 3730 3731 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3732 synchronized (stats) { 3733 stats.noteProcessDiedLocked(app.info.uid, pid); 3734 } 3735 3736 // Clean up already done if the process has been re-started. 3737 if (app.pid == pid && app.thread != null && 3738 app.thread.asBinder() == thread.asBinder()) { 3739 boolean doLowMem = app.instrumentationClass == null; 3740 boolean doOomAdj = doLowMem; 3741 if (!app.killedByAm) { 3742 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3743 + ") has died."); 3744 mAllowLowerMemLevel = true; 3745 } else { 3746 // Note that we always want to do oom adj to update our state with the 3747 // new number of procs. 3748 mAllowLowerMemLevel = false; 3749 doLowMem = false; 3750 } 3751 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3752 if (DEBUG_CLEANUP) Slog.v( 3753 TAG, "Dying app: " + app + ", pid: " + pid 3754 + ", thread: " + thread.asBinder()); 3755 handleAppDiedLocked(app, false, true); 3756 3757 if (doOomAdj) { 3758 updateOomAdjLocked(); 3759 } 3760 if (doLowMem) { 3761 doLowMemReportIfNeededLocked(app); 3762 } 3763 } else if (app.pid != pid) { 3764 // A new process has already been started. 3765 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3766 + ") has died and restarted (pid " + app.pid + ")."); 3767 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3768 } else if (DEBUG_PROCESSES) { 3769 Slog.d(TAG, "Received spurious death notification for thread " 3770 + thread.asBinder()); 3771 } 3772 } 3773 3774 /** 3775 * If a stack trace dump file is configured, dump process stack traces. 3776 * @param clearTraces causes the dump file to be erased prior to the new 3777 * traces being written, if true; when false, the new traces will be 3778 * appended to any existing file content. 3779 * @param firstPids of dalvik VM processes to dump stack traces for first 3780 * @param lastPids of dalvik VM processes to dump stack traces for last 3781 * @param nativeProcs optional list of native process names to dump stack crawls 3782 * @return file containing stack traces, or null if no dump file is configured 3783 */ 3784 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3785 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3786 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3787 if (tracesPath == null || tracesPath.length() == 0) { 3788 return null; 3789 } 3790 3791 File tracesFile = new File(tracesPath); 3792 try { 3793 File tracesDir = tracesFile.getParentFile(); 3794 if (!tracesDir.exists()) { 3795 tracesFile.mkdirs(); 3796 if (!SELinux.restorecon(tracesDir)) { 3797 return null; 3798 } 3799 } 3800 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3801 3802 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3803 tracesFile.createNewFile(); 3804 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3805 } catch (IOException e) { 3806 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3807 return null; 3808 } 3809 3810 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3811 return tracesFile; 3812 } 3813 3814 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3815 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3816 // Use a FileObserver to detect when traces finish writing. 3817 // The order of traces is considered important to maintain for legibility. 3818 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3819 @Override 3820 public synchronized void onEvent(int event, String path) { notify(); } 3821 }; 3822 3823 try { 3824 observer.startWatching(); 3825 3826 // First collect all of the stacks of the most important pids. 3827 if (firstPids != null) { 3828 try { 3829 int num = firstPids.size(); 3830 for (int i = 0; i < num; i++) { 3831 synchronized (observer) { 3832 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3833 observer.wait(200); // Wait for write-close, give up after 200msec 3834 } 3835 } 3836 } catch (InterruptedException e) { 3837 Log.wtf(TAG, e); 3838 } 3839 } 3840 3841 // Next collect the stacks of the native pids 3842 if (nativeProcs != null) { 3843 int[] pids = Process.getPidsForCommands(nativeProcs); 3844 if (pids != null) { 3845 for (int pid : pids) { 3846 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3847 } 3848 } 3849 } 3850 3851 // Lastly, measure CPU usage. 3852 if (processCpuTracker != null) { 3853 processCpuTracker.init(); 3854 System.gc(); 3855 processCpuTracker.update(); 3856 try { 3857 synchronized (processCpuTracker) { 3858 processCpuTracker.wait(500); // measure over 1/2 second. 3859 } 3860 } catch (InterruptedException e) { 3861 } 3862 processCpuTracker.update(); 3863 3864 // We'll take the stack crawls of just the top apps using CPU. 3865 final int N = processCpuTracker.countWorkingStats(); 3866 int numProcs = 0; 3867 for (int i=0; i<N && numProcs<5; i++) { 3868 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3869 if (lastPids.indexOfKey(stats.pid) >= 0) { 3870 numProcs++; 3871 try { 3872 synchronized (observer) { 3873 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3874 observer.wait(200); // Wait for write-close, give up after 200msec 3875 } 3876 } catch (InterruptedException e) { 3877 Log.wtf(TAG, e); 3878 } 3879 3880 } 3881 } 3882 } 3883 } finally { 3884 observer.stopWatching(); 3885 } 3886 } 3887 3888 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3889 if (true || IS_USER_BUILD) { 3890 return; 3891 } 3892 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3893 if (tracesPath == null || tracesPath.length() == 0) { 3894 return; 3895 } 3896 3897 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3898 StrictMode.allowThreadDiskWrites(); 3899 try { 3900 final File tracesFile = new File(tracesPath); 3901 final File tracesDir = tracesFile.getParentFile(); 3902 final File tracesTmp = new File(tracesDir, "__tmp__"); 3903 try { 3904 if (!tracesDir.exists()) { 3905 tracesFile.mkdirs(); 3906 if (!SELinux.restorecon(tracesDir.getPath())) { 3907 return; 3908 } 3909 } 3910 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3911 3912 if (tracesFile.exists()) { 3913 tracesTmp.delete(); 3914 tracesFile.renameTo(tracesTmp); 3915 } 3916 StringBuilder sb = new StringBuilder(); 3917 Time tobj = new Time(); 3918 tobj.set(System.currentTimeMillis()); 3919 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3920 sb.append(": "); 3921 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3922 sb.append(" since "); 3923 sb.append(msg); 3924 FileOutputStream fos = new FileOutputStream(tracesFile); 3925 fos.write(sb.toString().getBytes()); 3926 if (app == null) { 3927 fos.write("\n*** No application process!".getBytes()); 3928 } 3929 fos.close(); 3930 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3931 } catch (IOException e) { 3932 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3933 return; 3934 } 3935 3936 if (app != null) { 3937 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3938 firstPids.add(app.pid); 3939 dumpStackTraces(tracesPath, firstPids, null, null, null); 3940 } 3941 3942 File lastTracesFile = null; 3943 File curTracesFile = null; 3944 for (int i=9; i>=0; i--) { 3945 String name = String.format(Locale.US, "slow%02d.txt", i); 3946 curTracesFile = new File(tracesDir, name); 3947 if (curTracesFile.exists()) { 3948 if (lastTracesFile != null) { 3949 curTracesFile.renameTo(lastTracesFile); 3950 } else { 3951 curTracesFile.delete(); 3952 } 3953 } 3954 lastTracesFile = curTracesFile; 3955 } 3956 tracesFile.renameTo(curTracesFile); 3957 if (tracesTmp.exists()) { 3958 tracesTmp.renameTo(tracesFile); 3959 } 3960 } finally { 3961 StrictMode.setThreadPolicy(oldPolicy); 3962 } 3963 } 3964 3965 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3966 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3967 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3968 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3969 3970 if (mController != null) { 3971 try { 3972 // 0 == continue, -1 = kill process immediately 3973 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3974 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3975 } catch (RemoteException e) { 3976 mController = null; 3977 Watchdog.getInstance().setActivityController(null); 3978 } 3979 } 3980 3981 long anrTime = SystemClock.uptimeMillis(); 3982 if (MONITOR_CPU_USAGE) { 3983 updateCpuStatsNow(); 3984 } 3985 3986 synchronized (this) { 3987 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3988 if (mShuttingDown) { 3989 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3990 return; 3991 } else if (app.notResponding) { 3992 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3993 return; 3994 } else if (app.crashing) { 3995 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3996 return; 3997 } 3998 3999 // In case we come through here for the same app before completing 4000 // this one, mark as anring now so we will bail out. 4001 app.notResponding = true; 4002 4003 // Log the ANR to the event log. 4004 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4005 app.processName, app.info.flags, annotation); 4006 4007 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4008 firstPids.add(app.pid); 4009 4010 int parentPid = app.pid; 4011 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4012 if (parentPid != app.pid) firstPids.add(parentPid); 4013 4014 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4015 4016 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4017 ProcessRecord r = mLruProcesses.get(i); 4018 if (r != null && r.thread != null) { 4019 int pid = r.pid; 4020 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4021 if (r.persistent) { 4022 firstPids.add(pid); 4023 } else { 4024 lastPids.put(pid, Boolean.TRUE); 4025 } 4026 } 4027 } 4028 } 4029 } 4030 4031 // Log the ANR to the main log. 4032 StringBuilder info = new StringBuilder(); 4033 info.setLength(0); 4034 info.append("ANR in ").append(app.processName); 4035 if (activity != null && activity.shortComponentName != null) { 4036 info.append(" (").append(activity.shortComponentName).append(")"); 4037 } 4038 info.append("\n"); 4039 info.append("PID: ").append(app.pid).append("\n"); 4040 if (annotation != null) { 4041 info.append("Reason: ").append(annotation).append("\n"); 4042 } 4043 if (parent != null && parent != activity) { 4044 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4045 } 4046 4047 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4048 4049 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4050 NATIVE_STACKS_OF_INTEREST); 4051 4052 String cpuInfo = null; 4053 if (MONITOR_CPU_USAGE) { 4054 updateCpuStatsNow(); 4055 synchronized (mProcessCpuThread) { 4056 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4057 } 4058 info.append(processCpuTracker.printCurrentLoad()); 4059 info.append(cpuInfo); 4060 } 4061 4062 info.append(processCpuTracker.printCurrentState(anrTime)); 4063 4064 Slog.e(TAG, info.toString()); 4065 if (tracesFile == null) { 4066 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4067 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4068 } 4069 4070 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4071 cpuInfo, tracesFile, null); 4072 4073 if (mController != null) { 4074 try { 4075 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4076 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4077 if (res != 0) { 4078 if (res < 0 && app.pid != MY_PID) { 4079 Process.killProcess(app.pid); 4080 } else { 4081 synchronized (this) { 4082 mServices.scheduleServiceTimeoutLocked(app); 4083 } 4084 } 4085 return; 4086 } 4087 } catch (RemoteException e) { 4088 mController = null; 4089 Watchdog.getInstance().setActivityController(null); 4090 } 4091 } 4092 4093 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4094 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4095 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4096 4097 synchronized (this) { 4098 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4099 killUnneededProcessLocked(app, "background ANR"); 4100 return; 4101 } 4102 4103 // Set the app's notResponding state, and look up the errorReportReceiver 4104 makeAppNotRespondingLocked(app, 4105 activity != null ? activity.shortComponentName : null, 4106 annotation != null ? "ANR " + annotation : "ANR", 4107 info.toString()); 4108 4109 // Bring up the infamous App Not Responding dialog 4110 Message msg = Message.obtain(); 4111 HashMap<String, Object> map = new HashMap<String, Object>(); 4112 msg.what = SHOW_NOT_RESPONDING_MSG; 4113 msg.obj = map; 4114 msg.arg1 = aboveSystem ? 1 : 0; 4115 map.put("app", app); 4116 if (activity != null) { 4117 map.put("activity", activity); 4118 } 4119 4120 mHandler.sendMessage(msg); 4121 } 4122 } 4123 4124 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4125 if (!mLaunchWarningShown) { 4126 mLaunchWarningShown = true; 4127 mHandler.post(new Runnable() { 4128 @Override 4129 public void run() { 4130 synchronized (ActivityManagerService.this) { 4131 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4132 d.show(); 4133 mHandler.postDelayed(new Runnable() { 4134 @Override 4135 public void run() { 4136 synchronized (ActivityManagerService.this) { 4137 d.dismiss(); 4138 mLaunchWarningShown = false; 4139 } 4140 } 4141 }, 4000); 4142 } 4143 } 4144 }); 4145 } 4146 } 4147 4148 @Override 4149 public boolean clearApplicationUserData(final String packageName, 4150 final IPackageDataObserver observer, int userId) { 4151 enforceNotIsolatedCaller("clearApplicationUserData"); 4152 int uid = Binder.getCallingUid(); 4153 int pid = Binder.getCallingPid(); 4154 userId = handleIncomingUser(pid, uid, 4155 userId, false, true, "clearApplicationUserData", null); 4156 long callingId = Binder.clearCallingIdentity(); 4157 try { 4158 IPackageManager pm = AppGlobals.getPackageManager(); 4159 int pkgUid = -1; 4160 synchronized(this) { 4161 try { 4162 pkgUid = pm.getPackageUid(packageName, userId); 4163 } catch (RemoteException e) { 4164 } 4165 if (pkgUid == -1) { 4166 Slog.w(TAG, "Invalid packageName: " + packageName); 4167 if (observer != null) { 4168 try { 4169 observer.onRemoveCompleted(packageName, false); 4170 } catch (RemoteException e) { 4171 Slog.i(TAG, "Observer no longer exists."); 4172 } 4173 } 4174 return false; 4175 } 4176 if (uid == pkgUid || checkComponentPermission( 4177 android.Manifest.permission.CLEAR_APP_USER_DATA, 4178 pid, uid, -1, true) 4179 == PackageManager.PERMISSION_GRANTED) { 4180 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4181 } else { 4182 throw new SecurityException("PID " + pid + " does not have permission " 4183 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4184 + " of package " + packageName); 4185 } 4186 } 4187 4188 try { 4189 // Clear application user data 4190 pm.clearApplicationUserData(packageName, observer, userId); 4191 4192 // Remove all permissions granted from/to this package 4193 removeUriPermissionsForPackageLocked(packageName, userId, true); 4194 4195 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4196 Uri.fromParts("package", packageName, null)); 4197 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4198 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4199 null, null, 0, null, null, null, false, false, userId); 4200 } catch (RemoteException e) { 4201 } 4202 } finally { 4203 Binder.restoreCallingIdentity(callingId); 4204 } 4205 return true; 4206 } 4207 4208 @Override 4209 public void killBackgroundProcesses(final String packageName, int userId) { 4210 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4211 != PackageManager.PERMISSION_GRANTED && 4212 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4213 != PackageManager.PERMISSION_GRANTED) { 4214 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4215 + Binder.getCallingPid() 4216 + ", uid=" + Binder.getCallingUid() 4217 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4218 Slog.w(TAG, msg); 4219 throw new SecurityException(msg); 4220 } 4221 4222 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4223 userId, true, true, "killBackgroundProcesses", null); 4224 long callingId = Binder.clearCallingIdentity(); 4225 try { 4226 IPackageManager pm = AppGlobals.getPackageManager(); 4227 synchronized(this) { 4228 int appId = -1; 4229 try { 4230 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4231 } catch (RemoteException e) { 4232 } 4233 if (appId == -1) { 4234 Slog.w(TAG, "Invalid packageName: " + packageName); 4235 return; 4236 } 4237 killPackageProcessesLocked(packageName, appId, userId, 4238 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4239 } 4240 } finally { 4241 Binder.restoreCallingIdentity(callingId); 4242 } 4243 } 4244 4245 @Override 4246 public void killAllBackgroundProcesses() { 4247 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4248 != PackageManager.PERMISSION_GRANTED) { 4249 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4250 + Binder.getCallingPid() 4251 + ", uid=" + Binder.getCallingUid() 4252 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4253 Slog.w(TAG, msg); 4254 throw new SecurityException(msg); 4255 } 4256 4257 long callingId = Binder.clearCallingIdentity(); 4258 try { 4259 synchronized(this) { 4260 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4261 final int NP = mProcessNames.getMap().size(); 4262 for (int ip=0; ip<NP; ip++) { 4263 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4264 final int NA = apps.size(); 4265 for (int ia=0; ia<NA; ia++) { 4266 ProcessRecord app = apps.valueAt(ia); 4267 if (app.persistent) { 4268 // we don't kill persistent processes 4269 continue; 4270 } 4271 if (app.removed) { 4272 procs.add(app); 4273 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4274 app.removed = true; 4275 procs.add(app); 4276 } 4277 } 4278 } 4279 4280 int N = procs.size(); 4281 for (int i=0; i<N; i++) { 4282 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4283 } 4284 mAllowLowerMemLevel = true; 4285 updateOomAdjLocked(); 4286 doLowMemReportIfNeededLocked(null); 4287 } 4288 } finally { 4289 Binder.restoreCallingIdentity(callingId); 4290 } 4291 } 4292 4293 @Override 4294 public void forceStopPackage(final String packageName, int userId) { 4295 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4296 != PackageManager.PERMISSION_GRANTED) { 4297 String msg = "Permission Denial: forceStopPackage() from pid=" 4298 + Binder.getCallingPid() 4299 + ", uid=" + Binder.getCallingUid() 4300 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4301 Slog.w(TAG, msg); 4302 throw new SecurityException(msg); 4303 } 4304 final int callingPid = Binder.getCallingPid(); 4305 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4306 userId, true, true, "forceStopPackage", null); 4307 long callingId = Binder.clearCallingIdentity(); 4308 try { 4309 IPackageManager pm = AppGlobals.getPackageManager(); 4310 synchronized(this) { 4311 int[] users = userId == UserHandle.USER_ALL 4312 ? getUsersLocked() : new int[] { userId }; 4313 for (int user : users) { 4314 int pkgUid = -1; 4315 try { 4316 pkgUid = pm.getPackageUid(packageName, user); 4317 } catch (RemoteException e) { 4318 } 4319 if (pkgUid == -1) { 4320 Slog.w(TAG, "Invalid packageName: " + packageName); 4321 continue; 4322 } 4323 try { 4324 pm.setPackageStoppedState(packageName, true, user); 4325 } catch (RemoteException e) { 4326 } catch (IllegalArgumentException e) { 4327 Slog.w(TAG, "Failed trying to unstop package " 4328 + packageName + ": " + e); 4329 } 4330 if (isUserRunningLocked(user, false)) { 4331 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4332 } 4333 } 4334 } 4335 } finally { 4336 Binder.restoreCallingIdentity(callingId); 4337 } 4338 } 4339 4340 /* 4341 * The pkg name and app id have to be specified. 4342 */ 4343 @Override 4344 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4345 if (pkg == null) { 4346 return; 4347 } 4348 // Make sure the uid is valid. 4349 if (appid < 0) { 4350 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4351 return; 4352 } 4353 int callerUid = Binder.getCallingUid(); 4354 // Only the system server can kill an application 4355 if (callerUid == Process.SYSTEM_UID) { 4356 // Post an aysnc message to kill the application 4357 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4358 msg.arg1 = appid; 4359 msg.arg2 = 0; 4360 Bundle bundle = new Bundle(); 4361 bundle.putString("pkg", pkg); 4362 bundle.putString("reason", reason); 4363 msg.obj = bundle; 4364 mHandler.sendMessage(msg); 4365 } else { 4366 throw new SecurityException(callerUid + " cannot kill pkg: " + 4367 pkg); 4368 } 4369 } 4370 4371 @Override 4372 public void closeSystemDialogs(String reason) { 4373 enforceNotIsolatedCaller("closeSystemDialogs"); 4374 4375 final int pid = Binder.getCallingPid(); 4376 final int uid = Binder.getCallingUid(); 4377 final long origId = Binder.clearCallingIdentity(); 4378 try { 4379 synchronized (this) { 4380 // Only allow this from foreground processes, so that background 4381 // applications can't abuse it to prevent system UI from being shown. 4382 if (uid >= Process.FIRST_APPLICATION_UID) { 4383 ProcessRecord proc; 4384 synchronized (mPidsSelfLocked) { 4385 proc = mPidsSelfLocked.get(pid); 4386 } 4387 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4388 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4389 + " from background process " + proc); 4390 return; 4391 } 4392 } 4393 closeSystemDialogsLocked(reason); 4394 } 4395 } finally { 4396 Binder.restoreCallingIdentity(origId); 4397 } 4398 } 4399 4400 void closeSystemDialogsLocked(String reason) { 4401 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4402 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4403 | Intent.FLAG_RECEIVER_FOREGROUND); 4404 if (reason != null) { 4405 intent.putExtra("reason", reason); 4406 } 4407 mWindowManager.closeSystemDialogs(reason); 4408 4409 mStackSupervisor.closeSystemDialogsLocked(); 4410 4411 broadcastIntentLocked(null, null, intent, null, 4412 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4413 Process.SYSTEM_UID, UserHandle.USER_ALL); 4414 } 4415 4416 @Override 4417 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4418 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4419 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4420 for (int i=pids.length-1; i>=0; i--) { 4421 ProcessRecord proc; 4422 int oomAdj; 4423 synchronized (this) { 4424 synchronized (mPidsSelfLocked) { 4425 proc = mPidsSelfLocked.get(pids[i]); 4426 oomAdj = proc != null ? proc.setAdj : 0; 4427 } 4428 } 4429 infos[i] = new Debug.MemoryInfo(); 4430 Debug.getMemoryInfo(pids[i], infos[i]); 4431 if (proc != null) { 4432 synchronized (this) { 4433 if (proc.thread != null && proc.setAdj == oomAdj) { 4434 // Record this for posterity if the process has been stable. 4435 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4436 infos[i].getTotalUss(), false, proc.pkgList); 4437 } 4438 } 4439 } 4440 } 4441 return infos; 4442 } 4443 4444 @Override 4445 public long[] getProcessPss(int[] pids) { 4446 enforceNotIsolatedCaller("getProcessPss"); 4447 long[] pss = new long[pids.length]; 4448 for (int i=pids.length-1; i>=0; i--) { 4449 ProcessRecord proc; 4450 int oomAdj; 4451 synchronized (this) { 4452 synchronized (mPidsSelfLocked) { 4453 proc = mPidsSelfLocked.get(pids[i]); 4454 oomAdj = proc != null ? proc.setAdj : 0; 4455 } 4456 } 4457 long[] tmpUss = new long[1]; 4458 pss[i] = Debug.getPss(pids[i], tmpUss); 4459 if (proc != null) { 4460 synchronized (this) { 4461 if (proc.thread != null && proc.setAdj == oomAdj) { 4462 // Record this for posterity if the process has been stable. 4463 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4464 } 4465 } 4466 } 4467 } 4468 return pss; 4469 } 4470 4471 @Override 4472 public void killApplicationProcess(String processName, int uid) { 4473 if (processName == null) { 4474 return; 4475 } 4476 4477 int callerUid = Binder.getCallingUid(); 4478 // Only the system server can kill an application 4479 if (callerUid == Process.SYSTEM_UID) { 4480 synchronized (this) { 4481 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4482 if (app != null && app.thread != null) { 4483 try { 4484 app.thread.scheduleSuicide(); 4485 } catch (RemoteException e) { 4486 // If the other end already died, then our work here is done. 4487 } 4488 } else { 4489 Slog.w(TAG, "Process/uid not found attempting kill of " 4490 + processName + " / " + uid); 4491 } 4492 } 4493 } else { 4494 throw new SecurityException(callerUid + " cannot kill app process: " + 4495 processName); 4496 } 4497 } 4498 4499 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4500 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4501 false, true, false, false, UserHandle.getUserId(uid), reason); 4502 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4503 Uri.fromParts("package", packageName, null)); 4504 if (!mProcessesReady) { 4505 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4506 | Intent.FLAG_RECEIVER_FOREGROUND); 4507 } 4508 intent.putExtra(Intent.EXTRA_UID, uid); 4509 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4510 broadcastIntentLocked(null, null, intent, 4511 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4512 false, false, 4513 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4514 } 4515 4516 private void forceStopUserLocked(int userId, String reason) { 4517 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4518 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4519 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4520 | Intent.FLAG_RECEIVER_FOREGROUND); 4521 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4522 broadcastIntentLocked(null, null, intent, 4523 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4524 false, false, 4525 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4526 } 4527 4528 private final boolean killPackageProcessesLocked(String packageName, int appId, 4529 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4530 boolean doit, boolean evenPersistent, String reason) { 4531 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4532 4533 // Remove all processes this package may have touched: all with the 4534 // same UID (except for the system or root user), and all whose name 4535 // matches the package name. 4536 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4537 final int NP = mProcessNames.getMap().size(); 4538 for (int ip=0; ip<NP; ip++) { 4539 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4540 final int NA = apps.size(); 4541 for (int ia=0; ia<NA; ia++) { 4542 ProcessRecord app = apps.valueAt(ia); 4543 if (app.persistent && !evenPersistent) { 4544 // we don't kill persistent processes 4545 continue; 4546 } 4547 if (app.removed) { 4548 if (doit) { 4549 procs.add(app); 4550 } 4551 continue; 4552 } 4553 4554 // Skip process if it doesn't meet our oom adj requirement. 4555 if (app.setAdj < minOomAdj) { 4556 continue; 4557 } 4558 4559 // If no package is specified, we call all processes under the 4560 // give user id. 4561 if (packageName == null) { 4562 if (app.userId != userId) { 4563 continue; 4564 } 4565 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4566 continue; 4567 } 4568 // Package has been specified, we want to hit all processes 4569 // that match it. We need to qualify this by the processes 4570 // that are running under the specified app and user ID. 4571 } else { 4572 if (UserHandle.getAppId(app.uid) != appId) { 4573 continue; 4574 } 4575 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4576 continue; 4577 } 4578 if (!app.pkgList.containsKey(packageName)) { 4579 continue; 4580 } 4581 } 4582 4583 // Process has passed all conditions, kill it! 4584 if (!doit) { 4585 return true; 4586 } 4587 app.removed = true; 4588 procs.add(app); 4589 } 4590 } 4591 4592 int N = procs.size(); 4593 for (int i=0; i<N; i++) { 4594 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4595 } 4596 updateOomAdjLocked(); 4597 return N > 0; 4598 } 4599 4600 private final boolean forceStopPackageLocked(String name, int appId, 4601 boolean callerWillRestart, boolean purgeCache, boolean doit, 4602 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4603 int i; 4604 int N; 4605 4606 if (userId == UserHandle.USER_ALL && name == null) { 4607 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4608 } 4609 4610 if (appId < 0 && name != null) { 4611 try { 4612 appId = UserHandle.getAppId( 4613 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4614 } catch (RemoteException e) { 4615 } 4616 } 4617 4618 if (doit) { 4619 if (name != null) { 4620 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4621 + " user=" + userId + ": " + reason); 4622 } else { 4623 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4624 } 4625 4626 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4627 for (int ip=pmap.size()-1; ip>=0; ip--) { 4628 SparseArray<Long> ba = pmap.valueAt(ip); 4629 for (i=ba.size()-1; i>=0; i--) { 4630 boolean remove = false; 4631 final int entUid = ba.keyAt(i); 4632 if (name != null) { 4633 if (userId == UserHandle.USER_ALL) { 4634 if (UserHandle.getAppId(entUid) == appId) { 4635 remove = true; 4636 } 4637 } else { 4638 if (entUid == UserHandle.getUid(userId, appId)) { 4639 remove = true; 4640 } 4641 } 4642 } else if (UserHandle.getUserId(entUid) == userId) { 4643 remove = true; 4644 } 4645 if (remove) { 4646 ba.removeAt(i); 4647 } 4648 } 4649 if (ba.size() == 0) { 4650 pmap.removeAt(ip); 4651 } 4652 } 4653 } 4654 4655 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4656 -100, callerWillRestart, true, doit, evenPersistent, 4657 name == null ? ("stop user " + userId) : ("stop " + name)); 4658 4659 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4660 if (!doit) { 4661 return true; 4662 } 4663 didSomething = true; 4664 } 4665 4666 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4667 if (!doit) { 4668 return true; 4669 } 4670 didSomething = true; 4671 } 4672 4673 if (name == null) { 4674 // Remove all sticky broadcasts from this user. 4675 mStickyBroadcasts.remove(userId); 4676 } 4677 4678 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4679 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4680 userId, providers)) { 4681 if (!doit) { 4682 return true; 4683 } 4684 didSomething = true; 4685 } 4686 N = providers.size(); 4687 for (i=0; i<N; i++) { 4688 removeDyingProviderLocked(null, providers.get(i), true); 4689 } 4690 4691 // Remove transient permissions granted from/to this package/user 4692 removeUriPermissionsForPackageLocked(name, userId, false); 4693 4694 if (name == null || uninstalling) { 4695 // Remove pending intents. For now we only do this when force 4696 // stopping users, because we have some problems when doing this 4697 // for packages -- app widgets are not currently cleaned up for 4698 // such packages, so they can be left with bad pending intents. 4699 if (mIntentSenderRecords.size() > 0) { 4700 Iterator<WeakReference<PendingIntentRecord>> it 4701 = mIntentSenderRecords.values().iterator(); 4702 while (it.hasNext()) { 4703 WeakReference<PendingIntentRecord> wpir = it.next(); 4704 if (wpir == null) { 4705 it.remove(); 4706 continue; 4707 } 4708 PendingIntentRecord pir = wpir.get(); 4709 if (pir == null) { 4710 it.remove(); 4711 continue; 4712 } 4713 if (name == null) { 4714 // Stopping user, remove all objects for the user. 4715 if (pir.key.userId != userId) { 4716 // Not the same user, skip it. 4717 continue; 4718 } 4719 } else { 4720 if (UserHandle.getAppId(pir.uid) != appId) { 4721 // Different app id, skip it. 4722 continue; 4723 } 4724 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4725 // Different user, skip it. 4726 continue; 4727 } 4728 if (!pir.key.packageName.equals(name)) { 4729 // Different package, skip it. 4730 continue; 4731 } 4732 } 4733 if (!doit) { 4734 return true; 4735 } 4736 didSomething = true; 4737 it.remove(); 4738 pir.canceled = true; 4739 if (pir.key.activity != null) { 4740 pir.key.activity.pendingResults.remove(pir.ref); 4741 } 4742 } 4743 } 4744 } 4745 4746 if (doit) { 4747 if (purgeCache && name != null) { 4748 AttributeCache ac = AttributeCache.instance(); 4749 if (ac != null) { 4750 ac.removePackage(name); 4751 } 4752 } 4753 if (mBooted) { 4754 mStackSupervisor.resumeTopActivitiesLocked(); 4755 mStackSupervisor.scheduleIdleLocked(); 4756 } 4757 } 4758 4759 return didSomething; 4760 } 4761 4762 private final boolean removeProcessLocked(ProcessRecord app, 4763 boolean callerWillRestart, boolean allowRestart, String reason) { 4764 final String name = app.processName; 4765 final int uid = app.uid; 4766 if (DEBUG_PROCESSES) Slog.d( 4767 TAG, "Force removing proc " + app.toShortString() + " (" + name 4768 + "/" + uid + ")"); 4769 4770 mProcessNames.remove(name, uid); 4771 mIsolatedProcesses.remove(app.uid); 4772 if (mHeavyWeightProcess == app) { 4773 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4774 mHeavyWeightProcess.userId, 0)); 4775 mHeavyWeightProcess = null; 4776 } 4777 boolean needRestart = false; 4778 if (app.pid > 0 && app.pid != MY_PID) { 4779 int pid = app.pid; 4780 synchronized (mPidsSelfLocked) { 4781 mPidsSelfLocked.remove(pid); 4782 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4783 } 4784 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4785 app.processName, app.info.uid); 4786 if (app.isolated) { 4787 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4788 } 4789 killUnneededProcessLocked(app, reason); 4790 handleAppDiedLocked(app, true, allowRestart); 4791 removeLruProcessLocked(app); 4792 4793 if (app.persistent && !app.isolated) { 4794 if (!callerWillRestart) { 4795 addAppLocked(app.info, false); 4796 } else { 4797 needRestart = true; 4798 } 4799 } 4800 } else { 4801 mRemovedProcesses.add(app); 4802 } 4803 4804 return needRestart; 4805 } 4806 4807 private final void processStartTimedOutLocked(ProcessRecord app) { 4808 final int pid = app.pid; 4809 boolean gone = false; 4810 synchronized (mPidsSelfLocked) { 4811 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4812 if (knownApp != null && knownApp.thread == null) { 4813 mPidsSelfLocked.remove(pid); 4814 gone = true; 4815 } 4816 } 4817 4818 if (gone) { 4819 Slog.w(TAG, "Process " + app + " failed to attach"); 4820 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4821 pid, app.uid, app.processName); 4822 mProcessNames.remove(app.processName, app.uid); 4823 mIsolatedProcesses.remove(app.uid); 4824 if (mHeavyWeightProcess == app) { 4825 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4826 mHeavyWeightProcess.userId, 0)); 4827 mHeavyWeightProcess = null; 4828 } 4829 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4830 app.processName, app.info.uid); 4831 if (app.isolated) { 4832 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4833 } 4834 // Take care of any launching providers waiting for this process. 4835 checkAppInLaunchingProvidersLocked(app, true); 4836 // Take care of any services that are waiting for the process. 4837 mServices.processStartTimedOutLocked(app); 4838 killUnneededProcessLocked(app, "start timeout"); 4839 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4840 Slog.w(TAG, "Unattached app died before backup, skipping"); 4841 try { 4842 IBackupManager bm = IBackupManager.Stub.asInterface( 4843 ServiceManager.getService(Context.BACKUP_SERVICE)); 4844 bm.agentDisconnected(app.info.packageName); 4845 } catch (RemoteException e) { 4846 // Can't happen; the backup manager is local 4847 } 4848 } 4849 if (isPendingBroadcastProcessLocked(pid)) { 4850 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4851 skipPendingBroadcastLocked(pid); 4852 } 4853 } else { 4854 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4855 } 4856 } 4857 4858 private final boolean attachApplicationLocked(IApplicationThread thread, 4859 int pid) { 4860 4861 // Find the application record that is being attached... either via 4862 // the pid if we are running in multiple processes, or just pull the 4863 // next app record if we are emulating process with anonymous threads. 4864 ProcessRecord app; 4865 if (pid != MY_PID && pid >= 0) { 4866 synchronized (mPidsSelfLocked) { 4867 app = mPidsSelfLocked.get(pid); 4868 } 4869 } else { 4870 app = null; 4871 } 4872 4873 if (app == null) { 4874 Slog.w(TAG, "No pending application record for pid " + pid 4875 + " (IApplicationThread " + thread + "); dropping process"); 4876 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4877 if (pid > 0 && pid != MY_PID) { 4878 Process.killProcessQuiet(pid); 4879 } else { 4880 try { 4881 thread.scheduleExit(); 4882 } catch (Exception e) { 4883 // Ignore exceptions. 4884 } 4885 } 4886 return false; 4887 } 4888 4889 // If this application record is still attached to a previous 4890 // process, clean it up now. 4891 if (app.thread != null) { 4892 handleAppDiedLocked(app, true, true); 4893 } 4894 4895 // Tell the process all about itself. 4896 4897 if (localLOGV) Slog.v( 4898 TAG, "Binding process pid " + pid + " to record " + app); 4899 4900 final String processName = app.processName; 4901 try { 4902 AppDeathRecipient adr = new AppDeathRecipient( 4903 app, pid, thread); 4904 thread.asBinder().linkToDeath(adr, 0); 4905 app.deathRecipient = adr; 4906 } catch (RemoteException e) { 4907 app.resetPackageList(mProcessStats); 4908 startProcessLocked(app, "link fail", processName); 4909 return false; 4910 } 4911 4912 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4913 4914 app.makeActive(thread, mProcessStats); 4915 app.curAdj = app.setAdj = -100; 4916 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4917 app.forcingToForeground = null; 4918 updateProcessForegroundLocked(app, false, false); 4919 app.hasShownUi = false; 4920 app.debugging = false; 4921 app.cached = false; 4922 4923 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4924 4925 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4926 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4927 4928 if (!normalMode) { 4929 Slog.i(TAG, "Launching preboot mode app: " + app); 4930 } 4931 4932 if (localLOGV) Slog.v( 4933 TAG, "New app record " + app 4934 + " thread=" + thread.asBinder() + " pid=" + pid); 4935 try { 4936 int testMode = IApplicationThread.DEBUG_OFF; 4937 if (mDebugApp != null && mDebugApp.equals(processName)) { 4938 testMode = mWaitForDebugger 4939 ? IApplicationThread.DEBUG_WAIT 4940 : IApplicationThread.DEBUG_ON; 4941 app.debugging = true; 4942 if (mDebugTransient) { 4943 mDebugApp = mOrigDebugApp; 4944 mWaitForDebugger = mOrigWaitForDebugger; 4945 } 4946 } 4947 String profileFile = app.instrumentationProfileFile; 4948 ParcelFileDescriptor profileFd = null; 4949 boolean profileAutoStop = false; 4950 if (mProfileApp != null && mProfileApp.equals(processName)) { 4951 mProfileProc = app; 4952 profileFile = mProfileFile; 4953 profileFd = mProfileFd; 4954 profileAutoStop = mAutoStopProfiler; 4955 } 4956 boolean enableOpenGlTrace = false; 4957 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4958 enableOpenGlTrace = true; 4959 mOpenGlTraceApp = null; 4960 } 4961 4962 // If the app is being launched for restore or full backup, set it up specially 4963 boolean isRestrictedBackupMode = false; 4964 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4965 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4966 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4967 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4968 } 4969 4970 ensurePackageDexOpt(app.instrumentationInfo != null 4971 ? app.instrumentationInfo.packageName 4972 : app.info.packageName); 4973 if (app.instrumentationClass != null) { 4974 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4975 } 4976 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4977 + processName + " with config " + mConfiguration); 4978 ApplicationInfo appInfo = app.instrumentationInfo != null 4979 ? app.instrumentationInfo : app.info; 4980 app.compat = compatibilityInfoForPackageLocked(appInfo); 4981 if (profileFd != null) { 4982 profileFd = profileFd.dup(); 4983 } 4984 thread.bindApplication(processName, appInfo, providers, 4985 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4986 app.instrumentationArguments, app.instrumentationWatcher, 4987 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4988 isRestrictedBackupMode || !normalMode, app.persistent, 4989 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4990 mCoreSettingsObserver.getCoreSettingsLocked()); 4991 updateLruProcessLocked(app, false, null); 4992 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4993 } catch (Exception e) { 4994 // todo: Yikes! What should we do? For now we will try to 4995 // start another process, but that could easily get us in 4996 // an infinite loop of restarting processes... 4997 Slog.w(TAG, "Exception thrown during bind!", e); 4998 4999 app.resetPackageList(mProcessStats); 5000 app.unlinkDeathRecipient(); 5001 startProcessLocked(app, "bind fail", processName); 5002 return false; 5003 } 5004 5005 // Remove this record from the list of starting applications. 5006 mPersistentStartingProcesses.remove(app); 5007 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5008 "Attach application locked removing on hold: " + app); 5009 mProcessesOnHold.remove(app); 5010 5011 boolean badApp = false; 5012 boolean didSomething = false; 5013 5014 // See if the top visible activity is waiting to run in this process... 5015 if (normalMode) { 5016 try { 5017 if (mStackSupervisor.attachApplicationLocked(app)) { 5018 didSomething = true; 5019 } 5020 } catch (Exception e) { 5021 badApp = true; 5022 } 5023 } 5024 5025 // Find any services that should be running in this process... 5026 if (!badApp) { 5027 try { 5028 didSomething |= mServices.attachApplicationLocked(app, processName); 5029 } catch (Exception e) { 5030 badApp = true; 5031 } 5032 } 5033 5034 // Check if a next-broadcast receiver is in this process... 5035 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5036 try { 5037 didSomething |= sendPendingBroadcastsLocked(app); 5038 } catch (Exception e) { 5039 // If the app died trying to launch the receiver we declare it 'bad' 5040 badApp = true; 5041 } 5042 } 5043 5044 // Check whether the next backup agent is in this process... 5045 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5046 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5047 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5048 try { 5049 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5050 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5051 mBackupTarget.backupMode); 5052 } catch (Exception e) { 5053 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5054 e.printStackTrace(); 5055 } 5056 } 5057 5058 if (badApp) { 5059 // todo: Also need to kill application to deal with all 5060 // kinds of exceptions. 5061 handleAppDiedLocked(app, false, true); 5062 return false; 5063 } 5064 5065 if (!didSomething) { 5066 updateOomAdjLocked(); 5067 } 5068 5069 return true; 5070 } 5071 5072 @Override 5073 public final void attachApplication(IApplicationThread thread) { 5074 synchronized (this) { 5075 int callingPid = Binder.getCallingPid(); 5076 final long origId = Binder.clearCallingIdentity(); 5077 attachApplicationLocked(thread, callingPid); 5078 Binder.restoreCallingIdentity(origId); 5079 } 5080 } 5081 5082 @Override 5083 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5084 final long origId = Binder.clearCallingIdentity(); 5085 synchronized (this) { 5086 ActivityStack stack = ActivityRecord.getStackLocked(token); 5087 if (stack != null) { 5088 ActivityRecord r = 5089 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5090 if (stopProfiling) { 5091 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5092 try { 5093 mProfileFd.close(); 5094 } catch (IOException e) { 5095 } 5096 clearProfilerLocked(); 5097 } 5098 } 5099 } 5100 } 5101 Binder.restoreCallingIdentity(origId); 5102 } 5103 5104 void enableScreenAfterBoot() { 5105 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5106 SystemClock.uptimeMillis()); 5107 mWindowManager.enableScreenAfterBoot(); 5108 5109 synchronized (this) { 5110 updateEventDispatchingLocked(); 5111 } 5112 } 5113 5114 @Override 5115 public void showBootMessage(final CharSequence msg, final boolean always) { 5116 enforceNotIsolatedCaller("showBootMessage"); 5117 mWindowManager.showBootMessage(msg, always); 5118 } 5119 5120 @Override 5121 public void dismissKeyguardOnNextActivity() { 5122 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5123 final long token = Binder.clearCallingIdentity(); 5124 try { 5125 synchronized (this) { 5126 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5127 if (mLockScreenShown) { 5128 mLockScreenShown = false; 5129 comeOutOfSleepIfNeededLocked(); 5130 } 5131 mStackSupervisor.setDismissKeyguard(true); 5132 } 5133 } finally { 5134 Binder.restoreCallingIdentity(token); 5135 } 5136 } 5137 5138 final void finishBooting() { 5139 IntentFilter pkgFilter = new IntentFilter(); 5140 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5141 pkgFilter.addDataScheme("package"); 5142 mContext.registerReceiver(new BroadcastReceiver() { 5143 @Override 5144 public void onReceive(Context context, Intent intent) { 5145 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5146 if (pkgs != null) { 5147 for (String pkg : pkgs) { 5148 synchronized (ActivityManagerService.this) { 5149 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5150 "finished booting")) { 5151 setResultCode(Activity.RESULT_OK); 5152 return; 5153 } 5154 } 5155 } 5156 } 5157 } 5158 }, pkgFilter); 5159 5160 synchronized (this) { 5161 // Ensure that any processes we had put on hold are now started 5162 // up. 5163 final int NP = mProcessesOnHold.size(); 5164 if (NP > 0) { 5165 ArrayList<ProcessRecord> procs = 5166 new ArrayList<ProcessRecord>(mProcessesOnHold); 5167 for (int ip=0; ip<NP; ip++) { 5168 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5169 + procs.get(ip)); 5170 startProcessLocked(procs.get(ip), "on-hold", null); 5171 } 5172 } 5173 5174 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5175 // Start looking for apps that are abusing wake locks. 5176 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5177 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5178 // Tell anyone interested that we are done booting! 5179 SystemProperties.set("sys.boot_completed", "1"); 5180 SystemProperties.set("dev.bootcomplete", "1"); 5181 for (int i=0; i<mStartedUsers.size(); i++) { 5182 UserStartedState uss = mStartedUsers.valueAt(i); 5183 if (uss.mState == UserStartedState.STATE_BOOTING) { 5184 uss.mState = UserStartedState.STATE_RUNNING; 5185 final int userId = mStartedUsers.keyAt(i); 5186 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5187 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5188 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5189 broadcastIntentLocked(null, null, intent, null, 5190 new IIntentReceiver.Stub() { 5191 @Override 5192 public void performReceive(Intent intent, int resultCode, 5193 String data, Bundle extras, boolean ordered, 5194 boolean sticky, int sendingUser) { 5195 synchronized (ActivityManagerService.this) { 5196 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5197 true, false); 5198 } 5199 } 5200 }, 5201 0, null, null, 5202 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5203 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5204 userId); 5205 } 5206 } 5207 scheduleStartRelatedUsersLocked(); 5208 } 5209 } 5210 } 5211 5212 final void ensureBootCompleted() { 5213 boolean booting; 5214 boolean enableScreen; 5215 synchronized (this) { 5216 booting = mBooting; 5217 mBooting = false; 5218 enableScreen = !mBooted; 5219 mBooted = true; 5220 } 5221 5222 if (booting) { 5223 finishBooting(); 5224 } 5225 5226 if (enableScreen) { 5227 enableScreenAfterBoot(); 5228 } 5229 } 5230 5231 @Override 5232 public final void activityResumed(IBinder token) { 5233 final long origId = Binder.clearCallingIdentity(); 5234 synchronized(this) { 5235 ActivityStack stack = ActivityRecord.getStackLocked(token); 5236 if (stack != null) { 5237 ActivityRecord.activityResumedLocked(token); 5238 } 5239 } 5240 Binder.restoreCallingIdentity(origId); 5241 } 5242 5243 @Override 5244 public final void activityPaused(IBinder token) { 5245 final long origId = Binder.clearCallingIdentity(); 5246 synchronized(this) { 5247 ActivityStack stack = ActivityRecord.getStackLocked(token); 5248 if (stack != null) { 5249 stack.activityPausedLocked(token, false); 5250 } 5251 } 5252 Binder.restoreCallingIdentity(origId); 5253 } 5254 5255 @Override 5256 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5257 CharSequence description) { 5258 if (localLOGV) Slog.v( 5259 TAG, "Activity stopped: token=" + token); 5260 5261 // Refuse possible leaked file descriptors 5262 if (icicle != null && icicle.hasFileDescriptors()) { 5263 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5264 } 5265 5266 ActivityRecord r = null; 5267 5268 final long origId = Binder.clearCallingIdentity(); 5269 5270 synchronized (this) { 5271 r = ActivityRecord.isInStackLocked(token); 5272 if (r != null) { 5273 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5274 } 5275 } 5276 5277 if (r != null) { 5278 sendPendingThumbnail(r, null, null, null, false); 5279 } 5280 5281 trimApplications(); 5282 5283 Binder.restoreCallingIdentity(origId); 5284 } 5285 5286 @Override 5287 public final void activityDestroyed(IBinder token) { 5288 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5289 synchronized (this) { 5290 ActivityStack stack = ActivityRecord.getStackLocked(token); 5291 if (stack != null) { 5292 stack.activityDestroyedLocked(token); 5293 } 5294 } 5295 } 5296 5297 @Override 5298 public String getCallingPackage(IBinder token) { 5299 synchronized (this) { 5300 ActivityRecord r = getCallingRecordLocked(token); 5301 return r != null ? r.info.packageName : null; 5302 } 5303 } 5304 5305 @Override 5306 public ComponentName getCallingActivity(IBinder token) { 5307 synchronized (this) { 5308 ActivityRecord r = getCallingRecordLocked(token); 5309 return r != null ? r.intent.getComponent() : null; 5310 } 5311 } 5312 5313 private ActivityRecord getCallingRecordLocked(IBinder token) { 5314 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5315 if (r == null) { 5316 return null; 5317 } 5318 return r.resultTo; 5319 } 5320 5321 @Override 5322 public ComponentName getActivityClassForToken(IBinder token) { 5323 synchronized(this) { 5324 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5325 if (r == null) { 5326 return null; 5327 } 5328 return r.intent.getComponent(); 5329 } 5330 } 5331 5332 @Override 5333 public String getPackageForToken(IBinder token) { 5334 synchronized(this) { 5335 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5336 if (r == null) { 5337 return null; 5338 } 5339 return r.packageName; 5340 } 5341 } 5342 5343 @Override 5344 public IIntentSender getIntentSender(int type, 5345 String packageName, IBinder token, String resultWho, 5346 int requestCode, Intent[] intents, String[] resolvedTypes, 5347 int flags, Bundle options, int userId) { 5348 enforceNotIsolatedCaller("getIntentSender"); 5349 // Refuse possible leaked file descriptors 5350 if (intents != null) { 5351 if (intents.length < 1) { 5352 throw new IllegalArgumentException("Intents array length must be >= 1"); 5353 } 5354 for (int i=0; i<intents.length; i++) { 5355 Intent intent = intents[i]; 5356 if (intent != null) { 5357 if (intent.hasFileDescriptors()) { 5358 throw new IllegalArgumentException("File descriptors passed in Intent"); 5359 } 5360 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5361 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5362 throw new IllegalArgumentException( 5363 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5364 } 5365 intents[i] = new Intent(intent); 5366 } 5367 } 5368 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5369 throw new IllegalArgumentException( 5370 "Intent array length does not match resolvedTypes length"); 5371 } 5372 } 5373 if (options != null) { 5374 if (options.hasFileDescriptors()) { 5375 throw new IllegalArgumentException("File descriptors passed in options"); 5376 } 5377 } 5378 5379 synchronized(this) { 5380 int callingUid = Binder.getCallingUid(); 5381 int origUserId = userId; 5382 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5383 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5384 "getIntentSender", null); 5385 if (origUserId == UserHandle.USER_CURRENT) { 5386 // We don't want to evaluate this until the pending intent is 5387 // actually executed. However, we do want to always do the 5388 // security checking for it above. 5389 userId = UserHandle.USER_CURRENT; 5390 } 5391 try { 5392 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5393 int uid = AppGlobals.getPackageManager() 5394 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5395 if (!UserHandle.isSameApp(callingUid, uid)) { 5396 String msg = "Permission Denial: getIntentSender() from pid=" 5397 + Binder.getCallingPid() 5398 + ", uid=" + Binder.getCallingUid() 5399 + ", (need uid=" + uid + ")" 5400 + " is not allowed to send as package " + packageName; 5401 Slog.w(TAG, msg); 5402 throw new SecurityException(msg); 5403 } 5404 } 5405 5406 return getIntentSenderLocked(type, packageName, callingUid, userId, 5407 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5408 5409 } catch (RemoteException e) { 5410 throw new SecurityException(e); 5411 } 5412 } 5413 } 5414 5415 IIntentSender getIntentSenderLocked(int type, String packageName, 5416 int callingUid, int userId, IBinder token, String resultWho, 5417 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5418 Bundle options) { 5419 if (DEBUG_MU) 5420 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5421 ActivityRecord activity = null; 5422 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5423 activity = ActivityRecord.isInStackLocked(token); 5424 if (activity == null) { 5425 return null; 5426 } 5427 if (activity.finishing) { 5428 return null; 5429 } 5430 } 5431 5432 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5433 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5434 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5435 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5436 |PendingIntent.FLAG_UPDATE_CURRENT); 5437 5438 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5439 type, packageName, activity, resultWho, 5440 requestCode, intents, resolvedTypes, flags, options, userId); 5441 WeakReference<PendingIntentRecord> ref; 5442 ref = mIntentSenderRecords.get(key); 5443 PendingIntentRecord rec = ref != null ? ref.get() : null; 5444 if (rec != null) { 5445 if (!cancelCurrent) { 5446 if (updateCurrent) { 5447 if (rec.key.requestIntent != null) { 5448 rec.key.requestIntent.replaceExtras(intents != null ? 5449 intents[intents.length - 1] : null); 5450 } 5451 if (intents != null) { 5452 intents[intents.length-1] = rec.key.requestIntent; 5453 rec.key.allIntents = intents; 5454 rec.key.allResolvedTypes = resolvedTypes; 5455 } else { 5456 rec.key.allIntents = null; 5457 rec.key.allResolvedTypes = null; 5458 } 5459 } 5460 return rec; 5461 } 5462 rec.canceled = true; 5463 mIntentSenderRecords.remove(key); 5464 } 5465 if (noCreate) { 5466 return rec; 5467 } 5468 rec = new PendingIntentRecord(this, key, callingUid); 5469 mIntentSenderRecords.put(key, rec.ref); 5470 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5471 if (activity.pendingResults == null) { 5472 activity.pendingResults 5473 = new HashSet<WeakReference<PendingIntentRecord>>(); 5474 } 5475 activity.pendingResults.add(rec.ref); 5476 } 5477 return rec; 5478 } 5479 5480 @Override 5481 public void cancelIntentSender(IIntentSender sender) { 5482 if (!(sender instanceof PendingIntentRecord)) { 5483 return; 5484 } 5485 synchronized(this) { 5486 PendingIntentRecord rec = (PendingIntentRecord)sender; 5487 try { 5488 int uid = AppGlobals.getPackageManager() 5489 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5490 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5491 String msg = "Permission Denial: cancelIntentSender() from pid=" 5492 + Binder.getCallingPid() 5493 + ", uid=" + Binder.getCallingUid() 5494 + " is not allowed to cancel packges " 5495 + rec.key.packageName; 5496 Slog.w(TAG, msg); 5497 throw new SecurityException(msg); 5498 } 5499 } catch (RemoteException e) { 5500 throw new SecurityException(e); 5501 } 5502 cancelIntentSenderLocked(rec, true); 5503 } 5504 } 5505 5506 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5507 rec.canceled = true; 5508 mIntentSenderRecords.remove(rec.key); 5509 if (cleanActivity && rec.key.activity != null) { 5510 rec.key.activity.pendingResults.remove(rec.ref); 5511 } 5512 } 5513 5514 @Override 5515 public String getPackageForIntentSender(IIntentSender pendingResult) { 5516 if (!(pendingResult instanceof PendingIntentRecord)) { 5517 return null; 5518 } 5519 try { 5520 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5521 return res.key.packageName; 5522 } catch (ClassCastException e) { 5523 } 5524 return null; 5525 } 5526 5527 @Override 5528 public int getUidForIntentSender(IIntentSender sender) { 5529 if (sender instanceof PendingIntentRecord) { 5530 try { 5531 PendingIntentRecord res = (PendingIntentRecord)sender; 5532 return res.uid; 5533 } catch (ClassCastException e) { 5534 } 5535 } 5536 return -1; 5537 } 5538 5539 @Override 5540 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5541 if (!(pendingResult instanceof PendingIntentRecord)) { 5542 return false; 5543 } 5544 try { 5545 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5546 if (res.key.allIntents == null) { 5547 return false; 5548 } 5549 for (int i=0; i<res.key.allIntents.length; i++) { 5550 Intent intent = res.key.allIntents[i]; 5551 if (intent.getPackage() != null && intent.getComponent() != null) { 5552 return false; 5553 } 5554 } 5555 return true; 5556 } catch (ClassCastException e) { 5557 } 5558 return false; 5559 } 5560 5561 @Override 5562 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5563 if (!(pendingResult instanceof PendingIntentRecord)) { 5564 return false; 5565 } 5566 try { 5567 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5568 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5569 return true; 5570 } 5571 return false; 5572 } catch (ClassCastException e) { 5573 } 5574 return false; 5575 } 5576 5577 @Override 5578 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5579 if (!(pendingResult instanceof PendingIntentRecord)) { 5580 return null; 5581 } 5582 try { 5583 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5584 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5585 } catch (ClassCastException e) { 5586 } 5587 return null; 5588 } 5589 5590 @Override 5591 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5592 if (!(pendingResult instanceof PendingIntentRecord)) { 5593 return null; 5594 } 5595 try { 5596 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5597 Intent intent = res.key.requestIntent; 5598 if (intent != null) { 5599 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5600 || res.lastTagPrefix.equals(prefix))) { 5601 return res.lastTag; 5602 } 5603 res.lastTagPrefix = prefix; 5604 StringBuilder sb = new StringBuilder(128); 5605 if (prefix != null) { 5606 sb.append(prefix); 5607 } 5608 if (intent.getAction() != null) { 5609 sb.append(intent.getAction()); 5610 } else if (intent.getComponent() != null) { 5611 intent.getComponent().appendShortString(sb); 5612 } else { 5613 sb.append("?"); 5614 } 5615 return res.lastTag = sb.toString(); 5616 } 5617 } catch (ClassCastException e) { 5618 } 5619 return null; 5620 } 5621 5622 @Override 5623 public void setProcessLimit(int max) { 5624 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5625 "setProcessLimit()"); 5626 synchronized (this) { 5627 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5628 mProcessLimitOverride = max; 5629 } 5630 trimApplications(); 5631 } 5632 5633 @Override 5634 public int getProcessLimit() { 5635 synchronized (this) { 5636 return mProcessLimitOverride; 5637 } 5638 } 5639 5640 void foregroundTokenDied(ForegroundToken token) { 5641 synchronized (ActivityManagerService.this) { 5642 synchronized (mPidsSelfLocked) { 5643 ForegroundToken cur 5644 = mForegroundProcesses.get(token.pid); 5645 if (cur != token) { 5646 return; 5647 } 5648 mForegroundProcesses.remove(token.pid); 5649 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5650 if (pr == null) { 5651 return; 5652 } 5653 pr.forcingToForeground = null; 5654 updateProcessForegroundLocked(pr, false, false); 5655 } 5656 updateOomAdjLocked(); 5657 } 5658 } 5659 5660 @Override 5661 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5662 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5663 "setProcessForeground()"); 5664 synchronized(this) { 5665 boolean changed = false; 5666 5667 synchronized (mPidsSelfLocked) { 5668 ProcessRecord pr = mPidsSelfLocked.get(pid); 5669 if (pr == null && isForeground) { 5670 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5671 return; 5672 } 5673 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5674 if (oldToken != null) { 5675 oldToken.token.unlinkToDeath(oldToken, 0); 5676 mForegroundProcesses.remove(pid); 5677 if (pr != null) { 5678 pr.forcingToForeground = null; 5679 } 5680 changed = true; 5681 } 5682 if (isForeground && token != null) { 5683 ForegroundToken newToken = new ForegroundToken() { 5684 @Override 5685 public void binderDied() { 5686 foregroundTokenDied(this); 5687 } 5688 }; 5689 newToken.pid = pid; 5690 newToken.token = token; 5691 try { 5692 token.linkToDeath(newToken, 0); 5693 mForegroundProcesses.put(pid, newToken); 5694 pr.forcingToForeground = token; 5695 changed = true; 5696 } catch (RemoteException e) { 5697 // If the process died while doing this, we will later 5698 // do the cleanup with the process death link. 5699 } 5700 } 5701 } 5702 5703 if (changed) { 5704 updateOomAdjLocked(); 5705 } 5706 } 5707 } 5708 5709 // ========================================================= 5710 // PERMISSIONS 5711 // ========================================================= 5712 5713 static class PermissionController extends IPermissionController.Stub { 5714 ActivityManagerService mActivityManagerService; 5715 PermissionController(ActivityManagerService activityManagerService) { 5716 mActivityManagerService = activityManagerService; 5717 } 5718 5719 @Override 5720 public boolean checkPermission(String permission, int pid, int uid) { 5721 return mActivityManagerService.checkPermission(permission, pid, 5722 uid) == PackageManager.PERMISSION_GRANTED; 5723 } 5724 } 5725 5726 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5727 @Override 5728 public int checkComponentPermission(String permission, int pid, int uid, 5729 int owningUid, boolean exported) { 5730 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5731 owningUid, exported); 5732 } 5733 5734 @Override 5735 public Object getAMSLock() { 5736 return ActivityManagerService.this; 5737 } 5738 } 5739 5740 /** 5741 * This can be called with or without the global lock held. 5742 */ 5743 int checkComponentPermission(String permission, int pid, int uid, 5744 int owningUid, boolean exported) { 5745 // We might be performing an operation on behalf of an indirect binder 5746 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5747 // client identity accordingly before proceeding. 5748 Identity tlsIdentity = sCallerIdentity.get(); 5749 if (tlsIdentity != null) { 5750 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5751 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5752 uid = tlsIdentity.uid; 5753 pid = tlsIdentity.pid; 5754 } 5755 5756 if (pid == MY_PID) { 5757 return PackageManager.PERMISSION_GRANTED; 5758 } 5759 5760 return ActivityManager.checkComponentPermission(permission, uid, 5761 owningUid, exported); 5762 } 5763 5764 /** 5765 * As the only public entry point for permissions checking, this method 5766 * can enforce the semantic that requesting a check on a null global 5767 * permission is automatically denied. (Internally a null permission 5768 * string is used when calling {@link #checkComponentPermission} in cases 5769 * when only uid-based security is needed.) 5770 * 5771 * This can be called with or without the global lock held. 5772 */ 5773 @Override 5774 public int checkPermission(String permission, int pid, int uid) { 5775 if (permission == null) { 5776 return PackageManager.PERMISSION_DENIED; 5777 } 5778 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5779 } 5780 5781 /** 5782 * Binder IPC calls go through the public entry point. 5783 * This can be called with or without the global lock held. 5784 */ 5785 int checkCallingPermission(String permission) { 5786 return checkPermission(permission, 5787 Binder.getCallingPid(), 5788 UserHandle.getAppId(Binder.getCallingUid())); 5789 } 5790 5791 /** 5792 * This can be called with or without the global lock held. 5793 */ 5794 void enforceCallingPermission(String permission, String func) { 5795 if (checkCallingPermission(permission) 5796 == PackageManager.PERMISSION_GRANTED) { 5797 return; 5798 } 5799 5800 String msg = "Permission Denial: " + func + " from pid=" 5801 + Binder.getCallingPid() 5802 + ", uid=" + Binder.getCallingUid() 5803 + " requires " + permission; 5804 Slog.w(TAG, msg); 5805 throw new SecurityException(msg); 5806 } 5807 5808 /** 5809 * Determine if UID is holding permissions required to access {@link Uri} in 5810 * the given {@link ProviderInfo}. Final permission checking is always done 5811 * in {@link ContentProvider}. 5812 */ 5813 private final boolean checkHoldingPermissionsLocked( 5814 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5815 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5816 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5817 5818 if (pi.applicationInfo.uid == uid) { 5819 return true; 5820 } else if (!pi.exported) { 5821 return false; 5822 } 5823 5824 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5825 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5826 try { 5827 // check if target holds top-level <provider> permissions 5828 if (!readMet && pi.readPermission != null 5829 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5830 readMet = true; 5831 } 5832 if (!writeMet && pi.writePermission != null 5833 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5834 writeMet = true; 5835 } 5836 5837 // track if unprotected read/write is allowed; any denied 5838 // <path-permission> below removes this ability 5839 boolean allowDefaultRead = pi.readPermission == null; 5840 boolean allowDefaultWrite = pi.writePermission == null; 5841 5842 // check if target holds any <path-permission> that match uri 5843 final PathPermission[] pps = pi.pathPermissions; 5844 if (pps != null) { 5845 final String path = uri.getPath(); 5846 int i = pps.length; 5847 while (i > 0 && (!readMet || !writeMet)) { 5848 i--; 5849 PathPermission pp = pps[i]; 5850 if (pp.match(path)) { 5851 if (!readMet) { 5852 final String pprperm = pp.getReadPermission(); 5853 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5854 + pprperm + " for " + pp.getPath() 5855 + ": match=" + pp.match(path) 5856 + " check=" + pm.checkUidPermission(pprperm, uid)); 5857 if (pprperm != null) { 5858 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5859 readMet = true; 5860 } else { 5861 allowDefaultRead = false; 5862 } 5863 } 5864 } 5865 if (!writeMet) { 5866 final String ppwperm = pp.getWritePermission(); 5867 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5868 + ppwperm + " for " + pp.getPath() 5869 + ": match=" + pp.match(path) 5870 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5871 if (ppwperm != null) { 5872 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5873 writeMet = true; 5874 } else { 5875 allowDefaultWrite = false; 5876 } 5877 } 5878 } 5879 } 5880 } 5881 } 5882 5883 // grant unprotected <provider> read/write, if not blocked by 5884 // <path-permission> above 5885 if (allowDefaultRead) readMet = true; 5886 if (allowDefaultWrite) writeMet = true; 5887 5888 } catch (RemoteException e) { 5889 return false; 5890 } 5891 5892 return readMet && writeMet; 5893 } 5894 5895 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5896 ProviderInfo pi = null; 5897 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5898 if (cpr != null) { 5899 pi = cpr.info; 5900 } else { 5901 try { 5902 pi = AppGlobals.getPackageManager().resolveContentProvider( 5903 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5904 } catch (RemoteException ex) { 5905 } 5906 } 5907 return pi; 5908 } 5909 5910 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5911 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5912 if (targetUris != null) { 5913 return targetUris.get(uri); 5914 } else { 5915 return null; 5916 } 5917 } 5918 5919 private UriPermission findOrCreateUriPermissionLocked( 5920 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5921 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5922 if (targetUris == null) { 5923 targetUris = Maps.newArrayMap(); 5924 mGrantedUriPermissions.put(targetUid, targetUris); 5925 } 5926 5927 UriPermission perm = targetUris.get(uri); 5928 if (perm == null) { 5929 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5930 targetUris.put(uri, perm); 5931 } 5932 5933 return perm; 5934 } 5935 5936 private final boolean checkUriPermissionLocked( 5937 Uri uri, int uid, int modeFlags, int minStrength) { 5938 // Root gets to do everything. 5939 if (uid == 0) { 5940 return true; 5941 } 5942 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5943 if (perms == null) return false; 5944 UriPermission perm = perms.get(uri); 5945 if (perm == null) return false; 5946 return perm.getStrength(modeFlags) >= minStrength; 5947 } 5948 5949 @Override 5950 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5951 enforceNotIsolatedCaller("checkUriPermission"); 5952 5953 // Another redirected-binder-call permissions check as in 5954 // {@link checkComponentPermission}. 5955 Identity tlsIdentity = sCallerIdentity.get(); 5956 if (tlsIdentity != null) { 5957 uid = tlsIdentity.uid; 5958 pid = tlsIdentity.pid; 5959 } 5960 5961 // Our own process gets to do everything. 5962 if (pid == MY_PID) { 5963 return PackageManager.PERMISSION_GRANTED; 5964 } 5965 synchronized(this) { 5966 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5967 ? PackageManager.PERMISSION_GRANTED 5968 : PackageManager.PERMISSION_DENIED; 5969 } 5970 } 5971 5972 /** 5973 * Check if the targetPkg can be granted permission to access uri by 5974 * the callingUid using the given modeFlags. Throws a security exception 5975 * if callingUid is not allowed to do this. Returns the uid of the target 5976 * if the URI permission grant should be performed; returns -1 if it is not 5977 * needed (for example targetPkg already has permission to access the URI). 5978 * If you already know the uid of the target, you can supply it in 5979 * lastTargetUid else set that to -1. 5980 */ 5981 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5982 Uri uri, int modeFlags, int lastTargetUid) { 5983 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5984 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5985 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5986 if (modeFlags == 0) { 5987 return -1; 5988 } 5989 5990 if (targetPkg != null) { 5991 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5992 "Checking grant " + targetPkg + " permission to " + uri); 5993 } 5994 5995 final IPackageManager pm = AppGlobals.getPackageManager(); 5996 5997 // If this is not a content: uri, we can't do anything with it. 5998 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5999 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6000 "Can't grant URI permission for non-content URI: " + uri); 6001 return -1; 6002 } 6003 6004 final String authority = uri.getAuthority(); 6005 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6006 if (pi == null) { 6007 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6008 return -1; 6009 } 6010 6011 int targetUid = lastTargetUid; 6012 if (targetUid < 0 && targetPkg != null) { 6013 try { 6014 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6015 if (targetUid < 0) { 6016 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6017 "Can't grant URI permission no uid for: " + targetPkg); 6018 return -1; 6019 } 6020 } catch (RemoteException ex) { 6021 return -1; 6022 } 6023 } 6024 6025 if (targetUid >= 0) { 6026 // First... does the target actually need this permission? 6027 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6028 // No need to grant the target this permission. 6029 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6030 "Target " + targetPkg + " already has full permission to " + uri); 6031 return -1; 6032 } 6033 } else { 6034 // First... there is no target package, so can anyone access it? 6035 boolean allowed = pi.exported; 6036 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6037 if (pi.readPermission != null) { 6038 allowed = false; 6039 } 6040 } 6041 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6042 if (pi.writePermission != null) { 6043 allowed = false; 6044 } 6045 } 6046 if (allowed) { 6047 return -1; 6048 } 6049 } 6050 6051 // Second... is the provider allowing granting of URI permissions? 6052 if (!pi.grantUriPermissions) { 6053 throw new SecurityException("Provider " + pi.packageName 6054 + "/" + pi.name 6055 + " does not allow granting of Uri permissions (uri " 6056 + uri + ")"); 6057 } 6058 if (pi.uriPermissionPatterns != null) { 6059 final int N = pi.uriPermissionPatterns.length; 6060 boolean allowed = false; 6061 for (int i=0; i<N; i++) { 6062 if (pi.uriPermissionPatterns[i] != null 6063 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6064 allowed = true; 6065 break; 6066 } 6067 } 6068 if (!allowed) { 6069 throw new SecurityException("Provider " + pi.packageName 6070 + "/" + pi.name 6071 + " does not allow granting of permission to path of Uri " 6072 + uri); 6073 } 6074 } 6075 6076 // Third... does the caller itself have permission to access 6077 // this uri? 6078 if (callingUid != Process.myUid()) { 6079 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6080 // Require they hold a strong enough Uri permission 6081 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6082 : UriPermission.STRENGTH_OWNED; 6083 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6084 throw new SecurityException("Uid " + callingUid 6085 + " does not have permission to uri " + uri); 6086 } 6087 } 6088 } 6089 6090 return targetUid; 6091 } 6092 6093 @Override 6094 public int checkGrantUriPermission(int callingUid, String targetPkg, 6095 Uri uri, int modeFlags) { 6096 enforceNotIsolatedCaller("checkGrantUriPermission"); 6097 synchronized(this) { 6098 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6099 } 6100 } 6101 6102 void grantUriPermissionUncheckedLocked( 6103 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6104 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6105 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6106 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6107 if (modeFlags == 0) { 6108 return; 6109 } 6110 6111 // So here we are: the caller has the assumed permission 6112 // to the uri, and the target doesn't. Let's now give this to 6113 // the target. 6114 6115 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6116 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6117 6118 final String authority = uri.getAuthority(); 6119 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6120 if (pi == null) { 6121 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6122 return; 6123 } 6124 6125 final UriPermission perm = findOrCreateUriPermissionLocked( 6126 pi.packageName, targetPkg, targetUid, uri); 6127 perm.grantModes(modeFlags, persistable, owner); 6128 } 6129 6130 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6131 int modeFlags, UriPermissionOwner owner) { 6132 if (targetPkg == null) { 6133 throw new NullPointerException("targetPkg"); 6134 } 6135 6136 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6137 if (targetUid < 0) { 6138 return; 6139 } 6140 6141 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6142 } 6143 6144 static class NeededUriGrants extends ArrayList<Uri> { 6145 final String targetPkg; 6146 final int targetUid; 6147 final int flags; 6148 6149 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6150 this.targetPkg = targetPkg; 6151 this.targetUid = targetUid; 6152 this.flags = flags; 6153 } 6154 } 6155 6156 /** 6157 * Like checkGrantUriPermissionLocked, but takes an Intent. 6158 */ 6159 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6160 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6161 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6162 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6163 + " clip=" + (intent != null ? intent.getClipData() : null) 6164 + " from " + intent + "; flags=0x" 6165 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6166 6167 if (targetPkg == null) { 6168 throw new NullPointerException("targetPkg"); 6169 } 6170 6171 if (intent == null) { 6172 return null; 6173 } 6174 Uri data = intent.getData(); 6175 ClipData clip = intent.getClipData(); 6176 if (data == null && clip == null) { 6177 return null; 6178 } 6179 6180 if (data != null) { 6181 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6182 mode, needed != null ? needed.targetUid : -1); 6183 if (targetUid > 0) { 6184 if (needed == null) { 6185 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6186 } 6187 needed.add(data); 6188 } 6189 } 6190 if (clip != null) { 6191 for (int i=0; i<clip.getItemCount(); i++) { 6192 Uri uri = clip.getItemAt(i).getUri(); 6193 if (uri != null) { 6194 int targetUid = -1; 6195 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6196 mode, needed != null ? needed.targetUid : -1); 6197 if (targetUid > 0) { 6198 if (needed == null) { 6199 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6200 } 6201 needed.add(uri); 6202 } 6203 } else { 6204 Intent clipIntent = clip.getItemAt(i).getIntent(); 6205 if (clipIntent != null) { 6206 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6207 callingUid, targetPkg, clipIntent, mode, needed); 6208 if (newNeeded != null) { 6209 needed = newNeeded; 6210 } 6211 } 6212 } 6213 } 6214 } 6215 6216 return needed; 6217 } 6218 6219 /** 6220 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6221 */ 6222 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6223 UriPermissionOwner owner) { 6224 if (needed != null) { 6225 for (int i=0; i<needed.size(); i++) { 6226 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6227 needed.get(i), needed.flags, owner); 6228 } 6229 } 6230 } 6231 6232 void grantUriPermissionFromIntentLocked(int callingUid, 6233 String targetPkg, Intent intent, UriPermissionOwner owner) { 6234 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6235 intent, intent != null ? intent.getFlags() : 0, null); 6236 if (needed == null) { 6237 return; 6238 } 6239 6240 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6241 } 6242 6243 @Override 6244 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6245 Uri uri, int modeFlags) { 6246 enforceNotIsolatedCaller("grantUriPermission"); 6247 synchronized(this) { 6248 final ProcessRecord r = getRecordForAppLocked(caller); 6249 if (r == null) { 6250 throw new SecurityException("Unable to find app for caller " 6251 + caller 6252 + " when granting permission to uri " + uri); 6253 } 6254 if (targetPkg == null) { 6255 throw new IllegalArgumentException("null target"); 6256 } 6257 if (uri == null) { 6258 throw new IllegalArgumentException("null uri"); 6259 } 6260 6261 // Persistable only supported through Intents 6262 Preconditions.checkFlagsArgument(modeFlags, 6263 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6264 6265 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6266 null); 6267 } 6268 } 6269 6270 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6271 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6272 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6273 ArrayMap<Uri, UriPermission> perms 6274 = mGrantedUriPermissions.get(perm.targetUid); 6275 if (perms != null) { 6276 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6277 "Removing " + perm.targetUid + " permission to " + perm.uri); 6278 perms.remove(perm.uri); 6279 if (perms.size() == 0) { 6280 mGrantedUriPermissions.remove(perm.targetUid); 6281 } 6282 } 6283 } 6284 } 6285 6286 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6287 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6288 6289 final IPackageManager pm = AppGlobals.getPackageManager(); 6290 final String authority = uri.getAuthority(); 6291 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6292 if (pi == null) { 6293 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6294 return; 6295 } 6296 6297 // Does the caller have this permission on the URI? 6298 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6299 // Right now, if you are not the original owner of the permission, 6300 // you are not allowed to revoke it. 6301 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6302 throw new SecurityException("Uid " + callingUid 6303 + " does not have permission to uri " + uri); 6304 //} 6305 } 6306 6307 boolean persistChanged = false; 6308 6309 // Go through all of the permissions and remove any that match. 6310 final List<String> SEGMENTS = uri.getPathSegments(); 6311 if (SEGMENTS != null) { 6312 final int NS = SEGMENTS.size(); 6313 int N = mGrantedUriPermissions.size(); 6314 for (int i=0; i<N; i++) { 6315 ArrayMap<Uri, UriPermission> perms 6316 = mGrantedUriPermissions.valueAt(i); 6317 Iterator<UriPermission> it = perms.values().iterator(); 6318 toploop: 6319 while (it.hasNext()) { 6320 UriPermission perm = it.next(); 6321 Uri targetUri = perm.uri; 6322 if (!authority.equals(targetUri.getAuthority())) { 6323 continue; 6324 } 6325 List<String> targetSegments = targetUri.getPathSegments(); 6326 if (targetSegments == null) { 6327 continue; 6328 } 6329 if (targetSegments.size() < NS) { 6330 continue; 6331 } 6332 for (int j=0; j<NS; j++) { 6333 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6334 continue toploop; 6335 } 6336 } 6337 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6338 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6339 persistChanged |= perm.clearModes(modeFlags, true); 6340 if (perm.modeFlags == 0) { 6341 it.remove(); 6342 } 6343 } 6344 if (perms.size() == 0) { 6345 mGrantedUriPermissions.remove( 6346 mGrantedUriPermissions.keyAt(i)); 6347 N--; 6348 i--; 6349 } 6350 } 6351 } 6352 6353 if (persistChanged) { 6354 schedulePersistUriGrants(); 6355 } 6356 } 6357 6358 @Override 6359 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6360 int modeFlags) { 6361 enforceNotIsolatedCaller("revokeUriPermission"); 6362 synchronized(this) { 6363 final ProcessRecord r = getRecordForAppLocked(caller); 6364 if (r == null) { 6365 throw new SecurityException("Unable to find app for caller " 6366 + caller 6367 + " when revoking permission to uri " + uri); 6368 } 6369 if (uri == null) { 6370 Slog.w(TAG, "revokeUriPermission: null uri"); 6371 return; 6372 } 6373 6374 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6375 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6376 if (modeFlags == 0) { 6377 return; 6378 } 6379 6380 final IPackageManager pm = AppGlobals.getPackageManager(); 6381 final String authority = uri.getAuthority(); 6382 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6383 if (pi == null) { 6384 Slog.w(TAG, "No content provider found for permission revoke: " 6385 + uri.toSafeString()); 6386 return; 6387 } 6388 6389 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6390 } 6391 } 6392 6393 /** 6394 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6395 * given package. 6396 * 6397 * @param packageName Package name to match, or {@code null} to apply to all 6398 * packages. 6399 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6400 * to all users. 6401 * @param persistable If persistable grants should be removed. 6402 */ 6403 private void removeUriPermissionsForPackageLocked( 6404 String packageName, int userHandle, boolean persistable) { 6405 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6406 throw new IllegalArgumentException("Must narrow by either package or user"); 6407 } 6408 6409 boolean persistChanged = false; 6410 6411 final int size = mGrantedUriPermissions.size(); 6412 for (int i = 0; i < size; i++) { 6413 // Only inspect grants matching user 6414 if (userHandle == UserHandle.USER_ALL 6415 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6416 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6417 .values().iterator(); 6418 while (it.hasNext()) { 6419 final UriPermission perm = it.next(); 6420 6421 // Only inspect grants matching package 6422 if (packageName == null || perm.sourcePkg.equals(packageName) 6423 || perm.targetPkg.equals(packageName)) { 6424 persistChanged |= perm.clearModes(~0, persistable); 6425 6426 // Only remove when no modes remain; any persisted grants 6427 // will keep this alive. 6428 if (perm.modeFlags == 0) { 6429 it.remove(); 6430 } 6431 } 6432 } 6433 } 6434 } 6435 6436 if (persistChanged) { 6437 schedulePersistUriGrants(); 6438 } 6439 } 6440 6441 @Override 6442 public IBinder newUriPermissionOwner(String name) { 6443 enforceNotIsolatedCaller("newUriPermissionOwner"); 6444 synchronized(this) { 6445 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6446 return owner.getExternalTokenLocked(); 6447 } 6448 } 6449 6450 @Override 6451 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6452 Uri uri, int modeFlags) { 6453 synchronized(this) { 6454 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6455 if (owner == null) { 6456 throw new IllegalArgumentException("Unknown owner: " + token); 6457 } 6458 if (fromUid != Binder.getCallingUid()) { 6459 if (Binder.getCallingUid() != Process.myUid()) { 6460 // Only system code can grant URI permissions on behalf 6461 // of other users. 6462 throw new SecurityException("nice try"); 6463 } 6464 } 6465 if (targetPkg == null) { 6466 throw new IllegalArgumentException("null target"); 6467 } 6468 if (uri == null) { 6469 throw new IllegalArgumentException("null uri"); 6470 } 6471 6472 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6473 } 6474 } 6475 6476 @Override 6477 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6478 synchronized(this) { 6479 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6480 if (owner == null) { 6481 throw new IllegalArgumentException("Unknown owner: " + token); 6482 } 6483 6484 if (uri == null) { 6485 owner.removeUriPermissionsLocked(mode); 6486 } else { 6487 owner.removeUriPermissionLocked(uri, mode); 6488 } 6489 } 6490 } 6491 6492 private void schedulePersistUriGrants() { 6493 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6494 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6495 10 * DateUtils.SECOND_IN_MILLIS); 6496 } 6497 } 6498 6499 private void writeGrantedUriPermissions() { 6500 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6501 6502 // Snapshot permissions so we can persist without lock 6503 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6504 synchronized (this) { 6505 final int size = mGrantedUriPermissions.size(); 6506 for (int i = 0 ; i < size; i++) { 6507 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6508 if (perm.persistedModeFlags != 0) { 6509 persist.add(perm.snapshot()); 6510 } 6511 } 6512 } 6513 } 6514 6515 FileOutputStream fos = null; 6516 try { 6517 fos = mGrantFile.startWrite(); 6518 6519 XmlSerializer out = new FastXmlSerializer(); 6520 out.setOutput(fos, "utf-8"); 6521 out.startDocument(null, true); 6522 out.startTag(null, TAG_URI_GRANTS); 6523 for (UriPermission.Snapshot perm : persist) { 6524 out.startTag(null, TAG_URI_GRANT); 6525 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6526 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6527 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6528 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6529 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6530 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6531 out.endTag(null, TAG_URI_GRANT); 6532 } 6533 out.endTag(null, TAG_URI_GRANTS); 6534 out.endDocument(); 6535 6536 mGrantFile.finishWrite(fos); 6537 } catch (IOException e) { 6538 if (fos != null) { 6539 mGrantFile.failWrite(fos); 6540 } 6541 } 6542 } 6543 6544 private void readGrantedUriPermissionsLocked() { 6545 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6546 6547 final long now = System.currentTimeMillis(); 6548 6549 FileInputStream fis = null; 6550 try { 6551 fis = mGrantFile.openRead(); 6552 final XmlPullParser in = Xml.newPullParser(); 6553 in.setInput(fis, null); 6554 6555 int type; 6556 while ((type = in.next()) != END_DOCUMENT) { 6557 final String tag = in.getName(); 6558 if (type == START_TAG) { 6559 if (TAG_URI_GRANT.equals(tag)) { 6560 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6561 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6562 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6563 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6564 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6565 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6566 6567 // Sanity check that provider still belongs to source package 6568 final ProviderInfo pi = getProviderInfoLocked( 6569 uri.getAuthority(), userHandle); 6570 if (pi != null && sourcePkg.equals(pi.packageName)) { 6571 int targetUid = -1; 6572 try { 6573 targetUid = AppGlobals.getPackageManager() 6574 .getPackageUid(targetPkg, userHandle); 6575 } catch (RemoteException e) { 6576 } 6577 if (targetUid != -1) { 6578 final UriPermission perm = findOrCreateUriPermissionLocked( 6579 sourcePkg, targetPkg, targetUid, uri); 6580 perm.initPersistedModes(modeFlags, createdTime); 6581 } 6582 } else { 6583 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6584 + " but instead found " + pi); 6585 } 6586 } 6587 } 6588 } 6589 } catch (FileNotFoundException e) { 6590 // Missing grants is okay 6591 } catch (IOException e) { 6592 Log.wtf(TAG, "Failed reading Uri grants", e); 6593 } catch (XmlPullParserException e) { 6594 Log.wtf(TAG, "Failed reading Uri grants", e); 6595 } finally { 6596 IoUtils.closeQuietly(fis); 6597 } 6598 } 6599 6600 @Override 6601 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6602 enforceNotIsolatedCaller("takePersistableUriPermission"); 6603 6604 Preconditions.checkFlagsArgument(modeFlags, 6605 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6606 6607 synchronized (this) { 6608 final int callingUid = Binder.getCallingUid(); 6609 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6610 if (perm == null) { 6611 throw new SecurityException("No permission grant found for UID " + callingUid 6612 + " and Uri " + uri.toSafeString()); 6613 } 6614 6615 boolean persistChanged = perm.takePersistableModes(modeFlags); 6616 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6617 6618 if (persistChanged) { 6619 schedulePersistUriGrants(); 6620 } 6621 } 6622 } 6623 6624 @Override 6625 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6626 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6627 6628 Preconditions.checkFlagsArgument(modeFlags, 6629 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6630 6631 synchronized (this) { 6632 final int callingUid = Binder.getCallingUid(); 6633 6634 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6635 if (perm == null) { 6636 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6637 + uri.toSafeString()); 6638 return; 6639 } 6640 6641 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6642 removeUriPermissionIfNeededLocked(perm); 6643 if (persistChanged) { 6644 schedulePersistUriGrants(); 6645 } 6646 } 6647 } 6648 6649 /** 6650 * Prune any older {@link UriPermission} for the given UID until outstanding 6651 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6652 * 6653 * @return if any mutations occured that require persisting. 6654 */ 6655 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6656 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6657 if (perms == null) return false; 6658 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6659 6660 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6661 for (UriPermission perm : perms.values()) { 6662 if (perm.persistedModeFlags != 0) { 6663 persisted.add(perm); 6664 } 6665 } 6666 6667 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6668 if (trimCount <= 0) return false; 6669 6670 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6671 for (int i = 0; i < trimCount; i++) { 6672 final UriPermission perm = persisted.get(i); 6673 6674 if (DEBUG_URI_PERMISSION) { 6675 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6676 } 6677 6678 perm.releasePersistableModes(~0); 6679 removeUriPermissionIfNeededLocked(perm); 6680 } 6681 6682 return true; 6683 } 6684 6685 @Override 6686 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6687 String packageName, boolean incoming) { 6688 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6689 Preconditions.checkNotNull(packageName, "packageName"); 6690 6691 final int callingUid = Binder.getCallingUid(); 6692 final IPackageManager pm = AppGlobals.getPackageManager(); 6693 try { 6694 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6695 if (packageUid != callingUid) { 6696 throw new SecurityException( 6697 "Package " + packageName + " does not belong to calling UID " + callingUid); 6698 } 6699 } catch (RemoteException e) { 6700 throw new SecurityException("Failed to verify package name ownership"); 6701 } 6702 6703 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6704 synchronized (this) { 6705 if (incoming) { 6706 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6707 if (perms == null) { 6708 Slog.w(TAG, "No permission grants found for " + packageName); 6709 } else { 6710 final int size = perms.size(); 6711 for (int i = 0; i < size; i++) { 6712 final UriPermission perm = perms.valueAt(i); 6713 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6714 result.add(perm.buildPersistedPublicApiObject()); 6715 } 6716 } 6717 } 6718 } else { 6719 final int size = mGrantedUriPermissions.size(); 6720 for (int i = 0; i < size; i++) { 6721 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6722 final int permsSize = perms.size(); 6723 for (int j = 0; j < permsSize; j++) { 6724 final UriPermission perm = perms.valueAt(j); 6725 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6726 result.add(perm.buildPersistedPublicApiObject()); 6727 } 6728 } 6729 } 6730 } 6731 } 6732 return new ParceledListSlice<android.content.UriPermission>(result); 6733 } 6734 6735 @Override 6736 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6737 synchronized (this) { 6738 ProcessRecord app = 6739 who != null ? getRecordForAppLocked(who) : null; 6740 if (app == null) return; 6741 6742 Message msg = Message.obtain(); 6743 msg.what = WAIT_FOR_DEBUGGER_MSG; 6744 msg.obj = app; 6745 msg.arg1 = waiting ? 1 : 0; 6746 mHandler.sendMessage(msg); 6747 } 6748 } 6749 6750 @Override 6751 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6752 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6753 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6754 outInfo.availMem = Process.getFreeMemory(); 6755 outInfo.totalMem = Process.getTotalMemory(); 6756 outInfo.threshold = homeAppMem; 6757 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6758 outInfo.hiddenAppThreshold = cachedAppMem; 6759 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6760 ProcessList.SERVICE_ADJ); 6761 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6762 ProcessList.VISIBLE_APP_ADJ); 6763 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6764 ProcessList.FOREGROUND_APP_ADJ); 6765 } 6766 6767 // ========================================================= 6768 // TASK MANAGEMENT 6769 // ========================================================= 6770 6771 @Override 6772 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6773 IThumbnailReceiver receiver) { 6774 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6775 6776 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6777 ActivityRecord topRecord = null; 6778 6779 synchronized(this) { 6780 if (localLOGV) Slog.v( 6781 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6782 + ", receiver=" + receiver); 6783 6784 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6785 != PackageManager.PERMISSION_GRANTED) { 6786 if (receiver != null) { 6787 // If the caller wants to wait for pending thumbnails, 6788 // it ain't gonna get them. 6789 try { 6790 receiver.finished(); 6791 } catch (RemoteException ex) { 6792 } 6793 } 6794 String msg = "Permission Denial: getTasks() from pid=" 6795 + Binder.getCallingPid() 6796 + ", uid=" + Binder.getCallingUid() 6797 + " requires " + android.Manifest.permission.GET_TASKS; 6798 Slog.w(TAG, msg); 6799 throw new SecurityException(msg); 6800 } 6801 6802 // TODO: Improve with MRU list from all ActivityStacks. 6803 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6804 6805 if (!pending.pendingRecords.isEmpty()) { 6806 mPendingThumbnails.add(pending); 6807 } 6808 } 6809 6810 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6811 6812 if (topRecord != null) { 6813 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6814 try { 6815 IApplicationThread topThumbnail = topRecord.app.thread; 6816 topThumbnail.requestThumbnail(topRecord.appToken); 6817 } catch (Exception e) { 6818 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6819 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6820 } 6821 } 6822 6823 if (pending == null && receiver != null) { 6824 // In this case all thumbnails were available and the client 6825 // is being asked to be told when the remaining ones come in... 6826 // which is unusually, since the top-most currently running 6827 // activity should never have a canned thumbnail! Oh well. 6828 try { 6829 receiver.finished(); 6830 } catch (RemoteException ex) { 6831 } 6832 } 6833 6834 return list; 6835 } 6836 6837 TaskRecord getMostRecentTask() { 6838 return mRecentTasks.get(0); 6839 } 6840 6841 @Override 6842 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6843 int flags, int userId) { 6844 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6845 false, true, "getRecentTasks", null); 6846 6847 synchronized (this) { 6848 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6849 "getRecentTasks()"); 6850 final boolean detailed = checkCallingPermission( 6851 android.Manifest.permission.GET_DETAILED_TASKS) 6852 == PackageManager.PERMISSION_GRANTED; 6853 6854 IPackageManager pm = AppGlobals.getPackageManager(); 6855 6856 final int N = mRecentTasks.size(); 6857 ArrayList<ActivityManager.RecentTaskInfo> res 6858 = new ArrayList<ActivityManager.RecentTaskInfo>( 6859 maxNum < N ? maxNum : N); 6860 6861 final Set<Integer> includedUsers; 6862 if ((flags & ActivityManager.RECENT_INCLUDE_RELATED) != 0) { 6863 includedUsers = getRelatedUsersLocked(userId); 6864 } else { 6865 includedUsers = new HashSet<Integer>(); 6866 } 6867 includedUsers.add(Integer.valueOf(userId)); 6868 for (int i=0; i<N && maxNum > 0; i++) { 6869 TaskRecord tr = mRecentTasks.get(i); 6870 // Only add calling user or related users recent tasks 6871 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 6872 6873 // Return the entry if desired by the caller. We always return 6874 // the first entry, because callers always expect this to be the 6875 // foreground app. We may filter others if the caller has 6876 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6877 // we should exclude the entry. 6878 6879 if (i == 0 6880 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6881 || (tr.intent == null) 6882 || ((tr.intent.getFlags() 6883 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6884 ActivityManager.RecentTaskInfo rti 6885 = new ActivityManager.RecentTaskInfo(); 6886 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6887 rti.persistentId = tr.taskId; 6888 rti.baseIntent = new Intent( 6889 tr.intent != null ? tr.intent : tr.affinityIntent); 6890 if (!detailed) { 6891 rti.baseIntent.replaceExtras((Bundle)null); 6892 } 6893 rti.origActivity = tr.origActivity; 6894 rti.description = tr.lastDescription; 6895 rti.stackId = tr.stack.mStackId; 6896 rti.userId = tr.userId; 6897 6898 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6899 // Check whether this activity is currently available. 6900 try { 6901 if (rti.origActivity != null) { 6902 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6903 == null) { 6904 continue; 6905 } 6906 } else if (rti.baseIntent != null) { 6907 if (pm.queryIntentActivities(rti.baseIntent, 6908 null, 0, userId) == null) { 6909 continue; 6910 } 6911 } 6912 } catch (RemoteException e) { 6913 // Will never happen. 6914 } 6915 } 6916 6917 res.add(rti); 6918 maxNum--; 6919 } 6920 } 6921 return res; 6922 } 6923 } 6924 6925 private TaskRecord recentTaskForIdLocked(int id) { 6926 final int N = mRecentTasks.size(); 6927 for (int i=0; i<N; i++) { 6928 TaskRecord tr = mRecentTasks.get(i); 6929 if (tr.taskId == id) { 6930 return tr; 6931 } 6932 } 6933 return null; 6934 } 6935 6936 @Override 6937 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6938 synchronized (this) { 6939 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6940 "getTaskThumbnails()"); 6941 TaskRecord tr = recentTaskForIdLocked(id); 6942 if (tr != null) { 6943 return tr.getTaskThumbnailsLocked(); 6944 } 6945 } 6946 return null; 6947 } 6948 6949 @Override 6950 public Bitmap getTaskTopThumbnail(int id) { 6951 synchronized (this) { 6952 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6953 "getTaskTopThumbnail()"); 6954 TaskRecord tr = recentTaskForIdLocked(id); 6955 if (tr != null) { 6956 return tr.getTaskTopThumbnailLocked(); 6957 } 6958 } 6959 return null; 6960 } 6961 6962 @Override 6963 public boolean removeSubTask(int taskId, int subTaskIndex) { 6964 synchronized (this) { 6965 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6966 "removeSubTask()"); 6967 long ident = Binder.clearCallingIdentity(); 6968 try { 6969 TaskRecord tr = recentTaskForIdLocked(taskId); 6970 if (tr != null) { 6971 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6972 } 6973 return false; 6974 } finally { 6975 Binder.restoreCallingIdentity(ident); 6976 } 6977 } 6978 } 6979 6980 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6981 if (!pr.killedByAm) { 6982 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6983 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6984 pr.processName, pr.setAdj, reason); 6985 pr.killedByAm = true; 6986 Process.killProcessQuiet(pr.pid); 6987 } 6988 } 6989 6990 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6991 tr.disposeThumbnail(); 6992 mRecentTasks.remove(tr); 6993 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6994 Intent baseIntent = new Intent( 6995 tr.intent != null ? tr.intent : tr.affinityIntent); 6996 ComponentName component = baseIntent.getComponent(); 6997 if (component == null) { 6998 Slog.w(TAG, "Now component for base intent of task: " + tr); 6999 return; 7000 } 7001 7002 // Find any running services associated with this app. 7003 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7004 7005 if (killProcesses) { 7006 // Find any running processes associated with this app. 7007 final String pkg = component.getPackageName(); 7008 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7009 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7010 for (int i=0; i<pmap.size(); i++) { 7011 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7012 for (int j=0; j<uids.size(); j++) { 7013 ProcessRecord proc = uids.valueAt(j); 7014 if (proc.userId != tr.userId) { 7015 continue; 7016 } 7017 if (!proc.pkgList.containsKey(pkg)) { 7018 continue; 7019 } 7020 procs.add(proc); 7021 } 7022 } 7023 7024 // Kill the running processes. 7025 for (int i=0; i<procs.size(); i++) { 7026 ProcessRecord pr = procs.get(i); 7027 if (pr == mHomeProcess) { 7028 // Don't kill the home process along with tasks from the same package. 7029 continue; 7030 } 7031 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7032 killUnneededProcessLocked(pr, "remove task"); 7033 } else { 7034 pr.waitingToKill = "remove task"; 7035 } 7036 } 7037 } 7038 } 7039 7040 @Override 7041 public boolean removeTask(int taskId, int flags) { 7042 synchronized (this) { 7043 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7044 "removeTask()"); 7045 long ident = Binder.clearCallingIdentity(); 7046 try { 7047 TaskRecord tr = recentTaskForIdLocked(taskId); 7048 if (tr != null) { 7049 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7050 if (r != null) { 7051 cleanUpRemovedTaskLocked(tr, flags); 7052 return true; 7053 } 7054 if (tr.mActivities.size() == 0) { 7055 // Caller is just removing a recent task that is 7056 // not actively running. That is easy! 7057 cleanUpRemovedTaskLocked(tr, flags); 7058 return true; 7059 } 7060 Slog.w(TAG, "removeTask: task " + taskId 7061 + " does not have activities to remove, " 7062 + " but numActivities=" + tr.numActivities 7063 + ": " + tr); 7064 } 7065 } finally { 7066 Binder.restoreCallingIdentity(ident); 7067 } 7068 } 7069 return false; 7070 } 7071 7072 /** 7073 * TODO: Add mController hook 7074 */ 7075 @Override 7076 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7077 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7078 "moveTaskToFront()"); 7079 7080 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7081 synchronized(this) { 7082 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7083 Binder.getCallingUid(), "Task to front")) { 7084 ActivityOptions.abort(options); 7085 return; 7086 } 7087 final long origId = Binder.clearCallingIdentity(); 7088 try { 7089 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7090 if (task == null) { 7091 return; 7092 } 7093 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7094 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7095 return; 7096 } 7097 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7098 } finally { 7099 Binder.restoreCallingIdentity(origId); 7100 } 7101 ActivityOptions.abort(options); 7102 } 7103 } 7104 7105 @Override 7106 public void moveTaskToBack(int taskId) { 7107 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7108 "moveTaskToBack()"); 7109 7110 synchronized(this) { 7111 TaskRecord tr = recentTaskForIdLocked(taskId); 7112 if (tr != null) { 7113 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7114 ActivityStack stack = tr.stack; 7115 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7116 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7117 Binder.getCallingUid(), "Task to back")) { 7118 return; 7119 } 7120 } 7121 final long origId = Binder.clearCallingIdentity(); 7122 try { 7123 stack.moveTaskToBackLocked(taskId, null); 7124 } finally { 7125 Binder.restoreCallingIdentity(origId); 7126 } 7127 } 7128 } 7129 } 7130 7131 /** 7132 * Moves an activity, and all of the other activities within the same task, to the bottom 7133 * of the history stack. The activity's order within the task is unchanged. 7134 * 7135 * @param token A reference to the activity we wish to move 7136 * @param nonRoot If false then this only works if the activity is the root 7137 * of a task; if true it will work for any activity in a task. 7138 * @return Returns true if the move completed, false if not. 7139 */ 7140 @Override 7141 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7142 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7143 synchronized(this) { 7144 final long origId = Binder.clearCallingIdentity(); 7145 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7146 if (taskId >= 0) { 7147 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7148 } 7149 Binder.restoreCallingIdentity(origId); 7150 } 7151 return false; 7152 } 7153 7154 @Override 7155 public void moveTaskBackwards(int task) { 7156 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7157 "moveTaskBackwards()"); 7158 7159 synchronized(this) { 7160 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7161 Binder.getCallingUid(), "Task backwards")) { 7162 return; 7163 } 7164 final long origId = Binder.clearCallingIdentity(); 7165 moveTaskBackwardsLocked(task); 7166 Binder.restoreCallingIdentity(origId); 7167 } 7168 } 7169 7170 private final void moveTaskBackwardsLocked(int task) { 7171 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7172 } 7173 7174 @Override 7175 public IBinder getHomeActivityToken() throws RemoteException { 7176 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7177 "getHomeActivityToken()"); 7178 synchronized (this) { 7179 return mStackSupervisor.getHomeActivityToken(); 7180 } 7181 } 7182 7183 @Override 7184 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7185 IActivityContainerCallback callback) throws RemoteException { 7186 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7187 "createActivityContainer()"); 7188 synchronized (this) { 7189 if (parentActivityToken == null) { 7190 throw new IllegalArgumentException("parent token must not be null"); 7191 } 7192 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7193 if (r == null) { 7194 return null; 7195 } 7196 return mStackSupervisor.createActivityContainer(r, callback); 7197 } 7198 } 7199 7200 @Override 7201 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7202 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7203 "deleteActivityContainer()"); 7204 synchronized (this) { 7205 mStackSupervisor.deleteActivityContainer(container); 7206 } 7207 } 7208 7209 @Override 7210 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7211 throws RemoteException { 7212 synchronized (this) { 7213 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7214 if (stack != null) { 7215 return stack.mActivityContainer; 7216 } 7217 return null; 7218 } 7219 } 7220 7221 @Override 7222 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7223 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7224 "moveTaskToStack()"); 7225 if (stackId == HOME_STACK_ID) { 7226 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7227 new RuntimeException("here").fillInStackTrace()); 7228 } 7229 synchronized (this) { 7230 long ident = Binder.clearCallingIdentity(); 7231 try { 7232 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7233 + stackId + " toTop=" + toTop); 7234 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7235 } finally { 7236 Binder.restoreCallingIdentity(ident); 7237 } 7238 } 7239 } 7240 7241 @Override 7242 public void resizeStack(int stackBoxId, Rect bounds) { 7243 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7244 "resizeStackBox()"); 7245 long ident = Binder.clearCallingIdentity(); 7246 try { 7247 mWindowManager.resizeStack(stackBoxId, bounds); 7248 } finally { 7249 Binder.restoreCallingIdentity(ident); 7250 } 7251 } 7252 7253 @Override 7254 public List<StackInfo> getAllStackInfos() { 7255 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7256 "getAllStackInfos()"); 7257 long ident = Binder.clearCallingIdentity(); 7258 try { 7259 synchronized (this) { 7260 return mStackSupervisor.getAllStackInfosLocked(); 7261 } 7262 } finally { 7263 Binder.restoreCallingIdentity(ident); 7264 } 7265 } 7266 7267 @Override 7268 public StackInfo getStackInfo(int stackId) { 7269 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7270 "getStackInfo()"); 7271 long ident = Binder.clearCallingIdentity(); 7272 try { 7273 synchronized (this) { 7274 return mStackSupervisor.getStackInfoLocked(stackId); 7275 } 7276 } finally { 7277 Binder.restoreCallingIdentity(ident); 7278 } 7279 } 7280 7281 @Override 7282 public boolean isInHomeStack(int taskId) { 7283 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7284 "getStackInfo()"); 7285 long ident = Binder.clearCallingIdentity(); 7286 try { 7287 synchronized (this) { 7288 TaskRecord tr = recentTaskForIdLocked(taskId); 7289 if (tr != null) { 7290 return tr.stack.isHomeStack(); 7291 } 7292 } 7293 } finally { 7294 Binder.restoreCallingIdentity(ident); 7295 } 7296 return false; 7297 } 7298 7299 @Override 7300 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7301 synchronized(this) { 7302 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7303 } 7304 } 7305 7306 private boolean isLockTaskAuthorized(ComponentName name) { 7307// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7308// "startLockTaskMode()"); 7309// DevicePolicyManager dpm = (DevicePolicyManager) 7310// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7311// return dpm != null && dpm.isLockTaskPermitted(name); 7312 return true; 7313 } 7314 7315 private void startLockTaskMode(TaskRecord task) { 7316 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7317 return; 7318 } 7319 long ident = Binder.clearCallingIdentity(); 7320 try { 7321 synchronized (this) { 7322 // Since we lost lock on task, make sure it is still there. 7323 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7324 if (task != null) { 7325 mStackSupervisor.setLockTaskModeLocked(task); 7326 } 7327 } 7328 } finally { 7329 Binder.restoreCallingIdentity(ident); 7330 } 7331 } 7332 7333 @Override 7334 public void startLockTaskMode(int taskId) { 7335 long ident = Binder.clearCallingIdentity(); 7336 try { 7337 final TaskRecord task; 7338 synchronized (this) { 7339 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7340 } 7341 if (task != null) { 7342 startLockTaskMode(task); 7343 } 7344 } finally { 7345 Binder.restoreCallingIdentity(ident); 7346 } 7347 } 7348 7349 @Override 7350 public void startLockTaskMode(IBinder token) { 7351 long ident = Binder.clearCallingIdentity(); 7352 try { 7353 final TaskRecord task; 7354 synchronized (this) { 7355 final ActivityRecord r = ActivityRecord.forToken(token); 7356 if (r == null) { 7357 return; 7358 } 7359 task = r.task; 7360 } 7361 if (task != null) { 7362 startLockTaskMode(task); 7363 } 7364 } finally { 7365 Binder.restoreCallingIdentity(ident); 7366 } 7367 } 7368 7369 @Override 7370 public void stopLockTaskMode() { 7371// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7372// "stopLockTaskMode()"); 7373 synchronized (this) { 7374 mStackSupervisor.setLockTaskModeLocked(null); 7375 } 7376 } 7377 7378 @Override 7379 public boolean isInLockTaskMode() { 7380 synchronized (this) { 7381 return mStackSupervisor.isInLockTaskMode(); 7382 } 7383 } 7384 7385 // ========================================================= 7386 // THUMBNAILS 7387 // ========================================================= 7388 7389 public void reportThumbnail(IBinder token, 7390 Bitmap thumbnail, CharSequence description) { 7391 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7392 final long origId = Binder.clearCallingIdentity(); 7393 sendPendingThumbnail(null, token, thumbnail, description, true); 7394 Binder.restoreCallingIdentity(origId); 7395 } 7396 7397 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7398 Bitmap thumbnail, CharSequence description, boolean always) { 7399 TaskRecord task; 7400 ArrayList<PendingThumbnailsRecord> receivers = null; 7401 7402 //System.out.println("Send pending thumbnail: " + r); 7403 7404 synchronized(this) { 7405 if (r == null) { 7406 r = ActivityRecord.isInStackLocked(token); 7407 if (r == null) { 7408 return; 7409 } 7410 } 7411 if (thumbnail == null && r.thumbHolder != null) { 7412 thumbnail = r.thumbHolder.lastThumbnail; 7413 description = r.thumbHolder.lastDescription; 7414 } 7415 if (thumbnail == null && !always) { 7416 // If there is no thumbnail, and this entry is not actually 7417 // going away, then abort for now and pick up the next 7418 // thumbnail we get. 7419 return; 7420 } 7421 task = r.task; 7422 7423 int N = mPendingThumbnails.size(); 7424 int i=0; 7425 while (i<N) { 7426 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7427 //System.out.println("Looking in " + pr.pendingRecords); 7428 if (pr.pendingRecords.remove(r)) { 7429 if (receivers == null) { 7430 receivers = new ArrayList<PendingThumbnailsRecord>(); 7431 } 7432 receivers.add(pr); 7433 if (pr.pendingRecords.size() == 0) { 7434 pr.finished = true; 7435 mPendingThumbnails.remove(i); 7436 N--; 7437 continue; 7438 } 7439 } 7440 i++; 7441 } 7442 } 7443 7444 if (receivers != null) { 7445 final int N = receivers.size(); 7446 for (int i=0; i<N; i++) { 7447 try { 7448 PendingThumbnailsRecord pr = receivers.get(i); 7449 pr.receiver.newThumbnail( 7450 task != null ? task.taskId : -1, thumbnail, description); 7451 if (pr.finished) { 7452 pr.receiver.finished(); 7453 } 7454 } catch (Exception e) { 7455 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7456 } 7457 } 7458 } 7459 } 7460 7461 // ========================================================= 7462 // CONTENT PROVIDERS 7463 // ========================================================= 7464 7465 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7466 List<ProviderInfo> providers = null; 7467 try { 7468 providers = AppGlobals.getPackageManager(). 7469 queryContentProviders(app.processName, app.uid, 7470 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7471 } catch (RemoteException ex) { 7472 } 7473 if (DEBUG_MU) 7474 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7475 int userId = app.userId; 7476 if (providers != null) { 7477 int N = providers.size(); 7478 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7479 for (int i=0; i<N; i++) { 7480 ProviderInfo cpi = 7481 (ProviderInfo)providers.get(i); 7482 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7483 cpi.name, cpi.flags); 7484 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7485 // This is a singleton provider, but a user besides the 7486 // default user is asking to initialize a process it runs 7487 // in... well, no, it doesn't actually run in this process, 7488 // it runs in the process of the default user. Get rid of it. 7489 providers.remove(i); 7490 N--; 7491 i--; 7492 continue; 7493 } 7494 7495 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7496 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7497 if (cpr == null) { 7498 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7499 mProviderMap.putProviderByClass(comp, cpr); 7500 } 7501 if (DEBUG_MU) 7502 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7503 app.pubProviders.put(cpi.name, cpr); 7504 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7505 // Don't add this if it is a platform component that is marked 7506 // to run in multiple processes, because this is actually 7507 // part of the framework so doesn't make sense to track as a 7508 // separate apk in the process. 7509 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7510 } 7511 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7512 } 7513 } 7514 return providers; 7515 } 7516 7517 /** 7518 * Check if {@link ProcessRecord} has a possible chance at accessing the 7519 * given {@link ProviderInfo}. Final permission checking is always done 7520 * in {@link ContentProvider}. 7521 */ 7522 private final String checkContentProviderPermissionLocked( 7523 ProviderInfo cpi, ProcessRecord r) { 7524 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7525 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7526 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7527 cpi.applicationInfo.uid, cpi.exported) 7528 == PackageManager.PERMISSION_GRANTED) { 7529 return null; 7530 } 7531 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7532 cpi.applicationInfo.uid, cpi.exported) 7533 == PackageManager.PERMISSION_GRANTED) { 7534 return null; 7535 } 7536 7537 PathPermission[] pps = cpi.pathPermissions; 7538 if (pps != null) { 7539 int i = pps.length; 7540 while (i > 0) { 7541 i--; 7542 PathPermission pp = pps[i]; 7543 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7544 cpi.applicationInfo.uid, cpi.exported) 7545 == PackageManager.PERMISSION_GRANTED) { 7546 return null; 7547 } 7548 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7549 cpi.applicationInfo.uid, cpi.exported) 7550 == PackageManager.PERMISSION_GRANTED) { 7551 return null; 7552 } 7553 } 7554 } 7555 7556 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7557 if (perms != null) { 7558 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7559 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7560 return null; 7561 } 7562 } 7563 } 7564 7565 String msg; 7566 if (!cpi.exported) { 7567 msg = "Permission Denial: opening provider " + cpi.name 7568 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7569 + ", uid=" + callingUid + ") that is not exported from uid " 7570 + cpi.applicationInfo.uid; 7571 } else { 7572 msg = "Permission Denial: opening provider " + cpi.name 7573 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7574 + ", uid=" + callingUid + ") requires " 7575 + cpi.readPermission + " or " + cpi.writePermission; 7576 } 7577 Slog.w(TAG, msg); 7578 return msg; 7579 } 7580 7581 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7582 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7583 if (r != null) { 7584 for (int i=0; i<r.conProviders.size(); i++) { 7585 ContentProviderConnection conn = r.conProviders.get(i); 7586 if (conn.provider == cpr) { 7587 if (DEBUG_PROVIDER) Slog.v(TAG, 7588 "Adding provider requested by " 7589 + r.processName + " from process " 7590 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7591 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7592 if (stable) { 7593 conn.stableCount++; 7594 conn.numStableIncs++; 7595 } else { 7596 conn.unstableCount++; 7597 conn.numUnstableIncs++; 7598 } 7599 return conn; 7600 } 7601 } 7602 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7603 if (stable) { 7604 conn.stableCount = 1; 7605 conn.numStableIncs = 1; 7606 } else { 7607 conn.unstableCount = 1; 7608 conn.numUnstableIncs = 1; 7609 } 7610 cpr.connections.add(conn); 7611 r.conProviders.add(conn); 7612 return conn; 7613 } 7614 cpr.addExternalProcessHandleLocked(externalProcessToken); 7615 return null; 7616 } 7617 7618 boolean decProviderCountLocked(ContentProviderConnection conn, 7619 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7620 if (conn != null) { 7621 cpr = conn.provider; 7622 if (DEBUG_PROVIDER) Slog.v(TAG, 7623 "Removing provider requested by " 7624 + conn.client.processName + " from process " 7625 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7626 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7627 if (stable) { 7628 conn.stableCount--; 7629 } else { 7630 conn.unstableCount--; 7631 } 7632 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7633 cpr.connections.remove(conn); 7634 conn.client.conProviders.remove(conn); 7635 return true; 7636 } 7637 return false; 7638 } 7639 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7640 return false; 7641 } 7642 7643 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7644 String name, IBinder token, boolean stable, int userId) { 7645 ContentProviderRecord cpr; 7646 ContentProviderConnection conn = null; 7647 ProviderInfo cpi = null; 7648 7649 synchronized(this) { 7650 ProcessRecord r = null; 7651 if (caller != null) { 7652 r = getRecordForAppLocked(caller); 7653 if (r == null) { 7654 throw new SecurityException( 7655 "Unable to find app for caller " + caller 7656 + " (pid=" + Binder.getCallingPid() 7657 + ") when getting content provider " + name); 7658 } 7659 } 7660 7661 // First check if this content provider has been published... 7662 cpr = mProviderMap.getProviderByName(name, userId); 7663 boolean providerRunning = cpr != null; 7664 if (providerRunning) { 7665 cpi = cpr.info; 7666 String msg; 7667 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7668 throw new SecurityException(msg); 7669 } 7670 7671 if (r != null && cpr.canRunHere(r)) { 7672 // This provider has been published or is in the process 7673 // of being published... but it is also allowed to run 7674 // in the caller's process, so don't make a connection 7675 // and just let the caller instantiate its own instance. 7676 ContentProviderHolder holder = cpr.newHolder(null); 7677 // don't give caller the provider object, it needs 7678 // to make its own. 7679 holder.provider = null; 7680 return holder; 7681 } 7682 7683 final long origId = Binder.clearCallingIdentity(); 7684 7685 // In this case the provider instance already exists, so we can 7686 // return it right away. 7687 conn = incProviderCountLocked(r, cpr, token, stable); 7688 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7689 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7690 // If this is a perceptible app accessing the provider, 7691 // make sure to count it as being accessed and thus 7692 // back up on the LRU list. This is good because 7693 // content providers are often expensive to start. 7694 updateLruProcessLocked(cpr.proc, false, null); 7695 } 7696 } 7697 7698 if (cpr.proc != null) { 7699 if (false) { 7700 if (cpr.name.flattenToShortString().equals( 7701 "com.android.providers.calendar/.CalendarProvider2")) { 7702 Slog.v(TAG, "****************** KILLING " 7703 + cpr.name.flattenToShortString()); 7704 Process.killProcess(cpr.proc.pid); 7705 } 7706 } 7707 boolean success = updateOomAdjLocked(cpr.proc); 7708 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7709 // NOTE: there is still a race here where a signal could be 7710 // pending on the process even though we managed to update its 7711 // adj level. Not sure what to do about this, but at least 7712 // the race is now smaller. 7713 if (!success) { 7714 // Uh oh... it looks like the provider's process 7715 // has been killed on us. We need to wait for a new 7716 // process to be started, and make sure its death 7717 // doesn't kill our process. 7718 Slog.i(TAG, 7719 "Existing provider " + cpr.name.flattenToShortString() 7720 + " is crashing; detaching " + r); 7721 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7722 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7723 if (!lastRef) { 7724 // This wasn't the last ref our process had on 7725 // the provider... we have now been killed, bail. 7726 return null; 7727 } 7728 providerRunning = false; 7729 conn = null; 7730 } 7731 } 7732 7733 Binder.restoreCallingIdentity(origId); 7734 } 7735 7736 boolean singleton; 7737 if (!providerRunning) { 7738 try { 7739 cpi = AppGlobals.getPackageManager(). 7740 resolveContentProvider(name, 7741 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7742 } catch (RemoteException ex) { 7743 } 7744 if (cpi == null) { 7745 return null; 7746 } 7747 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7748 cpi.name, cpi.flags); 7749 if (singleton) { 7750 userId = 0; 7751 } 7752 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7753 7754 String msg; 7755 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7756 throw new SecurityException(msg); 7757 } 7758 7759 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7760 && !cpi.processName.equals("system")) { 7761 // If this content provider does not run in the system 7762 // process, and the system is not yet ready to run other 7763 // processes, then fail fast instead of hanging. 7764 throw new IllegalArgumentException( 7765 "Attempt to launch content provider before system ready"); 7766 } 7767 7768 // Make sure that the user who owns this provider is started. If not, 7769 // we don't want to allow it to run. 7770 if (mStartedUsers.get(userId) == null) { 7771 Slog.w(TAG, "Unable to launch app " 7772 + cpi.applicationInfo.packageName + "/" 7773 + cpi.applicationInfo.uid + " for provider " 7774 + name + ": user " + userId + " is stopped"); 7775 return null; 7776 } 7777 7778 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7779 cpr = mProviderMap.getProviderByClass(comp, userId); 7780 final boolean firstClass = cpr == null; 7781 if (firstClass) { 7782 try { 7783 ApplicationInfo ai = 7784 AppGlobals.getPackageManager(). 7785 getApplicationInfo( 7786 cpi.applicationInfo.packageName, 7787 STOCK_PM_FLAGS, userId); 7788 if (ai == null) { 7789 Slog.w(TAG, "No package info for content provider " 7790 + cpi.name); 7791 return null; 7792 } 7793 ai = getAppInfoForUser(ai, userId); 7794 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7795 } catch (RemoteException ex) { 7796 // pm is in same process, this will never happen. 7797 } 7798 } 7799 7800 if (r != null && cpr.canRunHere(r)) { 7801 // If this is a multiprocess provider, then just return its 7802 // info and allow the caller to instantiate it. Only do 7803 // this if the provider is the same user as the caller's 7804 // process, or can run as root (so can be in any process). 7805 return cpr.newHolder(null); 7806 } 7807 7808 if (DEBUG_PROVIDER) { 7809 RuntimeException e = new RuntimeException("here"); 7810 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7811 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7812 } 7813 7814 // This is single process, and our app is now connecting to it. 7815 // See if we are already in the process of launching this 7816 // provider. 7817 final int N = mLaunchingProviders.size(); 7818 int i; 7819 for (i=0; i<N; i++) { 7820 if (mLaunchingProviders.get(i) == cpr) { 7821 break; 7822 } 7823 } 7824 7825 // If the provider is not already being launched, then get it 7826 // started. 7827 if (i >= N) { 7828 final long origId = Binder.clearCallingIdentity(); 7829 7830 try { 7831 // Content provider is now in use, its package can't be stopped. 7832 try { 7833 AppGlobals.getPackageManager().setPackageStoppedState( 7834 cpr.appInfo.packageName, false, userId); 7835 } catch (RemoteException e) { 7836 } catch (IllegalArgumentException e) { 7837 Slog.w(TAG, "Failed trying to unstop package " 7838 + cpr.appInfo.packageName + ": " + e); 7839 } 7840 7841 // Use existing process if already started 7842 ProcessRecord proc = getProcessRecordLocked( 7843 cpi.processName, cpr.appInfo.uid, false); 7844 if (proc != null && proc.thread != null) { 7845 if (DEBUG_PROVIDER) { 7846 Slog.d(TAG, "Installing in existing process " + proc); 7847 } 7848 proc.pubProviders.put(cpi.name, cpr); 7849 try { 7850 proc.thread.scheduleInstallProvider(cpi); 7851 } catch (RemoteException e) { 7852 } 7853 } else { 7854 proc = startProcessLocked(cpi.processName, 7855 cpr.appInfo, false, 0, "content provider", 7856 new ComponentName(cpi.applicationInfo.packageName, 7857 cpi.name), false, false, false); 7858 if (proc == null) { 7859 Slog.w(TAG, "Unable to launch app " 7860 + cpi.applicationInfo.packageName + "/" 7861 + cpi.applicationInfo.uid + " for provider " 7862 + name + ": process is bad"); 7863 return null; 7864 } 7865 } 7866 cpr.launchingApp = proc; 7867 mLaunchingProviders.add(cpr); 7868 } finally { 7869 Binder.restoreCallingIdentity(origId); 7870 } 7871 } 7872 7873 // Make sure the provider is published (the same provider class 7874 // may be published under multiple names). 7875 if (firstClass) { 7876 mProviderMap.putProviderByClass(comp, cpr); 7877 } 7878 7879 mProviderMap.putProviderByName(name, cpr); 7880 conn = incProviderCountLocked(r, cpr, token, stable); 7881 if (conn != null) { 7882 conn.waiting = true; 7883 } 7884 } 7885 } 7886 7887 // Wait for the provider to be published... 7888 synchronized (cpr) { 7889 while (cpr.provider == null) { 7890 if (cpr.launchingApp == null) { 7891 Slog.w(TAG, "Unable to launch app " 7892 + cpi.applicationInfo.packageName + "/" 7893 + cpi.applicationInfo.uid + " for provider " 7894 + name + ": launching app became null"); 7895 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7896 UserHandle.getUserId(cpi.applicationInfo.uid), 7897 cpi.applicationInfo.packageName, 7898 cpi.applicationInfo.uid, name); 7899 return null; 7900 } 7901 try { 7902 if (DEBUG_MU) { 7903 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7904 + cpr.launchingApp); 7905 } 7906 if (conn != null) { 7907 conn.waiting = true; 7908 } 7909 cpr.wait(); 7910 } catch (InterruptedException ex) { 7911 } finally { 7912 if (conn != null) { 7913 conn.waiting = false; 7914 } 7915 } 7916 } 7917 } 7918 return cpr != null ? cpr.newHolder(conn) : null; 7919 } 7920 7921 public final ContentProviderHolder getContentProvider( 7922 IApplicationThread caller, String name, int userId, boolean stable) { 7923 enforceNotIsolatedCaller("getContentProvider"); 7924 if (caller == null) { 7925 String msg = "null IApplicationThread when getting content provider " 7926 + name; 7927 Slog.w(TAG, msg); 7928 throw new SecurityException(msg); 7929 } 7930 7931 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7932 false, true, "getContentProvider", null); 7933 return getContentProviderImpl(caller, name, null, stable, userId); 7934 } 7935 7936 public ContentProviderHolder getContentProviderExternal( 7937 String name, int userId, IBinder token) { 7938 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7939 "Do not have permission in call getContentProviderExternal()"); 7940 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7941 false, true, "getContentProvider", null); 7942 return getContentProviderExternalUnchecked(name, token, userId); 7943 } 7944 7945 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7946 IBinder token, int userId) { 7947 return getContentProviderImpl(null, name, token, true, userId); 7948 } 7949 7950 /** 7951 * Drop a content provider from a ProcessRecord's bookkeeping 7952 */ 7953 public void removeContentProvider(IBinder connection, boolean stable) { 7954 enforceNotIsolatedCaller("removeContentProvider"); 7955 long ident = Binder.clearCallingIdentity(); 7956 try { 7957 synchronized (this) { 7958 ContentProviderConnection conn; 7959 try { 7960 conn = (ContentProviderConnection)connection; 7961 } catch (ClassCastException e) { 7962 String msg ="removeContentProvider: " + connection 7963 + " not a ContentProviderConnection"; 7964 Slog.w(TAG, msg); 7965 throw new IllegalArgumentException(msg); 7966 } 7967 if (conn == null) { 7968 throw new NullPointerException("connection is null"); 7969 } 7970 if (decProviderCountLocked(conn, null, null, stable)) { 7971 updateOomAdjLocked(); 7972 } 7973 } 7974 } finally { 7975 Binder.restoreCallingIdentity(ident); 7976 } 7977 } 7978 7979 public void removeContentProviderExternal(String name, IBinder token) { 7980 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7981 "Do not have permission in call removeContentProviderExternal()"); 7982 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7983 } 7984 7985 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7986 synchronized (this) { 7987 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7988 if(cpr == null) { 7989 //remove from mProvidersByClass 7990 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7991 return; 7992 } 7993 7994 //update content provider record entry info 7995 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7996 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7997 if (localCpr.hasExternalProcessHandles()) { 7998 if (localCpr.removeExternalProcessHandleLocked(token)) { 7999 updateOomAdjLocked(); 8000 } else { 8001 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8002 + " with no external reference for token: " 8003 + token + "."); 8004 } 8005 } else { 8006 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8007 + " with no external references."); 8008 } 8009 } 8010 } 8011 8012 public final void publishContentProviders(IApplicationThread caller, 8013 List<ContentProviderHolder> providers) { 8014 if (providers == null) { 8015 return; 8016 } 8017 8018 enforceNotIsolatedCaller("publishContentProviders"); 8019 synchronized (this) { 8020 final ProcessRecord r = getRecordForAppLocked(caller); 8021 if (DEBUG_MU) 8022 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8023 if (r == null) { 8024 throw new SecurityException( 8025 "Unable to find app for caller " + caller 8026 + " (pid=" + Binder.getCallingPid() 8027 + ") when publishing content providers"); 8028 } 8029 8030 final long origId = Binder.clearCallingIdentity(); 8031 8032 final int N = providers.size(); 8033 for (int i=0; i<N; i++) { 8034 ContentProviderHolder src = providers.get(i); 8035 if (src == null || src.info == null || src.provider == null) { 8036 continue; 8037 } 8038 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8039 if (DEBUG_MU) 8040 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8041 if (dst != null) { 8042 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8043 mProviderMap.putProviderByClass(comp, dst); 8044 String names[] = dst.info.authority.split(";"); 8045 for (int j = 0; j < names.length; j++) { 8046 mProviderMap.putProviderByName(names[j], dst); 8047 } 8048 8049 int NL = mLaunchingProviders.size(); 8050 int j; 8051 for (j=0; j<NL; j++) { 8052 if (mLaunchingProviders.get(j) == dst) { 8053 mLaunchingProviders.remove(j); 8054 j--; 8055 NL--; 8056 } 8057 } 8058 synchronized (dst) { 8059 dst.provider = src.provider; 8060 dst.proc = r; 8061 dst.notifyAll(); 8062 } 8063 updateOomAdjLocked(r); 8064 } 8065 } 8066 8067 Binder.restoreCallingIdentity(origId); 8068 } 8069 } 8070 8071 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8072 ContentProviderConnection conn; 8073 try { 8074 conn = (ContentProviderConnection)connection; 8075 } catch (ClassCastException e) { 8076 String msg ="refContentProvider: " + connection 8077 + " not a ContentProviderConnection"; 8078 Slog.w(TAG, msg); 8079 throw new IllegalArgumentException(msg); 8080 } 8081 if (conn == null) { 8082 throw new NullPointerException("connection is null"); 8083 } 8084 8085 synchronized (this) { 8086 if (stable > 0) { 8087 conn.numStableIncs += stable; 8088 } 8089 stable = conn.stableCount + stable; 8090 if (stable < 0) { 8091 throw new IllegalStateException("stableCount < 0: " + stable); 8092 } 8093 8094 if (unstable > 0) { 8095 conn.numUnstableIncs += unstable; 8096 } 8097 unstable = conn.unstableCount + unstable; 8098 if (unstable < 0) { 8099 throw new IllegalStateException("unstableCount < 0: " + unstable); 8100 } 8101 8102 if ((stable+unstable) <= 0) { 8103 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8104 + stable + " unstable=" + unstable); 8105 } 8106 conn.stableCount = stable; 8107 conn.unstableCount = unstable; 8108 return !conn.dead; 8109 } 8110 } 8111 8112 public void unstableProviderDied(IBinder connection) { 8113 ContentProviderConnection conn; 8114 try { 8115 conn = (ContentProviderConnection)connection; 8116 } catch (ClassCastException e) { 8117 String msg ="refContentProvider: " + connection 8118 + " not a ContentProviderConnection"; 8119 Slog.w(TAG, msg); 8120 throw new IllegalArgumentException(msg); 8121 } 8122 if (conn == null) { 8123 throw new NullPointerException("connection is null"); 8124 } 8125 8126 // Safely retrieve the content provider associated with the connection. 8127 IContentProvider provider; 8128 synchronized (this) { 8129 provider = conn.provider.provider; 8130 } 8131 8132 if (provider == null) { 8133 // Um, yeah, we're way ahead of you. 8134 return; 8135 } 8136 8137 // Make sure the caller is being honest with us. 8138 if (provider.asBinder().pingBinder()) { 8139 // Er, no, still looks good to us. 8140 synchronized (this) { 8141 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8142 + " says " + conn + " died, but we don't agree"); 8143 return; 8144 } 8145 } 8146 8147 // Well look at that! It's dead! 8148 synchronized (this) { 8149 if (conn.provider.provider != provider) { 8150 // But something changed... good enough. 8151 return; 8152 } 8153 8154 ProcessRecord proc = conn.provider.proc; 8155 if (proc == null || proc.thread == null) { 8156 // Seems like the process is already cleaned up. 8157 return; 8158 } 8159 8160 // As far as we're concerned, this is just like receiving a 8161 // death notification... just a bit prematurely. 8162 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8163 + ") early provider death"); 8164 final long ident = Binder.clearCallingIdentity(); 8165 try { 8166 appDiedLocked(proc, proc.pid, proc.thread); 8167 } finally { 8168 Binder.restoreCallingIdentity(ident); 8169 } 8170 } 8171 } 8172 8173 @Override 8174 public void appNotRespondingViaProvider(IBinder connection) { 8175 enforceCallingPermission( 8176 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8177 8178 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8179 if (conn == null) { 8180 Slog.w(TAG, "ContentProviderConnection is null"); 8181 return; 8182 } 8183 8184 final ProcessRecord host = conn.provider.proc; 8185 if (host == null) { 8186 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8187 return; 8188 } 8189 8190 final long token = Binder.clearCallingIdentity(); 8191 try { 8192 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8193 } finally { 8194 Binder.restoreCallingIdentity(token); 8195 } 8196 } 8197 8198 public final void installSystemProviders() { 8199 List<ProviderInfo> providers; 8200 synchronized (this) { 8201 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8202 providers = generateApplicationProvidersLocked(app); 8203 if (providers != null) { 8204 for (int i=providers.size()-1; i>=0; i--) { 8205 ProviderInfo pi = (ProviderInfo)providers.get(i); 8206 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8207 Slog.w(TAG, "Not installing system proc provider " + pi.name 8208 + ": not system .apk"); 8209 providers.remove(i); 8210 } 8211 } 8212 } 8213 } 8214 if (providers != null) { 8215 mSystemThread.installSystemProviders(providers); 8216 } 8217 8218 mCoreSettingsObserver = new CoreSettingsObserver(this); 8219 8220 mUsageStatsService.monitorPackages(); 8221 } 8222 8223 /** 8224 * Allows app to retrieve the MIME type of a URI without having permission 8225 * to access its content provider. 8226 * 8227 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8228 * 8229 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8230 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8231 */ 8232 public String getProviderMimeType(Uri uri, int userId) { 8233 enforceNotIsolatedCaller("getProviderMimeType"); 8234 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8235 userId, false, true, "getProviderMimeType", null); 8236 final String name = uri.getAuthority(); 8237 final long ident = Binder.clearCallingIdentity(); 8238 ContentProviderHolder holder = null; 8239 8240 try { 8241 holder = getContentProviderExternalUnchecked(name, null, userId); 8242 if (holder != null) { 8243 return holder.provider.getType(uri); 8244 } 8245 } catch (RemoteException e) { 8246 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8247 return null; 8248 } finally { 8249 if (holder != null) { 8250 removeContentProviderExternalUnchecked(name, null, userId); 8251 } 8252 Binder.restoreCallingIdentity(ident); 8253 } 8254 8255 return null; 8256 } 8257 8258 // ========================================================= 8259 // GLOBAL MANAGEMENT 8260 // ========================================================= 8261 8262 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8263 boolean isolated) { 8264 String proc = customProcess != null ? customProcess : info.processName; 8265 BatteryStatsImpl.Uid.Proc ps = null; 8266 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8267 int uid = info.uid; 8268 if (isolated) { 8269 int userId = UserHandle.getUserId(uid); 8270 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8271 while (true) { 8272 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8273 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8274 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8275 } 8276 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8277 mNextIsolatedProcessUid++; 8278 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8279 // No process for this uid, use it. 8280 break; 8281 } 8282 stepsLeft--; 8283 if (stepsLeft <= 0) { 8284 return null; 8285 } 8286 } 8287 } 8288 return new ProcessRecord(stats, info, proc, uid); 8289 } 8290 8291 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8292 ProcessRecord app; 8293 if (!isolated) { 8294 app = getProcessRecordLocked(info.processName, info.uid, true); 8295 } else { 8296 app = null; 8297 } 8298 8299 if (app == null) { 8300 app = newProcessRecordLocked(info, null, isolated); 8301 mProcessNames.put(info.processName, app.uid, app); 8302 if (isolated) { 8303 mIsolatedProcesses.put(app.uid, app); 8304 } 8305 updateLruProcessLocked(app, false, null); 8306 updateOomAdjLocked(); 8307 } 8308 8309 // This package really, really can not be stopped. 8310 try { 8311 AppGlobals.getPackageManager().setPackageStoppedState( 8312 info.packageName, false, UserHandle.getUserId(app.uid)); 8313 } catch (RemoteException e) { 8314 } catch (IllegalArgumentException e) { 8315 Slog.w(TAG, "Failed trying to unstop package " 8316 + info.packageName + ": " + e); 8317 } 8318 8319 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8320 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8321 app.persistent = true; 8322 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8323 } 8324 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8325 mPersistentStartingProcesses.add(app); 8326 startProcessLocked(app, "added application", app.processName); 8327 } 8328 8329 return app; 8330 } 8331 8332 public void unhandledBack() { 8333 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8334 "unhandledBack()"); 8335 8336 synchronized(this) { 8337 final long origId = Binder.clearCallingIdentity(); 8338 try { 8339 getFocusedStack().unhandledBackLocked(); 8340 } finally { 8341 Binder.restoreCallingIdentity(origId); 8342 } 8343 } 8344 } 8345 8346 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8347 enforceNotIsolatedCaller("openContentUri"); 8348 final int userId = UserHandle.getCallingUserId(); 8349 String name = uri.getAuthority(); 8350 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8351 ParcelFileDescriptor pfd = null; 8352 if (cph != null) { 8353 // We record the binder invoker's uid in thread-local storage before 8354 // going to the content provider to open the file. Later, in the code 8355 // that handles all permissions checks, we look for this uid and use 8356 // that rather than the Activity Manager's own uid. The effect is that 8357 // we do the check against the caller's permissions even though it looks 8358 // to the content provider like the Activity Manager itself is making 8359 // the request. 8360 sCallerIdentity.set(new Identity( 8361 Binder.getCallingPid(), Binder.getCallingUid())); 8362 try { 8363 pfd = cph.provider.openFile(null, uri, "r", null); 8364 } catch (FileNotFoundException e) { 8365 // do nothing; pfd will be returned null 8366 } finally { 8367 // Ensure that whatever happens, we clean up the identity state 8368 sCallerIdentity.remove(); 8369 } 8370 8371 // We've got the fd now, so we're done with the provider. 8372 removeContentProviderExternalUnchecked(name, null, userId); 8373 } else { 8374 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8375 } 8376 return pfd; 8377 } 8378 8379 // Actually is sleeping or shutting down or whatever else in the future 8380 // is an inactive state. 8381 public boolean isSleepingOrShuttingDown() { 8382 return mSleeping || mShuttingDown; 8383 } 8384 8385 public void goingToSleep() { 8386 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8387 != PackageManager.PERMISSION_GRANTED) { 8388 throw new SecurityException("Requires permission " 8389 + android.Manifest.permission.DEVICE_POWER); 8390 } 8391 8392 synchronized(this) { 8393 mWentToSleep = true; 8394 updateEventDispatchingLocked(); 8395 8396 if (!mSleeping) { 8397 mSleeping = true; 8398 mStackSupervisor.goingToSleepLocked(); 8399 8400 // Initialize the wake times of all processes. 8401 checkExcessivePowerUsageLocked(false); 8402 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8403 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8404 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8405 } 8406 } 8407 } 8408 8409 @Override 8410 public boolean shutdown(int timeout) { 8411 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8412 != PackageManager.PERMISSION_GRANTED) { 8413 throw new SecurityException("Requires permission " 8414 + android.Manifest.permission.SHUTDOWN); 8415 } 8416 8417 boolean timedout = false; 8418 8419 synchronized(this) { 8420 mShuttingDown = true; 8421 updateEventDispatchingLocked(); 8422 timedout = mStackSupervisor.shutdownLocked(timeout); 8423 } 8424 8425 mAppOpsService.shutdown(); 8426 mUsageStatsService.shutdown(); 8427 mBatteryStatsService.shutdown(); 8428 synchronized (this) { 8429 mProcessStats.shutdownLocked(); 8430 } 8431 8432 return timedout; 8433 } 8434 8435 public final void activitySlept(IBinder token) { 8436 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8437 8438 final long origId = Binder.clearCallingIdentity(); 8439 8440 synchronized (this) { 8441 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8442 if (r != null) { 8443 mStackSupervisor.activitySleptLocked(r); 8444 } 8445 } 8446 8447 Binder.restoreCallingIdentity(origId); 8448 } 8449 8450 void logLockScreen(String msg) { 8451 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8452 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8453 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8454 mStackSupervisor.mDismissKeyguardOnNextActivity); 8455 } 8456 8457 private void comeOutOfSleepIfNeededLocked() { 8458 if (!mWentToSleep && !mLockScreenShown) { 8459 if (mSleeping) { 8460 mSleeping = false; 8461 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8462 } 8463 } 8464 } 8465 8466 public void wakingUp() { 8467 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8468 != PackageManager.PERMISSION_GRANTED) { 8469 throw new SecurityException("Requires permission " 8470 + android.Manifest.permission.DEVICE_POWER); 8471 } 8472 8473 synchronized(this) { 8474 mWentToSleep = false; 8475 updateEventDispatchingLocked(); 8476 comeOutOfSleepIfNeededLocked(); 8477 } 8478 } 8479 8480 private void updateEventDispatchingLocked() { 8481 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8482 } 8483 8484 public void setLockScreenShown(boolean shown) { 8485 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8486 != PackageManager.PERMISSION_GRANTED) { 8487 throw new SecurityException("Requires permission " 8488 + android.Manifest.permission.DEVICE_POWER); 8489 } 8490 8491 synchronized(this) { 8492 long ident = Binder.clearCallingIdentity(); 8493 try { 8494 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8495 mLockScreenShown = shown; 8496 comeOutOfSleepIfNeededLocked(); 8497 } finally { 8498 Binder.restoreCallingIdentity(ident); 8499 } 8500 } 8501 } 8502 8503 public void stopAppSwitches() { 8504 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8505 != PackageManager.PERMISSION_GRANTED) { 8506 throw new SecurityException("Requires permission " 8507 + android.Manifest.permission.STOP_APP_SWITCHES); 8508 } 8509 8510 synchronized(this) { 8511 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8512 + APP_SWITCH_DELAY_TIME; 8513 mDidAppSwitch = false; 8514 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8515 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8516 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8517 } 8518 } 8519 8520 public void resumeAppSwitches() { 8521 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8522 != PackageManager.PERMISSION_GRANTED) { 8523 throw new SecurityException("Requires permission " 8524 + android.Manifest.permission.STOP_APP_SWITCHES); 8525 } 8526 8527 synchronized(this) { 8528 // Note that we don't execute any pending app switches... we will 8529 // let those wait until either the timeout, or the next start 8530 // activity request. 8531 mAppSwitchesAllowedTime = 0; 8532 } 8533 } 8534 8535 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8536 String name) { 8537 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8538 return true; 8539 } 8540 8541 final int perm = checkComponentPermission( 8542 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8543 callingUid, -1, true); 8544 if (perm == PackageManager.PERMISSION_GRANTED) { 8545 return true; 8546 } 8547 8548 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8549 return false; 8550 } 8551 8552 public void setDebugApp(String packageName, boolean waitForDebugger, 8553 boolean persistent) { 8554 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8555 "setDebugApp()"); 8556 8557 long ident = Binder.clearCallingIdentity(); 8558 try { 8559 // Note that this is not really thread safe if there are multiple 8560 // callers into it at the same time, but that's not a situation we 8561 // care about. 8562 if (persistent) { 8563 final ContentResolver resolver = mContext.getContentResolver(); 8564 Settings.Global.putString( 8565 resolver, Settings.Global.DEBUG_APP, 8566 packageName); 8567 Settings.Global.putInt( 8568 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8569 waitForDebugger ? 1 : 0); 8570 } 8571 8572 synchronized (this) { 8573 if (!persistent) { 8574 mOrigDebugApp = mDebugApp; 8575 mOrigWaitForDebugger = mWaitForDebugger; 8576 } 8577 mDebugApp = packageName; 8578 mWaitForDebugger = waitForDebugger; 8579 mDebugTransient = !persistent; 8580 if (packageName != null) { 8581 forceStopPackageLocked(packageName, -1, false, false, true, true, 8582 false, UserHandle.USER_ALL, "set debug app"); 8583 } 8584 } 8585 } finally { 8586 Binder.restoreCallingIdentity(ident); 8587 } 8588 } 8589 8590 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8591 synchronized (this) { 8592 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8593 if (!isDebuggable) { 8594 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8595 throw new SecurityException("Process not debuggable: " + app.packageName); 8596 } 8597 } 8598 8599 mOpenGlTraceApp = processName; 8600 } 8601 } 8602 8603 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8604 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8605 synchronized (this) { 8606 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8607 if (!isDebuggable) { 8608 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8609 throw new SecurityException("Process not debuggable: " + app.packageName); 8610 } 8611 } 8612 mProfileApp = processName; 8613 mProfileFile = profileFile; 8614 if (mProfileFd != null) { 8615 try { 8616 mProfileFd.close(); 8617 } catch (IOException e) { 8618 } 8619 mProfileFd = null; 8620 } 8621 mProfileFd = profileFd; 8622 mProfileType = 0; 8623 mAutoStopProfiler = autoStopProfiler; 8624 } 8625 } 8626 8627 @Override 8628 public void setAlwaysFinish(boolean enabled) { 8629 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8630 "setAlwaysFinish()"); 8631 8632 Settings.Global.putInt( 8633 mContext.getContentResolver(), 8634 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8635 8636 synchronized (this) { 8637 mAlwaysFinishActivities = enabled; 8638 } 8639 } 8640 8641 @Override 8642 public void setActivityController(IActivityController controller) { 8643 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8644 "setActivityController()"); 8645 synchronized (this) { 8646 mController = controller; 8647 Watchdog.getInstance().setActivityController(controller); 8648 } 8649 } 8650 8651 @Override 8652 public void setUserIsMonkey(boolean userIsMonkey) { 8653 synchronized (this) { 8654 synchronized (mPidsSelfLocked) { 8655 final int callingPid = Binder.getCallingPid(); 8656 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8657 if (precessRecord == null) { 8658 throw new SecurityException("Unknown process: " + callingPid); 8659 } 8660 if (precessRecord.instrumentationUiAutomationConnection == null) { 8661 throw new SecurityException("Only an instrumentation process " 8662 + "with a UiAutomation can call setUserIsMonkey"); 8663 } 8664 } 8665 mUserIsMonkey = userIsMonkey; 8666 } 8667 } 8668 8669 @Override 8670 public boolean isUserAMonkey() { 8671 synchronized (this) { 8672 // If there is a controller also implies the user is a monkey. 8673 return (mUserIsMonkey || mController != null); 8674 } 8675 } 8676 8677 public void requestBugReport() { 8678 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8679 SystemProperties.set("ctl.start", "bugreport"); 8680 } 8681 8682 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8683 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8684 } 8685 8686 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8687 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8688 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8689 } 8690 return KEY_DISPATCHING_TIMEOUT; 8691 } 8692 8693 @Override 8694 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8695 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8696 != PackageManager.PERMISSION_GRANTED) { 8697 throw new SecurityException("Requires permission " 8698 + android.Manifest.permission.FILTER_EVENTS); 8699 } 8700 ProcessRecord proc; 8701 long timeout; 8702 synchronized (this) { 8703 synchronized (mPidsSelfLocked) { 8704 proc = mPidsSelfLocked.get(pid); 8705 } 8706 timeout = getInputDispatchingTimeoutLocked(proc); 8707 } 8708 8709 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8710 return -1; 8711 } 8712 8713 return timeout; 8714 } 8715 8716 /** 8717 * Handle input dispatching timeouts. 8718 * Returns whether input dispatching should be aborted or not. 8719 */ 8720 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8721 final ActivityRecord activity, final ActivityRecord parent, 8722 final boolean aboveSystem, String reason) { 8723 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8724 != PackageManager.PERMISSION_GRANTED) { 8725 throw new SecurityException("Requires permission " 8726 + android.Manifest.permission.FILTER_EVENTS); 8727 } 8728 8729 final String annotation; 8730 if (reason == null) { 8731 annotation = "Input dispatching timed out"; 8732 } else { 8733 annotation = "Input dispatching timed out (" + reason + ")"; 8734 } 8735 8736 if (proc != null) { 8737 synchronized (this) { 8738 if (proc.debugging) { 8739 return false; 8740 } 8741 8742 if (mDidDexOpt) { 8743 // Give more time since we were dexopting. 8744 mDidDexOpt = false; 8745 return false; 8746 } 8747 8748 if (proc.instrumentationClass != null) { 8749 Bundle info = new Bundle(); 8750 info.putString("shortMsg", "keyDispatchingTimedOut"); 8751 info.putString("longMsg", annotation); 8752 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8753 return true; 8754 } 8755 } 8756 mHandler.post(new Runnable() { 8757 @Override 8758 public void run() { 8759 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8760 } 8761 }); 8762 } 8763 8764 return true; 8765 } 8766 8767 public Bundle getAssistContextExtras(int requestType) { 8768 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8769 "getAssistContextExtras()"); 8770 PendingAssistExtras pae; 8771 Bundle extras = new Bundle(); 8772 synchronized (this) { 8773 ActivityRecord activity = getFocusedStack().mResumedActivity; 8774 if (activity == null) { 8775 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8776 return null; 8777 } 8778 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8779 if (activity.app == null || activity.app.thread == null) { 8780 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8781 return extras; 8782 } 8783 if (activity.app.pid == Binder.getCallingPid()) { 8784 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8785 return extras; 8786 } 8787 pae = new PendingAssistExtras(activity); 8788 try { 8789 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8790 requestType); 8791 mPendingAssistExtras.add(pae); 8792 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8793 } catch (RemoteException e) { 8794 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8795 return extras; 8796 } 8797 } 8798 synchronized (pae) { 8799 while (!pae.haveResult) { 8800 try { 8801 pae.wait(); 8802 } catch (InterruptedException e) { 8803 } 8804 } 8805 if (pae.result != null) { 8806 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8807 } 8808 } 8809 synchronized (this) { 8810 mPendingAssistExtras.remove(pae); 8811 mHandler.removeCallbacks(pae); 8812 } 8813 return extras; 8814 } 8815 8816 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8817 PendingAssistExtras pae = (PendingAssistExtras)token; 8818 synchronized (pae) { 8819 pae.result = extras; 8820 pae.haveResult = true; 8821 pae.notifyAll(); 8822 } 8823 } 8824 8825 public void registerProcessObserver(IProcessObserver observer) { 8826 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8827 "registerProcessObserver()"); 8828 synchronized (this) { 8829 mProcessObservers.register(observer); 8830 } 8831 } 8832 8833 @Override 8834 public void unregisterProcessObserver(IProcessObserver observer) { 8835 synchronized (this) { 8836 mProcessObservers.unregister(observer); 8837 } 8838 } 8839 8840 @Override 8841 public boolean convertFromTranslucent(IBinder token) { 8842 final long origId = Binder.clearCallingIdentity(); 8843 try { 8844 synchronized (this) { 8845 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8846 if (r == null) { 8847 return false; 8848 } 8849 if (r.changeWindowTranslucency(true)) { 8850 mWindowManager.setAppFullscreen(token, true); 8851 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8852 return true; 8853 } 8854 return false; 8855 } 8856 } finally { 8857 Binder.restoreCallingIdentity(origId); 8858 } 8859 } 8860 8861 @Override 8862 public boolean convertToTranslucent(IBinder token) { 8863 final long origId = Binder.clearCallingIdentity(); 8864 try { 8865 synchronized (this) { 8866 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8867 if (r == null) { 8868 return false; 8869 } 8870 if (r.changeWindowTranslucency(false)) { 8871 r.task.stack.convertToTranslucent(r); 8872 mWindowManager.setAppFullscreen(token, false); 8873 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8874 return true; 8875 } 8876 return false; 8877 } 8878 } finally { 8879 Binder.restoreCallingIdentity(origId); 8880 } 8881 } 8882 8883 @Override 8884 public void setImmersive(IBinder token, boolean immersive) { 8885 synchronized(this) { 8886 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8887 if (r == null) { 8888 throw new IllegalArgumentException(); 8889 } 8890 r.immersive = immersive; 8891 8892 // update associated state if we're frontmost 8893 if (r == mFocusedActivity) { 8894 if (DEBUG_IMMERSIVE) { 8895 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8896 } 8897 applyUpdateLockStateLocked(r); 8898 } 8899 } 8900 } 8901 8902 @Override 8903 public boolean isImmersive(IBinder token) { 8904 synchronized (this) { 8905 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8906 if (r == null) { 8907 throw new IllegalArgumentException(); 8908 } 8909 return r.immersive; 8910 } 8911 } 8912 8913 public boolean isTopActivityImmersive() { 8914 enforceNotIsolatedCaller("startActivity"); 8915 synchronized (this) { 8916 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8917 return (r != null) ? r.immersive : false; 8918 } 8919 } 8920 8921 public final void enterSafeMode() { 8922 synchronized(this) { 8923 // It only makes sense to do this before the system is ready 8924 // and started launching other packages. 8925 if (!mSystemReady) { 8926 try { 8927 AppGlobals.getPackageManager().enterSafeMode(); 8928 } catch (RemoteException e) { 8929 } 8930 } 8931 } 8932 } 8933 8934 public final void showSafeModeOverlay() { 8935 View v = LayoutInflater.from(mContext).inflate( 8936 com.android.internal.R.layout.safe_mode, null); 8937 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8938 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8939 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8940 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8941 lp.gravity = Gravity.BOTTOM | Gravity.START; 8942 lp.format = v.getBackground().getOpacity(); 8943 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8944 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8945 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8946 ((WindowManager)mContext.getSystemService( 8947 Context.WINDOW_SERVICE)).addView(v, lp); 8948 } 8949 8950 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8951 if (!(sender instanceof PendingIntentRecord)) { 8952 return; 8953 } 8954 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8955 synchronized (stats) { 8956 if (mBatteryStatsService.isOnBattery()) { 8957 mBatteryStatsService.enforceCallingPermission(); 8958 PendingIntentRecord rec = (PendingIntentRecord)sender; 8959 int MY_UID = Binder.getCallingUid(); 8960 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8961 BatteryStatsImpl.Uid.Pkg pkg = 8962 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8963 sourcePkg != null ? sourcePkg : rec.key.packageName); 8964 pkg.incWakeupsLocked(); 8965 } 8966 } 8967 } 8968 8969 public boolean killPids(int[] pids, String pReason, boolean secure) { 8970 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8971 throw new SecurityException("killPids only available to the system"); 8972 } 8973 String reason = (pReason == null) ? "Unknown" : pReason; 8974 // XXX Note: don't acquire main activity lock here, because the window 8975 // manager calls in with its locks held. 8976 8977 boolean killed = false; 8978 synchronized (mPidsSelfLocked) { 8979 int[] types = new int[pids.length]; 8980 int worstType = 0; 8981 for (int i=0; i<pids.length; i++) { 8982 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8983 if (proc != null) { 8984 int type = proc.setAdj; 8985 types[i] = type; 8986 if (type > worstType) { 8987 worstType = type; 8988 } 8989 } 8990 } 8991 8992 // If the worst oom_adj is somewhere in the cached proc LRU range, 8993 // then constrain it so we will kill all cached procs. 8994 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8995 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8996 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8997 } 8998 8999 // If this is not a secure call, don't let it kill processes that 9000 // are important. 9001 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9002 worstType = ProcessList.SERVICE_ADJ; 9003 } 9004 9005 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9006 for (int i=0; i<pids.length; i++) { 9007 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9008 if (proc == null) { 9009 continue; 9010 } 9011 int adj = proc.setAdj; 9012 if (adj >= worstType && !proc.killedByAm) { 9013 killUnneededProcessLocked(proc, reason); 9014 killed = true; 9015 } 9016 } 9017 } 9018 return killed; 9019 } 9020 9021 @Override 9022 public void killUid(int uid, String reason) { 9023 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9024 throw new SecurityException("killUid only available to the system"); 9025 } 9026 synchronized (this) { 9027 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9028 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9029 reason != null ? reason : "kill uid"); 9030 } 9031 } 9032 9033 @Override 9034 public boolean killProcessesBelowForeground(String reason) { 9035 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9036 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9037 } 9038 9039 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9040 } 9041 9042 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9043 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9044 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9045 } 9046 9047 boolean killed = false; 9048 synchronized (mPidsSelfLocked) { 9049 final int size = mPidsSelfLocked.size(); 9050 for (int i = 0; i < size; i++) { 9051 final int pid = mPidsSelfLocked.keyAt(i); 9052 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9053 if (proc == null) continue; 9054 9055 final int adj = proc.setAdj; 9056 if (adj > belowAdj && !proc.killedByAm) { 9057 killUnneededProcessLocked(proc, reason); 9058 killed = true; 9059 } 9060 } 9061 } 9062 return killed; 9063 } 9064 9065 @Override 9066 public void hang(final IBinder who, boolean allowRestart) { 9067 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9068 != PackageManager.PERMISSION_GRANTED) { 9069 throw new SecurityException("Requires permission " 9070 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9071 } 9072 9073 final IBinder.DeathRecipient death = new DeathRecipient() { 9074 @Override 9075 public void binderDied() { 9076 synchronized (this) { 9077 notifyAll(); 9078 } 9079 } 9080 }; 9081 9082 try { 9083 who.linkToDeath(death, 0); 9084 } catch (RemoteException e) { 9085 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9086 return; 9087 } 9088 9089 synchronized (this) { 9090 Watchdog.getInstance().setAllowRestart(allowRestart); 9091 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9092 synchronized (death) { 9093 while (who.isBinderAlive()) { 9094 try { 9095 death.wait(); 9096 } catch (InterruptedException e) { 9097 } 9098 } 9099 } 9100 Watchdog.getInstance().setAllowRestart(true); 9101 } 9102 } 9103 9104 @Override 9105 public void restart() { 9106 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9107 != PackageManager.PERMISSION_GRANTED) { 9108 throw new SecurityException("Requires permission " 9109 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9110 } 9111 9112 Log.i(TAG, "Sending shutdown broadcast..."); 9113 9114 BroadcastReceiver br = new BroadcastReceiver() { 9115 @Override public void onReceive(Context context, Intent intent) { 9116 // Now the broadcast is done, finish up the low-level shutdown. 9117 Log.i(TAG, "Shutting down activity manager..."); 9118 shutdown(10000); 9119 Log.i(TAG, "Shutdown complete, restarting!"); 9120 Process.killProcess(Process.myPid()); 9121 System.exit(10); 9122 } 9123 }; 9124 9125 // First send the high-level shut down broadcast. 9126 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9127 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9128 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9129 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9130 mContext.sendOrderedBroadcastAsUser(intent, 9131 UserHandle.ALL, null, br, mHandler, 0, null, null); 9132 */ 9133 br.onReceive(mContext, intent); 9134 } 9135 9136 private long getLowRamTimeSinceIdle(long now) { 9137 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9138 } 9139 9140 @Override 9141 public void performIdleMaintenance() { 9142 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9143 != PackageManager.PERMISSION_GRANTED) { 9144 throw new SecurityException("Requires permission " 9145 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9146 } 9147 9148 synchronized (this) { 9149 final long now = SystemClock.uptimeMillis(); 9150 final long timeSinceLastIdle = now - mLastIdleTime; 9151 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9152 mLastIdleTime = now; 9153 mLowRamTimeSinceLastIdle = 0; 9154 if (mLowRamStartTime != 0) { 9155 mLowRamStartTime = now; 9156 } 9157 9158 StringBuilder sb = new StringBuilder(128); 9159 sb.append("Idle maintenance over "); 9160 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9161 sb.append(" low RAM for "); 9162 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9163 Slog.i(TAG, sb.toString()); 9164 9165 // If at least 1/3 of our time since the last idle period has been spent 9166 // with RAM low, then we want to kill processes. 9167 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9168 9169 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9170 ProcessRecord proc = mLruProcesses.get(i); 9171 if (proc.notCachedSinceIdle) { 9172 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9173 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9174 if (doKilling && proc.initialIdlePss != 0 9175 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9176 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9177 + " from " + proc.initialIdlePss + ")"); 9178 } 9179 } 9180 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9181 proc.notCachedSinceIdle = true; 9182 proc.initialIdlePss = 0; 9183 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9184 mSleeping, now); 9185 } 9186 } 9187 9188 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9189 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9190 } 9191 } 9192 9193 public final void startRunning(String pkg, String cls, String action, 9194 String data) { 9195 synchronized(this) { 9196 if (mStartRunning) { 9197 return; 9198 } 9199 mStartRunning = true; 9200 mTopComponent = pkg != null && cls != null 9201 ? new ComponentName(pkg, cls) : null; 9202 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9203 mTopData = data; 9204 if (!mSystemReady) { 9205 return; 9206 } 9207 } 9208 9209 systemReady(null); 9210 } 9211 9212 private void retrieveSettings() { 9213 final ContentResolver resolver = mContext.getContentResolver(); 9214 String debugApp = Settings.Global.getString( 9215 resolver, Settings.Global.DEBUG_APP); 9216 boolean waitForDebugger = Settings.Global.getInt( 9217 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9218 boolean alwaysFinishActivities = Settings.Global.getInt( 9219 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9220 boolean forceRtl = Settings.Global.getInt( 9221 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9222 // Transfer any global setting for forcing RTL layout, into a System Property 9223 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9224 9225 Configuration configuration = new Configuration(); 9226 Settings.System.getConfiguration(resolver, configuration); 9227 if (forceRtl) { 9228 // This will take care of setting the correct layout direction flags 9229 configuration.setLayoutDirection(configuration.locale); 9230 } 9231 9232 synchronized (this) { 9233 mDebugApp = mOrigDebugApp = debugApp; 9234 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9235 mAlwaysFinishActivities = alwaysFinishActivities; 9236 // This happens before any activities are started, so we can 9237 // change mConfiguration in-place. 9238 updateConfigurationLocked(configuration, null, false, true); 9239 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9240 } 9241 } 9242 9243 public boolean testIsSystemReady() { 9244 // no need to synchronize(this) just to read & return the value 9245 return mSystemReady; 9246 } 9247 9248 private static File getCalledPreBootReceiversFile() { 9249 File dataDir = Environment.getDataDirectory(); 9250 File systemDir = new File(dataDir, "system"); 9251 File fname = new File(systemDir, "called_pre_boots.dat"); 9252 return fname; 9253 } 9254 9255 static final int LAST_DONE_VERSION = 10000; 9256 9257 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9258 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9259 File file = getCalledPreBootReceiversFile(); 9260 FileInputStream fis = null; 9261 try { 9262 fis = new FileInputStream(file); 9263 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9264 int fvers = dis.readInt(); 9265 if (fvers == LAST_DONE_VERSION) { 9266 String vers = dis.readUTF(); 9267 String codename = dis.readUTF(); 9268 String build = dis.readUTF(); 9269 if (android.os.Build.VERSION.RELEASE.equals(vers) 9270 && android.os.Build.VERSION.CODENAME.equals(codename) 9271 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9272 int num = dis.readInt(); 9273 while (num > 0) { 9274 num--; 9275 String pkg = dis.readUTF(); 9276 String cls = dis.readUTF(); 9277 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9278 } 9279 } 9280 } 9281 } catch (FileNotFoundException e) { 9282 } catch (IOException e) { 9283 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9284 } finally { 9285 if (fis != null) { 9286 try { 9287 fis.close(); 9288 } catch (IOException e) { 9289 } 9290 } 9291 } 9292 return lastDoneReceivers; 9293 } 9294 9295 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9296 File file = getCalledPreBootReceiversFile(); 9297 FileOutputStream fos = null; 9298 DataOutputStream dos = null; 9299 try { 9300 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9301 fos = new FileOutputStream(file); 9302 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9303 dos.writeInt(LAST_DONE_VERSION); 9304 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9305 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9306 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9307 dos.writeInt(list.size()); 9308 for (int i=0; i<list.size(); i++) { 9309 dos.writeUTF(list.get(i).getPackageName()); 9310 dos.writeUTF(list.get(i).getClassName()); 9311 } 9312 } catch (IOException e) { 9313 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9314 file.delete(); 9315 } finally { 9316 FileUtils.sync(fos); 9317 if (dos != null) { 9318 try { 9319 dos.close(); 9320 } catch (IOException e) { 9321 // TODO Auto-generated catch block 9322 e.printStackTrace(); 9323 } 9324 } 9325 } 9326 } 9327 9328 public void systemReady(final Runnable goingCallback) { 9329 synchronized(this) { 9330 if (mSystemReady) { 9331 if (goingCallback != null) goingCallback.run(); 9332 return; 9333 } 9334 9335 // Check to see if there are any update receivers to run. 9336 if (!mDidUpdate) { 9337 if (mWaitingUpdate) { 9338 return; 9339 } 9340 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9341 List<ResolveInfo> ris = null; 9342 try { 9343 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9344 intent, null, 0, 0); 9345 } catch (RemoteException e) { 9346 } 9347 if (ris != null) { 9348 for (int i=ris.size()-1; i>=0; i--) { 9349 if ((ris.get(i).activityInfo.applicationInfo.flags 9350 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9351 ris.remove(i); 9352 } 9353 } 9354 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9355 9356 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9357 9358 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9359 for (int i=0; i<ris.size(); i++) { 9360 ActivityInfo ai = ris.get(i).activityInfo; 9361 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9362 if (lastDoneReceivers.contains(comp)) { 9363 // We already did the pre boot receiver for this app with the current 9364 // platform version, so don't do it again... 9365 ris.remove(i); 9366 i--; 9367 // ...however, do keep it as one that has been done, so we don't 9368 // forget about it when rewriting the file of last done receivers. 9369 doneReceivers.add(comp); 9370 } 9371 } 9372 9373 final int[] users = getUsersLocked(); 9374 for (int i=0; i<ris.size(); i++) { 9375 ActivityInfo ai = ris.get(i).activityInfo; 9376 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9377 doneReceivers.add(comp); 9378 intent.setComponent(comp); 9379 for (int j=0; j<users.length; j++) { 9380 IIntentReceiver finisher = null; 9381 if (i == ris.size()-1 && j == users.length-1) { 9382 finisher = new IIntentReceiver.Stub() { 9383 public void performReceive(Intent intent, int resultCode, 9384 String data, Bundle extras, boolean ordered, 9385 boolean sticky, int sendingUser) { 9386 // The raw IIntentReceiver interface is called 9387 // with the AM lock held, so redispatch to 9388 // execute our code without the lock. 9389 mHandler.post(new Runnable() { 9390 public void run() { 9391 synchronized (ActivityManagerService.this) { 9392 mDidUpdate = true; 9393 } 9394 writeLastDonePreBootReceivers(doneReceivers); 9395 showBootMessage(mContext.getText( 9396 R.string.android_upgrading_complete), 9397 false); 9398 systemReady(goingCallback); 9399 } 9400 }); 9401 } 9402 }; 9403 } 9404 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9405 + " for user " + users[j]); 9406 broadcastIntentLocked(null, null, intent, null, finisher, 9407 0, null, null, null, AppOpsManager.OP_NONE, 9408 true, false, MY_PID, Process.SYSTEM_UID, 9409 users[j]); 9410 if (finisher != null) { 9411 mWaitingUpdate = true; 9412 } 9413 } 9414 } 9415 } 9416 if (mWaitingUpdate) { 9417 return; 9418 } 9419 mDidUpdate = true; 9420 } 9421 9422 mAppOpsService.systemReady(); 9423 mSystemReady = true; 9424 if (!mStartRunning) { 9425 return; 9426 } 9427 } 9428 9429 ArrayList<ProcessRecord> procsToKill = null; 9430 synchronized(mPidsSelfLocked) { 9431 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9432 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9433 if (!isAllowedWhileBooting(proc.info)){ 9434 if (procsToKill == null) { 9435 procsToKill = new ArrayList<ProcessRecord>(); 9436 } 9437 procsToKill.add(proc); 9438 } 9439 } 9440 } 9441 9442 synchronized(this) { 9443 if (procsToKill != null) { 9444 for (int i=procsToKill.size()-1; i>=0; i--) { 9445 ProcessRecord proc = procsToKill.get(i); 9446 Slog.i(TAG, "Removing system update proc: " + proc); 9447 removeProcessLocked(proc, true, false, "system update done"); 9448 } 9449 } 9450 9451 // Now that we have cleaned up any update processes, we 9452 // are ready to start launching real processes and know that 9453 // we won't trample on them any more. 9454 mProcessesReady = true; 9455 } 9456 9457 Slog.i(TAG, "System now ready"); 9458 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9459 SystemClock.uptimeMillis()); 9460 9461 synchronized(this) { 9462 // Make sure we have no pre-ready processes sitting around. 9463 9464 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9465 ResolveInfo ri = mContext.getPackageManager() 9466 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9467 STOCK_PM_FLAGS); 9468 CharSequence errorMsg = null; 9469 if (ri != null) { 9470 ActivityInfo ai = ri.activityInfo; 9471 ApplicationInfo app = ai.applicationInfo; 9472 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9473 mTopAction = Intent.ACTION_FACTORY_TEST; 9474 mTopData = null; 9475 mTopComponent = new ComponentName(app.packageName, 9476 ai.name); 9477 } else { 9478 errorMsg = mContext.getResources().getText( 9479 com.android.internal.R.string.factorytest_not_system); 9480 } 9481 } else { 9482 errorMsg = mContext.getResources().getText( 9483 com.android.internal.R.string.factorytest_no_action); 9484 } 9485 if (errorMsg != null) { 9486 mTopAction = null; 9487 mTopData = null; 9488 mTopComponent = null; 9489 Message msg = Message.obtain(); 9490 msg.what = SHOW_FACTORY_ERROR_MSG; 9491 msg.getData().putCharSequence("msg", errorMsg); 9492 mHandler.sendMessage(msg); 9493 } 9494 } 9495 } 9496 9497 retrieveSettings(); 9498 9499 synchronized (this) { 9500 readGrantedUriPermissionsLocked(); 9501 } 9502 9503 if (goingCallback != null) goingCallback.run(); 9504 9505 synchronized (this) { 9506 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9507 try { 9508 List apps = AppGlobals.getPackageManager(). 9509 getPersistentApplications(STOCK_PM_FLAGS); 9510 if (apps != null) { 9511 int N = apps.size(); 9512 int i; 9513 for (i=0; i<N; i++) { 9514 ApplicationInfo info 9515 = (ApplicationInfo)apps.get(i); 9516 if (info != null && 9517 !info.packageName.equals("android")) { 9518 addAppLocked(info, false); 9519 } 9520 } 9521 } 9522 } catch (RemoteException ex) { 9523 // pm is in same process, this will never happen. 9524 } 9525 } 9526 9527 // Start up initial activity. 9528 mBooting = true; 9529 9530 try { 9531 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9532 Message msg = Message.obtain(); 9533 msg.what = SHOW_UID_ERROR_MSG; 9534 mHandler.sendMessage(msg); 9535 } 9536 } catch (RemoteException e) { 9537 } 9538 9539 long ident = Binder.clearCallingIdentity(); 9540 try { 9541 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9542 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9543 | Intent.FLAG_RECEIVER_FOREGROUND); 9544 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9545 broadcastIntentLocked(null, null, intent, 9546 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9547 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9548 intent = new Intent(Intent.ACTION_USER_STARTING); 9549 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9550 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9551 broadcastIntentLocked(null, null, intent, 9552 null, new IIntentReceiver.Stub() { 9553 @Override 9554 public void performReceive(Intent intent, int resultCode, String data, 9555 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9556 throws RemoteException { 9557 } 9558 }, 0, null, null, 9559 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9560 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9561 } finally { 9562 Binder.restoreCallingIdentity(ident); 9563 } 9564 mStackSupervisor.resumeTopActivitiesLocked(); 9565 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9566 } 9567 } 9568 9569 private boolean makeAppCrashingLocked(ProcessRecord app, 9570 String shortMsg, String longMsg, String stackTrace) { 9571 app.crashing = true; 9572 app.crashingReport = generateProcessError(app, 9573 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9574 startAppProblemLocked(app); 9575 app.stopFreezingAllLocked(); 9576 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9577 } 9578 9579 private void makeAppNotRespondingLocked(ProcessRecord app, 9580 String activity, String shortMsg, String longMsg) { 9581 app.notResponding = true; 9582 app.notRespondingReport = generateProcessError(app, 9583 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9584 activity, shortMsg, longMsg, null); 9585 startAppProblemLocked(app); 9586 app.stopFreezingAllLocked(); 9587 } 9588 9589 /** 9590 * Generate a process error record, suitable for attachment to a ProcessRecord. 9591 * 9592 * @param app The ProcessRecord in which the error occurred. 9593 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9594 * ActivityManager.AppErrorStateInfo 9595 * @param activity The activity associated with the crash, if known. 9596 * @param shortMsg Short message describing the crash. 9597 * @param longMsg Long message describing the crash. 9598 * @param stackTrace Full crash stack trace, may be null. 9599 * 9600 * @return Returns a fully-formed AppErrorStateInfo record. 9601 */ 9602 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9603 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9604 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9605 9606 report.condition = condition; 9607 report.processName = app.processName; 9608 report.pid = app.pid; 9609 report.uid = app.info.uid; 9610 report.tag = activity; 9611 report.shortMsg = shortMsg; 9612 report.longMsg = longMsg; 9613 report.stackTrace = stackTrace; 9614 9615 return report; 9616 } 9617 9618 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9619 synchronized (this) { 9620 app.crashing = false; 9621 app.crashingReport = null; 9622 app.notResponding = false; 9623 app.notRespondingReport = null; 9624 if (app.anrDialog == fromDialog) { 9625 app.anrDialog = null; 9626 } 9627 if (app.waitDialog == fromDialog) { 9628 app.waitDialog = null; 9629 } 9630 if (app.pid > 0 && app.pid != MY_PID) { 9631 handleAppCrashLocked(app, null, null, null); 9632 killUnneededProcessLocked(app, "user request after error"); 9633 } 9634 } 9635 } 9636 9637 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9638 String stackTrace) { 9639 long now = SystemClock.uptimeMillis(); 9640 9641 Long crashTime; 9642 if (!app.isolated) { 9643 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9644 } else { 9645 crashTime = null; 9646 } 9647 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9648 // This process loses! 9649 Slog.w(TAG, "Process " + app.info.processName 9650 + " has crashed too many times: killing!"); 9651 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9652 app.userId, app.info.processName, app.uid); 9653 mStackSupervisor.handleAppCrashLocked(app); 9654 if (!app.persistent) { 9655 // We don't want to start this process again until the user 9656 // explicitly does so... but for persistent process, we really 9657 // need to keep it running. If a persistent process is actually 9658 // repeatedly crashing, then badness for everyone. 9659 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9660 app.info.processName); 9661 if (!app.isolated) { 9662 // XXX We don't have a way to mark isolated processes 9663 // as bad, since they don't have a peristent identity. 9664 mBadProcesses.put(app.info.processName, app.uid, 9665 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9666 mProcessCrashTimes.remove(app.info.processName, app.uid); 9667 } 9668 app.bad = true; 9669 app.removed = true; 9670 // Don't let services in this process be restarted and potentially 9671 // annoy the user repeatedly. Unless it is persistent, since those 9672 // processes run critical code. 9673 removeProcessLocked(app, false, false, "crash"); 9674 mStackSupervisor.resumeTopActivitiesLocked(); 9675 return false; 9676 } 9677 mStackSupervisor.resumeTopActivitiesLocked(); 9678 } else { 9679 mStackSupervisor.finishTopRunningActivityLocked(app); 9680 } 9681 9682 // Bump up the crash count of any services currently running in the proc. 9683 for (int i=app.services.size()-1; i>=0; i--) { 9684 // Any services running in the application need to be placed 9685 // back in the pending list. 9686 ServiceRecord sr = app.services.valueAt(i); 9687 sr.crashCount++; 9688 } 9689 9690 // If the crashing process is what we consider to be the "home process" and it has been 9691 // replaced by a third-party app, clear the package preferred activities from packages 9692 // with a home activity running in the process to prevent a repeatedly crashing app 9693 // from blocking the user to manually clear the list. 9694 final ArrayList<ActivityRecord> activities = app.activities; 9695 if (app == mHomeProcess && activities.size() > 0 9696 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9697 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9698 final ActivityRecord r = activities.get(activityNdx); 9699 if (r.isHomeActivity()) { 9700 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9701 try { 9702 ActivityThread.getPackageManager() 9703 .clearPackagePreferredActivities(r.packageName); 9704 } catch (RemoteException c) { 9705 // pm is in same process, this will never happen. 9706 } 9707 } 9708 } 9709 } 9710 9711 if (!app.isolated) { 9712 // XXX Can't keep track of crash times for isolated processes, 9713 // because they don't have a perisistent identity. 9714 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9715 } 9716 9717 return true; 9718 } 9719 9720 void startAppProblemLocked(ProcessRecord app) { 9721 if (app.userId == mCurrentUserId) { 9722 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9723 mContext, app.info.packageName, app.info.flags); 9724 } else { 9725 // If this app is not running under the current user, then we 9726 // can't give it a report button because that would require 9727 // launching the report UI under a different user. 9728 app.errorReportReceiver = null; 9729 } 9730 skipCurrentReceiverLocked(app); 9731 } 9732 9733 void skipCurrentReceiverLocked(ProcessRecord app) { 9734 for (BroadcastQueue queue : mBroadcastQueues) { 9735 queue.skipCurrentReceiverLocked(app); 9736 } 9737 } 9738 9739 /** 9740 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9741 * The application process will exit immediately after this call returns. 9742 * @param app object of the crashing app, null for the system server 9743 * @param crashInfo describing the exception 9744 */ 9745 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9746 ProcessRecord r = findAppProcess(app, "Crash"); 9747 final String processName = app == null ? "system_server" 9748 : (r == null ? "unknown" : r.processName); 9749 9750 handleApplicationCrashInner("crash", r, processName, crashInfo); 9751 } 9752 9753 /* Native crash reporting uses this inner version because it needs to be somewhat 9754 * decoupled from the AM-managed cleanup lifecycle 9755 */ 9756 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9757 ApplicationErrorReport.CrashInfo crashInfo) { 9758 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9759 UserHandle.getUserId(Binder.getCallingUid()), processName, 9760 r == null ? -1 : r.info.flags, 9761 crashInfo.exceptionClassName, 9762 crashInfo.exceptionMessage, 9763 crashInfo.throwFileName, 9764 crashInfo.throwLineNumber); 9765 9766 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9767 9768 crashApplication(r, crashInfo); 9769 } 9770 9771 public void handleApplicationStrictModeViolation( 9772 IBinder app, 9773 int violationMask, 9774 StrictMode.ViolationInfo info) { 9775 ProcessRecord r = findAppProcess(app, "StrictMode"); 9776 if (r == null) { 9777 return; 9778 } 9779 9780 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9781 Integer stackFingerprint = info.hashCode(); 9782 boolean logIt = true; 9783 synchronized (mAlreadyLoggedViolatedStacks) { 9784 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9785 logIt = false; 9786 // TODO: sub-sample into EventLog for these, with 9787 // the info.durationMillis? Then we'd get 9788 // the relative pain numbers, without logging all 9789 // the stack traces repeatedly. We'd want to do 9790 // likewise in the client code, which also does 9791 // dup suppression, before the Binder call. 9792 } else { 9793 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9794 mAlreadyLoggedViolatedStacks.clear(); 9795 } 9796 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9797 } 9798 } 9799 if (logIt) { 9800 logStrictModeViolationToDropBox(r, info); 9801 } 9802 } 9803 9804 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9805 AppErrorResult result = new AppErrorResult(); 9806 synchronized (this) { 9807 final long origId = Binder.clearCallingIdentity(); 9808 9809 Message msg = Message.obtain(); 9810 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9811 HashMap<String, Object> data = new HashMap<String, Object>(); 9812 data.put("result", result); 9813 data.put("app", r); 9814 data.put("violationMask", violationMask); 9815 data.put("info", info); 9816 msg.obj = data; 9817 mHandler.sendMessage(msg); 9818 9819 Binder.restoreCallingIdentity(origId); 9820 } 9821 int res = result.get(); 9822 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9823 } 9824 } 9825 9826 // Depending on the policy in effect, there could be a bunch of 9827 // these in quick succession so we try to batch these together to 9828 // minimize disk writes, number of dropbox entries, and maximize 9829 // compression, by having more fewer, larger records. 9830 private void logStrictModeViolationToDropBox( 9831 ProcessRecord process, 9832 StrictMode.ViolationInfo info) { 9833 if (info == null) { 9834 return; 9835 } 9836 final boolean isSystemApp = process == null || 9837 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9838 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9839 final String processName = process == null ? "unknown" : process.processName; 9840 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9841 final DropBoxManager dbox = (DropBoxManager) 9842 mContext.getSystemService(Context.DROPBOX_SERVICE); 9843 9844 // Exit early if the dropbox isn't configured to accept this report type. 9845 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9846 9847 boolean bufferWasEmpty; 9848 boolean needsFlush; 9849 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9850 synchronized (sb) { 9851 bufferWasEmpty = sb.length() == 0; 9852 appendDropBoxProcessHeaders(process, processName, sb); 9853 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9854 sb.append("System-App: ").append(isSystemApp).append("\n"); 9855 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9856 if (info.violationNumThisLoop != 0) { 9857 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9858 } 9859 if (info.numAnimationsRunning != 0) { 9860 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9861 } 9862 if (info.broadcastIntentAction != null) { 9863 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9864 } 9865 if (info.durationMillis != -1) { 9866 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9867 } 9868 if (info.numInstances != -1) { 9869 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9870 } 9871 if (info.tags != null) { 9872 for (String tag : info.tags) { 9873 sb.append("Span-Tag: ").append(tag).append("\n"); 9874 } 9875 } 9876 sb.append("\n"); 9877 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9878 sb.append(info.crashInfo.stackTrace); 9879 } 9880 sb.append("\n"); 9881 9882 // Only buffer up to ~64k. Various logging bits truncate 9883 // things at 128k. 9884 needsFlush = (sb.length() > 64 * 1024); 9885 } 9886 9887 // Flush immediately if the buffer's grown too large, or this 9888 // is a non-system app. Non-system apps are isolated with a 9889 // different tag & policy and not batched. 9890 // 9891 // Batching is useful during internal testing with 9892 // StrictMode settings turned up high. Without batching, 9893 // thousands of separate files could be created on boot. 9894 if (!isSystemApp || needsFlush) { 9895 new Thread("Error dump: " + dropboxTag) { 9896 @Override 9897 public void run() { 9898 String report; 9899 synchronized (sb) { 9900 report = sb.toString(); 9901 sb.delete(0, sb.length()); 9902 sb.trimToSize(); 9903 } 9904 if (report.length() != 0) { 9905 dbox.addText(dropboxTag, report); 9906 } 9907 } 9908 }.start(); 9909 return; 9910 } 9911 9912 // System app batching: 9913 if (!bufferWasEmpty) { 9914 // An existing dropbox-writing thread is outstanding, so 9915 // we don't need to start it up. The existing thread will 9916 // catch the buffer appends we just did. 9917 return; 9918 } 9919 9920 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9921 // (After this point, we shouldn't access AMS internal data structures.) 9922 new Thread("Error dump: " + dropboxTag) { 9923 @Override 9924 public void run() { 9925 // 5 second sleep to let stacks arrive and be batched together 9926 try { 9927 Thread.sleep(5000); // 5 seconds 9928 } catch (InterruptedException e) {} 9929 9930 String errorReport; 9931 synchronized (mStrictModeBuffer) { 9932 errorReport = mStrictModeBuffer.toString(); 9933 if (errorReport.length() == 0) { 9934 return; 9935 } 9936 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9937 mStrictModeBuffer.trimToSize(); 9938 } 9939 dbox.addText(dropboxTag, errorReport); 9940 } 9941 }.start(); 9942 } 9943 9944 /** 9945 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9946 * @param app object of the crashing app, null for the system server 9947 * @param tag reported by the caller 9948 * @param crashInfo describing the context of the error 9949 * @return true if the process should exit immediately (WTF is fatal) 9950 */ 9951 public boolean handleApplicationWtf(IBinder app, String tag, 9952 ApplicationErrorReport.CrashInfo crashInfo) { 9953 ProcessRecord r = findAppProcess(app, "WTF"); 9954 final String processName = app == null ? "system_server" 9955 : (r == null ? "unknown" : r.processName); 9956 9957 EventLog.writeEvent(EventLogTags.AM_WTF, 9958 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9959 processName, 9960 r == null ? -1 : r.info.flags, 9961 tag, crashInfo.exceptionMessage); 9962 9963 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9964 9965 if (r != null && r.pid != Process.myPid() && 9966 Settings.Global.getInt(mContext.getContentResolver(), 9967 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9968 crashApplication(r, crashInfo); 9969 return true; 9970 } else { 9971 return false; 9972 } 9973 } 9974 9975 /** 9976 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9977 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9978 */ 9979 private ProcessRecord findAppProcess(IBinder app, String reason) { 9980 if (app == null) { 9981 return null; 9982 } 9983 9984 synchronized (this) { 9985 final int NP = mProcessNames.getMap().size(); 9986 for (int ip=0; ip<NP; ip++) { 9987 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9988 final int NA = apps.size(); 9989 for (int ia=0; ia<NA; ia++) { 9990 ProcessRecord p = apps.valueAt(ia); 9991 if (p.thread != null && p.thread.asBinder() == app) { 9992 return p; 9993 } 9994 } 9995 } 9996 9997 Slog.w(TAG, "Can't find mystery application for " + reason 9998 + " from pid=" + Binder.getCallingPid() 9999 + " uid=" + Binder.getCallingUid() + ": " + app); 10000 return null; 10001 } 10002 } 10003 10004 /** 10005 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10006 * to append various headers to the dropbox log text. 10007 */ 10008 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10009 StringBuilder sb) { 10010 // Watchdog thread ends up invoking this function (with 10011 // a null ProcessRecord) to add the stack file to dropbox. 10012 // Do not acquire a lock on this (am) in such cases, as it 10013 // could cause a potential deadlock, if and when watchdog 10014 // is invoked due to unavailability of lock on am and it 10015 // would prevent watchdog from killing system_server. 10016 if (process == null) { 10017 sb.append("Process: ").append(processName).append("\n"); 10018 return; 10019 } 10020 // Note: ProcessRecord 'process' is guarded by the service 10021 // instance. (notably process.pkgList, which could otherwise change 10022 // concurrently during execution of this method) 10023 synchronized (this) { 10024 sb.append("Process: ").append(processName).append("\n"); 10025 int flags = process.info.flags; 10026 IPackageManager pm = AppGlobals.getPackageManager(); 10027 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10028 for (int ip=0; ip<process.pkgList.size(); ip++) { 10029 String pkg = process.pkgList.keyAt(ip); 10030 sb.append("Package: ").append(pkg); 10031 try { 10032 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10033 if (pi != null) { 10034 sb.append(" v").append(pi.versionCode); 10035 if (pi.versionName != null) { 10036 sb.append(" (").append(pi.versionName).append(")"); 10037 } 10038 } 10039 } catch (RemoteException e) { 10040 Slog.e(TAG, "Error getting package info: " + pkg, e); 10041 } 10042 sb.append("\n"); 10043 } 10044 } 10045 } 10046 10047 private static String processClass(ProcessRecord process) { 10048 if (process == null || process.pid == MY_PID) { 10049 return "system_server"; 10050 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10051 return "system_app"; 10052 } else { 10053 return "data_app"; 10054 } 10055 } 10056 10057 /** 10058 * Write a description of an error (crash, WTF, ANR) to the drop box. 10059 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10060 * @param process which caused the error, null means the system server 10061 * @param activity which triggered the error, null if unknown 10062 * @param parent activity related to the error, null if unknown 10063 * @param subject line related to the error, null if absent 10064 * @param report in long form describing the error, null if absent 10065 * @param logFile to include in the report, null if none 10066 * @param crashInfo giving an application stack trace, null if absent 10067 */ 10068 public void addErrorToDropBox(String eventType, 10069 ProcessRecord process, String processName, ActivityRecord activity, 10070 ActivityRecord parent, String subject, 10071 final String report, final File logFile, 10072 final ApplicationErrorReport.CrashInfo crashInfo) { 10073 // NOTE -- this must never acquire the ActivityManagerService lock, 10074 // otherwise the watchdog may be prevented from resetting the system. 10075 10076 final String dropboxTag = processClass(process) + "_" + eventType; 10077 final DropBoxManager dbox = (DropBoxManager) 10078 mContext.getSystemService(Context.DROPBOX_SERVICE); 10079 10080 // Exit early if the dropbox isn't configured to accept this report type. 10081 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10082 10083 final StringBuilder sb = new StringBuilder(1024); 10084 appendDropBoxProcessHeaders(process, processName, sb); 10085 if (activity != null) { 10086 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10087 } 10088 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10089 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10090 } 10091 if (parent != null && parent != activity) { 10092 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10093 } 10094 if (subject != null) { 10095 sb.append("Subject: ").append(subject).append("\n"); 10096 } 10097 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10098 if (Debug.isDebuggerConnected()) { 10099 sb.append("Debugger: Connected\n"); 10100 } 10101 sb.append("\n"); 10102 10103 // Do the rest in a worker thread to avoid blocking the caller on I/O 10104 // (After this point, we shouldn't access AMS internal data structures.) 10105 Thread worker = new Thread("Error dump: " + dropboxTag) { 10106 @Override 10107 public void run() { 10108 if (report != null) { 10109 sb.append(report); 10110 } 10111 if (logFile != null) { 10112 try { 10113 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10114 "\n\n[[TRUNCATED]]")); 10115 } catch (IOException e) { 10116 Slog.e(TAG, "Error reading " + logFile, e); 10117 } 10118 } 10119 if (crashInfo != null && crashInfo.stackTrace != null) { 10120 sb.append(crashInfo.stackTrace); 10121 } 10122 10123 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10124 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10125 if (lines > 0) { 10126 sb.append("\n"); 10127 10128 // Merge several logcat streams, and take the last N lines 10129 InputStreamReader input = null; 10130 try { 10131 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10132 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10133 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10134 10135 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10136 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10137 input = new InputStreamReader(logcat.getInputStream()); 10138 10139 int num; 10140 char[] buf = new char[8192]; 10141 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10142 } catch (IOException e) { 10143 Slog.e(TAG, "Error running logcat", e); 10144 } finally { 10145 if (input != null) try { input.close(); } catch (IOException e) {} 10146 } 10147 } 10148 10149 dbox.addText(dropboxTag, sb.toString()); 10150 } 10151 }; 10152 10153 if (process == null) { 10154 // If process is null, we are being called from some internal code 10155 // and may be about to die -- run this synchronously. 10156 worker.run(); 10157 } else { 10158 worker.start(); 10159 } 10160 } 10161 10162 /** 10163 * Bring up the "unexpected error" dialog box for a crashing app. 10164 * Deal with edge cases (intercepts from instrumented applications, 10165 * ActivityController, error intent receivers, that sort of thing). 10166 * @param r the application crashing 10167 * @param crashInfo describing the failure 10168 */ 10169 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10170 long timeMillis = System.currentTimeMillis(); 10171 String shortMsg = crashInfo.exceptionClassName; 10172 String longMsg = crashInfo.exceptionMessage; 10173 String stackTrace = crashInfo.stackTrace; 10174 if (shortMsg != null && longMsg != null) { 10175 longMsg = shortMsg + ": " + longMsg; 10176 } else if (shortMsg != null) { 10177 longMsg = shortMsg; 10178 } 10179 10180 AppErrorResult result = new AppErrorResult(); 10181 synchronized (this) { 10182 if (mController != null) { 10183 try { 10184 String name = r != null ? r.processName : null; 10185 int pid = r != null ? r.pid : Binder.getCallingPid(); 10186 if (!mController.appCrashed(name, pid, 10187 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10188 Slog.w(TAG, "Force-killing crashed app " + name 10189 + " at watcher's request"); 10190 Process.killProcess(pid); 10191 return; 10192 } 10193 } catch (RemoteException e) { 10194 mController = null; 10195 Watchdog.getInstance().setActivityController(null); 10196 } 10197 } 10198 10199 final long origId = Binder.clearCallingIdentity(); 10200 10201 // If this process is running instrumentation, finish it. 10202 if (r != null && r.instrumentationClass != null) { 10203 Slog.w(TAG, "Error in app " + r.processName 10204 + " running instrumentation " + r.instrumentationClass + ":"); 10205 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10206 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10207 Bundle info = new Bundle(); 10208 info.putString("shortMsg", shortMsg); 10209 info.putString("longMsg", longMsg); 10210 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10211 Binder.restoreCallingIdentity(origId); 10212 return; 10213 } 10214 10215 // If we can't identify the process or it's already exceeded its crash quota, 10216 // quit right away without showing a crash dialog. 10217 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10218 Binder.restoreCallingIdentity(origId); 10219 return; 10220 } 10221 10222 Message msg = Message.obtain(); 10223 msg.what = SHOW_ERROR_MSG; 10224 HashMap data = new HashMap(); 10225 data.put("result", result); 10226 data.put("app", r); 10227 msg.obj = data; 10228 mHandler.sendMessage(msg); 10229 10230 Binder.restoreCallingIdentity(origId); 10231 } 10232 10233 int res = result.get(); 10234 10235 Intent appErrorIntent = null; 10236 synchronized (this) { 10237 if (r != null && !r.isolated) { 10238 // XXX Can't keep track of crash time for isolated processes, 10239 // since they don't have a persistent identity. 10240 mProcessCrashTimes.put(r.info.processName, r.uid, 10241 SystemClock.uptimeMillis()); 10242 } 10243 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10244 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10245 } 10246 } 10247 10248 if (appErrorIntent != null) { 10249 try { 10250 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10251 } catch (ActivityNotFoundException e) { 10252 Slog.w(TAG, "bug report receiver dissappeared", e); 10253 } 10254 } 10255 } 10256 10257 Intent createAppErrorIntentLocked(ProcessRecord r, 10258 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10259 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10260 if (report == null) { 10261 return null; 10262 } 10263 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10264 result.setComponent(r.errorReportReceiver); 10265 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10266 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10267 return result; 10268 } 10269 10270 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10271 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10272 if (r.errorReportReceiver == null) { 10273 return null; 10274 } 10275 10276 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10277 return null; 10278 } 10279 10280 ApplicationErrorReport report = new ApplicationErrorReport(); 10281 report.packageName = r.info.packageName; 10282 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10283 report.processName = r.processName; 10284 report.time = timeMillis; 10285 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10286 10287 if (r.crashing || r.forceCrashReport) { 10288 report.type = ApplicationErrorReport.TYPE_CRASH; 10289 report.crashInfo = crashInfo; 10290 } else if (r.notResponding) { 10291 report.type = ApplicationErrorReport.TYPE_ANR; 10292 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10293 10294 report.anrInfo.activity = r.notRespondingReport.tag; 10295 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10296 report.anrInfo.info = r.notRespondingReport.longMsg; 10297 } 10298 10299 return report; 10300 } 10301 10302 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10303 enforceNotIsolatedCaller("getProcessesInErrorState"); 10304 // assume our apps are happy - lazy create the list 10305 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10306 10307 final boolean allUsers = ActivityManager.checkUidPermission( 10308 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10309 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10310 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10311 10312 synchronized (this) { 10313 10314 // iterate across all processes 10315 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10316 ProcessRecord app = mLruProcesses.get(i); 10317 if (!allUsers && app.userId != userId) { 10318 continue; 10319 } 10320 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10321 // This one's in trouble, so we'll generate a report for it 10322 // crashes are higher priority (in case there's a crash *and* an anr) 10323 ActivityManager.ProcessErrorStateInfo report = null; 10324 if (app.crashing) { 10325 report = app.crashingReport; 10326 } else if (app.notResponding) { 10327 report = app.notRespondingReport; 10328 } 10329 10330 if (report != null) { 10331 if (errList == null) { 10332 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10333 } 10334 errList.add(report); 10335 } else { 10336 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10337 " crashing = " + app.crashing + 10338 " notResponding = " + app.notResponding); 10339 } 10340 } 10341 } 10342 } 10343 10344 return errList; 10345 } 10346 10347 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10348 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10349 if (currApp != null) { 10350 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10351 } 10352 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10353 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10354 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10355 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10356 if (currApp != null) { 10357 currApp.lru = 0; 10358 } 10359 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10360 } else if (adj >= ProcessList.SERVICE_ADJ) { 10361 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10362 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10363 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10364 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10365 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10366 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10367 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10368 } else { 10369 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10370 } 10371 } 10372 10373 private void fillInProcMemInfo(ProcessRecord app, 10374 ActivityManager.RunningAppProcessInfo outInfo) { 10375 outInfo.pid = app.pid; 10376 outInfo.uid = app.info.uid; 10377 if (mHeavyWeightProcess == app) { 10378 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10379 } 10380 if (app.persistent) { 10381 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10382 } 10383 if (app.activities.size() > 0) { 10384 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10385 } 10386 outInfo.lastTrimLevel = app.trimMemoryLevel; 10387 int adj = app.curAdj; 10388 outInfo.importance = oomAdjToImportance(adj, outInfo); 10389 outInfo.importanceReasonCode = app.adjTypeCode; 10390 } 10391 10392 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10393 enforceNotIsolatedCaller("getRunningAppProcesses"); 10394 // Lazy instantiation of list 10395 List<ActivityManager.RunningAppProcessInfo> runList = null; 10396 final boolean allUsers = ActivityManager.checkUidPermission( 10397 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10398 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10399 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10400 synchronized (this) { 10401 // Iterate across all processes 10402 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10403 ProcessRecord app = mLruProcesses.get(i); 10404 if (!allUsers && app.userId != userId) { 10405 continue; 10406 } 10407 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10408 // Generate process state info for running application 10409 ActivityManager.RunningAppProcessInfo currApp = 10410 new ActivityManager.RunningAppProcessInfo(app.processName, 10411 app.pid, app.getPackageList()); 10412 fillInProcMemInfo(app, currApp); 10413 if (app.adjSource instanceof ProcessRecord) { 10414 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10415 currApp.importanceReasonImportance = oomAdjToImportance( 10416 app.adjSourceOom, null); 10417 } else if (app.adjSource instanceof ActivityRecord) { 10418 ActivityRecord r = (ActivityRecord)app.adjSource; 10419 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10420 } 10421 if (app.adjTarget instanceof ComponentName) { 10422 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10423 } 10424 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10425 // + " lru=" + currApp.lru); 10426 if (runList == null) { 10427 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10428 } 10429 runList.add(currApp); 10430 } 10431 } 10432 } 10433 return runList; 10434 } 10435 10436 public List<ApplicationInfo> getRunningExternalApplications() { 10437 enforceNotIsolatedCaller("getRunningExternalApplications"); 10438 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10439 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10440 if (runningApps != null && runningApps.size() > 0) { 10441 Set<String> extList = new HashSet<String>(); 10442 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10443 if (app.pkgList != null) { 10444 for (String pkg : app.pkgList) { 10445 extList.add(pkg); 10446 } 10447 } 10448 } 10449 IPackageManager pm = AppGlobals.getPackageManager(); 10450 for (String pkg : extList) { 10451 try { 10452 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10453 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10454 retList.add(info); 10455 } 10456 } catch (RemoteException e) { 10457 } 10458 } 10459 } 10460 return retList; 10461 } 10462 10463 @Override 10464 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10465 enforceNotIsolatedCaller("getMyMemoryState"); 10466 synchronized (this) { 10467 ProcessRecord proc; 10468 synchronized (mPidsSelfLocked) { 10469 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10470 } 10471 fillInProcMemInfo(proc, outInfo); 10472 } 10473 } 10474 10475 @Override 10476 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10477 if (checkCallingPermission(android.Manifest.permission.DUMP) 10478 != PackageManager.PERMISSION_GRANTED) { 10479 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10480 + Binder.getCallingPid() 10481 + ", uid=" + Binder.getCallingUid() 10482 + " without permission " 10483 + android.Manifest.permission.DUMP); 10484 return; 10485 } 10486 10487 boolean dumpAll = false; 10488 boolean dumpClient = false; 10489 String dumpPackage = null; 10490 10491 int opti = 0; 10492 while (opti < args.length) { 10493 String opt = args[opti]; 10494 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10495 break; 10496 } 10497 opti++; 10498 if ("-a".equals(opt)) { 10499 dumpAll = true; 10500 } else if ("-c".equals(opt)) { 10501 dumpClient = true; 10502 } else if ("-h".equals(opt)) { 10503 pw.println("Activity manager dump options:"); 10504 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10505 pw.println(" cmd may be one of:"); 10506 pw.println(" a[ctivities]: activity stack state"); 10507 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10508 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10509 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10510 pw.println(" o[om]: out of memory management"); 10511 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10512 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10513 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10514 pw.println(" service [COMP_SPEC]: service client-side state"); 10515 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10516 pw.println(" all: dump all activities"); 10517 pw.println(" top: dump the top activity"); 10518 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10519 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10520 pw.println(" a partial substring in a component name, a"); 10521 pw.println(" hex object identifier."); 10522 pw.println(" -a: include all available server state."); 10523 pw.println(" -c: include client state."); 10524 return; 10525 } else { 10526 pw.println("Unknown argument: " + opt + "; use -h for help"); 10527 } 10528 } 10529 10530 long origId = Binder.clearCallingIdentity(); 10531 boolean more = false; 10532 // Is the caller requesting to dump a particular piece of data? 10533 if (opti < args.length) { 10534 String cmd = args[opti]; 10535 opti++; 10536 if ("activities".equals(cmd) || "a".equals(cmd)) { 10537 synchronized (this) { 10538 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10539 } 10540 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10541 String[] newArgs; 10542 String name; 10543 if (opti >= args.length) { 10544 name = null; 10545 newArgs = EMPTY_STRING_ARRAY; 10546 } else { 10547 name = args[opti]; 10548 opti++; 10549 newArgs = new String[args.length - opti]; 10550 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10551 args.length - opti); 10552 } 10553 synchronized (this) { 10554 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10555 } 10556 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10557 String[] newArgs; 10558 String name; 10559 if (opti >= args.length) { 10560 name = null; 10561 newArgs = EMPTY_STRING_ARRAY; 10562 } else { 10563 name = args[opti]; 10564 opti++; 10565 newArgs = new String[args.length - opti]; 10566 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10567 args.length - opti); 10568 } 10569 synchronized (this) { 10570 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10571 } 10572 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10573 String[] newArgs; 10574 String name; 10575 if (opti >= args.length) { 10576 name = null; 10577 newArgs = EMPTY_STRING_ARRAY; 10578 } else { 10579 name = args[opti]; 10580 opti++; 10581 newArgs = new String[args.length - opti]; 10582 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10583 args.length - opti); 10584 } 10585 synchronized (this) { 10586 dumpProcessesLocked(fd, pw, args, opti, true, name); 10587 } 10588 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10589 synchronized (this) { 10590 dumpOomLocked(fd, pw, args, opti, true); 10591 } 10592 } else if ("provider".equals(cmd)) { 10593 String[] newArgs; 10594 String name; 10595 if (opti >= args.length) { 10596 name = null; 10597 newArgs = EMPTY_STRING_ARRAY; 10598 } else { 10599 name = args[opti]; 10600 opti++; 10601 newArgs = new String[args.length - opti]; 10602 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10603 } 10604 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10605 pw.println("No providers match: " + name); 10606 pw.println("Use -h for help."); 10607 } 10608 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10609 synchronized (this) { 10610 dumpProvidersLocked(fd, pw, args, opti, true, null); 10611 } 10612 } else if ("service".equals(cmd)) { 10613 String[] newArgs; 10614 String name; 10615 if (opti >= args.length) { 10616 name = null; 10617 newArgs = EMPTY_STRING_ARRAY; 10618 } else { 10619 name = args[opti]; 10620 opti++; 10621 newArgs = new String[args.length - opti]; 10622 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10623 args.length - opti); 10624 } 10625 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10626 pw.println("No services match: " + name); 10627 pw.println("Use -h for help."); 10628 } 10629 } else if ("package".equals(cmd)) { 10630 String[] newArgs; 10631 if (opti >= args.length) { 10632 pw.println("package: no package name specified"); 10633 pw.println("Use -h for help."); 10634 } else { 10635 dumpPackage = args[opti]; 10636 opti++; 10637 newArgs = new String[args.length - opti]; 10638 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10639 args.length - opti); 10640 args = newArgs; 10641 opti = 0; 10642 more = true; 10643 } 10644 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10645 synchronized (this) { 10646 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10647 } 10648 } else { 10649 // Dumping a single activity? 10650 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10651 pw.println("Bad activity command, or no activities match: " + cmd); 10652 pw.println("Use -h for help."); 10653 } 10654 } 10655 if (!more) { 10656 Binder.restoreCallingIdentity(origId); 10657 return; 10658 } 10659 } 10660 10661 // No piece of data specified, dump everything. 10662 synchronized (this) { 10663 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10664 pw.println(); 10665 if (dumpAll) { 10666 pw.println("-------------------------------------------------------------------------------"); 10667 } 10668 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10669 pw.println(); 10670 if (dumpAll) { 10671 pw.println("-------------------------------------------------------------------------------"); 10672 } 10673 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10674 pw.println(); 10675 if (dumpAll) { 10676 pw.println("-------------------------------------------------------------------------------"); 10677 } 10678 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10679 pw.println(); 10680 if (dumpAll) { 10681 pw.println("-------------------------------------------------------------------------------"); 10682 } 10683 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10684 pw.println(); 10685 if (dumpAll) { 10686 pw.println("-------------------------------------------------------------------------------"); 10687 } 10688 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10689 } 10690 Binder.restoreCallingIdentity(origId); 10691 } 10692 10693 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10694 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10695 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10696 10697 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10698 dumpPackage); 10699 boolean needSep = printedAnything; 10700 10701 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10702 dumpPackage, needSep, " mFocusedActivity: "); 10703 if (printed) { 10704 printedAnything = true; 10705 needSep = false; 10706 } 10707 10708 if (dumpPackage == null) { 10709 if (needSep) { 10710 pw.println(); 10711 } 10712 needSep = true; 10713 printedAnything = true; 10714 mStackSupervisor.dump(pw, " "); 10715 } 10716 10717 if (mRecentTasks.size() > 0) { 10718 boolean printedHeader = false; 10719 10720 final int N = mRecentTasks.size(); 10721 for (int i=0; i<N; i++) { 10722 TaskRecord tr = mRecentTasks.get(i); 10723 if (dumpPackage != null) { 10724 if (tr.realActivity == null || 10725 !dumpPackage.equals(tr.realActivity)) { 10726 continue; 10727 } 10728 } 10729 if (!printedHeader) { 10730 if (needSep) { 10731 pw.println(); 10732 } 10733 pw.println(" Recent tasks:"); 10734 printedHeader = true; 10735 printedAnything = true; 10736 } 10737 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10738 pw.println(tr); 10739 if (dumpAll) { 10740 mRecentTasks.get(i).dump(pw, " "); 10741 } 10742 } 10743 } 10744 10745 if (!printedAnything) { 10746 pw.println(" (nothing)"); 10747 } 10748 } 10749 10750 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10751 int opti, boolean dumpAll, String dumpPackage) { 10752 boolean needSep = false; 10753 boolean printedAnything = false; 10754 int numPers = 0; 10755 10756 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10757 10758 if (dumpAll) { 10759 final int NP = mProcessNames.getMap().size(); 10760 for (int ip=0; ip<NP; ip++) { 10761 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10762 final int NA = procs.size(); 10763 for (int ia=0; ia<NA; ia++) { 10764 ProcessRecord r = procs.valueAt(ia); 10765 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10766 continue; 10767 } 10768 if (!needSep) { 10769 pw.println(" All known processes:"); 10770 needSep = true; 10771 printedAnything = true; 10772 } 10773 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10774 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10775 pw.print(" "); pw.println(r); 10776 r.dump(pw, " "); 10777 if (r.persistent) { 10778 numPers++; 10779 } 10780 } 10781 } 10782 } 10783 10784 if (mIsolatedProcesses.size() > 0) { 10785 boolean printed = false; 10786 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10787 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10788 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10789 continue; 10790 } 10791 if (!printed) { 10792 if (needSep) { 10793 pw.println(); 10794 } 10795 pw.println(" Isolated process list (sorted by uid):"); 10796 printedAnything = true; 10797 printed = true; 10798 needSep = true; 10799 } 10800 pw.println(String.format("%sIsolated #%2d: %s", 10801 " ", i, r.toString())); 10802 } 10803 } 10804 10805 if (mLruProcesses.size() > 0) { 10806 if (needSep) { 10807 pw.println(); 10808 } 10809 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10810 pw.print(" total, non-act at "); 10811 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10812 pw.print(", non-svc at "); 10813 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10814 pw.println("):"); 10815 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10816 needSep = true; 10817 printedAnything = true; 10818 } 10819 10820 if (dumpAll || dumpPackage != null) { 10821 synchronized (mPidsSelfLocked) { 10822 boolean printed = false; 10823 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10824 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10825 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10826 continue; 10827 } 10828 if (!printed) { 10829 if (needSep) pw.println(); 10830 needSep = true; 10831 pw.println(" PID mappings:"); 10832 printed = true; 10833 printedAnything = true; 10834 } 10835 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10836 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10837 } 10838 } 10839 } 10840 10841 if (mForegroundProcesses.size() > 0) { 10842 synchronized (mPidsSelfLocked) { 10843 boolean printed = false; 10844 for (int i=0; i<mForegroundProcesses.size(); i++) { 10845 ProcessRecord r = mPidsSelfLocked.get( 10846 mForegroundProcesses.valueAt(i).pid); 10847 if (dumpPackage != null && (r == null 10848 || !r.pkgList.containsKey(dumpPackage))) { 10849 continue; 10850 } 10851 if (!printed) { 10852 if (needSep) pw.println(); 10853 needSep = true; 10854 pw.println(" Foreground Processes:"); 10855 printed = true; 10856 printedAnything = true; 10857 } 10858 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10859 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10860 } 10861 } 10862 } 10863 10864 if (mPersistentStartingProcesses.size() > 0) { 10865 if (needSep) pw.println(); 10866 needSep = true; 10867 printedAnything = true; 10868 pw.println(" Persisent processes that are starting:"); 10869 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10870 "Starting Norm", "Restarting PERS", dumpPackage); 10871 } 10872 10873 if (mRemovedProcesses.size() > 0) { 10874 if (needSep) pw.println(); 10875 needSep = true; 10876 printedAnything = true; 10877 pw.println(" Processes that are being removed:"); 10878 dumpProcessList(pw, this, mRemovedProcesses, " ", 10879 "Removed Norm", "Removed PERS", dumpPackage); 10880 } 10881 10882 if (mProcessesOnHold.size() > 0) { 10883 if (needSep) pw.println(); 10884 needSep = true; 10885 printedAnything = true; 10886 pw.println(" Processes that are on old until the system is ready:"); 10887 dumpProcessList(pw, this, mProcessesOnHold, " ", 10888 "OnHold Norm", "OnHold PERS", dumpPackage); 10889 } 10890 10891 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10892 10893 if (mProcessCrashTimes.getMap().size() > 0) { 10894 boolean printed = false; 10895 long now = SystemClock.uptimeMillis(); 10896 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10897 final int NP = pmap.size(); 10898 for (int ip=0; ip<NP; ip++) { 10899 String pname = pmap.keyAt(ip); 10900 SparseArray<Long> uids = pmap.valueAt(ip); 10901 final int N = uids.size(); 10902 for (int i=0; i<N; i++) { 10903 int puid = uids.keyAt(i); 10904 ProcessRecord r = mProcessNames.get(pname, puid); 10905 if (dumpPackage != null && (r == null 10906 || !r.pkgList.containsKey(dumpPackage))) { 10907 continue; 10908 } 10909 if (!printed) { 10910 if (needSep) pw.println(); 10911 needSep = true; 10912 pw.println(" Time since processes crashed:"); 10913 printed = true; 10914 printedAnything = true; 10915 } 10916 pw.print(" Process "); pw.print(pname); 10917 pw.print(" uid "); pw.print(puid); 10918 pw.print(": last crashed "); 10919 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10920 pw.println(" ago"); 10921 } 10922 } 10923 } 10924 10925 if (mBadProcesses.getMap().size() > 0) { 10926 boolean printed = false; 10927 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10928 final int NP = pmap.size(); 10929 for (int ip=0; ip<NP; ip++) { 10930 String pname = pmap.keyAt(ip); 10931 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10932 final int N = uids.size(); 10933 for (int i=0; i<N; i++) { 10934 int puid = uids.keyAt(i); 10935 ProcessRecord r = mProcessNames.get(pname, puid); 10936 if (dumpPackage != null && (r == null 10937 || !r.pkgList.containsKey(dumpPackage))) { 10938 continue; 10939 } 10940 if (!printed) { 10941 if (needSep) pw.println(); 10942 needSep = true; 10943 pw.println(" Bad processes:"); 10944 printedAnything = true; 10945 } 10946 BadProcessInfo info = uids.valueAt(i); 10947 pw.print(" Bad process "); pw.print(pname); 10948 pw.print(" uid "); pw.print(puid); 10949 pw.print(": crashed at time "); pw.println(info.time); 10950 if (info.shortMsg != null) { 10951 pw.print(" Short msg: "); pw.println(info.shortMsg); 10952 } 10953 if (info.longMsg != null) { 10954 pw.print(" Long msg: "); pw.println(info.longMsg); 10955 } 10956 if (info.stack != null) { 10957 pw.println(" Stack:"); 10958 int lastPos = 0; 10959 for (int pos=0; pos<info.stack.length(); pos++) { 10960 if (info.stack.charAt(pos) == '\n') { 10961 pw.print(" "); 10962 pw.write(info.stack, lastPos, pos-lastPos); 10963 pw.println(); 10964 lastPos = pos+1; 10965 } 10966 } 10967 if (lastPos < info.stack.length()) { 10968 pw.print(" "); 10969 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10970 pw.println(); 10971 } 10972 } 10973 } 10974 } 10975 } 10976 10977 if (dumpPackage == null) { 10978 pw.println(); 10979 needSep = false; 10980 pw.println(" mStartedUsers:"); 10981 for (int i=0; i<mStartedUsers.size(); i++) { 10982 UserStartedState uss = mStartedUsers.valueAt(i); 10983 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10984 pw.print(": "); uss.dump("", pw); 10985 } 10986 pw.print(" mStartedUserArray: ["); 10987 for (int i=0; i<mStartedUserArray.length; i++) { 10988 if (i > 0) pw.print(", "); 10989 pw.print(mStartedUserArray[i]); 10990 } 10991 pw.println("]"); 10992 pw.print(" mUserLru: ["); 10993 for (int i=0; i<mUserLru.size(); i++) { 10994 if (i > 0) pw.print(", "); 10995 pw.print(mUserLru.get(i)); 10996 } 10997 pw.println("]"); 10998 if (dumpAll) { 10999 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11000 } 11001 } 11002 if (mHomeProcess != null && (dumpPackage == null 11003 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11004 if (needSep) { 11005 pw.println(); 11006 needSep = false; 11007 } 11008 pw.println(" mHomeProcess: " + mHomeProcess); 11009 } 11010 if (mPreviousProcess != null && (dumpPackage == null 11011 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11012 if (needSep) { 11013 pw.println(); 11014 needSep = false; 11015 } 11016 pw.println(" mPreviousProcess: " + mPreviousProcess); 11017 } 11018 if (dumpAll) { 11019 StringBuilder sb = new StringBuilder(128); 11020 sb.append(" mPreviousProcessVisibleTime: "); 11021 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11022 pw.println(sb); 11023 } 11024 if (mHeavyWeightProcess != null && (dumpPackage == null 11025 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11026 if (needSep) { 11027 pw.println(); 11028 needSep = false; 11029 } 11030 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11031 } 11032 if (dumpPackage == null) { 11033 pw.println(" mConfiguration: " + mConfiguration); 11034 } 11035 if (dumpAll) { 11036 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11037 if (mCompatModePackages.getPackages().size() > 0) { 11038 boolean printed = false; 11039 for (Map.Entry<String, Integer> entry 11040 : mCompatModePackages.getPackages().entrySet()) { 11041 String pkg = entry.getKey(); 11042 int mode = entry.getValue(); 11043 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11044 continue; 11045 } 11046 if (!printed) { 11047 pw.println(" mScreenCompatPackages:"); 11048 printed = true; 11049 } 11050 pw.print(" "); pw.print(pkg); pw.print(": "); 11051 pw.print(mode); pw.println(); 11052 } 11053 } 11054 } 11055 if (dumpPackage == null) { 11056 if (mSleeping || mWentToSleep || mLockScreenShown) { 11057 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11058 + " mLockScreenShown " + mLockScreenShown); 11059 } 11060 if (mShuttingDown) { 11061 pw.println(" mShuttingDown=" + mShuttingDown); 11062 } 11063 } 11064 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11065 || mOrigWaitForDebugger) { 11066 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11067 || dumpPackage.equals(mOrigDebugApp)) { 11068 if (needSep) { 11069 pw.println(); 11070 needSep = false; 11071 } 11072 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11073 + " mDebugTransient=" + mDebugTransient 11074 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11075 } 11076 } 11077 if (mOpenGlTraceApp != null) { 11078 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11079 if (needSep) { 11080 pw.println(); 11081 needSep = false; 11082 } 11083 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11084 } 11085 } 11086 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11087 || mProfileFd != null) { 11088 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11089 if (needSep) { 11090 pw.println(); 11091 needSep = false; 11092 } 11093 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11094 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11095 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11096 + mAutoStopProfiler); 11097 } 11098 } 11099 if (dumpPackage == null) { 11100 if (mAlwaysFinishActivities || mController != null) { 11101 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11102 + " mController=" + mController); 11103 } 11104 if (dumpAll) { 11105 pw.println(" Total persistent processes: " + numPers); 11106 pw.println(" mStartRunning=" + mStartRunning 11107 + " mProcessesReady=" + mProcessesReady 11108 + " mSystemReady=" + mSystemReady); 11109 pw.println(" mBooting=" + mBooting 11110 + " mBooted=" + mBooted 11111 + " mFactoryTest=" + mFactoryTest); 11112 pw.print(" mLastPowerCheckRealtime="); 11113 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11114 pw.println(""); 11115 pw.print(" mLastPowerCheckUptime="); 11116 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11117 pw.println(""); 11118 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11119 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11120 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11121 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11122 + " (" + mLruProcesses.size() + " total)" 11123 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11124 + " mNumServiceProcs=" + mNumServiceProcs 11125 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11126 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11127 + " mLastMemoryLevel" + mLastMemoryLevel 11128 + " mLastNumProcesses" + mLastNumProcesses); 11129 long now = SystemClock.uptimeMillis(); 11130 pw.print(" mLastIdleTime="); 11131 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11132 pw.print(" mLowRamSinceLastIdle="); 11133 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11134 pw.println(); 11135 } 11136 } 11137 11138 if (!printedAnything) { 11139 pw.println(" (nothing)"); 11140 } 11141 } 11142 11143 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11144 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11145 if (mProcessesToGc.size() > 0) { 11146 boolean printed = false; 11147 long now = SystemClock.uptimeMillis(); 11148 for (int i=0; i<mProcessesToGc.size(); i++) { 11149 ProcessRecord proc = mProcessesToGc.get(i); 11150 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11151 continue; 11152 } 11153 if (!printed) { 11154 if (needSep) pw.println(); 11155 needSep = true; 11156 pw.println(" Processes that are waiting to GC:"); 11157 printed = true; 11158 } 11159 pw.print(" Process "); pw.println(proc); 11160 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11161 pw.print(", last gced="); 11162 pw.print(now-proc.lastRequestedGc); 11163 pw.print(" ms ago, last lowMem="); 11164 pw.print(now-proc.lastLowMemory); 11165 pw.println(" ms ago"); 11166 11167 } 11168 } 11169 return needSep; 11170 } 11171 11172 void printOomLevel(PrintWriter pw, String name, int adj) { 11173 pw.print(" "); 11174 if (adj >= 0) { 11175 pw.print(' '); 11176 if (adj < 10) pw.print(' '); 11177 } else { 11178 if (adj > -10) pw.print(' '); 11179 } 11180 pw.print(adj); 11181 pw.print(": "); 11182 pw.print(name); 11183 pw.print(" ("); 11184 pw.print(mProcessList.getMemLevel(adj)/1024); 11185 pw.println(" kB)"); 11186 } 11187 11188 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11189 int opti, boolean dumpAll) { 11190 boolean needSep = false; 11191 11192 if (mLruProcesses.size() > 0) { 11193 if (needSep) pw.println(); 11194 needSep = true; 11195 pw.println(" OOM levels:"); 11196 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11197 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11198 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11199 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11200 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11201 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11202 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11203 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11204 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11205 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11206 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11207 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11208 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11209 11210 if (needSep) pw.println(); 11211 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11212 pw.print(" total, non-act at "); 11213 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11214 pw.print(", non-svc at "); 11215 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11216 pw.println("):"); 11217 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11218 needSep = true; 11219 } 11220 11221 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11222 11223 pw.println(); 11224 pw.println(" mHomeProcess: " + mHomeProcess); 11225 pw.println(" mPreviousProcess: " + mPreviousProcess); 11226 if (mHeavyWeightProcess != null) { 11227 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11228 } 11229 11230 return true; 11231 } 11232 11233 /** 11234 * There are three ways to call this: 11235 * - no provider specified: dump all the providers 11236 * - a flattened component name that matched an existing provider was specified as the 11237 * first arg: dump that one provider 11238 * - the first arg isn't the flattened component name of an existing provider: 11239 * dump all providers whose component contains the first arg as a substring 11240 */ 11241 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11242 int opti, boolean dumpAll) { 11243 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11244 } 11245 11246 static class ItemMatcher { 11247 ArrayList<ComponentName> components; 11248 ArrayList<String> strings; 11249 ArrayList<Integer> objects; 11250 boolean all; 11251 11252 ItemMatcher() { 11253 all = true; 11254 } 11255 11256 void build(String name) { 11257 ComponentName componentName = ComponentName.unflattenFromString(name); 11258 if (componentName != null) { 11259 if (components == null) { 11260 components = new ArrayList<ComponentName>(); 11261 } 11262 components.add(componentName); 11263 all = false; 11264 } else { 11265 int objectId = 0; 11266 // Not a '/' separated full component name; maybe an object ID? 11267 try { 11268 objectId = Integer.parseInt(name, 16); 11269 if (objects == null) { 11270 objects = new ArrayList<Integer>(); 11271 } 11272 objects.add(objectId); 11273 all = false; 11274 } catch (RuntimeException e) { 11275 // Not an integer; just do string match. 11276 if (strings == null) { 11277 strings = new ArrayList<String>(); 11278 } 11279 strings.add(name); 11280 all = false; 11281 } 11282 } 11283 } 11284 11285 int build(String[] args, int opti) { 11286 for (; opti<args.length; opti++) { 11287 String name = args[opti]; 11288 if ("--".equals(name)) { 11289 return opti+1; 11290 } 11291 build(name); 11292 } 11293 return opti; 11294 } 11295 11296 boolean match(Object object, ComponentName comp) { 11297 if (all) { 11298 return true; 11299 } 11300 if (components != null) { 11301 for (int i=0; i<components.size(); i++) { 11302 if (components.get(i).equals(comp)) { 11303 return true; 11304 } 11305 } 11306 } 11307 if (objects != null) { 11308 for (int i=0; i<objects.size(); i++) { 11309 if (System.identityHashCode(object) == objects.get(i)) { 11310 return true; 11311 } 11312 } 11313 } 11314 if (strings != null) { 11315 String flat = comp.flattenToString(); 11316 for (int i=0; i<strings.size(); i++) { 11317 if (flat.contains(strings.get(i))) { 11318 return true; 11319 } 11320 } 11321 } 11322 return false; 11323 } 11324 } 11325 11326 /** 11327 * There are three things that cmd can be: 11328 * - a flattened component name that matches an existing activity 11329 * - the cmd arg isn't the flattened component name of an existing activity: 11330 * dump all activity whose component contains the cmd as a substring 11331 * - A hex number of the ActivityRecord object instance. 11332 */ 11333 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11334 int opti, boolean dumpAll) { 11335 ArrayList<ActivityRecord> activities; 11336 11337 synchronized (this) { 11338 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11339 } 11340 11341 if (activities.size() <= 0) { 11342 return false; 11343 } 11344 11345 String[] newArgs = new String[args.length - opti]; 11346 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11347 11348 TaskRecord lastTask = null; 11349 boolean needSep = false; 11350 for (int i=activities.size()-1; i>=0; i--) { 11351 ActivityRecord r = activities.get(i); 11352 if (needSep) { 11353 pw.println(); 11354 } 11355 needSep = true; 11356 synchronized (this) { 11357 if (lastTask != r.task) { 11358 lastTask = r.task; 11359 pw.print("TASK "); pw.print(lastTask.affinity); 11360 pw.print(" id="); pw.println(lastTask.taskId); 11361 if (dumpAll) { 11362 lastTask.dump(pw, " "); 11363 } 11364 } 11365 } 11366 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11367 } 11368 return true; 11369 } 11370 11371 /** 11372 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11373 * there is a thread associated with the activity. 11374 */ 11375 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11376 final ActivityRecord r, String[] args, boolean dumpAll) { 11377 String innerPrefix = prefix + " "; 11378 synchronized (this) { 11379 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11380 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11381 pw.print(" pid="); 11382 if (r.app != null) pw.println(r.app.pid); 11383 else pw.println("(not running)"); 11384 if (dumpAll) { 11385 r.dump(pw, innerPrefix); 11386 } 11387 } 11388 if (r.app != null && r.app.thread != null) { 11389 // flush anything that is already in the PrintWriter since the thread is going 11390 // to write to the file descriptor directly 11391 pw.flush(); 11392 try { 11393 TransferPipe tp = new TransferPipe(); 11394 try { 11395 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11396 r.appToken, innerPrefix, args); 11397 tp.go(fd); 11398 } finally { 11399 tp.kill(); 11400 } 11401 } catch (IOException e) { 11402 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11403 } catch (RemoteException e) { 11404 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11405 } 11406 } 11407 } 11408 11409 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11410 int opti, boolean dumpAll, String dumpPackage) { 11411 boolean needSep = false; 11412 boolean onlyHistory = false; 11413 boolean printedAnything = false; 11414 11415 if ("history".equals(dumpPackage)) { 11416 if (opti < args.length && "-s".equals(args[opti])) { 11417 dumpAll = false; 11418 } 11419 onlyHistory = true; 11420 dumpPackage = null; 11421 } 11422 11423 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11424 if (!onlyHistory && dumpAll) { 11425 if (mRegisteredReceivers.size() > 0) { 11426 boolean printed = false; 11427 Iterator it = mRegisteredReceivers.values().iterator(); 11428 while (it.hasNext()) { 11429 ReceiverList r = (ReceiverList)it.next(); 11430 if (dumpPackage != null && (r.app == null || 11431 !dumpPackage.equals(r.app.info.packageName))) { 11432 continue; 11433 } 11434 if (!printed) { 11435 pw.println(" Registered Receivers:"); 11436 needSep = true; 11437 printed = true; 11438 printedAnything = true; 11439 } 11440 pw.print(" * "); pw.println(r); 11441 r.dump(pw, " "); 11442 } 11443 } 11444 11445 if (mReceiverResolver.dump(pw, needSep ? 11446 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11447 " ", dumpPackage, false)) { 11448 needSep = true; 11449 printedAnything = true; 11450 } 11451 } 11452 11453 for (BroadcastQueue q : mBroadcastQueues) { 11454 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11455 printedAnything |= needSep; 11456 } 11457 11458 needSep = true; 11459 11460 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11461 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11462 if (needSep) { 11463 pw.println(); 11464 } 11465 needSep = true; 11466 printedAnything = true; 11467 pw.print(" Sticky broadcasts for user "); 11468 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11469 StringBuilder sb = new StringBuilder(128); 11470 for (Map.Entry<String, ArrayList<Intent>> ent 11471 : mStickyBroadcasts.valueAt(user).entrySet()) { 11472 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11473 if (dumpAll) { 11474 pw.println(":"); 11475 ArrayList<Intent> intents = ent.getValue(); 11476 final int N = intents.size(); 11477 for (int i=0; i<N; i++) { 11478 sb.setLength(0); 11479 sb.append(" Intent: "); 11480 intents.get(i).toShortString(sb, false, true, false, false); 11481 pw.println(sb.toString()); 11482 Bundle bundle = intents.get(i).getExtras(); 11483 if (bundle != null) { 11484 pw.print(" "); 11485 pw.println(bundle.toString()); 11486 } 11487 } 11488 } else { 11489 pw.println(""); 11490 } 11491 } 11492 } 11493 } 11494 11495 if (!onlyHistory && dumpAll) { 11496 pw.println(); 11497 for (BroadcastQueue queue : mBroadcastQueues) { 11498 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11499 + queue.mBroadcastsScheduled); 11500 } 11501 pw.println(" mHandler:"); 11502 mHandler.dump(new PrintWriterPrinter(pw), " "); 11503 needSep = true; 11504 printedAnything = true; 11505 } 11506 11507 if (!printedAnything) { 11508 pw.println(" (nothing)"); 11509 } 11510 } 11511 11512 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11513 int opti, boolean dumpAll, String dumpPackage) { 11514 boolean needSep; 11515 boolean printedAnything = false; 11516 11517 ItemMatcher matcher = new ItemMatcher(); 11518 matcher.build(args, opti); 11519 11520 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11521 11522 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11523 printedAnything |= needSep; 11524 11525 if (mLaunchingProviders.size() > 0) { 11526 boolean printed = false; 11527 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11528 ContentProviderRecord r = mLaunchingProviders.get(i); 11529 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11530 continue; 11531 } 11532 if (!printed) { 11533 if (needSep) pw.println(); 11534 needSep = true; 11535 pw.println(" Launching content providers:"); 11536 printed = true; 11537 printedAnything = true; 11538 } 11539 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11540 pw.println(r); 11541 } 11542 } 11543 11544 if (mGrantedUriPermissions.size() > 0) { 11545 boolean printed = false; 11546 int dumpUid = -2; 11547 if (dumpPackage != null) { 11548 try { 11549 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11550 } catch (NameNotFoundException e) { 11551 dumpUid = -1; 11552 } 11553 } 11554 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11555 int uid = mGrantedUriPermissions.keyAt(i); 11556 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11557 continue; 11558 } 11559 ArrayMap<Uri, UriPermission> perms 11560 = mGrantedUriPermissions.valueAt(i); 11561 if (!printed) { 11562 if (needSep) pw.println(); 11563 needSep = true; 11564 pw.println(" Granted Uri Permissions:"); 11565 printed = true; 11566 printedAnything = true; 11567 } 11568 pw.print(" * UID "); pw.print(uid); 11569 pw.println(" holds:"); 11570 for (UriPermission perm : perms.values()) { 11571 pw.print(" "); pw.println(perm); 11572 if (dumpAll) { 11573 perm.dump(pw, " "); 11574 } 11575 } 11576 } 11577 } 11578 11579 if (!printedAnything) { 11580 pw.println(" (nothing)"); 11581 } 11582 } 11583 11584 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11585 int opti, boolean dumpAll, String dumpPackage) { 11586 boolean printed = false; 11587 11588 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11589 11590 if (mIntentSenderRecords.size() > 0) { 11591 Iterator<WeakReference<PendingIntentRecord>> it 11592 = mIntentSenderRecords.values().iterator(); 11593 while (it.hasNext()) { 11594 WeakReference<PendingIntentRecord> ref = it.next(); 11595 PendingIntentRecord rec = ref != null ? ref.get(): null; 11596 if (dumpPackage != null && (rec == null 11597 || !dumpPackage.equals(rec.key.packageName))) { 11598 continue; 11599 } 11600 printed = true; 11601 if (rec != null) { 11602 pw.print(" * "); pw.println(rec); 11603 if (dumpAll) { 11604 rec.dump(pw, " "); 11605 } 11606 } else { 11607 pw.print(" * "); pw.println(ref); 11608 } 11609 } 11610 } 11611 11612 if (!printed) { 11613 pw.println(" (nothing)"); 11614 } 11615 } 11616 11617 private static final int dumpProcessList(PrintWriter pw, 11618 ActivityManagerService service, List list, 11619 String prefix, String normalLabel, String persistentLabel, 11620 String dumpPackage) { 11621 int numPers = 0; 11622 final int N = list.size()-1; 11623 for (int i=N; i>=0; i--) { 11624 ProcessRecord r = (ProcessRecord)list.get(i); 11625 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11626 continue; 11627 } 11628 pw.println(String.format("%s%s #%2d: %s", 11629 prefix, (r.persistent ? persistentLabel : normalLabel), 11630 i, r.toString())); 11631 if (r.persistent) { 11632 numPers++; 11633 } 11634 } 11635 return numPers; 11636 } 11637 11638 private static final boolean dumpProcessOomList(PrintWriter pw, 11639 ActivityManagerService service, List<ProcessRecord> origList, 11640 String prefix, String normalLabel, String persistentLabel, 11641 boolean inclDetails, String dumpPackage) { 11642 11643 ArrayList<Pair<ProcessRecord, Integer>> list 11644 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11645 for (int i=0; i<origList.size(); i++) { 11646 ProcessRecord r = origList.get(i); 11647 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11648 continue; 11649 } 11650 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11651 } 11652 11653 if (list.size() <= 0) { 11654 return false; 11655 } 11656 11657 Comparator<Pair<ProcessRecord, Integer>> comparator 11658 = new Comparator<Pair<ProcessRecord, Integer>>() { 11659 @Override 11660 public int compare(Pair<ProcessRecord, Integer> object1, 11661 Pair<ProcessRecord, Integer> object2) { 11662 if (object1.first.setAdj != object2.first.setAdj) { 11663 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11664 } 11665 if (object1.second.intValue() != object2.second.intValue()) { 11666 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11667 } 11668 return 0; 11669 } 11670 }; 11671 11672 Collections.sort(list, comparator); 11673 11674 final long curRealtime = SystemClock.elapsedRealtime(); 11675 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11676 final long curUptime = SystemClock.uptimeMillis(); 11677 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11678 11679 for (int i=list.size()-1; i>=0; i--) { 11680 ProcessRecord r = list.get(i).first; 11681 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11682 char schedGroup; 11683 switch (r.setSchedGroup) { 11684 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11685 schedGroup = 'B'; 11686 break; 11687 case Process.THREAD_GROUP_DEFAULT: 11688 schedGroup = 'F'; 11689 break; 11690 default: 11691 schedGroup = '?'; 11692 break; 11693 } 11694 char foreground; 11695 if (r.foregroundActivities) { 11696 foreground = 'A'; 11697 } else if (r.foregroundServices) { 11698 foreground = 'S'; 11699 } else { 11700 foreground = ' '; 11701 } 11702 String procState = ProcessList.makeProcStateString(r.curProcState); 11703 pw.print(prefix); 11704 pw.print(r.persistent ? persistentLabel : normalLabel); 11705 pw.print(" #"); 11706 int num = (origList.size()-1)-list.get(i).second; 11707 if (num < 10) pw.print(' '); 11708 pw.print(num); 11709 pw.print(": "); 11710 pw.print(oomAdj); 11711 pw.print(' '); 11712 pw.print(schedGroup); 11713 pw.print('/'); 11714 pw.print(foreground); 11715 pw.print('/'); 11716 pw.print(procState); 11717 pw.print(" trm:"); 11718 if (r.trimMemoryLevel < 10) pw.print(' '); 11719 pw.print(r.trimMemoryLevel); 11720 pw.print(' '); 11721 pw.print(r.toShortString()); 11722 pw.print(" ("); 11723 pw.print(r.adjType); 11724 pw.println(')'); 11725 if (r.adjSource != null || r.adjTarget != null) { 11726 pw.print(prefix); 11727 pw.print(" "); 11728 if (r.adjTarget instanceof ComponentName) { 11729 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11730 } else if (r.adjTarget != null) { 11731 pw.print(r.adjTarget.toString()); 11732 } else { 11733 pw.print("{null}"); 11734 } 11735 pw.print("<="); 11736 if (r.adjSource instanceof ProcessRecord) { 11737 pw.print("Proc{"); 11738 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11739 pw.println("}"); 11740 } else if (r.adjSource != null) { 11741 pw.println(r.adjSource.toString()); 11742 } else { 11743 pw.println("{null}"); 11744 } 11745 } 11746 if (inclDetails) { 11747 pw.print(prefix); 11748 pw.print(" "); 11749 pw.print("oom: max="); pw.print(r.maxAdj); 11750 pw.print(" curRaw="); pw.print(r.curRawAdj); 11751 pw.print(" setRaw="); pw.print(r.setRawAdj); 11752 pw.print(" cur="); pw.print(r.curAdj); 11753 pw.print(" set="); pw.println(r.setAdj); 11754 pw.print(prefix); 11755 pw.print(" "); 11756 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11757 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11758 pw.print(" lastPss="); pw.print(r.lastPss); 11759 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11760 pw.print(prefix); 11761 pw.print(" "); 11762 pw.print("keeping="); pw.print(r.keeping); 11763 pw.print(" cached="); pw.print(r.cached); 11764 pw.print(" empty="); pw.print(r.empty); 11765 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11766 11767 if (!r.keeping) { 11768 if (r.lastWakeTime != 0) { 11769 long wtime; 11770 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11771 synchronized (stats) { 11772 wtime = stats.getProcessWakeTime(r.info.uid, 11773 r.pid, curRealtime); 11774 } 11775 long timeUsed = wtime - r.lastWakeTime; 11776 pw.print(prefix); 11777 pw.print(" "); 11778 pw.print("keep awake over "); 11779 TimeUtils.formatDuration(realtimeSince, pw); 11780 pw.print(" used "); 11781 TimeUtils.formatDuration(timeUsed, pw); 11782 pw.print(" ("); 11783 pw.print((timeUsed*100)/realtimeSince); 11784 pw.println("%)"); 11785 } 11786 if (r.lastCpuTime != 0) { 11787 long timeUsed = r.curCpuTime - r.lastCpuTime; 11788 pw.print(prefix); 11789 pw.print(" "); 11790 pw.print("run cpu over "); 11791 TimeUtils.formatDuration(uptimeSince, pw); 11792 pw.print(" used "); 11793 TimeUtils.formatDuration(timeUsed, pw); 11794 pw.print(" ("); 11795 pw.print((timeUsed*100)/uptimeSince); 11796 pw.println("%)"); 11797 } 11798 } 11799 } 11800 } 11801 return true; 11802 } 11803 11804 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11805 ArrayList<ProcessRecord> procs; 11806 synchronized (this) { 11807 if (args != null && args.length > start 11808 && args[start].charAt(0) != '-') { 11809 procs = new ArrayList<ProcessRecord>(); 11810 int pid = -1; 11811 try { 11812 pid = Integer.parseInt(args[start]); 11813 } catch (NumberFormatException e) { 11814 } 11815 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11816 ProcessRecord proc = mLruProcesses.get(i); 11817 if (proc.pid == pid) { 11818 procs.add(proc); 11819 } else if (proc.processName.equals(args[start])) { 11820 procs.add(proc); 11821 } 11822 } 11823 if (procs.size() <= 0) { 11824 return null; 11825 } 11826 } else { 11827 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11828 } 11829 } 11830 return procs; 11831 } 11832 11833 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11834 PrintWriter pw, String[] args) { 11835 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11836 if (procs == null) { 11837 pw.println("No process found for: " + args[0]); 11838 return; 11839 } 11840 11841 long uptime = SystemClock.uptimeMillis(); 11842 long realtime = SystemClock.elapsedRealtime(); 11843 pw.println("Applications Graphics Acceleration Info:"); 11844 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11845 11846 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11847 ProcessRecord r = procs.get(i); 11848 if (r.thread != null) { 11849 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11850 pw.flush(); 11851 try { 11852 TransferPipe tp = new TransferPipe(); 11853 try { 11854 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11855 tp.go(fd); 11856 } finally { 11857 tp.kill(); 11858 } 11859 } catch (IOException e) { 11860 pw.println("Failure while dumping the app: " + r); 11861 pw.flush(); 11862 } catch (RemoteException e) { 11863 pw.println("Got a RemoteException while dumping the app " + r); 11864 pw.flush(); 11865 } 11866 } 11867 } 11868 } 11869 11870 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11871 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11872 if (procs == null) { 11873 pw.println("No process found for: " + args[0]); 11874 return; 11875 } 11876 11877 pw.println("Applications Database Info:"); 11878 11879 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11880 ProcessRecord r = procs.get(i); 11881 if (r.thread != null) { 11882 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11883 pw.flush(); 11884 try { 11885 TransferPipe tp = new TransferPipe(); 11886 try { 11887 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11888 tp.go(fd); 11889 } finally { 11890 tp.kill(); 11891 } 11892 } catch (IOException e) { 11893 pw.println("Failure while dumping the app: " + r); 11894 pw.flush(); 11895 } catch (RemoteException e) { 11896 pw.println("Got a RemoteException while dumping the app " + r); 11897 pw.flush(); 11898 } 11899 } 11900 } 11901 } 11902 11903 final static class MemItem { 11904 final boolean isProc; 11905 final String label; 11906 final String shortLabel; 11907 final long pss; 11908 final int id; 11909 final boolean hasActivities; 11910 ArrayList<MemItem> subitems; 11911 11912 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11913 boolean _hasActivities) { 11914 isProc = true; 11915 label = _label; 11916 shortLabel = _shortLabel; 11917 pss = _pss; 11918 id = _id; 11919 hasActivities = _hasActivities; 11920 } 11921 11922 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11923 isProc = false; 11924 label = _label; 11925 shortLabel = _shortLabel; 11926 pss = _pss; 11927 id = _id; 11928 hasActivities = false; 11929 } 11930 } 11931 11932 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11933 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11934 if (sort && !isCompact) { 11935 Collections.sort(items, new Comparator<MemItem>() { 11936 @Override 11937 public int compare(MemItem lhs, MemItem rhs) { 11938 if (lhs.pss < rhs.pss) { 11939 return 1; 11940 } else if (lhs.pss > rhs.pss) { 11941 return -1; 11942 } 11943 return 0; 11944 } 11945 }); 11946 } 11947 11948 for (int i=0; i<items.size(); i++) { 11949 MemItem mi = items.get(i); 11950 if (!isCompact) { 11951 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11952 } else if (mi.isProc) { 11953 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11954 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11955 pw.println(mi.hasActivities ? ",a" : ",e"); 11956 } else { 11957 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11958 pw.println(mi.pss); 11959 } 11960 if (mi.subitems != null) { 11961 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11962 true, isCompact); 11963 } 11964 } 11965 } 11966 11967 // These are in KB. 11968 static final long[] DUMP_MEM_BUCKETS = new long[] { 11969 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11970 120*1024, 160*1024, 200*1024, 11971 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11972 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11973 }; 11974 11975 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11976 boolean stackLike) { 11977 int start = label.lastIndexOf('.'); 11978 if (start >= 0) start++; 11979 else start = 0; 11980 int end = label.length(); 11981 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11982 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11983 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11984 out.append(bucket); 11985 out.append(stackLike ? "MB." : "MB "); 11986 out.append(label, start, end); 11987 return; 11988 } 11989 } 11990 out.append(memKB/1024); 11991 out.append(stackLike ? "MB." : "MB "); 11992 out.append(label, start, end); 11993 } 11994 11995 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11996 ProcessList.NATIVE_ADJ, 11997 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11998 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11999 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12000 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12001 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12002 }; 12003 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12004 "Native", 12005 "System", "Persistent", "Foreground", 12006 "Visible", "Perceptible", 12007 "Heavy Weight", "Backup", 12008 "A Services", "Home", 12009 "Previous", "B Services", "Cached" 12010 }; 12011 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12012 "native", 12013 "sys", "pers", "fore", 12014 "vis", "percept", 12015 "heavy", "backup", 12016 "servicea", "home", 12017 "prev", "serviceb", "cached" 12018 }; 12019 12020 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12021 long realtime, boolean isCheckinRequest, boolean isCompact) { 12022 if (isCheckinRequest || isCompact) { 12023 // short checkin version 12024 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12025 } else { 12026 pw.println("Applications Memory Usage (kB):"); 12027 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12028 } 12029 } 12030 12031 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12032 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12033 boolean dumpDetails = false; 12034 boolean dumpFullDetails = false; 12035 boolean dumpDalvik = false; 12036 boolean oomOnly = false; 12037 boolean isCompact = false; 12038 boolean localOnly = false; 12039 12040 int opti = 0; 12041 while (opti < args.length) { 12042 String opt = args[opti]; 12043 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12044 break; 12045 } 12046 opti++; 12047 if ("-a".equals(opt)) { 12048 dumpDetails = true; 12049 dumpFullDetails = true; 12050 dumpDalvik = true; 12051 } else if ("-d".equals(opt)) { 12052 dumpDalvik = true; 12053 } else if ("-c".equals(opt)) { 12054 isCompact = true; 12055 } else if ("--oom".equals(opt)) { 12056 oomOnly = true; 12057 } else if ("--local".equals(opt)) { 12058 localOnly = true; 12059 } else if ("-h".equals(opt)) { 12060 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12061 pw.println(" -a: include all available information for each process."); 12062 pw.println(" -d: include dalvik details when dumping process details."); 12063 pw.println(" -c: dump in a compact machine-parseable representation."); 12064 pw.println(" --oom: only show processes organized by oom adj."); 12065 pw.println(" --local: only collect details locally, don't call process."); 12066 pw.println("If [process] is specified it can be the name or "); 12067 pw.println("pid of a specific process to dump."); 12068 return; 12069 } else { 12070 pw.println("Unknown argument: " + opt + "; use -h for help"); 12071 } 12072 } 12073 12074 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12075 long uptime = SystemClock.uptimeMillis(); 12076 long realtime = SystemClock.elapsedRealtime(); 12077 final long[] tmpLong = new long[1]; 12078 12079 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12080 if (procs == null) { 12081 // No Java processes. Maybe they want to print a native process. 12082 if (args != null && args.length > opti 12083 && args[opti].charAt(0) != '-') { 12084 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12085 = new ArrayList<ProcessCpuTracker.Stats>(); 12086 updateCpuStatsNow(); 12087 int findPid = -1; 12088 try { 12089 findPid = Integer.parseInt(args[opti]); 12090 } catch (NumberFormatException e) { 12091 } 12092 synchronized (mProcessCpuThread) { 12093 final int N = mProcessCpuTracker.countStats(); 12094 for (int i=0; i<N; i++) { 12095 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12096 if (st.pid == findPid || (st.baseName != null 12097 && st.baseName.equals(args[opti]))) { 12098 nativeProcs.add(st); 12099 } 12100 } 12101 } 12102 if (nativeProcs.size() > 0) { 12103 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12104 isCompact); 12105 Debug.MemoryInfo mi = null; 12106 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12107 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12108 final int pid = r.pid; 12109 if (!isCheckinRequest && dumpDetails) { 12110 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12111 } 12112 if (mi == null) { 12113 mi = new Debug.MemoryInfo(); 12114 } 12115 if (dumpDetails || (!brief && !oomOnly)) { 12116 Debug.getMemoryInfo(pid, mi); 12117 } else { 12118 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12119 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12120 } 12121 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12122 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12123 if (isCheckinRequest) { 12124 pw.println(); 12125 } 12126 } 12127 return; 12128 } 12129 } 12130 pw.println("No process found for: " + args[opti]); 12131 return; 12132 } 12133 12134 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12135 dumpDetails = true; 12136 } 12137 12138 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12139 12140 String[] innerArgs = new String[args.length-opti]; 12141 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12142 12143 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12144 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12145 long nativePss=0, dalvikPss=0, otherPss=0; 12146 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12147 12148 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12149 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12150 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12151 12152 long totalPss = 0; 12153 long cachedPss = 0; 12154 12155 Debug.MemoryInfo mi = null; 12156 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12157 final ProcessRecord r = procs.get(i); 12158 final IApplicationThread thread; 12159 final int pid; 12160 final int oomAdj; 12161 final boolean hasActivities; 12162 synchronized (this) { 12163 thread = r.thread; 12164 pid = r.pid; 12165 oomAdj = r.getSetAdjWithServices(); 12166 hasActivities = r.activities.size() > 0; 12167 } 12168 if (thread != null) { 12169 if (!isCheckinRequest && dumpDetails) { 12170 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12171 } 12172 if (mi == null) { 12173 mi = new Debug.MemoryInfo(); 12174 } 12175 if (dumpDetails || (!brief && !oomOnly)) { 12176 Debug.getMemoryInfo(pid, mi); 12177 } else { 12178 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12179 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12180 } 12181 if (dumpDetails) { 12182 if (localOnly) { 12183 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12184 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12185 if (isCheckinRequest) { 12186 pw.println(); 12187 } 12188 } else { 12189 try { 12190 pw.flush(); 12191 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12192 dumpDalvik, innerArgs); 12193 } catch (RemoteException e) { 12194 if (!isCheckinRequest) { 12195 pw.println("Got RemoteException!"); 12196 pw.flush(); 12197 } 12198 } 12199 } 12200 } 12201 12202 final long myTotalPss = mi.getTotalPss(); 12203 final long myTotalUss = mi.getTotalUss(); 12204 12205 synchronized (this) { 12206 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12207 // Record this for posterity if the process has been stable. 12208 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12209 } 12210 } 12211 12212 if (!isCheckinRequest && mi != null) { 12213 totalPss += myTotalPss; 12214 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12215 (hasActivities ? " / activities)" : ")"), 12216 r.processName, myTotalPss, pid, hasActivities); 12217 procMems.add(pssItem); 12218 procMemsMap.put(pid, pssItem); 12219 12220 nativePss += mi.nativePss; 12221 dalvikPss += mi.dalvikPss; 12222 otherPss += mi.otherPss; 12223 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12224 long mem = mi.getOtherPss(j); 12225 miscPss[j] += mem; 12226 otherPss -= mem; 12227 } 12228 12229 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12230 cachedPss += myTotalPss; 12231 } 12232 12233 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12234 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12235 || oomIndex == (oomPss.length-1)) { 12236 oomPss[oomIndex] += myTotalPss; 12237 if (oomProcs[oomIndex] == null) { 12238 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12239 } 12240 oomProcs[oomIndex].add(pssItem); 12241 break; 12242 } 12243 } 12244 } 12245 } 12246 } 12247 12248 if (!isCheckinRequest && procs.size() > 1) { 12249 // If we are showing aggregations, also look for native processes to 12250 // include so that our aggregations are more accurate. 12251 updateCpuStatsNow(); 12252 synchronized (mProcessCpuThread) { 12253 final int N = mProcessCpuTracker.countStats(); 12254 for (int i=0; i<N; i++) { 12255 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12256 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12257 if (mi == null) { 12258 mi = new Debug.MemoryInfo(); 12259 } 12260 if (!brief && !oomOnly) { 12261 Debug.getMemoryInfo(st.pid, mi); 12262 } else { 12263 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12264 mi.nativePrivateDirty = (int)tmpLong[0]; 12265 } 12266 12267 final long myTotalPss = mi.getTotalPss(); 12268 totalPss += myTotalPss; 12269 12270 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12271 st.name, myTotalPss, st.pid, false); 12272 procMems.add(pssItem); 12273 12274 nativePss += mi.nativePss; 12275 dalvikPss += mi.dalvikPss; 12276 otherPss += mi.otherPss; 12277 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12278 long mem = mi.getOtherPss(j); 12279 miscPss[j] += mem; 12280 otherPss -= mem; 12281 } 12282 oomPss[0] += myTotalPss; 12283 if (oomProcs[0] == null) { 12284 oomProcs[0] = new ArrayList<MemItem>(); 12285 } 12286 oomProcs[0].add(pssItem); 12287 } 12288 } 12289 } 12290 12291 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12292 12293 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12294 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12295 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12296 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12297 String label = Debug.MemoryInfo.getOtherLabel(j); 12298 catMems.add(new MemItem(label, label, miscPss[j], j)); 12299 } 12300 12301 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12302 for (int j=0; j<oomPss.length; j++) { 12303 if (oomPss[j] != 0) { 12304 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12305 : DUMP_MEM_OOM_LABEL[j]; 12306 MemItem item = new MemItem(label, label, oomPss[j], 12307 DUMP_MEM_OOM_ADJ[j]); 12308 item.subitems = oomProcs[j]; 12309 oomMems.add(item); 12310 } 12311 } 12312 12313 if (!brief && !oomOnly && !isCompact) { 12314 pw.println(); 12315 pw.println("Total PSS by process:"); 12316 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12317 pw.println(); 12318 } 12319 if (!isCompact) { 12320 pw.println("Total PSS by OOM adjustment:"); 12321 } 12322 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12323 if (!brief && !oomOnly) { 12324 PrintWriter out = categoryPw != null ? categoryPw : pw; 12325 if (!isCompact) { 12326 out.println(); 12327 out.println("Total PSS by category:"); 12328 } 12329 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12330 } 12331 if (!isCompact) { 12332 pw.println(); 12333 } 12334 MemInfoReader memInfo = new MemInfoReader(); 12335 memInfo.readMemInfo(); 12336 if (!brief) { 12337 if (!isCompact) { 12338 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12339 pw.print(" kB (status "); 12340 switch (mLastMemoryLevel) { 12341 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12342 pw.println("normal)"); 12343 break; 12344 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12345 pw.println("moderate)"); 12346 break; 12347 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12348 pw.println("low)"); 12349 break; 12350 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12351 pw.println("critical)"); 12352 break; 12353 default: 12354 pw.print(mLastMemoryLevel); 12355 pw.println(")"); 12356 break; 12357 } 12358 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12359 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12360 pw.print(cachedPss); pw.print(" cached pss + "); 12361 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12362 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12363 } else { 12364 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12365 pw.print(cachedPss + memInfo.getCachedSizeKb() 12366 + memInfo.getFreeSizeKb()); pw.print(","); 12367 pw.println(totalPss - cachedPss); 12368 } 12369 } 12370 if (!isCompact) { 12371 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12372 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12373 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12374 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12375 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12376 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12377 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12378 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12379 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12380 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12381 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12382 } 12383 if (!brief) { 12384 if (memInfo.getZramTotalSizeKb() != 0) { 12385 if (!isCompact) { 12386 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12387 pw.print(" kB physical used for "); 12388 pw.print(memInfo.getSwapTotalSizeKb() 12389 - memInfo.getSwapFreeSizeKb()); 12390 pw.print(" kB in swap ("); 12391 pw.print(memInfo.getSwapTotalSizeKb()); 12392 pw.println(" kB total swap)"); 12393 } else { 12394 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12395 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12396 pw.println(memInfo.getSwapFreeSizeKb()); 12397 } 12398 } 12399 final int[] SINGLE_LONG_FORMAT = new int[] { 12400 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12401 }; 12402 long[] longOut = new long[1]; 12403 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12404 SINGLE_LONG_FORMAT, null, longOut, null); 12405 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12406 longOut[0] = 0; 12407 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12408 SINGLE_LONG_FORMAT, null, longOut, null); 12409 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12410 longOut[0] = 0; 12411 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12412 SINGLE_LONG_FORMAT, null, longOut, null); 12413 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12414 longOut[0] = 0; 12415 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12416 SINGLE_LONG_FORMAT, null, longOut, null); 12417 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12418 if (!isCompact) { 12419 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12420 pw.print(" KSM: "); pw.print(sharing); 12421 pw.print(" kB saved from shared "); 12422 pw.print(shared); pw.println(" kB"); 12423 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12424 pw.print(voltile); pw.println(" kB volatile"); 12425 } 12426 pw.print(" Tuning: "); 12427 pw.print(ActivityManager.staticGetMemoryClass()); 12428 pw.print(" (large "); 12429 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12430 pw.print("), oom "); 12431 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12432 pw.print(" kB"); 12433 pw.print(", restore limit "); 12434 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12435 pw.print(" kB"); 12436 if (ActivityManager.isLowRamDeviceStatic()) { 12437 pw.print(" (low-ram)"); 12438 } 12439 if (ActivityManager.isHighEndGfx()) { 12440 pw.print(" (high-end-gfx)"); 12441 } 12442 pw.println(); 12443 } else { 12444 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12445 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12446 pw.println(voltile); 12447 pw.print("tuning,"); 12448 pw.print(ActivityManager.staticGetMemoryClass()); 12449 pw.print(','); 12450 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12451 pw.print(','); 12452 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12453 if (ActivityManager.isLowRamDeviceStatic()) { 12454 pw.print(",low-ram"); 12455 } 12456 if (ActivityManager.isHighEndGfx()) { 12457 pw.print(",high-end-gfx"); 12458 } 12459 pw.println(); 12460 } 12461 } 12462 } 12463 } 12464 12465 /** 12466 * Searches array of arguments for the specified string 12467 * @param args array of argument strings 12468 * @param value value to search for 12469 * @return true if the value is contained in the array 12470 */ 12471 private static boolean scanArgs(String[] args, String value) { 12472 if (args != null) { 12473 for (String arg : args) { 12474 if (value.equals(arg)) { 12475 return true; 12476 } 12477 } 12478 } 12479 return false; 12480 } 12481 12482 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12483 ContentProviderRecord cpr, boolean always) { 12484 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12485 12486 if (!inLaunching || always) { 12487 synchronized (cpr) { 12488 cpr.launchingApp = null; 12489 cpr.notifyAll(); 12490 } 12491 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12492 String names[] = cpr.info.authority.split(";"); 12493 for (int j = 0; j < names.length; j++) { 12494 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12495 } 12496 } 12497 12498 for (int i=0; i<cpr.connections.size(); i++) { 12499 ContentProviderConnection conn = cpr.connections.get(i); 12500 if (conn.waiting) { 12501 // If this connection is waiting for the provider, then we don't 12502 // need to mess with its process unless we are always removing 12503 // or for some reason the provider is not currently launching. 12504 if (inLaunching && !always) { 12505 continue; 12506 } 12507 } 12508 ProcessRecord capp = conn.client; 12509 conn.dead = true; 12510 if (conn.stableCount > 0) { 12511 if (!capp.persistent && capp.thread != null 12512 && capp.pid != 0 12513 && capp.pid != MY_PID) { 12514 killUnneededProcessLocked(capp, "depends on provider " 12515 + cpr.name.flattenToShortString() 12516 + " in dying proc " + (proc != null ? proc.processName : "??")); 12517 } 12518 } else if (capp.thread != null && conn.provider.provider != null) { 12519 try { 12520 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12521 } catch (RemoteException e) { 12522 } 12523 // In the protocol here, we don't expect the client to correctly 12524 // clean up this connection, we'll just remove it. 12525 cpr.connections.remove(i); 12526 conn.client.conProviders.remove(conn); 12527 } 12528 } 12529 12530 if (inLaunching && always) { 12531 mLaunchingProviders.remove(cpr); 12532 } 12533 return inLaunching; 12534 } 12535 12536 /** 12537 * Main code for cleaning up a process when it has gone away. This is 12538 * called both as a result of the process dying, or directly when stopping 12539 * a process when running in single process mode. 12540 */ 12541 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12542 boolean restarting, boolean allowRestart, int index) { 12543 if (index >= 0) { 12544 removeLruProcessLocked(app); 12545 ProcessList.remove(app.pid); 12546 } 12547 12548 mProcessesToGc.remove(app); 12549 mPendingPssProcesses.remove(app); 12550 12551 // Dismiss any open dialogs. 12552 if (app.crashDialog != null && !app.forceCrashReport) { 12553 app.crashDialog.dismiss(); 12554 app.crashDialog = null; 12555 } 12556 if (app.anrDialog != null) { 12557 app.anrDialog.dismiss(); 12558 app.anrDialog = null; 12559 } 12560 if (app.waitDialog != null) { 12561 app.waitDialog.dismiss(); 12562 app.waitDialog = null; 12563 } 12564 12565 app.crashing = false; 12566 app.notResponding = false; 12567 12568 app.resetPackageList(mProcessStats); 12569 app.unlinkDeathRecipient(); 12570 app.makeInactive(mProcessStats); 12571 app.forcingToForeground = null; 12572 updateProcessForegroundLocked(app, false, false); 12573 app.foregroundActivities = false; 12574 app.hasShownUi = false; 12575 app.treatLikeActivity = false; 12576 app.hasAboveClient = false; 12577 app.hasClientActivities = false; 12578 12579 mServices.killServicesLocked(app, allowRestart); 12580 12581 boolean restart = false; 12582 12583 // Remove published content providers. 12584 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12585 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12586 final boolean always = app.bad || !allowRestart; 12587 if (removeDyingProviderLocked(app, cpr, always) || always) { 12588 // We left the provider in the launching list, need to 12589 // restart it. 12590 restart = true; 12591 } 12592 12593 cpr.provider = null; 12594 cpr.proc = null; 12595 } 12596 app.pubProviders.clear(); 12597 12598 // Take care of any launching providers waiting for this process. 12599 if (checkAppInLaunchingProvidersLocked(app, false)) { 12600 restart = true; 12601 } 12602 12603 // Unregister from connected content providers. 12604 if (!app.conProviders.isEmpty()) { 12605 for (int i=0; i<app.conProviders.size(); i++) { 12606 ContentProviderConnection conn = app.conProviders.get(i); 12607 conn.provider.connections.remove(conn); 12608 } 12609 app.conProviders.clear(); 12610 } 12611 12612 // At this point there may be remaining entries in mLaunchingProviders 12613 // where we were the only one waiting, so they are no longer of use. 12614 // Look for these and clean up if found. 12615 // XXX Commented out for now. Trying to figure out a way to reproduce 12616 // the actual situation to identify what is actually going on. 12617 if (false) { 12618 for (int i=0; i<mLaunchingProviders.size(); i++) { 12619 ContentProviderRecord cpr = (ContentProviderRecord) 12620 mLaunchingProviders.get(i); 12621 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12622 synchronized (cpr) { 12623 cpr.launchingApp = null; 12624 cpr.notifyAll(); 12625 } 12626 } 12627 } 12628 } 12629 12630 skipCurrentReceiverLocked(app); 12631 12632 // Unregister any receivers. 12633 for (int i=app.receivers.size()-1; i>=0; i--) { 12634 removeReceiverLocked(app.receivers.valueAt(i)); 12635 } 12636 app.receivers.clear(); 12637 12638 // If the app is undergoing backup, tell the backup manager about it 12639 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12640 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12641 + mBackupTarget.appInfo + " died during backup"); 12642 try { 12643 IBackupManager bm = IBackupManager.Stub.asInterface( 12644 ServiceManager.getService(Context.BACKUP_SERVICE)); 12645 bm.agentDisconnected(app.info.packageName); 12646 } catch (RemoteException e) { 12647 // can't happen; backup manager is local 12648 } 12649 } 12650 12651 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12652 ProcessChangeItem item = mPendingProcessChanges.get(i); 12653 if (item.pid == app.pid) { 12654 mPendingProcessChanges.remove(i); 12655 mAvailProcessChanges.add(item); 12656 } 12657 } 12658 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12659 12660 // If the caller is restarting this app, then leave it in its 12661 // current lists and let the caller take care of it. 12662 if (restarting) { 12663 return; 12664 } 12665 12666 if (!app.persistent || app.isolated) { 12667 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12668 "Removing non-persistent process during cleanup: " + app); 12669 mProcessNames.remove(app.processName, app.uid); 12670 mIsolatedProcesses.remove(app.uid); 12671 if (mHeavyWeightProcess == app) { 12672 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12673 mHeavyWeightProcess.userId, 0)); 12674 mHeavyWeightProcess = null; 12675 } 12676 } else if (!app.removed) { 12677 // This app is persistent, so we need to keep its record around. 12678 // If it is not already on the pending app list, add it there 12679 // and start a new process for it. 12680 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12681 mPersistentStartingProcesses.add(app); 12682 restart = true; 12683 } 12684 } 12685 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12686 "Clean-up removing on hold: " + app); 12687 mProcessesOnHold.remove(app); 12688 12689 if (app == mHomeProcess) { 12690 mHomeProcess = null; 12691 } 12692 if (app == mPreviousProcess) { 12693 mPreviousProcess = null; 12694 } 12695 12696 if (restart && !app.isolated) { 12697 // We have components that still need to be running in the 12698 // process, so re-launch it. 12699 mProcessNames.put(app.processName, app.uid, app); 12700 startProcessLocked(app, "restart", app.processName); 12701 } else if (app.pid > 0 && app.pid != MY_PID) { 12702 // Goodbye! 12703 boolean removed; 12704 synchronized (mPidsSelfLocked) { 12705 mPidsSelfLocked.remove(app.pid); 12706 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12707 } 12708 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12709 app.processName, app.info.uid); 12710 if (app.isolated) { 12711 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12712 } 12713 app.setPid(0); 12714 } 12715 } 12716 12717 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12718 // Look through the content providers we are waiting to have launched, 12719 // and if any run in this process then either schedule a restart of 12720 // the process or kill the client waiting for it if this process has 12721 // gone bad. 12722 int NL = mLaunchingProviders.size(); 12723 boolean restart = false; 12724 for (int i=0; i<NL; i++) { 12725 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12726 if (cpr.launchingApp == app) { 12727 if (!alwaysBad && !app.bad) { 12728 restart = true; 12729 } else { 12730 removeDyingProviderLocked(app, cpr, true); 12731 // cpr should have been removed from mLaunchingProviders 12732 NL = mLaunchingProviders.size(); 12733 i--; 12734 } 12735 } 12736 } 12737 return restart; 12738 } 12739 12740 // ========================================================= 12741 // SERVICES 12742 // ========================================================= 12743 12744 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12745 int flags) { 12746 enforceNotIsolatedCaller("getServices"); 12747 synchronized (this) { 12748 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12749 } 12750 } 12751 12752 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12753 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12754 synchronized (this) { 12755 return mServices.getRunningServiceControlPanelLocked(name); 12756 } 12757 } 12758 12759 public ComponentName startService(IApplicationThread caller, Intent service, 12760 String resolvedType, int userId) { 12761 enforceNotIsolatedCaller("startService"); 12762 // Refuse possible leaked file descriptors 12763 if (service != null && service.hasFileDescriptors() == true) { 12764 throw new IllegalArgumentException("File descriptors passed in Intent"); 12765 } 12766 12767 if (DEBUG_SERVICE) 12768 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12769 synchronized(this) { 12770 final int callingPid = Binder.getCallingPid(); 12771 final int callingUid = Binder.getCallingUid(); 12772 final long origId = Binder.clearCallingIdentity(); 12773 ComponentName res = mServices.startServiceLocked(caller, service, 12774 resolvedType, callingPid, callingUid, userId); 12775 Binder.restoreCallingIdentity(origId); 12776 return res; 12777 } 12778 } 12779 12780 ComponentName startServiceInPackage(int uid, 12781 Intent service, String resolvedType, int userId) { 12782 synchronized(this) { 12783 if (DEBUG_SERVICE) 12784 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12785 final long origId = Binder.clearCallingIdentity(); 12786 ComponentName res = mServices.startServiceLocked(null, service, 12787 resolvedType, -1, uid, userId); 12788 Binder.restoreCallingIdentity(origId); 12789 return res; 12790 } 12791 } 12792 12793 public int stopService(IApplicationThread caller, Intent service, 12794 String resolvedType, int userId) { 12795 enforceNotIsolatedCaller("stopService"); 12796 // Refuse possible leaked file descriptors 12797 if (service != null && service.hasFileDescriptors() == true) { 12798 throw new IllegalArgumentException("File descriptors passed in Intent"); 12799 } 12800 12801 synchronized(this) { 12802 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12803 } 12804 } 12805 12806 public IBinder peekService(Intent service, String resolvedType) { 12807 enforceNotIsolatedCaller("peekService"); 12808 // Refuse possible leaked file descriptors 12809 if (service != null && service.hasFileDescriptors() == true) { 12810 throw new IllegalArgumentException("File descriptors passed in Intent"); 12811 } 12812 synchronized(this) { 12813 return mServices.peekServiceLocked(service, resolvedType); 12814 } 12815 } 12816 12817 public boolean stopServiceToken(ComponentName className, IBinder token, 12818 int startId) { 12819 synchronized(this) { 12820 return mServices.stopServiceTokenLocked(className, token, startId); 12821 } 12822 } 12823 12824 public void setServiceForeground(ComponentName className, IBinder token, 12825 int id, Notification notification, boolean removeNotification) { 12826 synchronized(this) { 12827 mServices.setServiceForegroundLocked(className, token, id, notification, 12828 removeNotification); 12829 } 12830 } 12831 12832 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12833 boolean requireFull, String name, String callerPackage) { 12834 final int callingUserId = UserHandle.getUserId(callingUid); 12835 if (callingUserId != userId) { 12836 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12837 if ((requireFull || checkComponentPermission( 12838 android.Manifest.permission.INTERACT_ACROSS_USERS, 12839 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12840 && checkComponentPermission( 12841 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12842 callingPid, callingUid, -1, true) 12843 != PackageManager.PERMISSION_GRANTED) { 12844 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12845 // In this case, they would like to just execute as their 12846 // owner user instead of failing. 12847 userId = callingUserId; 12848 } else { 12849 StringBuilder builder = new StringBuilder(128); 12850 builder.append("Permission Denial: "); 12851 builder.append(name); 12852 if (callerPackage != null) { 12853 builder.append(" from "); 12854 builder.append(callerPackage); 12855 } 12856 builder.append(" asks to run as user "); 12857 builder.append(userId); 12858 builder.append(" but is calling from user "); 12859 builder.append(UserHandle.getUserId(callingUid)); 12860 builder.append("; this requires "); 12861 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12862 if (!requireFull) { 12863 builder.append(" or "); 12864 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12865 } 12866 String msg = builder.toString(); 12867 Slog.w(TAG, msg); 12868 throw new SecurityException(msg); 12869 } 12870 } 12871 } 12872 if (userId == UserHandle.USER_CURRENT 12873 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12874 // Note that we may be accessing this outside of a lock... 12875 // shouldn't be a big deal, if this is being called outside 12876 // of a locked context there is intrinsically a race with 12877 // the value the caller will receive and someone else changing it. 12878 userId = mCurrentUserId; 12879 } 12880 if (!allowAll && userId < 0) { 12881 throw new IllegalArgumentException( 12882 "Call does not support special user #" + userId); 12883 } 12884 } 12885 return userId; 12886 } 12887 12888 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12889 String className, int flags) { 12890 boolean result = false; 12891 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12892 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12893 if (ActivityManager.checkUidPermission( 12894 android.Manifest.permission.INTERACT_ACROSS_USERS, 12895 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12896 ComponentName comp = new ComponentName(aInfo.packageName, className); 12897 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12898 + " requests FLAG_SINGLE_USER, but app does not hold " 12899 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12900 Slog.w(TAG, msg); 12901 throw new SecurityException(msg); 12902 } 12903 result = true; 12904 } 12905 } else if (componentProcessName == aInfo.packageName) { 12906 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12907 } else if ("system".equals(componentProcessName)) { 12908 result = true; 12909 } 12910 if (DEBUG_MU) { 12911 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12912 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12913 } 12914 return result; 12915 } 12916 12917 public int bindService(IApplicationThread caller, IBinder token, 12918 Intent service, String resolvedType, 12919 IServiceConnection connection, int flags, int userId) { 12920 enforceNotIsolatedCaller("bindService"); 12921 // Refuse possible leaked file descriptors 12922 if (service != null && service.hasFileDescriptors() == true) { 12923 throw new IllegalArgumentException("File descriptors passed in Intent"); 12924 } 12925 12926 synchronized(this) { 12927 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12928 connection, flags, userId); 12929 } 12930 } 12931 12932 public boolean unbindService(IServiceConnection connection) { 12933 synchronized (this) { 12934 return mServices.unbindServiceLocked(connection); 12935 } 12936 } 12937 12938 public void publishService(IBinder token, Intent intent, IBinder service) { 12939 // Refuse possible leaked file descriptors 12940 if (intent != null && intent.hasFileDescriptors() == true) { 12941 throw new IllegalArgumentException("File descriptors passed in Intent"); 12942 } 12943 12944 synchronized(this) { 12945 if (!(token instanceof ServiceRecord)) { 12946 throw new IllegalArgumentException("Invalid service token"); 12947 } 12948 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12949 } 12950 } 12951 12952 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12953 // Refuse possible leaked file descriptors 12954 if (intent != null && intent.hasFileDescriptors() == true) { 12955 throw new IllegalArgumentException("File descriptors passed in Intent"); 12956 } 12957 12958 synchronized(this) { 12959 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12960 } 12961 } 12962 12963 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12964 synchronized(this) { 12965 if (!(token instanceof ServiceRecord)) { 12966 throw new IllegalArgumentException("Invalid service token"); 12967 } 12968 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12969 } 12970 } 12971 12972 // ========================================================= 12973 // BACKUP AND RESTORE 12974 // ========================================================= 12975 12976 // Cause the target app to be launched if necessary and its backup agent 12977 // instantiated. The backup agent will invoke backupAgentCreated() on the 12978 // activity manager to announce its creation. 12979 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12980 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12981 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12982 12983 synchronized(this) { 12984 // !!! TODO: currently no check here that we're already bound 12985 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12986 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12987 synchronized (stats) { 12988 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12989 } 12990 12991 // Backup agent is now in use, its package can't be stopped. 12992 try { 12993 AppGlobals.getPackageManager().setPackageStoppedState( 12994 app.packageName, false, UserHandle.getUserId(app.uid)); 12995 } catch (RemoteException e) { 12996 } catch (IllegalArgumentException e) { 12997 Slog.w(TAG, "Failed trying to unstop package " 12998 + app.packageName + ": " + e); 12999 } 13000 13001 BackupRecord r = new BackupRecord(ss, app, backupMode); 13002 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13003 ? new ComponentName(app.packageName, app.backupAgentName) 13004 : new ComponentName("android", "FullBackupAgent"); 13005 // startProcessLocked() returns existing proc's record if it's already running 13006 ProcessRecord proc = startProcessLocked(app.processName, app, 13007 false, 0, "backup", hostingName, false, false, false); 13008 if (proc == null) { 13009 Slog.e(TAG, "Unable to start backup agent process " + r); 13010 return false; 13011 } 13012 13013 r.app = proc; 13014 mBackupTarget = r; 13015 mBackupAppName = app.packageName; 13016 13017 // Try not to kill the process during backup 13018 updateOomAdjLocked(proc); 13019 13020 // If the process is already attached, schedule the creation of the backup agent now. 13021 // If it is not yet live, this will be done when it attaches to the framework. 13022 if (proc.thread != null) { 13023 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13024 try { 13025 proc.thread.scheduleCreateBackupAgent(app, 13026 compatibilityInfoForPackageLocked(app), backupMode); 13027 } catch (RemoteException e) { 13028 // Will time out on the backup manager side 13029 } 13030 } else { 13031 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13032 } 13033 // Invariants: at this point, the target app process exists and the application 13034 // is either already running or in the process of coming up. mBackupTarget and 13035 // mBackupAppName describe the app, so that when it binds back to the AM we 13036 // know that it's scheduled for a backup-agent operation. 13037 } 13038 13039 return true; 13040 } 13041 13042 @Override 13043 public void clearPendingBackup() { 13044 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13045 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13046 13047 synchronized (this) { 13048 mBackupTarget = null; 13049 mBackupAppName = null; 13050 } 13051 } 13052 13053 // A backup agent has just come up 13054 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13055 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13056 + " = " + agent); 13057 13058 synchronized(this) { 13059 if (!agentPackageName.equals(mBackupAppName)) { 13060 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13061 return; 13062 } 13063 } 13064 13065 long oldIdent = Binder.clearCallingIdentity(); 13066 try { 13067 IBackupManager bm = IBackupManager.Stub.asInterface( 13068 ServiceManager.getService(Context.BACKUP_SERVICE)); 13069 bm.agentConnected(agentPackageName, agent); 13070 } catch (RemoteException e) { 13071 // can't happen; the backup manager service is local 13072 } catch (Exception e) { 13073 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13074 e.printStackTrace(); 13075 } finally { 13076 Binder.restoreCallingIdentity(oldIdent); 13077 } 13078 } 13079 13080 // done with this agent 13081 public void unbindBackupAgent(ApplicationInfo appInfo) { 13082 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13083 if (appInfo == null) { 13084 Slog.w(TAG, "unbind backup agent for null app"); 13085 return; 13086 } 13087 13088 synchronized(this) { 13089 try { 13090 if (mBackupAppName == null) { 13091 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13092 return; 13093 } 13094 13095 if (!mBackupAppName.equals(appInfo.packageName)) { 13096 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13097 return; 13098 } 13099 13100 // Not backing this app up any more; reset its OOM adjustment 13101 final ProcessRecord proc = mBackupTarget.app; 13102 updateOomAdjLocked(proc); 13103 13104 // If the app crashed during backup, 'thread' will be null here 13105 if (proc.thread != null) { 13106 try { 13107 proc.thread.scheduleDestroyBackupAgent(appInfo, 13108 compatibilityInfoForPackageLocked(appInfo)); 13109 } catch (Exception e) { 13110 Slog.e(TAG, "Exception when unbinding backup agent:"); 13111 e.printStackTrace(); 13112 } 13113 } 13114 } finally { 13115 mBackupTarget = null; 13116 mBackupAppName = null; 13117 } 13118 } 13119 } 13120 // ========================================================= 13121 // BROADCASTS 13122 // ========================================================= 13123 13124 private final List getStickiesLocked(String action, IntentFilter filter, 13125 List cur, int userId) { 13126 final ContentResolver resolver = mContext.getContentResolver(); 13127 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13128 if (stickies == null) { 13129 return cur; 13130 } 13131 final ArrayList<Intent> list = stickies.get(action); 13132 if (list == null) { 13133 return cur; 13134 } 13135 int N = list.size(); 13136 for (int i=0; i<N; i++) { 13137 Intent intent = list.get(i); 13138 if (filter.match(resolver, intent, true, TAG) >= 0) { 13139 if (cur == null) { 13140 cur = new ArrayList<Intent>(); 13141 } 13142 cur.add(intent); 13143 } 13144 } 13145 return cur; 13146 } 13147 13148 boolean isPendingBroadcastProcessLocked(int pid) { 13149 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13150 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13151 } 13152 13153 void skipPendingBroadcastLocked(int pid) { 13154 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13155 for (BroadcastQueue queue : mBroadcastQueues) { 13156 queue.skipPendingBroadcastLocked(pid); 13157 } 13158 } 13159 13160 // The app just attached; send any pending broadcasts that it should receive 13161 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13162 boolean didSomething = false; 13163 for (BroadcastQueue queue : mBroadcastQueues) { 13164 didSomething |= queue.sendPendingBroadcastsLocked(app); 13165 } 13166 return didSomething; 13167 } 13168 13169 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13170 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13171 enforceNotIsolatedCaller("registerReceiver"); 13172 int callingUid; 13173 int callingPid; 13174 synchronized(this) { 13175 ProcessRecord callerApp = null; 13176 if (caller != null) { 13177 callerApp = getRecordForAppLocked(caller); 13178 if (callerApp == null) { 13179 throw new SecurityException( 13180 "Unable to find app for caller " + caller 13181 + " (pid=" + Binder.getCallingPid() 13182 + ") when registering receiver " + receiver); 13183 } 13184 if (callerApp.info.uid != Process.SYSTEM_UID && 13185 !callerApp.pkgList.containsKey(callerPackage) && 13186 !"android".equals(callerPackage)) { 13187 throw new SecurityException("Given caller package " + callerPackage 13188 + " is not running in process " + callerApp); 13189 } 13190 callingUid = callerApp.info.uid; 13191 callingPid = callerApp.pid; 13192 } else { 13193 callerPackage = null; 13194 callingUid = Binder.getCallingUid(); 13195 callingPid = Binder.getCallingPid(); 13196 } 13197 13198 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13199 true, true, "registerReceiver", callerPackage); 13200 13201 List allSticky = null; 13202 13203 // Look for any matching sticky broadcasts... 13204 Iterator actions = filter.actionsIterator(); 13205 if (actions != null) { 13206 while (actions.hasNext()) { 13207 String action = (String)actions.next(); 13208 allSticky = getStickiesLocked(action, filter, allSticky, 13209 UserHandle.USER_ALL); 13210 allSticky = getStickiesLocked(action, filter, allSticky, 13211 UserHandle.getUserId(callingUid)); 13212 } 13213 } else { 13214 allSticky = getStickiesLocked(null, filter, allSticky, 13215 UserHandle.USER_ALL); 13216 allSticky = getStickiesLocked(null, filter, allSticky, 13217 UserHandle.getUserId(callingUid)); 13218 } 13219 13220 // The first sticky in the list is returned directly back to 13221 // the client. 13222 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13223 13224 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13225 + ": " + sticky); 13226 13227 if (receiver == null) { 13228 return sticky; 13229 } 13230 13231 ReceiverList rl 13232 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13233 if (rl == null) { 13234 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13235 userId, receiver); 13236 if (rl.app != null) { 13237 rl.app.receivers.add(rl); 13238 } else { 13239 try { 13240 receiver.asBinder().linkToDeath(rl, 0); 13241 } catch (RemoteException e) { 13242 return sticky; 13243 } 13244 rl.linkedToDeath = true; 13245 } 13246 mRegisteredReceivers.put(receiver.asBinder(), rl); 13247 } else if (rl.uid != callingUid) { 13248 throw new IllegalArgumentException( 13249 "Receiver requested to register for uid " + callingUid 13250 + " was previously registered for uid " + rl.uid); 13251 } else if (rl.pid != callingPid) { 13252 throw new IllegalArgumentException( 13253 "Receiver requested to register for pid " + callingPid 13254 + " was previously registered for pid " + rl.pid); 13255 } else if (rl.userId != userId) { 13256 throw new IllegalArgumentException( 13257 "Receiver requested to register for user " + userId 13258 + " was previously registered for user " + rl.userId); 13259 } 13260 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13261 permission, callingUid, userId); 13262 rl.add(bf); 13263 if (!bf.debugCheck()) { 13264 Slog.w(TAG, "==> For Dynamic broadast"); 13265 } 13266 mReceiverResolver.addFilter(bf); 13267 13268 // Enqueue broadcasts for all existing stickies that match 13269 // this filter. 13270 if (allSticky != null) { 13271 ArrayList receivers = new ArrayList(); 13272 receivers.add(bf); 13273 13274 int N = allSticky.size(); 13275 for (int i=0; i<N; i++) { 13276 Intent intent = (Intent)allSticky.get(i); 13277 BroadcastQueue queue = broadcastQueueForIntent(intent); 13278 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13279 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13280 null, null, false, true, true, -1); 13281 queue.enqueueParallelBroadcastLocked(r); 13282 queue.scheduleBroadcastsLocked(); 13283 } 13284 } 13285 13286 return sticky; 13287 } 13288 } 13289 13290 public void unregisterReceiver(IIntentReceiver receiver) { 13291 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13292 13293 final long origId = Binder.clearCallingIdentity(); 13294 try { 13295 boolean doTrim = false; 13296 13297 synchronized(this) { 13298 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13299 if (rl != null) { 13300 if (rl.curBroadcast != null) { 13301 BroadcastRecord r = rl.curBroadcast; 13302 final boolean doNext = finishReceiverLocked( 13303 receiver.asBinder(), r.resultCode, r.resultData, 13304 r.resultExtras, r.resultAbort); 13305 if (doNext) { 13306 doTrim = true; 13307 r.queue.processNextBroadcast(false); 13308 } 13309 } 13310 13311 if (rl.app != null) { 13312 rl.app.receivers.remove(rl); 13313 } 13314 removeReceiverLocked(rl); 13315 if (rl.linkedToDeath) { 13316 rl.linkedToDeath = false; 13317 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13318 } 13319 } 13320 } 13321 13322 // If we actually concluded any broadcasts, we might now be able 13323 // to trim the recipients' apps from our working set 13324 if (doTrim) { 13325 trimApplications(); 13326 return; 13327 } 13328 13329 } finally { 13330 Binder.restoreCallingIdentity(origId); 13331 } 13332 } 13333 13334 void removeReceiverLocked(ReceiverList rl) { 13335 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13336 int N = rl.size(); 13337 for (int i=0; i<N; i++) { 13338 mReceiverResolver.removeFilter(rl.get(i)); 13339 } 13340 } 13341 13342 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13343 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13344 ProcessRecord r = mLruProcesses.get(i); 13345 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13346 try { 13347 r.thread.dispatchPackageBroadcast(cmd, packages); 13348 } catch (RemoteException ex) { 13349 } 13350 } 13351 } 13352 } 13353 13354 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13355 int[] users) { 13356 List<ResolveInfo> receivers = null; 13357 try { 13358 HashSet<ComponentName> singleUserReceivers = null; 13359 boolean scannedFirstReceivers = false; 13360 for (int user : users) { 13361 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13362 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13363 if (user != 0 && newReceivers != null) { 13364 // If this is not the primary user, we need to check for 13365 // any receivers that should be filtered out. 13366 for (int i=0; i<newReceivers.size(); i++) { 13367 ResolveInfo ri = newReceivers.get(i); 13368 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13369 newReceivers.remove(i); 13370 i--; 13371 } 13372 } 13373 } 13374 if (newReceivers != null && newReceivers.size() == 0) { 13375 newReceivers = null; 13376 } 13377 if (receivers == null) { 13378 receivers = newReceivers; 13379 } else if (newReceivers != null) { 13380 // We need to concatenate the additional receivers 13381 // found with what we have do far. This would be easy, 13382 // but we also need to de-dup any receivers that are 13383 // singleUser. 13384 if (!scannedFirstReceivers) { 13385 // Collect any single user receivers we had already retrieved. 13386 scannedFirstReceivers = true; 13387 for (int i=0; i<receivers.size(); i++) { 13388 ResolveInfo ri = receivers.get(i); 13389 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13390 ComponentName cn = new ComponentName( 13391 ri.activityInfo.packageName, ri.activityInfo.name); 13392 if (singleUserReceivers == null) { 13393 singleUserReceivers = new HashSet<ComponentName>(); 13394 } 13395 singleUserReceivers.add(cn); 13396 } 13397 } 13398 } 13399 // Add the new results to the existing results, tracking 13400 // and de-dupping single user receivers. 13401 for (int i=0; i<newReceivers.size(); i++) { 13402 ResolveInfo ri = newReceivers.get(i); 13403 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13404 ComponentName cn = new ComponentName( 13405 ri.activityInfo.packageName, ri.activityInfo.name); 13406 if (singleUserReceivers == null) { 13407 singleUserReceivers = new HashSet<ComponentName>(); 13408 } 13409 if (!singleUserReceivers.contains(cn)) { 13410 singleUserReceivers.add(cn); 13411 receivers.add(ri); 13412 } 13413 } else { 13414 receivers.add(ri); 13415 } 13416 } 13417 } 13418 } 13419 } catch (RemoteException ex) { 13420 // pm is in same process, this will never happen. 13421 } 13422 return receivers; 13423 } 13424 13425 private final int broadcastIntentLocked(ProcessRecord callerApp, 13426 String callerPackage, Intent intent, String resolvedType, 13427 IIntentReceiver resultTo, int resultCode, String resultData, 13428 Bundle map, String requiredPermission, int appOp, 13429 boolean ordered, boolean sticky, int callingPid, int callingUid, 13430 int userId) { 13431 intent = new Intent(intent); 13432 13433 // By default broadcasts do not go to stopped apps. 13434 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13435 13436 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13437 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13438 + " ordered=" + ordered + " userid=" + userId); 13439 if ((resultTo != null) && !ordered) { 13440 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13441 } 13442 13443 userId = handleIncomingUser(callingPid, callingUid, userId, 13444 true, false, "broadcast", callerPackage); 13445 13446 // Make sure that the user who is receiving this broadcast is started. 13447 // If not, we will just skip it. 13448 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13449 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13450 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13451 Slog.w(TAG, "Skipping broadcast of " + intent 13452 + ": user " + userId + " is stopped"); 13453 return ActivityManager.BROADCAST_SUCCESS; 13454 } 13455 } 13456 13457 /* 13458 * Prevent non-system code (defined here to be non-persistent 13459 * processes) from sending protected broadcasts. 13460 */ 13461 int callingAppId = UserHandle.getAppId(callingUid); 13462 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13463 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13464 callingUid == 0) { 13465 // Always okay. 13466 } else if (callerApp == null || !callerApp.persistent) { 13467 try { 13468 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13469 intent.getAction())) { 13470 String msg = "Permission Denial: not allowed to send broadcast " 13471 + intent.getAction() + " from pid=" 13472 + callingPid + ", uid=" + callingUid; 13473 Slog.w(TAG, msg); 13474 throw new SecurityException(msg); 13475 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13476 // Special case for compatibility: we don't want apps to send this, 13477 // but historically it has not been protected and apps may be using it 13478 // to poke their own app widget. So, instead of making it protected, 13479 // just limit it to the caller. 13480 if (callerApp == null) { 13481 String msg = "Permission Denial: not allowed to send broadcast " 13482 + intent.getAction() + " from unknown caller."; 13483 Slog.w(TAG, msg); 13484 throw new SecurityException(msg); 13485 } else if (intent.getComponent() != null) { 13486 // They are good enough to send to an explicit component... verify 13487 // it is being sent to the calling app. 13488 if (!intent.getComponent().getPackageName().equals( 13489 callerApp.info.packageName)) { 13490 String msg = "Permission Denial: not allowed to send broadcast " 13491 + intent.getAction() + " to " 13492 + intent.getComponent().getPackageName() + " from " 13493 + callerApp.info.packageName; 13494 Slog.w(TAG, msg); 13495 throw new SecurityException(msg); 13496 } 13497 } else { 13498 // Limit broadcast to their own package. 13499 intent.setPackage(callerApp.info.packageName); 13500 } 13501 } 13502 } catch (RemoteException e) { 13503 Slog.w(TAG, "Remote exception", e); 13504 return ActivityManager.BROADCAST_SUCCESS; 13505 } 13506 } 13507 13508 // Handle special intents: if this broadcast is from the package 13509 // manager about a package being removed, we need to remove all of 13510 // its activities from the history stack. 13511 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13512 intent.getAction()); 13513 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13514 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13515 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13516 || uidRemoved) { 13517 if (checkComponentPermission( 13518 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13519 callingPid, callingUid, -1, true) 13520 == PackageManager.PERMISSION_GRANTED) { 13521 if (uidRemoved) { 13522 final Bundle intentExtras = intent.getExtras(); 13523 final int uid = intentExtras != null 13524 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13525 if (uid >= 0) { 13526 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13527 synchronized (bs) { 13528 bs.removeUidStatsLocked(uid); 13529 } 13530 mAppOpsService.uidRemoved(uid); 13531 } 13532 } else { 13533 // If resources are unavailable just force stop all 13534 // those packages and flush the attribute cache as well. 13535 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13536 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13537 if (list != null && (list.length > 0)) { 13538 for (String pkg : list) { 13539 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13540 "storage unmount"); 13541 } 13542 sendPackageBroadcastLocked( 13543 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13544 } 13545 } else { 13546 Uri data = intent.getData(); 13547 String ssp; 13548 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13549 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13550 intent.getAction()); 13551 boolean fullUninstall = removed && 13552 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13553 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13554 forceStopPackageLocked(ssp, UserHandle.getAppId( 13555 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13556 false, fullUninstall, userId, 13557 removed ? "pkg removed" : "pkg changed"); 13558 } 13559 if (removed) { 13560 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13561 new String[] {ssp}, userId); 13562 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13563 mAppOpsService.packageRemoved( 13564 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13565 13566 // Remove all permissions granted from/to this package 13567 removeUriPermissionsForPackageLocked(ssp, userId, true); 13568 } 13569 } 13570 } 13571 } 13572 } 13573 } else { 13574 String msg = "Permission Denial: " + intent.getAction() 13575 + " broadcast from " + callerPackage + " (pid=" + callingPid 13576 + ", uid=" + callingUid + ")" 13577 + " requires " 13578 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13579 Slog.w(TAG, msg); 13580 throw new SecurityException(msg); 13581 } 13582 13583 // Special case for adding a package: by default turn on compatibility 13584 // mode. 13585 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13586 Uri data = intent.getData(); 13587 String ssp; 13588 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13589 mCompatModePackages.handlePackageAddedLocked(ssp, 13590 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13591 } 13592 } 13593 13594 /* 13595 * If this is the time zone changed action, queue up a message that will reset the timezone 13596 * of all currently running processes. This message will get queued up before the broadcast 13597 * happens. 13598 */ 13599 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13600 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13601 } 13602 13603 /* 13604 * If the user set the time, let all running processes know. 13605 */ 13606 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13607 final int is24Hour = intent.getBooleanExtra( 13608 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13609 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13610 } 13611 13612 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13613 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13614 } 13615 13616 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13617 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13618 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13619 } 13620 13621 // Add to the sticky list if requested. 13622 if (sticky) { 13623 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13624 callingPid, callingUid) 13625 != PackageManager.PERMISSION_GRANTED) { 13626 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13627 + callingPid + ", uid=" + callingUid 13628 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13629 Slog.w(TAG, msg); 13630 throw new SecurityException(msg); 13631 } 13632 if (requiredPermission != null) { 13633 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13634 + " and enforce permission " + requiredPermission); 13635 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13636 } 13637 if (intent.getComponent() != null) { 13638 throw new SecurityException( 13639 "Sticky broadcasts can't target a specific component"); 13640 } 13641 // We use userId directly here, since the "all" target is maintained 13642 // as a separate set of sticky broadcasts. 13643 if (userId != UserHandle.USER_ALL) { 13644 // But first, if this is not a broadcast to all users, then 13645 // make sure it doesn't conflict with an existing broadcast to 13646 // all users. 13647 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13648 UserHandle.USER_ALL); 13649 if (stickies != null) { 13650 ArrayList<Intent> list = stickies.get(intent.getAction()); 13651 if (list != null) { 13652 int N = list.size(); 13653 int i; 13654 for (i=0; i<N; i++) { 13655 if (intent.filterEquals(list.get(i))) { 13656 throw new IllegalArgumentException( 13657 "Sticky broadcast " + intent + " for user " 13658 + userId + " conflicts with existing global broadcast"); 13659 } 13660 } 13661 } 13662 } 13663 } 13664 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13665 if (stickies == null) { 13666 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13667 mStickyBroadcasts.put(userId, stickies); 13668 } 13669 ArrayList<Intent> list = stickies.get(intent.getAction()); 13670 if (list == null) { 13671 list = new ArrayList<Intent>(); 13672 stickies.put(intent.getAction(), list); 13673 } 13674 int N = list.size(); 13675 int i; 13676 for (i=0; i<N; i++) { 13677 if (intent.filterEquals(list.get(i))) { 13678 // This sticky already exists, replace it. 13679 list.set(i, new Intent(intent)); 13680 break; 13681 } 13682 } 13683 if (i >= N) { 13684 list.add(new Intent(intent)); 13685 } 13686 } 13687 13688 int[] users; 13689 if (userId == UserHandle.USER_ALL) { 13690 // Caller wants broadcast to go to all started users. 13691 users = mStartedUserArray; 13692 } else { 13693 // Caller wants broadcast to go to one specific user. 13694 users = new int[] {userId}; 13695 } 13696 13697 // Figure out who all will receive this broadcast. 13698 List receivers = null; 13699 List<BroadcastFilter> registeredReceivers = null; 13700 // Need to resolve the intent to interested receivers... 13701 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13702 == 0) { 13703 receivers = collectReceiverComponents(intent, resolvedType, users); 13704 } 13705 if (intent.getComponent() == null) { 13706 registeredReceivers = mReceiverResolver.queryIntent(intent, 13707 resolvedType, false, userId); 13708 } 13709 13710 final boolean replacePending = 13711 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13712 13713 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13714 + " replacePending=" + replacePending); 13715 13716 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13717 if (!ordered && NR > 0) { 13718 // If we are not serializing this broadcast, then send the 13719 // registered receivers separately so they don't wait for the 13720 // components to be launched. 13721 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13722 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13723 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13724 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13725 ordered, sticky, false, userId); 13726 if (DEBUG_BROADCAST) Slog.v( 13727 TAG, "Enqueueing parallel broadcast " + r); 13728 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13729 if (!replaced) { 13730 queue.enqueueParallelBroadcastLocked(r); 13731 queue.scheduleBroadcastsLocked(); 13732 } 13733 registeredReceivers = null; 13734 NR = 0; 13735 } 13736 13737 // Merge into one list. 13738 int ir = 0; 13739 if (receivers != null) { 13740 // A special case for PACKAGE_ADDED: do not allow the package 13741 // being added to see this broadcast. This prevents them from 13742 // using this as a back door to get run as soon as they are 13743 // installed. Maybe in the future we want to have a special install 13744 // broadcast or such for apps, but we'd like to deliberately make 13745 // this decision. 13746 String skipPackages[] = null; 13747 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13748 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13749 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13750 Uri data = intent.getData(); 13751 if (data != null) { 13752 String pkgName = data.getSchemeSpecificPart(); 13753 if (pkgName != null) { 13754 skipPackages = new String[] { pkgName }; 13755 } 13756 } 13757 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13758 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13759 } 13760 if (skipPackages != null && (skipPackages.length > 0)) { 13761 for (String skipPackage : skipPackages) { 13762 if (skipPackage != null) { 13763 int NT = receivers.size(); 13764 for (int it=0; it<NT; it++) { 13765 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13766 if (curt.activityInfo.packageName.equals(skipPackage)) { 13767 receivers.remove(it); 13768 it--; 13769 NT--; 13770 } 13771 } 13772 } 13773 } 13774 } 13775 13776 int NT = receivers != null ? receivers.size() : 0; 13777 int it = 0; 13778 ResolveInfo curt = null; 13779 BroadcastFilter curr = null; 13780 while (it < NT && ir < NR) { 13781 if (curt == null) { 13782 curt = (ResolveInfo)receivers.get(it); 13783 } 13784 if (curr == null) { 13785 curr = registeredReceivers.get(ir); 13786 } 13787 if (curr.getPriority() >= curt.priority) { 13788 // Insert this broadcast record into the final list. 13789 receivers.add(it, curr); 13790 ir++; 13791 curr = null; 13792 it++; 13793 NT++; 13794 } else { 13795 // Skip to the next ResolveInfo in the final list. 13796 it++; 13797 curt = null; 13798 } 13799 } 13800 } 13801 while (ir < NR) { 13802 if (receivers == null) { 13803 receivers = new ArrayList(); 13804 } 13805 receivers.add(registeredReceivers.get(ir)); 13806 ir++; 13807 } 13808 13809 if ((receivers != null && receivers.size() > 0) 13810 || resultTo != null) { 13811 BroadcastQueue queue = broadcastQueueForIntent(intent); 13812 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13813 callerPackage, callingPid, callingUid, resolvedType, 13814 requiredPermission, appOp, receivers, resultTo, resultCode, 13815 resultData, map, ordered, sticky, false, userId); 13816 if (DEBUG_BROADCAST) Slog.v( 13817 TAG, "Enqueueing ordered broadcast " + r 13818 + ": prev had " + queue.mOrderedBroadcasts.size()); 13819 if (DEBUG_BROADCAST) { 13820 int seq = r.intent.getIntExtra("seq", -1); 13821 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13822 } 13823 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13824 if (!replaced) { 13825 queue.enqueueOrderedBroadcastLocked(r); 13826 queue.scheduleBroadcastsLocked(); 13827 } 13828 } 13829 13830 return ActivityManager.BROADCAST_SUCCESS; 13831 } 13832 13833 final Intent verifyBroadcastLocked(Intent intent) { 13834 // Refuse possible leaked file descriptors 13835 if (intent != null && intent.hasFileDescriptors() == true) { 13836 throw new IllegalArgumentException("File descriptors passed in Intent"); 13837 } 13838 13839 int flags = intent.getFlags(); 13840 13841 if (!mProcessesReady) { 13842 // if the caller really truly claims to know what they're doing, go 13843 // ahead and allow the broadcast without launching any receivers 13844 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13845 intent = new Intent(intent); 13846 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13847 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13848 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13849 + " before boot completion"); 13850 throw new IllegalStateException("Cannot broadcast before boot completed"); 13851 } 13852 } 13853 13854 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13855 throw new IllegalArgumentException( 13856 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13857 } 13858 13859 return intent; 13860 } 13861 13862 public final int broadcastIntent(IApplicationThread caller, 13863 Intent intent, String resolvedType, IIntentReceiver resultTo, 13864 int resultCode, String resultData, Bundle map, 13865 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13866 enforceNotIsolatedCaller("broadcastIntent"); 13867 synchronized(this) { 13868 intent = verifyBroadcastLocked(intent); 13869 13870 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13871 final int callingPid = Binder.getCallingPid(); 13872 final int callingUid = Binder.getCallingUid(); 13873 final long origId = Binder.clearCallingIdentity(); 13874 int res = broadcastIntentLocked(callerApp, 13875 callerApp != null ? callerApp.info.packageName : null, 13876 intent, resolvedType, resultTo, 13877 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13878 callingPid, callingUid, userId); 13879 Binder.restoreCallingIdentity(origId); 13880 return res; 13881 } 13882 } 13883 13884 int broadcastIntentInPackage(String packageName, int uid, 13885 Intent intent, String resolvedType, IIntentReceiver resultTo, 13886 int resultCode, String resultData, Bundle map, 13887 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13888 synchronized(this) { 13889 intent = verifyBroadcastLocked(intent); 13890 13891 final long origId = Binder.clearCallingIdentity(); 13892 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13893 resultTo, resultCode, resultData, map, requiredPermission, 13894 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13895 Binder.restoreCallingIdentity(origId); 13896 return res; 13897 } 13898 } 13899 13900 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13901 // Refuse possible leaked file descriptors 13902 if (intent != null && intent.hasFileDescriptors() == true) { 13903 throw new IllegalArgumentException("File descriptors passed in Intent"); 13904 } 13905 13906 userId = handleIncomingUser(Binder.getCallingPid(), 13907 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13908 13909 synchronized(this) { 13910 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13911 != PackageManager.PERMISSION_GRANTED) { 13912 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13913 + Binder.getCallingPid() 13914 + ", uid=" + Binder.getCallingUid() 13915 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13916 Slog.w(TAG, msg); 13917 throw new SecurityException(msg); 13918 } 13919 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13920 if (stickies != null) { 13921 ArrayList<Intent> list = stickies.get(intent.getAction()); 13922 if (list != null) { 13923 int N = list.size(); 13924 int i; 13925 for (i=0; i<N; i++) { 13926 if (intent.filterEquals(list.get(i))) { 13927 list.remove(i); 13928 break; 13929 } 13930 } 13931 if (list.size() <= 0) { 13932 stickies.remove(intent.getAction()); 13933 } 13934 } 13935 if (stickies.size() <= 0) { 13936 mStickyBroadcasts.remove(userId); 13937 } 13938 } 13939 } 13940 } 13941 13942 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13943 String resultData, Bundle resultExtras, boolean resultAbort) { 13944 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13945 if (r == null) { 13946 Slog.w(TAG, "finishReceiver called but not found on queue"); 13947 return false; 13948 } 13949 13950 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13951 } 13952 13953 void backgroundServicesFinishedLocked(int userId) { 13954 for (BroadcastQueue queue : mBroadcastQueues) { 13955 queue.backgroundServicesFinishedLocked(userId); 13956 } 13957 } 13958 13959 public void finishReceiver(IBinder who, int resultCode, String resultData, 13960 Bundle resultExtras, boolean resultAbort) { 13961 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13962 13963 // Refuse possible leaked file descriptors 13964 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13965 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13966 } 13967 13968 final long origId = Binder.clearCallingIdentity(); 13969 try { 13970 boolean doNext = false; 13971 BroadcastRecord r; 13972 13973 synchronized(this) { 13974 r = broadcastRecordForReceiverLocked(who); 13975 if (r != null) { 13976 doNext = r.queue.finishReceiverLocked(r, resultCode, 13977 resultData, resultExtras, resultAbort, true); 13978 } 13979 } 13980 13981 if (doNext) { 13982 r.queue.processNextBroadcast(false); 13983 } 13984 trimApplications(); 13985 } finally { 13986 Binder.restoreCallingIdentity(origId); 13987 } 13988 } 13989 13990 // ========================================================= 13991 // INSTRUMENTATION 13992 // ========================================================= 13993 13994 public boolean startInstrumentation(ComponentName className, 13995 String profileFile, int flags, Bundle arguments, 13996 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13997 int userId) { 13998 enforceNotIsolatedCaller("startInstrumentation"); 13999 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14000 userId, false, true, "startInstrumentation", null); 14001 // Refuse possible leaked file descriptors 14002 if (arguments != null && arguments.hasFileDescriptors()) { 14003 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14004 } 14005 14006 synchronized(this) { 14007 InstrumentationInfo ii = null; 14008 ApplicationInfo ai = null; 14009 try { 14010 ii = mContext.getPackageManager().getInstrumentationInfo( 14011 className, STOCK_PM_FLAGS); 14012 ai = AppGlobals.getPackageManager().getApplicationInfo( 14013 ii.targetPackage, STOCK_PM_FLAGS, userId); 14014 } catch (PackageManager.NameNotFoundException e) { 14015 } catch (RemoteException e) { 14016 } 14017 if (ii == null) { 14018 reportStartInstrumentationFailure(watcher, className, 14019 "Unable to find instrumentation info for: " + className); 14020 return false; 14021 } 14022 if (ai == null) { 14023 reportStartInstrumentationFailure(watcher, className, 14024 "Unable to find instrumentation target package: " + ii.targetPackage); 14025 return false; 14026 } 14027 14028 int match = mContext.getPackageManager().checkSignatures( 14029 ii.targetPackage, ii.packageName); 14030 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14031 String msg = "Permission Denial: starting instrumentation " 14032 + className + " from pid=" 14033 + Binder.getCallingPid() 14034 + ", uid=" + Binder.getCallingPid() 14035 + " not allowed because package " + ii.packageName 14036 + " does not have a signature matching the target " 14037 + ii.targetPackage; 14038 reportStartInstrumentationFailure(watcher, className, msg); 14039 throw new SecurityException(msg); 14040 } 14041 14042 final long origId = Binder.clearCallingIdentity(); 14043 // Instrumentation can kill and relaunch even persistent processes 14044 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14045 "start instr"); 14046 ProcessRecord app = addAppLocked(ai, false); 14047 app.instrumentationClass = className; 14048 app.instrumentationInfo = ai; 14049 app.instrumentationProfileFile = profileFile; 14050 app.instrumentationArguments = arguments; 14051 app.instrumentationWatcher = watcher; 14052 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14053 app.instrumentationResultClass = className; 14054 Binder.restoreCallingIdentity(origId); 14055 } 14056 14057 return true; 14058 } 14059 14060 /** 14061 * Report errors that occur while attempting to start Instrumentation. Always writes the 14062 * error to the logs, but if somebody is watching, send the report there too. This enables 14063 * the "am" command to report errors with more information. 14064 * 14065 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14066 * @param cn The component name of the instrumentation. 14067 * @param report The error report. 14068 */ 14069 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14070 ComponentName cn, String report) { 14071 Slog.w(TAG, report); 14072 try { 14073 if (watcher != null) { 14074 Bundle results = new Bundle(); 14075 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14076 results.putString("Error", report); 14077 watcher.instrumentationStatus(cn, -1, results); 14078 } 14079 } catch (RemoteException e) { 14080 Slog.w(TAG, e); 14081 } 14082 } 14083 14084 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14085 if (app.instrumentationWatcher != null) { 14086 try { 14087 // NOTE: IInstrumentationWatcher *must* be oneway here 14088 app.instrumentationWatcher.instrumentationFinished( 14089 app.instrumentationClass, 14090 resultCode, 14091 results); 14092 } catch (RemoteException e) { 14093 } 14094 } 14095 if (app.instrumentationUiAutomationConnection != null) { 14096 try { 14097 app.instrumentationUiAutomationConnection.shutdown(); 14098 } catch (RemoteException re) { 14099 /* ignore */ 14100 } 14101 // Only a UiAutomation can set this flag and now that 14102 // it is finished we make sure it is reset to its default. 14103 mUserIsMonkey = false; 14104 } 14105 app.instrumentationWatcher = null; 14106 app.instrumentationUiAutomationConnection = null; 14107 app.instrumentationClass = null; 14108 app.instrumentationInfo = null; 14109 app.instrumentationProfileFile = null; 14110 app.instrumentationArguments = null; 14111 14112 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14113 "finished inst"); 14114 } 14115 14116 public void finishInstrumentation(IApplicationThread target, 14117 int resultCode, Bundle results) { 14118 int userId = UserHandle.getCallingUserId(); 14119 // Refuse possible leaked file descriptors 14120 if (results != null && results.hasFileDescriptors()) { 14121 throw new IllegalArgumentException("File descriptors passed in Intent"); 14122 } 14123 14124 synchronized(this) { 14125 ProcessRecord app = getRecordForAppLocked(target); 14126 if (app == null) { 14127 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14128 return; 14129 } 14130 final long origId = Binder.clearCallingIdentity(); 14131 finishInstrumentationLocked(app, resultCode, results); 14132 Binder.restoreCallingIdentity(origId); 14133 } 14134 } 14135 14136 // ========================================================= 14137 // CONFIGURATION 14138 // ========================================================= 14139 14140 public ConfigurationInfo getDeviceConfigurationInfo() { 14141 ConfigurationInfo config = new ConfigurationInfo(); 14142 synchronized (this) { 14143 config.reqTouchScreen = mConfiguration.touchscreen; 14144 config.reqKeyboardType = mConfiguration.keyboard; 14145 config.reqNavigation = mConfiguration.navigation; 14146 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14147 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14148 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14149 } 14150 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14151 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14152 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14153 } 14154 config.reqGlEsVersion = GL_ES_VERSION; 14155 } 14156 return config; 14157 } 14158 14159 ActivityStack getFocusedStack() { 14160 return mStackSupervisor.getFocusedStack(); 14161 } 14162 14163 public Configuration getConfiguration() { 14164 Configuration ci; 14165 synchronized(this) { 14166 ci = new Configuration(mConfiguration); 14167 } 14168 return ci; 14169 } 14170 14171 public void updatePersistentConfiguration(Configuration values) { 14172 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14173 "updateConfiguration()"); 14174 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14175 "updateConfiguration()"); 14176 if (values == null) { 14177 throw new NullPointerException("Configuration must not be null"); 14178 } 14179 14180 synchronized(this) { 14181 final long origId = Binder.clearCallingIdentity(); 14182 updateConfigurationLocked(values, null, true, false); 14183 Binder.restoreCallingIdentity(origId); 14184 } 14185 } 14186 14187 public void updateConfiguration(Configuration values) { 14188 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14189 "updateConfiguration()"); 14190 14191 synchronized(this) { 14192 if (values == null && mWindowManager != null) { 14193 // sentinel: fetch the current configuration from the window manager 14194 values = mWindowManager.computeNewConfiguration(); 14195 } 14196 14197 if (mWindowManager != null) { 14198 mProcessList.applyDisplaySize(mWindowManager); 14199 } 14200 14201 final long origId = Binder.clearCallingIdentity(); 14202 if (values != null) { 14203 Settings.System.clearConfiguration(values); 14204 } 14205 updateConfigurationLocked(values, null, false, false); 14206 Binder.restoreCallingIdentity(origId); 14207 } 14208 } 14209 14210 /** 14211 * Do either or both things: (1) change the current configuration, and (2) 14212 * make sure the given activity is running with the (now) current 14213 * configuration. Returns true if the activity has been left running, or 14214 * false if <var>starting</var> is being destroyed to match the new 14215 * configuration. 14216 * @param persistent TODO 14217 */ 14218 boolean updateConfigurationLocked(Configuration values, 14219 ActivityRecord starting, boolean persistent, boolean initLocale) { 14220 int changes = 0; 14221 14222 if (values != null) { 14223 Configuration newConfig = new Configuration(mConfiguration); 14224 changes = newConfig.updateFrom(values); 14225 if (changes != 0) { 14226 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14227 Slog.i(TAG, "Updating configuration to: " + values); 14228 } 14229 14230 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14231 14232 if (values.locale != null && !initLocale) { 14233 saveLocaleLocked(values.locale, 14234 !values.locale.equals(mConfiguration.locale), 14235 values.userSetLocale); 14236 } 14237 14238 mConfigurationSeq++; 14239 if (mConfigurationSeq <= 0) { 14240 mConfigurationSeq = 1; 14241 } 14242 newConfig.seq = mConfigurationSeq; 14243 mConfiguration = newConfig; 14244 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14245 14246 final Configuration configCopy = new Configuration(mConfiguration); 14247 14248 // TODO: If our config changes, should we auto dismiss any currently 14249 // showing dialogs? 14250 mShowDialogs = shouldShowDialogs(newConfig); 14251 14252 AttributeCache ac = AttributeCache.instance(); 14253 if (ac != null) { 14254 ac.updateConfiguration(configCopy); 14255 } 14256 14257 // Make sure all resources in our process are updated 14258 // right now, so that anyone who is going to retrieve 14259 // resource values after we return will be sure to get 14260 // the new ones. This is especially important during 14261 // boot, where the first config change needs to guarantee 14262 // all resources have that config before following boot 14263 // code is executed. 14264 mSystemThread.applyConfigurationToResources(configCopy); 14265 14266 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14267 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14268 msg.obj = new Configuration(configCopy); 14269 mHandler.sendMessage(msg); 14270 } 14271 14272 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14273 ProcessRecord app = mLruProcesses.get(i); 14274 try { 14275 if (app.thread != null) { 14276 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14277 + app.processName + " new config " + mConfiguration); 14278 app.thread.scheduleConfigurationChanged(configCopy); 14279 } 14280 } catch (Exception e) { 14281 } 14282 } 14283 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14284 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14285 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14286 | Intent.FLAG_RECEIVER_FOREGROUND); 14287 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14288 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14289 Process.SYSTEM_UID, UserHandle.USER_ALL); 14290 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14291 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14292 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14293 broadcastIntentLocked(null, null, intent, 14294 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14295 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14296 } 14297 } 14298 } 14299 14300 boolean kept = true; 14301 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14302 // mainStack is null during startup. 14303 if (mainStack != null) { 14304 if (changes != 0 && starting == null) { 14305 // If the configuration changed, and the caller is not already 14306 // in the process of starting an activity, then find the top 14307 // activity to check if its configuration needs to change. 14308 starting = mainStack.topRunningActivityLocked(null); 14309 } 14310 14311 if (starting != null) { 14312 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14313 // And we need to make sure at this point that all other activities 14314 // are made visible with the correct configuration. 14315 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14316 } 14317 } 14318 14319 if (values != null && mWindowManager != null) { 14320 mWindowManager.setNewConfiguration(mConfiguration); 14321 } 14322 14323 return kept; 14324 } 14325 14326 /** 14327 * Decide based on the configuration whether we should shouw the ANR, 14328 * crash, etc dialogs. The idea is that if there is no affordnace to 14329 * press the on-screen buttons, we shouldn't show the dialog. 14330 * 14331 * A thought: SystemUI might also want to get told about this, the Power 14332 * dialog / global actions also might want different behaviors. 14333 */ 14334 private static final boolean shouldShowDialogs(Configuration config) { 14335 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14336 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14337 } 14338 14339 /** 14340 * Save the locale. You must be inside a synchronized (this) block. 14341 */ 14342 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14343 if(isDiff) { 14344 SystemProperties.set("user.language", l.getLanguage()); 14345 SystemProperties.set("user.region", l.getCountry()); 14346 } 14347 14348 if(isPersist) { 14349 SystemProperties.set("persist.sys.language", l.getLanguage()); 14350 SystemProperties.set("persist.sys.country", l.getCountry()); 14351 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14352 } 14353 } 14354 14355 @Override 14356 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14357 ActivityRecord srec = ActivityRecord.forToken(token); 14358 return srec != null && srec.task.affinity != null && 14359 srec.task.affinity.equals(destAffinity); 14360 } 14361 14362 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14363 Intent resultData) { 14364 14365 synchronized (this) { 14366 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14367 if (stack != null) { 14368 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14369 } 14370 return false; 14371 } 14372 } 14373 14374 public int getLaunchedFromUid(IBinder activityToken) { 14375 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14376 if (srec == null) { 14377 return -1; 14378 } 14379 return srec.launchedFromUid; 14380 } 14381 14382 public String getLaunchedFromPackage(IBinder activityToken) { 14383 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14384 if (srec == null) { 14385 return null; 14386 } 14387 return srec.launchedFromPackage; 14388 } 14389 14390 // ========================================================= 14391 // LIFETIME MANAGEMENT 14392 // ========================================================= 14393 14394 // Returns which broadcast queue the app is the current [or imminent] receiver 14395 // on, or 'null' if the app is not an active broadcast recipient. 14396 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14397 BroadcastRecord r = app.curReceiver; 14398 if (r != null) { 14399 return r.queue; 14400 } 14401 14402 // It's not the current receiver, but it might be starting up to become one 14403 synchronized (this) { 14404 for (BroadcastQueue queue : mBroadcastQueues) { 14405 r = queue.mPendingBroadcast; 14406 if (r != null && r.curApp == app) { 14407 // found it; report which queue it's in 14408 return queue; 14409 } 14410 } 14411 } 14412 14413 return null; 14414 } 14415 14416 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14417 boolean doingAll, long now) { 14418 if (mAdjSeq == app.adjSeq) { 14419 // This adjustment has already been computed. 14420 return app.curRawAdj; 14421 } 14422 14423 if (app.thread == null) { 14424 app.adjSeq = mAdjSeq; 14425 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14426 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14427 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14428 } 14429 14430 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14431 app.adjSource = null; 14432 app.adjTarget = null; 14433 app.empty = false; 14434 app.cached = false; 14435 14436 final int activitiesSize = app.activities.size(); 14437 14438 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14439 // The max adjustment doesn't allow this app to be anything 14440 // below foreground, so it is not worth doing work for it. 14441 app.adjType = "fixed"; 14442 app.adjSeq = mAdjSeq; 14443 app.curRawAdj = app.maxAdj; 14444 app.foregroundActivities = false; 14445 app.keeping = true; 14446 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14447 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14448 // System process can do UI, and when they do we want to have 14449 // them trim their memory after the user leaves the UI. To 14450 // facilitate this, here we need to determine whether or not it 14451 // is currently showing UI. 14452 app.systemNoUi = true; 14453 if (app == TOP_APP) { 14454 app.systemNoUi = false; 14455 } else if (activitiesSize > 0) { 14456 for (int j = 0; j < activitiesSize; j++) { 14457 final ActivityRecord r = app.activities.get(j); 14458 if (r.visible) { 14459 app.systemNoUi = false; 14460 } 14461 } 14462 } 14463 if (!app.systemNoUi) { 14464 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14465 } 14466 return (app.curAdj=app.maxAdj); 14467 } 14468 14469 app.keeping = false; 14470 app.systemNoUi = false; 14471 14472 // Determine the importance of the process, starting with most 14473 // important to least, and assign an appropriate OOM adjustment. 14474 int adj; 14475 int schedGroup; 14476 int procState; 14477 boolean foregroundActivities = false; 14478 boolean interesting = false; 14479 BroadcastQueue queue; 14480 if (app == TOP_APP) { 14481 // The last app on the list is the foreground app. 14482 adj = ProcessList.FOREGROUND_APP_ADJ; 14483 schedGroup = Process.THREAD_GROUP_DEFAULT; 14484 app.adjType = "top-activity"; 14485 foregroundActivities = true; 14486 interesting = true; 14487 procState = ActivityManager.PROCESS_STATE_TOP; 14488 } else if (app.instrumentationClass != null) { 14489 // Don't want to kill running instrumentation. 14490 adj = ProcessList.FOREGROUND_APP_ADJ; 14491 schedGroup = Process.THREAD_GROUP_DEFAULT; 14492 app.adjType = "instrumentation"; 14493 interesting = true; 14494 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14495 } else if ((queue = isReceivingBroadcast(app)) != null) { 14496 // An app that is currently receiving a broadcast also 14497 // counts as being in the foreground for OOM killer purposes. 14498 // It's placed in a sched group based on the nature of the 14499 // broadcast as reflected by which queue it's active in. 14500 adj = ProcessList.FOREGROUND_APP_ADJ; 14501 schedGroup = (queue == mFgBroadcastQueue) 14502 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14503 app.adjType = "broadcast"; 14504 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14505 } else if (app.executingServices.size() > 0) { 14506 // An app that is currently executing a service callback also 14507 // counts as being in the foreground. 14508 adj = ProcessList.FOREGROUND_APP_ADJ; 14509 schedGroup = app.execServicesFg ? 14510 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14511 app.adjType = "exec-service"; 14512 procState = ActivityManager.PROCESS_STATE_SERVICE; 14513 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14514 } else { 14515 // As far as we know the process is empty. We may change our mind later. 14516 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14517 // At this point we don't actually know the adjustment. Use the cached adj 14518 // value that the caller wants us to. 14519 adj = cachedAdj; 14520 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14521 app.cached = true; 14522 app.empty = true; 14523 app.adjType = "cch-empty"; 14524 } 14525 14526 // Examine all activities if not already foreground. 14527 if (!foregroundActivities && activitiesSize > 0) { 14528 for (int j = 0; j < activitiesSize; j++) { 14529 final ActivityRecord r = app.activities.get(j); 14530 if (r.app != app) { 14531 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14532 + app + "?!?"); 14533 continue; 14534 } 14535 if (r.visible) { 14536 // App has a visible activity; only upgrade adjustment. 14537 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14538 adj = ProcessList.VISIBLE_APP_ADJ; 14539 app.adjType = "visible"; 14540 } 14541 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14542 procState = ActivityManager.PROCESS_STATE_TOP; 14543 } 14544 schedGroup = Process.THREAD_GROUP_DEFAULT; 14545 app.cached = false; 14546 app.empty = false; 14547 foregroundActivities = true; 14548 break; 14549 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14550 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14551 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14552 app.adjType = "pausing"; 14553 } 14554 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14555 procState = ActivityManager.PROCESS_STATE_TOP; 14556 } 14557 schedGroup = Process.THREAD_GROUP_DEFAULT; 14558 app.cached = false; 14559 app.empty = false; 14560 foregroundActivities = true; 14561 } else if (r.state == ActivityState.STOPPING) { 14562 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14563 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14564 app.adjType = "stopping"; 14565 } 14566 // For the process state, we will at this point consider the 14567 // process to be cached. It will be cached either as an activity 14568 // or empty depending on whether the activity is finishing. We do 14569 // this so that we can treat the process as cached for purposes of 14570 // memory trimming (determing current memory level, trim command to 14571 // send to process) since there can be an arbitrary number of stopping 14572 // processes and they should soon all go into the cached state. 14573 if (!r.finishing) { 14574 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14575 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14576 } 14577 } 14578 app.cached = false; 14579 app.empty = false; 14580 foregroundActivities = true; 14581 } else { 14582 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14583 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14584 app.adjType = "cch-act"; 14585 } 14586 } 14587 } 14588 } 14589 14590 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14591 if (app.foregroundServices) { 14592 // The user is aware of this app, so make it visible. 14593 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14594 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14595 app.cached = false; 14596 app.adjType = "fg-service"; 14597 schedGroup = Process.THREAD_GROUP_DEFAULT; 14598 } else if (app.forcingToForeground != null) { 14599 // The user is aware of this app, so make it visible. 14600 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14601 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14602 app.cached = false; 14603 app.adjType = "force-fg"; 14604 app.adjSource = app.forcingToForeground; 14605 schedGroup = Process.THREAD_GROUP_DEFAULT; 14606 } 14607 } 14608 14609 if (app.foregroundServices) { 14610 interesting = true; 14611 } 14612 14613 if (app == mHeavyWeightProcess) { 14614 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14615 // We don't want to kill the current heavy-weight process. 14616 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14617 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14618 app.cached = false; 14619 app.adjType = "heavy"; 14620 } 14621 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14622 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14623 } 14624 } 14625 14626 if (app == mHomeProcess) { 14627 if (adj > ProcessList.HOME_APP_ADJ) { 14628 // This process is hosting what we currently consider to be the 14629 // home app, so we don't want to let it go into the background. 14630 adj = ProcessList.HOME_APP_ADJ; 14631 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14632 app.cached = false; 14633 app.adjType = "home"; 14634 } 14635 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14636 procState = ActivityManager.PROCESS_STATE_HOME; 14637 } 14638 } 14639 14640 if (app == mPreviousProcess && app.activities.size() > 0) { 14641 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14642 // This was the previous process that showed UI to the user. 14643 // We want to try to keep it around more aggressively, to give 14644 // a good experience around switching between two apps. 14645 adj = ProcessList.PREVIOUS_APP_ADJ; 14646 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14647 app.cached = false; 14648 app.adjType = "previous"; 14649 } 14650 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14651 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14652 } 14653 } 14654 14655 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14656 + " reason=" + app.adjType); 14657 14658 // By default, we use the computed adjustment. It may be changed if 14659 // there are applications dependent on our services or providers, but 14660 // this gives us a baseline and makes sure we don't get into an 14661 // infinite recursion. 14662 app.adjSeq = mAdjSeq; 14663 app.curRawAdj = adj; 14664 app.hasStartedServices = false; 14665 14666 if (mBackupTarget != null && app == mBackupTarget.app) { 14667 // If possible we want to avoid killing apps while they're being backed up 14668 if (adj > ProcessList.BACKUP_APP_ADJ) { 14669 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14670 adj = ProcessList.BACKUP_APP_ADJ; 14671 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14672 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14673 } 14674 app.adjType = "backup"; 14675 app.cached = false; 14676 } 14677 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14678 procState = ActivityManager.PROCESS_STATE_BACKUP; 14679 } 14680 } 14681 14682 boolean mayBeTop = false; 14683 14684 for (int is = app.services.size()-1; 14685 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14686 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14687 || procState > ActivityManager.PROCESS_STATE_TOP); 14688 is--) { 14689 ServiceRecord s = app.services.valueAt(is); 14690 if (s.startRequested) { 14691 app.hasStartedServices = true; 14692 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14693 procState = ActivityManager.PROCESS_STATE_SERVICE; 14694 } 14695 if (app.hasShownUi && app != mHomeProcess) { 14696 // If this process has shown some UI, let it immediately 14697 // go to the LRU list because it may be pretty heavy with 14698 // UI stuff. We'll tag it with a label just to help 14699 // debug and understand what is going on. 14700 if (adj > ProcessList.SERVICE_ADJ) { 14701 app.adjType = "cch-started-ui-services"; 14702 } 14703 } else { 14704 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14705 // This service has seen some activity within 14706 // recent memory, so we will keep its process ahead 14707 // of the background processes. 14708 if (adj > ProcessList.SERVICE_ADJ) { 14709 adj = ProcessList.SERVICE_ADJ; 14710 app.adjType = "started-services"; 14711 app.cached = false; 14712 } 14713 } 14714 // If we have let the service slide into the background 14715 // state, still have some text describing what it is doing 14716 // even though the service no longer has an impact. 14717 if (adj > ProcessList.SERVICE_ADJ) { 14718 app.adjType = "cch-started-services"; 14719 } 14720 } 14721 // Don't kill this process because it is doing work; it 14722 // has said it is doing work. 14723 app.keeping = true; 14724 } 14725 for (int conni = s.connections.size()-1; 14726 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14727 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14728 || procState > ActivityManager.PROCESS_STATE_TOP); 14729 conni--) { 14730 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14731 for (int i = 0; 14732 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14733 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14734 || procState > ActivityManager.PROCESS_STATE_TOP); 14735 i++) { 14736 // XXX should compute this based on the max of 14737 // all connected clients. 14738 ConnectionRecord cr = clist.get(i); 14739 if (cr.binding.client == app) { 14740 // Binding to ourself is not interesting. 14741 continue; 14742 } 14743 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14744 ProcessRecord client = cr.binding.client; 14745 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14746 TOP_APP, doingAll, now); 14747 int clientProcState = client.curProcState; 14748 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14749 // If the other app is cached for any reason, for purposes here 14750 // we are going to consider it empty. The specific cached state 14751 // doesn't propagate except under certain conditions. 14752 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14753 } 14754 String adjType = null; 14755 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14756 // Not doing bind OOM management, so treat 14757 // this guy more like a started service. 14758 if (app.hasShownUi && app != mHomeProcess) { 14759 // If this process has shown some UI, let it immediately 14760 // go to the LRU list because it may be pretty heavy with 14761 // UI stuff. We'll tag it with a label just to help 14762 // debug and understand what is going on. 14763 if (adj > clientAdj) { 14764 adjType = "cch-bound-ui-services"; 14765 } 14766 app.cached = false; 14767 clientAdj = adj; 14768 clientProcState = procState; 14769 } else { 14770 if (now >= (s.lastActivity 14771 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14772 // This service has not seen activity within 14773 // recent memory, so allow it to drop to the 14774 // LRU list if there is no other reason to keep 14775 // it around. We'll also tag it with a label just 14776 // to help debug and undertand what is going on. 14777 if (adj > clientAdj) { 14778 adjType = "cch-bound-services"; 14779 } 14780 clientAdj = adj; 14781 } 14782 } 14783 } 14784 if (adj > clientAdj) { 14785 // If this process has recently shown UI, and 14786 // the process that is binding to it is less 14787 // important than being visible, then we don't 14788 // care about the binding as much as we care 14789 // about letting this process get into the LRU 14790 // list to be killed and restarted if needed for 14791 // memory. 14792 if (app.hasShownUi && app != mHomeProcess 14793 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14794 adjType = "cch-bound-ui-services"; 14795 } else { 14796 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14797 |Context.BIND_IMPORTANT)) != 0) { 14798 adj = clientAdj; 14799 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14800 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14801 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14802 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14803 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14804 adj = clientAdj; 14805 } else { 14806 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14807 adj = ProcessList.VISIBLE_APP_ADJ; 14808 } 14809 } 14810 if (!client.cached) { 14811 app.cached = false; 14812 } 14813 if (client.keeping) { 14814 app.keeping = true; 14815 } 14816 adjType = "service"; 14817 } 14818 } 14819 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14820 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14821 schedGroup = Process.THREAD_GROUP_DEFAULT; 14822 } 14823 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14824 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14825 // Special handling of clients who are in the top state. 14826 // We *may* want to consider this process to be in the 14827 // top state as well, but only if there is not another 14828 // reason for it to be running. Being on the top is a 14829 // special state, meaning you are specifically running 14830 // for the current top app. If the process is already 14831 // running in the background for some other reason, it 14832 // is more important to continue considering it to be 14833 // in the background state. 14834 mayBeTop = true; 14835 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14836 } else { 14837 // Special handling for above-top states (persistent 14838 // processes). These should not bring the current process 14839 // into the top state, since they are not on top. Instead 14840 // give them the best state after that. 14841 clientProcState = 14842 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14843 } 14844 } 14845 } else { 14846 if (clientProcState < 14847 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14848 clientProcState = 14849 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14850 } 14851 } 14852 if (procState > clientProcState) { 14853 procState = clientProcState; 14854 } 14855 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14856 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14857 app.pendingUiClean = true; 14858 } 14859 if (adjType != null) { 14860 app.adjType = adjType; 14861 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14862 .REASON_SERVICE_IN_USE; 14863 app.adjSource = cr.binding.client; 14864 app.adjSourceOom = clientAdj; 14865 app.adjTarget = s.name; 14866 } 14867 } 14868 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14869 app.treatLikeActivity = true; 14870 } 14871 final ActivityRecord a = cr.activity; 14872 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14873 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14874 (a.visible || a.state == ActivityState.RESUMED 14875 || a.state == ActivityState.PAUSING)) { 14876 adj = ProcessList.FOREGROUND_APP_ADJ; 14877 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14878 schedGroup = Process.THREAD_GROUP_DEFAULT; 14879 } 14880 app.cached = false; 14881 app.adjType = "service"; 14882 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14883 .REASON_SERVICE_IN_USE; 14884 app.adjSource = a; 14885 app.adjSourceOom = adj; 14886 app.adjTarget = s.name; 14887 } 14888 } 14889 } 14890 } 14891 } 14892 14893 for (int provi = app.pubProviders.size()-1; 14894 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14895 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14896 || procState > ActivityManager.PROCESS_STATE_TOP); 14897 provi--) { 14898 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14899 for (int i = cpr.connections.size()-1; 14900 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14901 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14902 || procState > ActivityManager.PROCESS_STATE_TOP); 14903 i--) { 14904 ContentProviderConnection conn = cpr.connections.get(i); 14905 ProcessRecord client = conn.client; 14906 if (client == app) { 14907 // Being our own client is not interesting. 14908 continue; 14909 } 14910 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14911 int clientProcState = client.curProcState; 14912 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14913 // If the other app is cached for any reason, for purposes here 14914 // we are going to consider it empty. 14915 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14916 } 14917 if (adj > clientAdj) { 14918 if (app.hasShownUi && app != mHomeProcess 14919 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14920 app.adjType = "cch-ui-provider"; 14921 } else { 14922 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14923 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14924 app.adjType = "provider"; 14925 } 14926 app.cached &= client.cached; 14927 app.keeping |= client.keeping; 14928 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14929 .REASON_PROVIDER_IN_USE; 14930 app.adjSource = client; 14931 app.adjSourceOom = clientAdj; 14932 app.adjTarget = cpr.name; 14933 } 14934 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14935 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14936 // Special handling of clients who are in the top state. 14937 // We *may* want to consider this process to be in the 14938 // top state as well, but only if there is not another 14939 // reason for it to be running. Being on the top is a 14940 // special state, meaning you are specifically running 14941 // for the current top app. If the process is already 14942 // running in the background for some other reason, it 14943 // is more important to continue considering it to be 14944 // in the background state. 14945 mayBeTop = true; 14946 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14947 } else { 14948 // Special handling for above-top states (persistent 14949 // processes). These should not bring the current process 14950 // into the top state, since they are not on top. Instead 14951 // give them the best state after that. 14952 clientProcState = 14953 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14954 } 14955 } 14956 if (procState > clientProcState) { 14957 procState = clientProcState; 14958 } 14959 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14960 schedGroup = Process.THREAD_GROUP_DEFAULT; 14961 } 14962 } 14963 // If the provider has external (non-framework) process 14964 // dependencies, ensure that its adjustment is at least 14965 // FOREGROUND_APP_ADJ. 14966 if (cpr.hasExternalProcessHandles()) { 14967 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14968 adj = ProcessList.FOREGROUND_APP_ADJ; 14969 schedGroup = Process.THREAD_GROUP_DEFAULT; 14970 app.cached = false; 14971 app.keeping = true; 14972 app.adjType = "provider"; 14973 app.adjTarget = cpr.name; 14974 } 14975 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14976 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14977 } 14978 } 14979 } 14980 14981 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14982 // A client of one of our services or providers is in the top state. We 14983 // *may* want to be in the top state, but not if we are already running in 14984 // the background for some other reason. For the decision here, we are going 14985 // to pick out a few specific states that we want to remain in when a client 14986 // is top (states that tend to be longer-term) and otherwise allow it to go 14987 // to the top state. 14988 switch (procState) { 14989 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14990 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14991 case ActivityManager.PROCESS_STATE_SERVICE: 14992 // These all are longer-term states, so pull them up to the top 14993 // of the background states, but not all the way to the top state. 14994 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14995 break; 14996 default: 14997 // Otherwise, top is a better choice, so take it. 14998 procState = ActivityManager.PROCESS_STATE_TOP; 14999 break; 15000 } 15001 } 15002 15003 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15004 if (app.hasClientActivities) { 15005 // This is a cached process, but with client activities. Mark it so. 15006 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15007 app.adjType = "cch-client-act"; 15008 } else if (app.treatLikeActivity) { 15009 // This is a cached process, but somebody wants us to treat it like it has 15010 // an activity, okay! 15011 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15012 app.adjType = "cch-as-act"; 15013 } 15014 } 15015 15016 if (adj == ProcessList.SERVICE_ADJ) { 15017 if (doingAll) { 15018 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15019 mNewNumServiceProcs++; 15020 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15021 if (!app.serviceb) { 15022 // This service isn't far enough down on the LRU list to 15023 // normally be a B service, but if we are low on RAM and it 15024 // is large we want to force it down since we would prefer to 15025 // keep launcher over it. 15026 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15027 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15028 app.serviceHighRam = true; 15029 app.serviceb = true; 15030 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15031 } else { 15032 mNewNumAServiceProcs++; 15033 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15034 } 15035 } else { 15036 app.serviceHighRam = false; 15037 } 15038 } 15039 if (app.serviceb) { 15040 adj = ProcessList.SERVICE_B_ADJ; 15041 } 15042 } 15043 15044 app.curRawAdj = adj; 15045 15046 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15047 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15048 if (adj > app.maxAdj) { 15049 adj = app.maxAdj; 15050 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15051 schedGroup = Process.THREAD_GROUP_DEFAULT; 15052 } 15053 } 15054 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15055 app.keeping = true; 15056 } 15057 15058 // Do final modification to adj. Everything we do between here and applying 15059 // the final setAdj must be done in this function, because we will also use 15060 // it when computing the final cached adj later. Note that we don't need to 15061 // worry about this for max adj above, since max adj will always be used to 15062 // keep it out of the cached vaues. 15063 adj = app.modifyRawOomAdj(adj); 15064 15065 app.curProcState = procState; 15066 15067 int importance = app.memImportance; 15068 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15069 app.curAdj = adj; 15070 app.curSchedGroup = schedGroup; 15071 if (!interesting) { 15072 // For this reporting, if there is not something explicitly 15073 // interesting in this process then we will push it to the 15074 // background importance. 15075 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15076 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15077 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15078 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15079 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15080 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15081 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15082 } else if (adj >= ProcessList.SERVICE_ADJ) { 15083 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15084 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15085 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15086 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15087 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15088 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15089 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15090 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15091 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15092 } else { 15093 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15094 } 15095 } 15096 15097 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15098 if (foregroundActivities != app.foregroundActivities) { 15099 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15100 } 15101 if (changes != 0) { 15102 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15103 app.memImportance = importance; 15104 app.foregroundActivities = foregroundActivities; 15105 int i = mPendingProcessChanges.size()-1; 15106 ProcessChangeItem item = null; 15107 while (i >= 0) { 15108 item = mPendingProcessChanges.get(i); 15109 if (item.pid == app.pid) { 15110 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15111 break; 15112 } 15113 i--; 15114 } 15115 if (i < 0) { 15116 // No existing item in pending changes; need a new one. 15117 final int NA = mAvailProcessChanges.size(); 15118 if (NA > 0) { 15119 item = mAvailProcessChanges.remove(NA-1); 15120 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15121 } else { 15122 item = new ProcessChangeItem(); 15123 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15124 } 15125 item.changes = 0; 15126 item.pid = app.pid; 15127 item.uid = app.info.uid; 15128 if (mPendingProcessChanges.size() == 0) { 15129 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15130 "*** Enqueueing dispatch processes changed!"); 15131 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15132 } 15133 mPendingProcessChanges.add(item); 15134 } 15135 item.changes |= changes; 15136 item.importance = importance; 15137 item.foregroundActivities = foregroundActivities; 15138 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15139 + Integer.toHexString(System.identityHashCode(item)) 15140 + " " + app.toShortString() + ": changes=" + item.changes 15141 + " importance=" + item.importance 15142 + " foreground=" + item.foregroundActivities 15143 + " type=" + app.adjType + " source=" + app.adjSource 15144 + " target=" + app.adjTarget); 15145 } 15146 15147 return app.curRawAdj; 15148 } 15149 15150 /** 15151 * Schedule PSS collection of a process. 15152 */ 15153 void requestPssLocked(ProcessRecord proc, int procState) { 15154 if (mPendingPssProcesses.contains(proc)) { 15155 return; 15156 } 15157 if (mPendingPssProcesses.size() == 0) { 15158 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15159 } 15160 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15161 proc.pssProcState = procState; 15162 mPendingPssProcesses.add(proc); 15163 } 15164 15165 /** 15166 * Schedule PSS collection of all processes. 15167 */ 15168 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15169 if (!always) { 15170 if (now < (mLastFullPssTime + 15171 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15172 return; 15173 } 15174 } 15175 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15176 mLastFullPssTime = now; 15177 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15178 mPendingPssProcesses.clear(); 15179 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15180 ProcessRecord app = mLruProcesses.get(i); 15181 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15182 app.pssProcState = app.setProcState; 15183 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15184 mSleeping, now); 15185 mPendingPssProcesses.add(app); 15186 } 15187 } 15188 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15189 } 15190 15191 /** 15192 * Ask a given process to GC right now. 15193 */ 15194 final void performAppGcLocked(ProcessRecord app) { 15195 try { 15196 app.lastRequestedGc = SystemClock.uptimeMillis(); 15197 if (app.thread != null) { 15198 if (app.reportLowMemory) { 15199 app.reportLowMemory = false; 15200 app.thread.scheduleLowMemory(); 15201 } else { 15202 app.thread.processInBackground(); 15203 } 15204 } 15205 } catch (Exception e) { 15206 // whatever. 15207 } 15208 } 15209 15210 /** 15211 * Returns true if things are idle enough to perform GCs. 15212 */ 15213 private final boolean canGcNowLocked() { 15214 boolean processingBroadcasts = false; 15215 for (BroadcastQueue q : mBroadcastQueues) { 15216 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15217 processingBroadcasts = true; 15218 } 15219 } 15220 return !processingBroadcasts 15221 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15222 } 15223 15224 /** 15225 * Perform GCs on all processes that are waiting for it, but only 15226 * if things are idle. 15227 */ 15228 final void performAppGcsLocked() { 15229 final int N = mProcessesToGc.size(); 15230 if (N <= 0) { 15231 return; 15232 } 15233 if (canGcNowLocked()) { 15234 while (mProcessesToGc.size() > 0) { 15235 ProcessRecord proc = mProcessesToGc.remove(0); 15236 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15237 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15238 <= SystemClock.uptimeMillis()) { 15239 // To avoid spamming the system, we will GC processes one 15240 // at a time, waiting a few seconds between each. 15241 performAppGcLocked(proc); 15242 scheduleAppGcsLocked(); 15243 return; 15244 } else { 15245 // It hasn't been long enough since we last GCed this 15246 // process... put it in the list to wait for its time. 15247 addProcessToGcListLocked(proc); 15248 break; 15249 } 15250 } 15251 } 15252 15253 scheduleAppGcsLocked(); 15254 } 15255 } 15256 15257 /** 15258 * If all looks good, perform GCs on all processes waiting for them. 15259 */ 15260 final void performAppGcsIfAppropriateLocked() { 15261 if (canGcNowLocked()) { 15262 performAppGcsLocked(); 15263 return; 15264 } 15265 // Still not idle, wait some more. 15266 scheduleAppGcsLocked(); 15267 } 15268 15269 /** 15270 * Schedule the execution of all pending app GCs. 15271 */ 15272 final void scheduleAppGcsLocked() { 15273 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15274 15275 if (mProcessesToGc.size() > 0) { 15276 // Schedule a GC for the time to the next process. 15277 ProcessRecord proc = mProcessesToGc.get(0); 15278 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15279 15280 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15281 long now = SystemClock.uptimeMillis(); 15282 if (when < (now+GC_TIMEOUT)) { 15283 when = now + GC_TIMEOUT; 15284 } 15285 mHandler.sendMessageAtTime(msg, when); 15286 } 15287 } 15288 15289 /** 15290 * Add a process to the array of processes waiting to be GCed. Keeps the 15291 * list in sorted order by the last GC time. The process can't already be 15292 * on the list. 15293 */ 15294 final void addProcessToGcListLocked(ProcessRecord proc) { 15295 boolean added = false; 15296 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15297 if (mProcessesToGc.get(i).lastRequestedGc < 15298 proc.lastRequestedGc) { 15299 added = true; 15300 mProcessesToGc.add(i+1, proc); 15301 break; 15302 } 15303 } 15304 if (!added) { 15305 mProcessesToGc.add(0, proc); 15306 } 15307 } 15308 15309 /** 15310 * Set up to ask a process to GC itself. This will either do it 15311 * immediately, or put it on the list of processes to gc the next 15312 * time things are idle. 15313 */ 15314 final void scheduleAppGcLocked(ProcessRecord app) { 15315 long now = SystemClock.uptimeMillis(); 15316 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15317 return; 15318 } 15319 if (!mProcessesToGc.contains(app)) { 15320 addProcessToGcListLocked(app); 15321 scheduleAppGcsLocked(); 15322 } 15323 } 15324 15325 final void checkExcessivePowerUsageLocked(boolean doKills) { 15326 updateCpuStatsNow(); 15327 15328 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15329 boolean doWakeKills = doKills; 15330 boolean doCpuKills = doKills; 15331 if (mLastPowerCheckRealtime == 0) { 15332 doWakeKills = false; 15333 } 15334 if (mLastPowerCheckUptime == 0) { 15335 doCpuKills = false; 15336 } 15337 if (stats.isScreenOn()) { 15338 doWakeKills = false; 15339 } 15340 final long curRealtime = SystemClock.elapsedRealtime(); 15341 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15342 final long curUptime = SystemClock.uptimeMillis(); 15343 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15344 mLastPowerCheckRealtime = curRealtime; 15345 mLastPowerCheckUptime = curUptime; 15346 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15347 doWakeKills = false; 15348 } 15349 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15350 doCpuKills = false; 15351 } 15352 int i = mLruProcesses.size(); 15353 while (i > 0) { 15354 i--; 15355 ProcessRecord app = mLruProcesses.get(i); 15356 if (!app.keeping) { 15357 long wtime; 15358 synchronized (stats) { 15359 wtime = stats.getProcessWakeTime(app.info.uid, 15360 app.pid, curRealtime); 15361 } 15362 long wtimeUsed = wtime - app.lastWakeTime; 15363 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15364 if (DEBUG_POWER) { 15365 StringBuilder sb = new StringBuilder(128); 15366 sb.append("Wake for "); 15367 app.toShortString(sb); 15368 sb.append(": over "); 15369 TimeUtils.formatDuration(realtimeSince, sb); 15370 sb.append(" used "); 15371 TimeUtils.formatDuration(wtimeUsed, sb); 15372 sb.append(" ("); 15373 sb.append((wtimeUsed*100)/realtimeSince); 15374 sb.append("%)"); 15375 Slog.i(TAG, sb.toString()); 15376 sb.setLength(0); 15377 sb.append("CPU for "); 15378 app.toShortString(sb); 15379 sb.append(": over "); 15380 TimeUtils.formatDuration(uptimeSince, sb); 15381 sb.append(" used "); 15382 TimeUtils.formatDuration(cputimeUsed, sb); 15383 sb.append(" ("); 15384 sb.append((cputimeUsed*100)/uptimeSince); 15385 sb.append("%)"); 15386 Slog.i(TAG, sb.toString()); 15387 } 15388 // If a process has held a wake lock for more 15389 // than 50% of the time during this period, 15390 // that sounds bad. Kill! 15391 if (doWakeKills && realtimeSince > 0 15392 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15393 synchronized (stats) { 15394 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15395 realtimeSince, wtimeUsed); 15396 } 15397 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15398 + " during " + realtimeSince); 15399 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15400 } else if (doCpuKills && uptimeSince > 0 15401 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15402 synchronized (stats) { 15403 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15404 uptimeSince, cputimeUsed); 15405 } 15406 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15407 + " during " + uptimeSince); 15408 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15409 } else { 15410 app.lastWakeTime = wtime; 15411 app.lastCpuTime = app.curCpuTime; 15412 } 15413 } 15414 } 15415 } 15416 15417 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15418 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15419 boolean success = true; 15420 15421 if (app.curRawAdj != app.setRawAdj) { 15422 if (wasKeeping && !app.keeping) { 15423 // This app is no longer something we want to keep. Note 15424 // its current wake lock time to later know to kill it if 15425 // it is not behaving well. 15426 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15427 synchronized (stats) { 15428 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15429 app.pid, SystemClock.elapsedRealtime()); 15430 } 15431 app.lastCpuTime = app.curCpuTime; 15432 } 15433 15434 app.setRawAdj = app.curRawAdj; 15435 } 15436 15437 if (app.curAdj != app.setAdj) { 15438 ProcessList.setOomAdj(app.pid, app.curAdj); 15439 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15440 TAG, "Set " + app.pid + " " + app.processName + 15441 " adj " + app.curAdj + ": " + app.adjType); 15442 app.setAdj = app.curAdj; 15443 } 15444 15445 if (app.setSchedGroup != app.curSchedGroup) { 15446 app.setSchedGroup = app.curSchedGroup; 15447 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15448 "Setting process group of " + app.processName 15449 + " to " + app.curSchedGroup); 15450 if (app.waitingToKill != null && 15451 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15452 killUnneededProcessLocked(app, app.waitingToKill); 15453 success = false; 15454 } else { 15455 if (true) { 15456 long oldId = Binder.clearCallingIdentity(); 15457 try { 15458 Process.setProcessGroup(app.pid, app.curSchedGroup); 15459 } catch (Exception e) { 15460 Slog.w(TAG, "Failed setting process group of " + app.pid 15461 + " to " + app.curSchedGroup); 15462 e.printStackTrace(); 15463 } finally { 15464 Binder.restoreCallingIdentity(oldId); 15465 } 15466 } else { 15467 if (app.thread != null) { 15468 try { 15469 app.thread.setSchedulingGroup(app.curSchedGroup); 15470 } catch (RemoteException e) { 15471 } 15472 } 15473 } 15474 Process.setSwappiness(app.pid, 15475 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15476 } 15477 } 15478 if (app.repProcState != app.curProcState) { 15479 app.repProcState = app.curProcState; 15480 if (!reportingProcessState && app.thread != null) { 15481 try { 15482 if (false) { 15483 //RuntimeException h = new RuntimeException("here"); 15484 Slog.i(TAG, "Sending new process state " + app.repProcState 15485 + " to " + app /*, h*/); 15486 } 15487 app.thread.setProcessState(app.repProcState); 15488 } catch (RemoteException e) { 15489 } 15490 } 15491 } 15492 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15493 app.setProcState)) { 15494 app.lastStateTime = now; 15495 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15496 mSleeping, now); 15497 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15498 + ProcessList.makeProcStateString(app.setProcState) + " to " 15499 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15500 + (app.nextPssTime-now) + ": " + app); 15501 } else { 15502 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15503 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15504 requestPssLocked(app, app.setProcState); 15505 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15506 mSleeping, now); 15507 } else if (false && DEBUG_PSS) { 15508 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15509 } 15510 } 15511 if (app.setProcState != app.curProcState) { 15512 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15513 "Proc state change of " + app.processName 15514 + " to " + app.curProcState); 15515 app.setProcState = app.curProcState; 15516 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15517 app.notCachedSinceIdle = false; 15518 } 15519 if (!doingAll) { 15520 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15521 } else { 15522 app.procStateChanged = true; 15523 } 15524 } 15525 return success; 15526 } 15527 15528 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15529 if (proc.thread != null && proc.baseProcessTracker != null) { 15530 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15531 } 15532 } 15533 15534 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15535 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15536 if (app.thread == null) { 15537 return false; 15538 } 15539 15540 final boolean wasKeeping = app.keeping; 15541 15542 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15543 15544 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15545 reportingProcessState, now); 15546 } 15547 15548 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15549 boolean oomAdj) { 15550 if (isForeground != proc.foregroundServices) { 15551 proc.foregroundServices = isForeground; 15552 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15553 proc.info.uid); 15554 if (isForeground) { 15555 if (curProcs == null) { 15556 curProcs = new ArrayList<ProcessRecord>(); 15557 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15558 } 15559 if (!curProcs.contains(proc)) { 15560 curProcs.add(proc); 15561 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15562 proc.info.packageName, proc.info.uid); 15563 } 15564 } else { 15565 if (curProcs != null) { 15566 if (curProcs.remove(proc)) { 15567 mBatteryStatsService.noteEvent( 15568 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15569 proc.info.packageName, proc.info.uid); 15570 if (curProcs.size() <= 0) { 15571 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15572 } 15573 } 15574 } 15575 } 15576 if (oomAdj) { 15577 updateOomAdjLocked(); 15578 } 15579 } 15580 } 15581 15582 private final ActivityRecord resumedAppLocked() { 15583 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15584 String pkg; 15585 int uid; 15586 if (act != null && !act.sleeping) { 15587 pkg = act.packageName; 15588 uid = act.info.applicationInfo.uid; 15589 } else { 15590 pkg = null; 15591 uid = -1; 15592 } 15593 // Has the UID or resumed package name changed? 15594 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15595 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15596 if (mCurResumedPackage != null) { 15597 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15598 mCurResumedPackage, mCurResumedUid); 15599 } 15600 mCurResumedPackage = pkg; 15601 mCurResumedUid = uid; 15602 if (mCurResumedPackage != null) { 15603 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15604 mCurResumedPackage, mCurResumedUid); 15605 } 15606 } 15607 return act; 15608 } 15609 15610 final boolean updateOomAdjLocked(ProcessRecord app) { 15611 return updateOomAdjLocked(app, false); 15612 } 15613 15614 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15615 final ActivityRecord TOP_ACT = resumedAppLocked(); 15616 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15617 final boolean wasCached = app.cached; 15618 15619 mAdjSeq++; 15620 15621 // This is the desired cached adjusment we want to tell it to use. 15622 // If our app is currently cached, we know it, and that is it. Otherwise, 15623 // we don't know it yet, and it needs to now be cached we will then 15624 // need to do a complete oom adj. 15625 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15626 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15627 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15628 SystemClock.uptimeMillis()); 15629 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15630 // Changed to/from cached state, so apps after it in the LRU 15631 // list may also be changed. 15632 updateOomAdjLocked(); 15633 } 15634 return success; 15635 } 15636 15637 final void updateOomAdjLocked() { 15638 final ActivityRecord TOP_ACT = resumedAppLocked(); 15639 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15640 final long now = SystemClock.uptimeMillis(); 15641 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15642 final int N = mLruProcesses.size(); 15643 15644 if (false) { 15645 RuntimeException e = new RuntimeException(); 15646 e.fillInStackTrace(); 15647 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15648 } 15649 15650 mAdjSeq++; 15651 mNewNumServiceProcs = 0; 15652 mNewNumAServiceProcs = 0; 15653 15654 final int emptyProcessLimit; 15655 final int cachedProcessLimit; 15656 if (mProcessLimit <= 0) { 15657 emptyProcessLimit = cachedProcessLimit = 0; 15658 } else if (mProcessLimit == 1) { 15659 emptyProcessLimit = 1; 15660 cachedProcessLimit = 0; 15661 } else { 15662 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15663 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15664 } 15665 15666 // Let's determine how many processes we have running vs. 15667 // how many slots we have for background processes; we may want 15668 // to put multiple processes in a slot of there are enough of 15669 // them. 15670 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15671 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15672 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15673 if (numEmptyProcs > cachedProcessLimit) { 15674 // If there are more empty processes than our limit on cached 15675 // processes, then use the cached process limit for the factor. 15676 // This ensures that the really old empty processes get pushed 15677 // down to the bottom, so if we are running low on memory we will 15678 // have a better chance at keeping around more cached processes 15679 // instead of a gazillion empty processes. 15680 numEmptyProcs = cachedProcessLimit; 15681 } 15682 int emptyFactor = numEmptyProcs/numSlots; 15683 if (emptyFactor < 1) emptyFactor = 1; 15684 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15685 if (cachedFactor < 1) cachedFactor = 1; 15686 int stepCached = 0; 15687 int stepEmpty = 0; 15688 int numCached = 0; 15689 int numEmpty = 0; 15690 int numTrimming = 0; 15691 15692 mNumNonCachedProcs = 0; 15693 mNumCachedHiddenProcs = 0; 15694 15695 // First update the OOM adjustment for each of the 15696 // application processes based on their current state. 15697 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15698 int nextCachedAdj = curCachedAdj+1; 15699 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15700 int nextEmptyAdj = curEmptyAdj+2; 15701 for (int i=N-1; i>=0; i--) { 15702 ProcessRecord app = mLruProcesses.get(i); 15703 if (!app.killedByAm && app.thread != null) { 15704 app.procStateChanged = false; 15705 final boolean wasKeeping = app.keeping; 15706 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15707 15708 // If we haven't yet assigned the final cached adj 15709 // to the process, do that now. 15710 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15711 switch (app.curProcState) { 15712 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15713 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15714 // This process is a cached process holding activities... 15715 // assign it the next cached value for that type, and then 15716 // step that cached level. 15717 app.curRawAdj = curCachedAdj; 15718 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15719 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15720 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15721 + ")"); 15722 if (curCachedAdj != nextCachedAdj) { 15723 stepCached++; 15724 if (stepCached >= cachedFactor) { 15725 stepCached = 0; 15726 curCachedAdj = nextCachedAdj; 15727 nextCachedAdj += 2; 15728 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15729 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15730 } 15731 } 15732 } 15733 break; 15734 default: 15735 // For everything else, assign next empty cached process 15736 // level and bump that up. Note that this means that 15737 // long-running services that have dropped down to the 15738 // cached level will be treated as empty (since their process 15739 // state is still as a service), which is what we want. 15740 app.curRawAdj = curEmptyAdj; 15741 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15742 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15743 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15744 + ")"); 15745 if (curEmptyAdj != nextEmptyAdj) { 15746 stepEmpty++; 15747 if (stepEmpty >= emptyFactor) { 15748 stepEmpty = 0; 15749 curEmptyAdj = nextEmptyAdj; 15750 nextEmptyAdj += 2; 15751 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15752 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15753 } 15754 } 15755 } 15756 break; 15757 } 15758 } 15759 15760 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15761 15762 // Count the number of process types. 15763 switch (app.curProcState) { 15764 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15765 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15766 mNumCachedHiddenProcs++; 15767 numCached++; 15768 if (numCached > cachedProcessLimit) { 15769 killUnneededProcessLocked(app, "cached #" + numCached); 15770 } 15771 break; 15772 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15773 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15774 && app.lastActivityTime < oldTime) { 15775 killUnneededProcessLocked(app, "empty for " 15776 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15777 / 1000) + "s"); 15778 } else { 15779 numEmpty++; 15780 if (numEmpty > emptyProcessLimit) { 15781 killUnneededProcessLocked(app, "empty #" + numEmpty); 15782 } 15783 } 15784 break; 15785 default: 15786 mNumNonCachedProcs++; 15787 break; 15788 } 15789 15790 if (app.isolated && app.services.size() <= 0) { 15791 // If this is an isolated process, and there are no 15792 // services running in it, then the process is no longer 15793 // needed. We agressively kill these because we can by 15794 // definition not re-use the same process again, and it is 15795 // good to avoid having whatever code was running in them 15796 // left sitting around after no longer needed. 15797 killUnneededProcessLocked(app, "isolated not needed"); 15798 } 15799 15800 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15801 && !app.killedByAm) { 15802 numTrimming++; 15803 } 15804 } 15805 } 15806 15807 mNumServiceProcs = mNewNumServiceProcs; 15808 15809 // Now determine the memory trimming level of background processes. 15810 // Unfortunately we need to start at the back of the list to do this 15811 // properly. We only do this if the number of background apps we 15812 // are managing to keep around is less than half the maximum we desire; 15813 // if we are keeping a good number around, we'll let them use whatever 15814 // memory they want. 15815 final int numCachedAndEmpty = numCached + numEmpty; 15816 int memFactor; 15817 if (numCached <= ProcessList.TRIM_CACHED_APPS 15818 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15819 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15820 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15821 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15822 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15823 } else { 15824 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15825 } 15826 } else { 15827 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15828 } 15829 // We always allow the memory level to go up (better). We only allow it to go 15830 // down if we are in a state where that is allowed, *and* the total number of processes 15831 // has gone down since last time. 15832 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15833 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15834 + " last=" + mLastNumProcesses); 15835 if (memFactor > mLastMemoryLevel) { 15836 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15837 memFactor = mLastMemoryLevel; 15838 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15839 } 15840 } 15841 mLastMemoryLevel = memFactor; 15842 mLastNumProcesses = mLruProcesses.size(); 15843 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15844 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15845 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15846 if (mLowRamStartTime == 0) { 15847 mLowRamStartTime = now; 15848 } 15849 int step = 0; 15850 int fgTrimLevel; 15851 switch (memFactor) { 15852 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15853 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15854 break; 15855 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15856 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15857 break; 15858 default: 15859 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15860 break; 15861 } 15862 int factor = numTrimming/3; 15863 int minFactor = 2; 15864 if (mHomeProcess != null) minFactor++; 15865 if (mPreviousProcess != null) minFactor++; 15866 if (factor < minFactor) factor = minFactor; 15867 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15868 for (int i=N-1; i>=0; i--) { 15869 ProcessRecord app = mLruProcesses.get(i); 15870 if (allChanged || app.procStateChanged) { 15871 setProcessTrackerState(app, trackerMemFactor, now); 15872 app.procStateChanged = false; 15873 } 15874 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15875 && !app.killedByAm) { 15876 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15877 try { 15878 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15879 "Trimming memory of " + app.processName 15880 + " to " + curLevel); 15881 app.thread.scheduleTrimMemory(curLevel); 15882 } catch (RemoteException e) { 15883 } 15884 if (false) { 15885 // For now we won't do this; our memory trimming seems 15886 // to be good enough at this point that destroying 15887 // activities causes more harm than good. 15888 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15889 && app != mHomeProcess && app != mPreviousProcess) { 15890 // Need to do this on its own message because the stack may not 15891 // be in a consistent state at this point. 15892 // For these apps we will also finish their activities 15893 // to help them free memory. 15894 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15895 } 15896 } 15897 } 15898 app.trimMemoryLevel = curLevel; 15899 step++; 15900 if (step >= factor) { 15901 step = 0; 15902 switch (curLevel) { 15903 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15904 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15905 break; 15906 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15907 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15908 break; 15909 } 15910 } 15911 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15912 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15913 && app.thread != null) { 15914 try { 15915 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15916 "Trimming memory of heavy-weight " + app.processName 15917 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15918 app.thread.scheduleTrimMemory( 15919 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15920 } catch (RemoteException e) { 15921 } 15922 } 15923 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15924 } else { 15925 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15926 || app.systemNoUi) && app.pendingUiClean) { 15927 // If this application is now in the background and it 15928 // had done UI, then give it the special trim level to 15929 // have it free UI resources. 15930 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15931 if (app.trimMemoryLevel < level && app.thread != null) { 15932 try { 15933 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15934 "Trimming memory of bg-ui " + app.processName 15935 + " to " + level); 15936 app.thread.scheduleTrimMemory(level); 15937 } catch (RemoteException e) { 15938 } 15939 } 15940 app.pendingUiClean = false; 15941 } 15942 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15943 try { 15944 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15945 "Trimming memory of fg " + app.processName 15946 + " to " + fgTrimLevel); 15947 app.thread.scheduleTrimMemory(fgTrimLevel); 15948 } catch (RemoteException e) { 15949 } 15950 } 15951 app.trimMemoryLevel = fgTrimLevel; 15952 } 15953 } 15954 } else { 15955 if (mLowRamStartTime != 0) { 15956 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15957 mLowRamStartTime = 0; 15958 } 15959 for (int i=N-1; i>=0; i--) { 15960 ProcessRecord app = mLruProcesses.get(i); 15961 if (allChanged || app.procStateChanged) { 15962 setProcessTrackerState(app, trackerMemFactor, now); 15963 app.procStateChanged = false; 15964 } 15965 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15966 || app.systemNoUi) && app.pendingUiClean) { 15967 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15968 && app.thread != null) { 15969 try { 15970 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15971 "Trimming memory of ui hidden " + app.processName 15972 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15973 app.thread.scheduleTrimMemory( 15974 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15975 } catch (RemoteException e) { 15976 } 15977 } 15978 app.pendingUiClean = false; 15979 } 15980 app.trimMemoryLevel = 0; 15981 } 15982 } 15983 15984 if (mAlwaysFinishActivities) { 15985 // Need to do this on its own message because the stack may not 15986 // be in a consistent state at this point. 15987 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15988 } 15989 15990 if (allChanged) { 15991 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15992 } 15993 15994 if (mProcessStats.shouldWriteNowLocked(now)) { 15995 mHandler.post(new Runnable() { 15996 @Override public void run() { 15997 synchronized (ActivityManagerService.this) { 15998 mProcessStats.writeStateAsyncLocked(); 15999 } 16000 } 16001 }); 16002 } 16003 16004 if (DEBUG_OOM_ADJ) { 16005 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16006 } 16007 } 16008 16009 final void trimApplications() { 16010 synchronized (this) { 16011 int i; 16012 16013 // First remove any unused application processes whose package 16014 // has been removed. 16015 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16016 final ProcessRecord app = mRemovedProcesses.get(i); 16017 if (app.activities.size() == 0 16018 && app.curReceiver == null && app.services.size() == 0) { 16019 Slog.i( 16020 TAG, "Exiting empty application process " 16021 + app.processName + " (" 16022 + (app.thread != null ? app.thread.asBinder() : null) 16023 + ")\n"); 16024 if (app.pid > 0 && app.pid != MY_PID) { 16025 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16026 app.processName, app.setAdj, "empty"); 16027 app.killedByAm = true; 16028 Process.killProcessQuiet(app.pid); 16029 } else { 16030 try { 16031 app.thread.scheduleExit(); 16032 } catch (Exception e) { 16033 // Ignore exceptions. 16034 } 16035 } 16036 cleanUpApplicationRecordLocked(app, false, true, -1); 16037 mRemovedProcesses.remove(i); 16038 16039 if (app.persistent) { 16040 if (app.persistent) { 16041 addAppLocked(app.info, false); 16042 } 16043 } 16044 } 16045 } 16046 16047 // Now update the oom adj for all processes. 16048 updateOomAdjLocked(); 16049 } 16050 } 16051 16052 /** This method sends the specified signal to each of the persistent apps */ 16053 public void signalPersistentProcesses(int sig) throws RemoteException { 16054 if (sig != Process.SIGNAL_USR1) { 16055 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16056 } 16057 16058 synchronized (this) { 16059 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16060 != PackageManager.PERMISSION_GRANTED) { 16061 throw new SecurityException("Requires permission " 16062 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16063 } 16064 16065 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16066 ProcessRecord r = mLruProcesses.get(i); 16067 if (r.thread != null && r.persistent) { 16068 Process.sendSignal(r.pid, sig); 16069 } 16070 } 16071 } 16072 } 16073 16074 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16075 if (proc == null || proc == mProfileProc) { 16076 proc = mProfileProc; 16077 path = mProfileFile; 16078 profileType = mProfileType; 16079 clearProfilerLocked(); 16080 } 16081 if (proc == null) { 16082 return; 16083 } 16084 try { 16085 proc.thread.profilerControl(false, path, null, profileType); 16086 } catch (RemoteException e) { 16087 throw new IllegalStateException("Process disappeared"); 16088 } 16089 } 16090 16091 private void clearProfilerLocked() { 16092 if (mProfileFd != null) { 16093 try { 16094 mProfileFd.close(); 16095 } catch (IOException e) { 16096 } 16097 } 16098 mProfileApp = null; 16099 mProfileProc = null; 16100 mProfileFile = null; 16101 mProfileType = 0; 16102 mAutoStopProfiler = false; 16103 } 16104 16105 public boolean profileControl(String process, int userId, boolean start, 16106 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16107 16108 try { 16109 synchronized (this) { 16110 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16111 // its own permission. 16112 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16113 != PackageManager.PERMISSION_GRANTED) { 16114 throw new SecurityException("Requires permission " 16115 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16116 } 16117 16118 if (start && fd == null) { 16119 throw new IllegalArgumentException("null fd"); 16120 } 16121 16122 ProcessRecord proc = null; 16123 if (process != null) { 16124 proc = findProcessLocked(process, userId, "profileControl"); 16125 } 16126 16127 if (start && (proc == null || proc.thread == null)) { 16128 throw new IllegalArgumentException("Unknown process: " + process); 16129 } 16130 16131 if (start) { 16132 stopProfilerLocked(null, null, 0); 16133 setProfileApp(proc.info, proc.processName, path, fd, false); 16134 mProfileProc = proc; 16135 mProfileType = profileType; 16136 try { 16137 fd = fd.dup(); 16138 } catch (IOException e) { 16139 fd = null; 16140 } 16141 proc.thread.profilerControl(start, path, fd, profileType); 16142 fd = null; 16143 mProfileFd = null; 16144 } else { 16145 stopProfilerLocked(proc, path, profileType); 16146 if (fd != null) { 16147 try { 16148 fd.close(); 16149 } catch (IOException e) { 16150 } 16151 } 16152 } 16153 16154 return true; 16155 } 16156 } catch (RemoteException e) { 16157 throw new IllegalStateException("Process disappeared"); 16158 } finally { 16159 if (fd != null) { 16160 try { 16161 fd.close(); 16162 } catch (IOException e) { 16163 } 16164 } 16165 } 16166 } 16167 16168 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16169 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16170 userId, true, true, callName, null); 16171 ProcessRecord proc = null; 16172 try { 16173 int pid = Integer.parseInt(process); 16174 synchronized (mPidsSelfLocked) { 16175 proc = mPidsSelfLocked.get(pid); 16176 } 16177 } catch (NumberFormatException e) { 16178 } 16179 16180 if (proc == null) { 16181 ArrayMap<String, SparseArray<ProcessRecord>> all 16182 = mProcessNames.getMap(); 16183 SparseArray<ProcessRecord> procs = all.get(process); 16184 if (procs != null && procs.size() > 0) { 16185 proc = procs.valueAt(0); 16186 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16187 for (int i=1; i<procs.size(); i++) { 16188 ProcessRecord thisProc = procs.valueAt(i); 16189 if (thisProc.userId == userId) { 16190 proc = thisProc; 16191 break; 16192 } 16193 } 16194 } 16195 } 16196 } 16197 16198 return proc; 16199 } 16200 16201 public boolean dumpHeap(String process, int userId, boolean managed, 16202 String path, ParcelFileDescriptor fd) throws RemoteException { 16203 16204 try { 16205 synchronized (this) { 16206 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16207 // its own permission (same as profileControl). 16208 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16209 != PackageManager.PERMISSION_GRANTED) { 16210 throw new SecurityException("Requires permission " 16211 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16212 } 16213 16214 if (fd == null) { 16215 throw new IllegalArgumentException("null fd"); 16216 } 16217 16218 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16219 if (proc == null || proc.thread == null) { 16220 throw new IllegalArgumentException("Unknown process: " + process); 16221 } 16222 16223 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16224 if (!isDebuggable) { 16225 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16226 throw new SecurityException("Process not debuggable: " + proc); 16227 } 16228 } 16229 16230 proc.thread.dumpHeap(managed, path, fd); 16231 fd = null; 16232 return true; 16233 } 16234 } catch (RemoteException e) { 16235 throw new IllegalStateException("Process disappeared"); 16236 } finally { 16237 if (fd != null) { 16238 try { 16239 fd.close(); 16240 } catch (IOException e) { 16241 } 16242 } 16243 } 16244 } 16245 16246 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16247 public void monitor() { 16248 synchronized (this) { } 16249 } 16250 16251 void onCoreSettingsChange(Bundle settings) { 16252 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16253 ProcessRecord processRecord = mLruProcesses.get(i); 16254 try { 16255 if (processRecord.thread != null) { 16256 processRecord.thread.setCoreSettings(settings); 16257 } 16258 } catch (RemoteException re) { 16259 /* ignore */ 16260 } 16261 } 16262 } 16263 16264 // Multi-user methods 16265 16266 /** 16267 * Start user, if its not already running, but don't bring it to foreground. 16268 */ 16269 @Override 16270 public boolean startUserInBackground(final int userId) { 16271 return startUser(userId, /* foreground */ false); 16272 } 16273 16274 /** 16275 * Refreshes the list of users related to the current user when either a 16276 * user switch happens or when a new related user is started in the 16277 * background. 16278 */ 16279 private void updateRelatedUserIdsLocked() { 16280 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16281 int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null 16282 for (int i = 0; i < relatedUserIds.length; i++) { 16283 relatedUserIds[i] = relatedUsers.get(i).id; 16284 } 16285 mRelatedUserIds = relatedUserIds; 16286 } 16287 16288 private Set getRelatedUsersLocked(int userId) { 16289 Set userIds = new HashSet<Integer>(); 16290 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId); 16291 for (UserInfo user : relatedUsers) { 16292 userIds.add(Integer.valueOf(user.id)); 16293 } 16294 return userIds; 16295 } 16296 16297 @Override 16298 public boolean switchUser(final int userId) { 16299 return startUser(userId, /* foregound */ true); 16300 } 16301 16302 private boolean startUser(final int userId, boolean foreground) { 16303 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16304 != PackageManager.PERMISSION_GRANTED) { 16305 String msg = "Permission Denial: switchUser() from pid=" 16306 + Binder.getCallingPid() 16307 + ", uid=" + Binder.getCallingUid() 16308 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16309 Slog.w(TAG, msg); 16310 throw new SecurityException(msg); 16311 } 16312 16313 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16314 16315 final long ident = Binder.clearCallingIdentity(); 16316 try { 16317 synchronized (this) { 16318 final int oldUserId = mCurrentUserId; 16319 if (oldUserId == userId) { 16320 return true; 16321 } 16322 16323 mStackSupervisor.setLockTaskModeLocked(null); 16324 16325 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16326 if (userInfo == null) { 16327 Slog.w(TAG, "No user info for user #" + userId); 16328 return false; 16329 } 16330 16331 if (foreground) { 16332 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16333 R.anim.screen_user_enter); 16334 } 16335 16336 boolean needStart = false; 16337 16338 // If the user we are switching to is not currently started, then 16339 // we need to start it now. 16340 if (mStartedUsers.get(userId) == null) { 16341 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16342 updateStartedUserArrayLocked(); 16343 needStart = true; 16344 } 16345 16346 final Integer userIdInt = Integer.valueOf(userId); 16347 mUserLru.remove(userIdInt); 16348 mUserLru.add(userIdInt); 16349 16350 if (foreground) { 16351 mCurrentUserId = userId; 16352 updateRelatedUserIdsLocked(); 16353 mWindowManager.setCurrentUser(userId, mRelatedUserIds); 16354 // Once the internal notion of the active user has switched, we lock the device 16355 // with the option to show the user switcher on the keyguard. 16356 mWindowManager.lockNow(null); 16357 } else { 16358 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16359 updateRelatedUserIdsLocked(); 16360 mWindowManager.updateRelatedUserIds(mRelatedUserIds); 16361 mUserLru.remove(currentUserIdInt); 16362 mUserLru.add(currentUserIdInt); 16363 } 16364 16365 final UserStartedState uss = mStartedUsers.get(userId); 16366 16367 // Make sure user is in the started state. If it is currently 16368 // stopping, we need to knock that off. 16369 if (uss.mState == UserStartedState.STATE_STOPPING) { 16370 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16371 // so we can just fairly silently bring the user back from 16372 // the almost-dead. 16373 uss.mState = UserStartedState.STATE_RUNNING; 16374 updateStartedUserArrayLocked(); 16375 needStart = true; 16376 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16377 // This means ACTION_SHUTDOWN has been sent, so we will 16378 // need to treat this as a new boot of the user. 16379 uss.mState = UserStartedState.STATE_BOOTING; 16380 updateStartedUserArrayLocked(); 16381 needStart = true; 16382 } 16383 16384 if (foreground) { 16385 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16386 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16387 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16388 oldUserId, userId, uss)); 16389 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16390 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16391 } 16392 16393 if (needStart) { 16394 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16395 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16396 | Intent.FLAG_RECEIVER_FOREGROUND); 16397 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16398 broadcastIntentLocked(null, null, intent, 16399 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16400 false, false, MY_PID, Process.SYSTEM_UID, userId); 16401 } 16402 16403 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16404 if (userId != 0) { 16405 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16406 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16407 broadcastIntentLocked(null, null, intent, null, 16408 new IIntentReceiver.Stub() { 16409 public void performReceive(Intent intent, int resultCode, 16410 String data, Bundle extras, boolean ordered, 16411 boolean sticky, int sendingUser) { 16412 userInitialized(uss, userId); 16413 } 16414 }, 0, null, null, null, AppOpsManager.OP_NONE, 16415 true, false, MY_PID, Process.SYSTEM_UID, 16416 userId); 16417 uss.initializing = true; 16418 } else { 16419 getUserManagerLocked().makeInitialized(userInfo.id); 16420 } 16421 } 16422 16423 if (foreground) { 16424 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16425 if (homeInFront) { 16426 startHomeActivityLocked(userId); 16427 } else { 16428 mStackSupervisor.resumeTopActivitiesLocked(); 16429 } 16430 EventLogTags.writeAmSwitchUser(userId); 16431 getUserManagerLocked().userForeground(userId); 16432 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16433 } 16434 16435 if (needStart) { 16436 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16437 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16438 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16439 broadcastIntentLocked(null, null, intent, 16440 null, new IIntentReceiver.Stub() { 16441 @Override 16442 public void performReceive(Intent intent, int resultCode, String data, 16443 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16444 throws RemoteException { 16445 } 16446 }, 0, null, null, 16447 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16448 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16449 } 16450 } 16451 } finally { 16452 Binder.restoreCallingIdentity(ident); 16453 } 16454 16455 return true; 16456 } 16457 16458 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16459 long ident = Binder.clearCallingIdentity(); 16460 try { 16461 Intent intent; 16462 if (oldUserId >= 0) { 16463 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16464 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16465 | Intent.FLAG_RECEIVER_FOREGROUND); 16466 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16467 broadcastIntentLocked(null, null, intent, 16468 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16469 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16470 } 16471 if (newUserId >= 0) { 16472 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16473 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16474 | Intent.FLAG_RECEIVER_FOREGROUND); 16475 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16476 broadcastIntentLocked(null, null, intent, 16477 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16478 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16479 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16480 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16481 | Intent.FLAG_RECEIVER_FOREGROUND); 16482 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16483 broadcastIntentLocked(null, null, intent, 16484 null, null, 0, null, null, 16485 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16486 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16487 } 16488 } finally { 16489 Binder.restoreCallingIdentity(ident); 16490 } 16491 } 16492 16493 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16494 final int newUserId) { 16495 final int N = mUserSwitchObservers.beginBroadcast(); 16496 if (N > 0) { 16497 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16498 int mCount = 0; 16499 @Override 16500 public void sendResult(Bundle data) throws RemoteException { 16501 synchronized (ActivityManagerService.this) { 16502 if (mCurUserSwitchCallback == this) { 16503 mCount++; 16504 if (mCount == N) { 16505 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16506 } 16507 } 16508 } 16509 } 16510 }; 16511 synchronized (this) { 16512 uss.switching = true; 16513 mCurUserSwitchCallback = callback; 16514 } 16515 for (int i=0; i<N; i++) { 16516 try { 16517 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16518 newUserId, callback); 16519 } catch (RemoteException e) { 16520 } 16521 } 16522 } else { 16523 synchronized (this) { 16524 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16525 } 16526 } 16527 mUserSwitchObservers.finishBroadcast(); 16528 } 16529 16530 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16531 synchronized (this) { 16532 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16533 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16534 } 16535 } 16536 16537 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16538 mCurUserSwitchCallback = null; 16539 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16540 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16541 oldUserId, newUserId, uss)); 16542 } 16543 16544 void userInitialized(UserStartedState uss, int newUserId) { 16545 completeSwitchAndInitalize(uss, newUserId, true, false); 16546 } 16547 16548 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16549 completeSwitchAndInitalize(uss, newUserId, false, true); 16550 } 16551 16552 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16553 boolean clearInitializing, boolean clearSwitching) { 16554 boolean unfrozen = false; 16555 synchronized (this) { 16556 if (clearInitializing) { 16557 uss.initializing = false; 16558 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16559 } 16560 if (clearSwitching) { 16561 uss.switching = false; 16562 } 16563 if (!uss.switching && !uss.initializing) { 16564 mWindowManager.stopFreezingScreen(); 16565 unfrozen = true; 16566 } 16567 } 16568 if (unfrozen) { 16569 final int N = mUserSwitchObservers.beginBroadcast(); 16570 for (int i=0; i<N; i++) { 16571 try { 16572 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16573 } catch (RemoteException e) { 16574 } 16575 } 16576 mUserSwitchObservers.finishBroadcast(); 16577 } 16578 } 16579 16580 void scheduleStartRelatedUsersLocked() { 16581 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16582 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16583 DateUtils.SECOND_IN_MILLIS); 16584 } 16585 } 16586 16587 void startRelatedUsersLocked() { 16588 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16589 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16590 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16591 for (UserInfo relatedUser : relatedUsers) { 16592 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16593 toStart.add(relatedUser); 16594 } 16595 } 16596 final int n = toStart.size(); 16597 int i = 0; 16598 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16599 startUserInBackground(toStart.get(i).id); 16600 } 16601 if (i < n) { 16602 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16603 } 16604 } 16605 16606 void finishUserSwitch(UserStartedState uss) { 16607 synchronized (this) { 16608 if (uss.mState == UserStartedState.STATE_BOOTING 16609 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16610 uss.mState = UserStartedState.STATE_RUNNING; 16611 final int userId = uss.mHandle.getIdentifier(); 16612 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16613 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16614 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16615 broadcastIntentLocked(null, null, intent, 16616 null, null, 0, null, null, 16617 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16618 true, false, MY_PID, Process.SYSTEM_UID, userId); 16619 } 16620 16621 startRelatedUsersLocked(); 16622 16623 int num = mUserLru.size(); 16624 int i = 0; 16625 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16626 Integer oldUserId = mUserLru.get(i); 16627 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16628 if (oldUss == null) { 16629 // Shouldn't happen, but be sane if it does. 16630 mUserLru.remove(i); 16631 num--; 16632 continue; 16633 } 16634 if (oldUss.mState == UserStartedState.STATE_STOPPING 16635 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16636 // This user is already stopping, doesn't count. 16637 num--; 16638 i++; 16639 continue; 16640 } 16641 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16642 // Owner and current can't be stopped, but count as running. 16643 i++; 16644 continue; 16645 } 16646 // This is a user to be stopped. 16647 stopUserLocked(oldUserId, null); 16648 num--; 16649 i++; 16650 } 16651 } 16652 } 16653 16654 @Override 16655 public int stopUser(final int userId, final IStopUserCallback callback) { 16656 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16657 != PackageManager.PERMISSION_GRANTED) { 16658 String msg = "Permission Denial: switchUser() from pid=" 16659 + Binder.getCallingPid() 16660 + ", uid=" + Binder.getCallingUid() 16661 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16662 Slog.w(TAG, msg); 16663 throw new SecurityException(msg); 16664 } 16665 if (userId <= 0) { 16666 throw new IllegalArgumentException("Can't stop primary user " + userId); 16667 } 16668 synchronized (this) { 16669 return stopUserLocked(userId, callback); 16670 } 16671 } 16672 16673 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16674 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16675 if (mCurrentUserId == userId) { 16676 return ActivityManager.USER_OP_IS_CURRENT; 16677 } 16678 16679 final UserStartedState uss = mStartedUsers.get(userId); 16680 if (uss == null) { 16681 // User is not started, nothing to do... but we do need to 16682 // callback if requested. 16683 if (callback != null) { 16684 mHandler.post(new Runnable() { 16685 @Override 16686 public void run() { 16687 try { 16688 callback.userStopped(userId); 16689 } catch (RemoteException e) { 16690 } 16691 } 16692 }); 16693 } 16694 return ActivityManager.USER_OP_SUCCESS; 16695 } 16696 16697 if (callback != null) { 16698 uss.mStopCallbacks.add(callback); 16699 } 16700 16701 if (uss.mState != UserStartedState.STATE_STOPPING 16702 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16703 uss.mState = UserStartedState.STATE_STOPPING; 16704 updateStartedUserArrayLocked(); 16705 16706 long ident = Binder.clearCallingIdentity(); 16707 try { 16708 // We are going to broadcast ACTION_USER_STOPPING and then 16709 // once that is done send a final ACTION_SHUTDOWN and then 16710 // stop the user. 16711 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16712 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16713 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16714 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16715 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16716 // This is the result receiver for the final shutdown broadcast. 16717 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16718 @Override 16719 public void performReceive(Intent intent, int resultCode, String data, 16720 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16721 finishUserStop(uss); 16722 } 16723 }; 16724 // This is the result receiver for the initial stopping broadcast. 16725 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16726 @Override 16727 public void performReceive(Intent intent, int resultCode, String data, 16728 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16729 // On to the next. 16730 synchronized (ActivityManagerService.this) { 16731 if (uss.mState != UserStartedState.STATE_STOPPING) { 16732 // Whoops, we are being started back up. Abort, abort! 16733 return; 16734 } 16735 uss.mState = UserStartedState.STATE_SHUTDOWN; 16736 } 16737 broadcastIntentLocked(null, null, shutdownIntent, 16738 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16739 true, false, MY_PID, Process.SYSTEM_UID, userId); 16740 } 16741 }; 16742 // Kick things off. 16743 broadcastIntentLocked(null, null, stoppingIntent, 16744 null, stoppingReceiver, 0, null, null, 16745 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16746 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16747 } finally { 16748 Binder.restoreCallingIdentity(ident); 16749 } 16750 } 16751 16752 return ActivityManager.USER_OP_SUCCESS; 16753 } 16754 16755 void finishUserStop(UserStartedState uss) { 16756 final int userId = uss.mHandle.getIdentifier(); 16757 boolean stopped; 16758 ArrayList<IStopUserCallback> callbacks; 16759 synchronized (this) { 16760 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16761 if (mStartedUsers.get(userId) != uss) { 16762 stopped = false; 16763 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16764 stopped = false; 16765 } else { 16766 stopped = true; 16767 // User can no longer run. 16768 mStartedUsers.remove(userId); 16769 mUserLru.remove(Integer.valueOf(userId)); 16770 updateStartedUserArrayLocked(); 16771 16772 // Clean up all state and processes associated with the user. 16773 // Kill all the processes for the user. 16774 forceStopUserLocked(userId, "finish user"); 16775 } 16776 } 16777 16778 for (int i=0; i<callbacks.size(); i++) { 16779 try { 16780 if (stopped) callbacks.get(i).userStopped(userId); 16781 else callbacks.get(i).userStopAborted(userId); 16782 } catch (RemoteException e) { 16783 } 16784 } 16785 16786 mStackSupervisor.removeUserLocked(userId); 16787 } 16788 16789 @Override 16790 public UserInfo getCurrentUser() { 16791 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16792 != PackageManager.PERMISSION_GRANTED) && ( 16793 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16794 != PackageManager.PERMISSION_GRANTED)) { 16795 String msg = "Permission Denial: getCurrentUser() from pid=" 16796 + Binder.getCallingPid() 16797 + ", uid=" + Binder.getCallingUid() 16798 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16799 Slog.w(TAG, msg); 16800 throw new SecurityException(msg); 16801 } 16802 synchronized (this) { 16803 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16804 } 16805 } 16806 16807 int getCurrentUserIdLocked() { 16808 return mCurrentUserId; 16809 } 16810 16811 @Override 16812 public boolean isUserRunning(int userId, boolean orStopped) { 16813 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16814 != PackageManager.PERMISSION_GRANTED) { 16815 String msg = "Permission Denial: isUserRunning() from pid=" 16816 + Binder.getCallingPid() 16817 + ", uid=" + Binder.getCallingUid() 16818 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16819 Slog.w(TAG, msg); 16820 throw new SecurityException(msg); 16821 } 16822 synchronized (this) { 16823 return isUserRunningLocked(userId, orStopped); 16824 } 16825 } 16826 16827 boolean isUserRunningLocked(int userId, boolean orStopped) { 16828 UserStartedState state = mStartedUsers.get(userId); 16829 if (state == null) { 16830 return false; 16831 } 16832 if (orStopped) { 16833 return true; 16834 } 16835 return state.mState != UserStartedState.STATE_STOPPING 16836 && state.mState != UserStartedState.STATE_SHUTDOWN; 16837 } 16838 16839 @Override 16840 public int[] getRunningUserIds() { 16841 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16842 != PackageManager.PERMISSION_GRANTED) { 16843 String msg = "Permission Denial: isUserRunning() from pid=" 16844 + Binder.getCallingPid() 16845 + ", uid=" + Binder.getCallingUid() 16846 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16847 Slog.w(TAG, msg); 16848 throw new SecurityException(msg); 16849 } 16850 synchronized (this) { 16851 return mStartedUserArray; 16852 } 16853 } 16854 16855 private void updateStartedUserArrayLocked() { 16856 int num = 0; 16857 for (int i=0; i<mStartedUsers.size(); i++) { 16858 UserStartedState uss = mStartedUsers.valueAt(i); 16859 // This list does not include stopping users. 16860 if (uss.mState != UserStartedState.STATE_STOPPING 16861 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16862 num++; 16863 } 16864 } 16865 mStartedUserArray = new int[num]; 16866 num = 0; 16867 for (int i=0; i<mStartedUsers.size(); i++) { 16868 UserStartedState uss = mStartedUsers.valueAt(i); 16869 if (uss.mState != UserStartedState.STATE_STOPPING 16870 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16871 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16872 num++; 16873 } 16874 } 16875 } 16876 16877 @Override 16878 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16879 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16880 != PackageManager.PERMISSION_GRANTED) { 16881 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16882 + Binder.getCallingPid() 16883 + ", uid=" + Binder.getCallingUid() 16884 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16885 Slog.w(TAG, msg); 16886 throw new SecurityException(msg); 16887 } 16888 16889 mUserSwitchObservers.register(observer); 16890 } 16891 16892 @Override 16893 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16894 mUserSwitchObservers.unregister(observer); 16895 } 16896 16897 private boolean userExists(int userId) { 16898 if (userId == 0) { 16899 return true; 16900 } 16901 UserManagerService ums = getUserManagerLocked(); 16902 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16903 } 16904 16905 int[] getUsersLocked() { 16906 UserManagerService ums = getUserManagerLocked(); 16907 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16908 } 16909 16910 UserManagerService getUserManagerLocked() { 16911 if (mUserManager == null) { 16912 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16913 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16914 } 16915 return mUserManager; 16916 } 16917 16918 private int applyUserId(int uid, int userId) { 16919 return UserHandle.getUid(userId, uid); 16920 } 16921 16922 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16923 if (info == null) return null; 16924 ApplicationInfo newInfo = new ApplicationInfo(info); 16925 newInfo.uid = applyUserId(info.uid, userId); 16926 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16927 + info.packageName; 16928 return newInfo; 16929 } 16930 16931 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16932 if (aInfo == null 16933 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16934 return aInfo; 16935 } 16936 16937 ActivityInfo info = new ActivityInfo(aInfo); 16938 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16939 return info; 16940 } 16941} 16942