ActivityManagerService.java revision 82326a98a4507deee89a90654dd0953c459811af
1/* 2 * Copyright (C) 2006-2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.server.am; 18 19import static android.content.pm.PackageManager.PERMISSION_GRANTED; 20import static com.android.internal.util.XmlUtils.readIntAttribute; 21import static com.android.internal.util.XmlUtils.readLongAttribute; 22import static com.android.internal.util.XmlUtils.writeIntAttribute; 23import static com.android.internal.util.XmlUtils.writeLongAttribute; 24import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 25import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 26import static org.xmlpull.v1.XmlPullParser.START_TAG; 27 28import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 29 30import android.app.AppOpsManager; 31import android.app.IActivityContainer; 32import android.app.IActivityContainerCallback; 33import android.appwidget.AppWidgetManager; 34import android.graphics.Rect; 35import android.os.BatteryStats; 36import android.util.ArrayMap; 37import com.android.internal.R; 38import com.android.internal.annotations.GuardedBy; 39import com.android.internal.app.IAppOpsService; 40import com.android.internal.app.ProcessMap; 41import com.android.internal.app.ProcessStats; 42import com.android.internal.os.BackgroundThread; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.ProcessCpuTracker; 45import com.android.internal.os.TransferPipe; 46import com.android.internal.util.FastPrintWriter; 47import com.android.internal.util.FastXmlSerializer; 48import com.android.internal.util.MemInfoReader; 49import com.android.internal.util.Preconditions; 50import com.android.server.AppOpsService; 51import com.android.server.AttributeCache; 52import com.android.server.IntentResolver; 53import com.android.server.ServiceThread; 54import com.android.server.SystemService; 55import com.android.server.Watchdog; 56import com.android.server.am.ActivityStack.ActivityState; 57import com.android.server.firewall.IntentFirewall; 58import com.android.server.pm.UserManagerService; 59import com.android.server.wm.AppTransition; 60import com.android.server.wm.WindowManagerService; 61import com.google.android.collect.Lists; 62import com.google.android.collect.Maps; 63 64import dalvik.system.Zygote; 65 66import libcore.io.IoUtils; 67 68import org.xmlpull.v1.XmlPullParser; 69import org.xmlpull.v1.XmlPullParserException; 70import org.xmlpull.v1.XmlSerializer; 71 72import android.app.Activity; 73import android.app.ActivityManager; 74import android.app.ActivityManager.RunningTaskInfo; 75import android.app.ActivityManager.StackInfo; 76import android.app.ActivityManagerNative; 77import android.app.ActivityOptions; 78import android.app.ActivityThread; 79import android.app.AlertDialog; 80import android.app.AppGlobals; 81import android.app.ApplicationErrorReport; 82import android.app.Dialog; 83import android.app.IActivityController; 84import android.app.IApplicationThread; 85import android.app.IInstrumentationWatcher; 86import android.app.INotificationManager; 87import android.app.IProcessObserver; 88import android.app.IServiceConnection; 89import android.app.IStopUserCallback; 90import android.app.IThumbnailReceiver; 91import android.app.IUiAutomationConnection; 92import android.app.IUserSwitchObserver; 93import android.app.Instrumentation; 94import android.app.Notification; 95import android.app.NotificationManager; 96import android.app.PendingIntent; 97import android.app.backup.IBackupManager; 98import android.content.ActivityNotFoundException; 99import android.content.BroadcastReceiver; 100import android.content.ClipData; 101import android.content.ComponentCallbacks2; 102import android.content.ComponentName; 103import android.content.ContentProvider; 104import android.content.ContentResolver; 105import android.content.Context; 106import android.content.DialogInterface; 107import android.content.IContentProvider; 108import android.content.IIntentReceiver; 109import android.content.IIntentSender; 110import android.content.Intent; 111import android.content.IntentFilter; 112import android.content.IntentSender; 113import android.content.pm.ActivityInfo; 114import android.content.pm.ApplicationInfo; 115import android.content.pm.ConfigurationInfo; 116import android.content.pm.IPackageDataObserver; 117import android.content.pm.IPackageManager; 118import android.content.pm.InstrumentationInfo; 119import android.content.pm.PackageInfo; 120import android.content.pm.PackageManager; 121import android.content.pm.ParceledListSlice; 122import android.content.pm.UserInfo; 123import android.content.pm.PackageManager.NameNotFoundException; 124import android.content.pm.PathPermission; 125import android.content.pm.ProviderInfo; 126import android.content.pm.ResolveInfo; 127import android.content.pm.ServiceInfo; 128import android.content.res.CompatibilityInfo; 129import android.content.res.Configuration; 130import android.graphics.Bitmap; 131import android.net.Proxy; 132import android.net.ProxyProperties; 133import android.net.Uri; 134import android.os.Binder; 135import android.os.Build; 136import android.os.Bundle; 137import android.os.Debug; 138import android.os.DropBoxManager; 139import android.os.Environment; 140import android.os.FactoryTest; 141import android.os.FileObserver; 142import android.os.FileUtils; 143import android.os.Handler; 144import android.os.IBinder; 145import android.os.IPermissionController; 146import android.os.IRemoteCallback; 147import android.os.IUserManager; 148import android.os.Looper; 149import android.os.Message; 150import android.os.Parcel; 151import android.os.ParcelFileDescriptor; 152import android.os.Process; 153import android.os.RemoteCallbackList; 154import android.os.RemoteException; 155import android.os.SELinux; 156import android.os.ServiceManager; 157import android.os.StrictMode; 158import android.os.SystemClock; 159import android.os.SystemProperties; 160import android.os.UpdateLock; 161import android.os.UserHandle; 162import android.provider.Settings; 163import android.text.format.DateUtils; 164import android.text.format.Time; 165import android.util.AtomicFile; 166import android.util.EventLog; 167import android.util.Log; 168import android.util.Pair; 169import android.util.PrintWriterPrinter; 170import android.util.Slog; 171import android.util.SparseArray; 172import android.util.TimeUtils; 173import android.util.Xml; 174import android.view.Gravity; 175import android.view.LayoutInflater; 176import android.view.View; 177import android.view.WindowManager; 178 179import java.io.BufferedInputStream; 180import java.io.BufferedOutputStream; 181import java.io.DataInputStream; 182import java.io.DataOutputStream; 183import java.io.File; 184import java.io.FileDescriptor; 185import java.io.FileInputStream; 186import java.io.FileNotFoundException; 187import java.io.FileOutputStream; 188import java.io.IOException; 189import java.io.InputStreamReader; 190import java.io.PrintWriter; 191import java.io.StringWriter; 192import java.lang.ref.WeakReference; 193import java.util.ArrayList; 194import java.util.Arrays; 195import java.util.Collections; 196import java.util.Comparator; 197import java.util.HashMap; 198import java.util.HashSet; 199import java.util.Iterator; 200import java.util.List; 201import java.util.Locale; 202import java.util.Map; 203import java.util.Set; 204import java.util.concurrent.atomic.AtomicBoolean; 205import java.util.concurrent.atomic.AtomicLong; 206 207public final class ActivityManagerService extends ActivityManagerNative 208 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 209 private static final String USER_DATA_DIR = "/data/user/"; 210 static final String TAG = "ActivityManager"; 211 static final String TAG_MU = "ActivityManagerServiceMU"; 212 static final boolean DEBUG = false; 213 static final boolean localLOGV = DEBUG; 214 static final boolean DEBUG_BACKUP = localLOGV || false; 215 static final boolean DEBUG_BROADCAST = localLOGV || false; 216 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 217 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 218 static final boolean DEBUG_CLEANUP = localLOGV || false; 219 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 220 static final boolean DEBUG_FOCUS = false; 221 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 222 static final boolean DEBUG_MU = localLOGV || false; 223 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 224 static final boolean DEBUG_LRU = localLOGV || false; 225 static final boolean DEBUG_PAUSE = localLOGV || false; 226 static final boolean DEBUG_POWER = localLOGV || false; 227 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 228 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 229 static final boolean DEBUG_PROCESSES = localLOGV || false; 230 static final boolean DEBUG_PROVIDER = localLOGV || false; 231 static final boolean DEBUG_RESULTS = localLOGV || false; 232 static final boolean DEBUG_SERVICE = localLOGV || false; 233 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 234 static final boolean DEBUG_STACK = localLOGV || false; 235 static final boolean DEBUG_SWITCH = localLOGV || false; 236 static final boolean DEBUG_TASKS = localLOGV || false; 237 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 238 static final boolean DEBUG_TRANSITION = localLOGV || false; 239 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 240 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 241 static final boolean DEBUG_VISBILITY = localLOGV || false; 242 static final boolean DEBUG_PSS = localLOGV || false; 243 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 244 static final boolean VALIDATE_TOKENS = false; 245 static final boolean SHOW_ACTIVITY_START_TIME = true; 246 247 // Control over CPU and battery monitoring. 248 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 249 static final boolean MONITOR_CPU_USAGE = true; 250 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 251 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 252 static final boolean MONITOR_THREAD_CPU_USAGE = false; 253 254 // The flags that are set for all calls we make to the package manager. 255 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 256 257 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 258 259 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 260 261 // Maximum number of recent tasks that we can remember. 262 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 263 264 // Amount of time after a call to stopAppSwitches() during which we will 265 // prevent further untrusted switches from happening. 266 static final long APP_SWITCH_DELAY_TIME = 5*1000; 267 268 // How long we wait for a launched process to attach to the activity manager 269 // before we decide it's never going to come up for real. 270 static final int PROC_START_TIMEOUT = 10*1000; 271 272 // How long we wait for a launched process to attach to the activity manager 273 // before we decide it's never going to come up for real, when the process was 274 // started with a wrapper for instrumentation (such as Valgrind) because it 275 // could take much longer than usual. 276 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 277 278 // How long to wait after going idle before forcing apps to GC. 279 static final int GC_TIMEOUT = 5*1000; 280 281 // The minimum amount of time between successive GC requests for a process. 282 static final int GC_MIN_INTERVAL = 60*1000; 283 284 // The minimum amount of time between successive PSS requests for a process. 285 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process 288 // when the request is due to the memory state being lowered. 289 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 290 291 // The rate at which we check for apps using excessive power -- 15 mins. 292 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 293 294 // The minimum sample duration we will allow before deciding we have 295 // enough data on wake locks to start killing things. 296 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 297 298 // The minimum sample duration we will allow before deciding we have 299 // enough data on CPU usage to start killing things. 300 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 301 302 // How long we allow a receiver to run before giving up on it. 303 static final int BROADCAST_FG_TIMEOUT = 10*1000; 304 static final int BROADCAST_BG_TIMEOUT = 60*1000; 305 306 // How long we wait until we timeout on key dispatching. 307 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 308 309 // How long we wait until we timeout on key dispatching during instrumentation. 310 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 311 312 // Amount of time we wait for observers to handle a user switch before 313 // giving up on them and unfreezing the screen. 314 static final int USER_SWITCH_TIMEOUT = 2*1000; 315 316 // Maximum number of users we allow to be running at a time. 317 static final int MAX_RUNNING_USERS = 3; 318 319 // How long to wait in getAssistContextExtras for the activity and foreground services 320 // to respond with the result. 321 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 322 323 // Maximum number of persisted Uri grants a package is allowed 324 static final int MAX_PERSISTED_URI_GRANTS = 128; 325 326 static final int MY_PID = Process.myPid(); 327 328 static final String[] EMPTY_STRING_ARRAY = new String[0]; 329 330 // How many bytes to write into the dropbox log before truncating 331 static final int DROPBOX_MAX_SIZE = 256 * 1024; 332 333 /** Run all ActivityStacks through this */ 334 ActivityStackSupervisor mStackSupervisor; 335 336 public IntentFirewall mIntentFirewall; 337 338 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 339 // default actuion automatically. Important for devices without direct input 340 // devices. 341 private boolean mShowDialogs = true; 342 343 /** 344 * Description of a request to start a new activity, which has been held 345 * due to app switches being disabled. 346 */ 347 static class PendingActivityLaunch { 348 final ActivityRecord r; 349 final ActivityRecord sourceRecord; 350 final int startFlags; 351 final ActivityStack stack; 352 353 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 354 int _startFlags, ActivityStack _stack) { 355 r = _r; 356 sourceRecord = _sourceRecord; 357 startFlags = _startFlags; 358 stack = _stack; 359 } 360 } 361 362 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 363 = new ArrayList<PendingActivityLaunch>(); 364 365 BroadcastQueue mFgBroadcastQueue; 366 BroadcastQueue mBgBroadcastQueue; 367 // Convenient for easy iteration over the queues. Foreground is first 368 // so that dispatch of foreground broadcasts gets precedence. 369 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 370 371 BroadcastQueue broadcastQueueForIntent(Intent intent) { 372 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 373 if (DEBUG_BACKGROUND_BROADCAST) { 374 Slog.i(TAG, "Broadcast intent " + intent + " on " 375 + (isFg ? "foreground" : "background") 376 + " queue"); 377 } 378 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 379 } 380 381 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 382 for (BroadcastQueue queue : mBroadcastQueues) { 383 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 384 if (r != null) { 385 return r; 386 } 387 } 388 return null; 389 } 390 391 /** 392 * Activity we have told the window manager to have key focus. 393 */ 394 ActivityRecord mFocusedActivity = null; 395 396 /** 397 * List of intents that were used to start the most recent tasks. 398 */ 399 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 400 401 public class PendingAssistExtras extends Binder implements Runnable { 402 public final ActivityRecord activity; 403 public boolean haveResult = false; 404 public Bundle result = null; 405 public PendingAssistExtras(ActivityRecord _activity) { 406 activity = _activity; 407 } 408 @Override 409 public void run() { 410 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 411 synchronized (this) { 412 haveResult = true; 413 notifyAll(); 414 } 415 } 416 } 417 418 final ArrayList<PendingAssistExtras> mPendingAssistExtras 419 = new ArrayList<PendingAssistExtras>(); 420 421 /** 422 * Process management. 423 */ 424 final ProcessList mProcessList = new ProcessList(); 425 426 /** 427 * All of the applications we currently have running organized by name. 428 * The keys are strings of the application package name (as 429 * returned by the package manager), and the keys are ApplicationRecord 430 * objects. 431 */ 432 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 433 434 /** 435 * Tracking long-term execution of processes to look for abuse and other 436 * bad app behavior. 437 */ 438 final ProcessStatsService mProcessStats; 439 440 /** 441 * The currently running isolated processes. 442 */ 443 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 444 445 /** 446 * Counter for assigning isolated process uids, to avoid frequently reusing the 447 * same ones. 448 */ 449 int mNextIsolatedProcessUid = 0; 450 451 /** 452 * The currently running heavy-weight process, if any. 453 */ 454 ProcessRecord mHeavyWeightProcess = null; 455 456 /** 457 * The last time that various processes have crashed. 458 */ 459 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 460 461 /** 462 * Information about a process that is currently marked as bad. 463 */ 464 static final class BadProcessInfo { 465 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 466 this.time = time; 467 this.shortMsg = shortMsg; 468 this.longMsg = longMsg; 469 this.stack = stack; 470 } 471 472 final long time; 473 final String shortMsg; 474 final String longMsg; 475 final String stack; 476 } 477 478 /** 479 * Set of applications that we consider to be bad, and will reject 480 * incoming broadcasts from (which the user has no control over). 481 * Processes are added to this set when they have crashed twice within 482 * a minimum amount of time; they are removed from it when they are 483 * later restarted (hopefully due to some user action). The value is the 484 * time it was added to the list. 485 */ 486 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 487 488 /** 489 * All of the processes we currently have running organized by pid. 490 * The keys are the pid running the application. 491 * 492 * <p>NOTE: This object is protected by its own lock, NOT the global 493 * activity manager lock! 494 */ 495 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 496 497 /** 498 * All of the processes that have been forced to be foreground. The key 499 * is the pid of the caller who requested it (we hold a death 500 * link on it). 501 */ 502 abstract class ForegroundToken implements IBinder.DeathRecipient { 503 int pid; 504 IBinder token; 505 } 506 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 507 508 /** 509 * List of records for processes that someone had tried to start before the 510 * system was ready. We don't start them at that point, but ensure they 511 * are started by the time booting is complete. 512 */ 513 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 514 515 /** 516 * List of persistent applications that are in the process 517 * of being started. 518 */ 519 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 520 521 /** 522 * Processes that are being forcibly torn down. 523 */ 524 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 525 526 /** 527 * List of running applications, sorted by recent usage. 528 * The first entry in the list is the least recently used. 529 */ 530 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 531 532 /** 533 * Where in mLruProcesses that the processes hosting activities start. 534 */ 535 int mLruProcessActivityStart = 0; 536 537 /** 538 * Where in mLruProcesses that the processes hosting services start. 539 * This is after (lower index) than mLruProcessesActivityStart. 540 */ 541 int mLruProcessServiceStart = 0; 542 543 /** 544 * List of processes that should gc as soon as things are idle. 545 */ 546 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 547 548 /** 549 * Processes we want to collect PSS data from. 550 */ 551 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 552 553 /** 554 * Last time we requested PSS data of all processes. 555 */ 556 long mLastFullPssTime = SystemClock.uptimeMillis(); 557 558 /** 559 * This is the process holding what we currently consider to be 560 * the "home" activity. 561 */ 562 ProcessRecord mHomeProcess; 563 564 /** 565 * This is the process holding the activity the user last visited that 566 * is in a different process from the one they are currently in. 567 */ 568 ProcessRecord mPreviousProcess; 569 570 /** 571 * The time at which the previous process was last visible. 572 */ 573 long mPreviousProcessVisibleTime; 574 575 /** 576 * Which uses have been started, so are allowed to run code. 577 */ 578 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 579 580 /** 581 * LRU list of history of current users. Most recently current is at the end. 582 */ 583 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 584 585 /** 586 * Constant array of the users that are currently started. 587 */ 588 int[] mStartedUserArray = new int[] { 0 }; 589 590 /** 591 * Registered observers of the user switching mechanics. 592 */ 593 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 594 = new RemoteCallbackList<IUserSwitchObserver>(); 595 596 /** 597 * Currently active user switch. 598 */ 599 Object mCurUserSwitchCallback; 600 601 /** 602 * Packages that the user has asked to have run in screen size 603 * compatibility mode instead of filling the screen. 604 */ 605 final CompatModePackages mCompatModePackages; 606 607 /** 608 * Set of IntentSenderRecord objects that are currently active. 609 */ 610 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 611 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 612 613 /** 614 * Fingerprints (hashCode()) of stack traces that we've 615 * already logged DropBox entries for. Guarded by itself. If 616 * something (rogue user app) forces this over 617 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 618 */ 619 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 620 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 621 622 /** 623 * Strict Mode background batched logging state. 624 * 625 * The string buffer is guarded by itself, and its lock is also 626 * used to determine if another batched write is already 627 * in-flight. 628 */ 629 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 630 631 /** 632 * Keeps track of all IIntentReceivers that have been registered for 633 * broadcasts. Hash keys are the receiver IBinder, hash value is 634 * a ReceiverList. 635 */ 636 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 637 new HashMap<IBinder, ReceiverList>(); 638 639 /** 640 * Resolver for broadcast intents to registered receivers. 641 * Holds BroadcastFilter (subclass of IntentFilter). 642 */ 643 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 644 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 645 @Override 646 protected boolean allowFilterResult( 647 BroadcastFilter filter, List<BroadcastFilter> dest) { 648 IBinder target = filter.receiverList.receiver.asBinder(); 649 for (int i=dest.size()-1; i>=0; i--) { 650 if (dest.get(i).receiverList.receiver.asBinder() == target) { 651 return false; 652 } 653 } 654 return true; 655 } 656 657 @Override 658 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 659 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 660 || userId == filter.owningUserId) { 661 return super.newResult(filter, match, userId); 662 } 663 return null; 664 } 665 666 @Override 667 protected BroadcastFilter[] newArray(int size) { 668 return new BroadcastFilter[size]; 669 } 670 671 @Override 672 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 673 return packageName.equals(filter.packageName); 674 } 675 }; 676 677 /** 678 * State of all active sticky broadcasts per user. Keys are the action of the 679 * sticky Intent, values are an ArrayList of all broadcasted intents with 680 * that action (which should usually be one). The SparseArray is keyed 681 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 682 * for stickies that are sent to all users. 683 */ 684 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 685 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 686 687 final ActiveServices mServices; 688 689 /** 690 * Backup/restore process management 691 */ 692 String mBackupAppName = null; 693 BackupRecord mBackupTarget = null; 694 695 /** 696 * List of PendingThumbnailsRecord objects of clients who are still 697 * waiting to receive all of the thumbnails for a task. 698 */ 699 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 700 new ArrayList<PendingThumbnailsRecord>(); 701 702 final ProviderMap mProviderMap; 703 704 /** 705 * List of content providers who have clients waiting for them. The 706 * application is currently being launched and the provider will be 707 * removed from this list once it is published. 708 */ 709 final ArrayList<ContentProviderRecord> mLaunchingProviders 710 = new ArrayList<ContentProviderRecord>(); 711 712 /** 713 * File storing persisted {@link #mGrantedUriPermissions}. 714 */ 715 private final AtomicFile mGrantFile; 716 717 /** XML constants used in {@link #mGrantFile} */ 718 private static final String TAG_URI_GRANTS = "uri-grants"; 719 private static final String TAG_URI_GRANT = "uri-grant"; 720 private static final String ATTR_USER_HANDLE = "userHandle"; 721 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 722 private static final String ATTR_TARGET_PKG = "targetPkg"; 723 private static final String ATTR_URI = "uri"; 724 private static final String ATTR_MODE_FLAGS = "modeFlags"; 725 private static final String ATTR_CREATED_TIME = "createdTime"; 726 727 /** 728 * Global set of specific {@link Uri} permissions that have been granted. 729 * This optimized lookup structure maps from {@link UriPermission#targetUid} 730 * to {@link UriPermission#uri} to {@link UriPermission}. 731 */ 732 @GuardedBy("this") 733 private final SparseArray<ArrayMap<Uri, UriPermission>> 734 mGrantedUriPermissions = new SparseArray<ArrayMap<Uri, UriPermission>>(); 735 736 CoreSettingsObserver mCoreSettingsObserver; 737 738 /** 739 * Thread-local storage used to carry caller permissions over through 740 * indirect content-provider access. 741 */ 742 private class Identity { 743 public int pid; 744 public int uid; 745 746 Identity(int _pid, int _uid) { 747 pid = _pid; 748 uid = _uid; 749 } 750 } 751 752 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 753 754 /** 755 * All information we have collected about the runtime performance of 756 * any user id that can impact battery performance. 757 */ 758 final BatteryStatsService mBatteryStatsService; 759 760 /** 761 * Information about component usage 762 */ 763 final UsageStatsService mUsageStatsService; 764 765 /** 766 * Information about and control over application operations 767 */ 768 final AppOpsService mAppOpsService; 769 770 /** 771 * Current configuration information. HistoryRecord objects are given 772 * a reference to this object to indicate which configuration they are 773 * currently running in, so this object must be kept immutable. 774 */ 775 Configuration mConfiguration = new Configuration(); 776 777 /** 778 * Current sequencing integer of the configuration, for skipping old 779 * configurations. 780 */ 781 int mConfigurationSeq = 0; 782 783 /** 784 * Hardware-reported OpenGLES version. 785 */ 786 final int GL_ES_VERSION; 787 788 /** 789 * List of initialization arguments to pass to all processes when binding applications to them. 790 * For example, references to the commonly used services. 791 */ 792 HashMap<String, IBinder> mAppBindArgs; 793 794 /** 795 * Temporary to avoid allocations. Protected by main lock. 796 */ 797 final StringBuilder mStringBuilder = new StringBuilder(256); 798 799 /** 800 * Used to control how we initialize the service. 801 */ 802 boolean mStartRunning = false; 803 ComponentName mTopComponent; 804 String mTopAction; 805 String mTopData; 806 boolean mProcessesReady = false; 807 boolean mSystemReady = false; 808 boolean mBooting = false; 809 boolean mWaitingUpdate = false; 810 boolean mDidUpdate = false; 811 boolean mOnBattery = false; 812 boolean mLaunchWarningShown = false; 813 814 Context mContext; 815 816 int mFactoryTest; 817 818 boolean mCheckedForSetup; 819 820 /** 821 * The time at which we will allow normal application switches again, 822 * after a call to {@link #stopAppSwitches()}. 823 */ 824 long mAppSwitchesAllowedTime; 825 826 /** 827 * This is set to true after the first switch after mAppSwitchesAllowedTime 828 * is set; any switches after that will clear the time. 829 */ 830 boolean mDidAppSwitch; 831 832 /** 833 * Last time (in realtime) at which we checked for power usage. 834 */ 835 long mLastPowerCheckRealtime; 836 837 /** 838 * Last time (in uptime) at which we checked for power usage. 839 */ 840 long mLastPowerCheckUptime; 841 842 /** 843 * Set while we are wanting to sleep, to prevent any 844 * activities from being started/resumed. 845 */ 846 boolean mSleeping = false; 847 848 /** 849 * State of external calls telling us if the device is asleep. 850 */ 851 boolean mWentToSleep = false; 852 853 /** 854 * State of external call telling us if the lock screen is shown. 855 */ 856 boolean mLockScreenShown = false; 857 858 /** 859 * Set if we are shutting down the system, similar to sleeping. 860 */ 861 boolean mShuttingDown = false; 862 863 /** 864 * Current sequence id for oom_adj computation traversal. 865 */ 866 int mAdjSeq = 0; 867 868 /** 869 * Current sequence id for process LRU updating. 870 */ 871 int mLruSeq = 0; 872 873 /** 874 * Keep track of the non-cached/empty process we last found, to help 875 * determine how to distribute cached/empty processes next time. 876 */ 877 int mNumNonCachedProcs = 0; 878 879 /** 880 * Keep track of the number of cached hidden procs, to balance oom adj 881 * distribution between those and empty procs. 882 */ 883 int mNumCachedHiddenProcs = 0; 884 885 /** 886 * Keep track of the number of service processes we last found, to 887 * determine on the next iteration which should be B services. 888 */ 889 int mNumServiceProcs = 0; 890 int mNewNumAServiceProcs = 0; 891 int mNewNumServiceProcs = 0; 892 893 /** 894 * Allow the current computed overall memory level of the system to go down? 895 * This is set to false when we are killing processes for reasons other than 896 * memory management, so that the now smaller process list will not be taken as 897 * an indication that memory is tighter. 898 */ 899 boolean mAllowLowerMemLevel = false; 900 901 /** 902 * The last computed memory level, for holding when we are in a state that 903 * processes are going away for other reasons. 904 */ 905 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 906 907 /** 908 * The last total number of process we have, to determine if changes actually look 909 * like a shrinking number of process due to lower RAM. 910 */ 911 int mLastNumProcesses; 912 913 /** 914 * The uptime of the last time we performed idle maintenance. 915 */ 916 long mLastIdleTime = SystemClock.uptimeMillis(); 917 918 /** 919 * Total time spent with RAM that has been added in the past since the last idle time. 920 */ 921 long mLowRamTimeSinceLastIdle = 0; 922 923 /** 924 * If RAM is currently low, when that horrible situation started. 925 */ 926 long mLowRamStartTime = 0; 927 928 /** 929 * For reporting to battery stats the current top application. 930 */ 931 private String mCurResumedPackage = null; 932 private int mCurResumedUid = -1; 933 934 /** 935 * For reporting to battery stats the apps currently running foreground 936 * service. The ProcessMap is package/uid tuples; each of these contain 937 * an array of the currently foreground processes. 938 */ 939 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 940 = new ProcessMap<ArrayList<ProcessRecord>>(); 941 942 /** 943 * This is set if we had to do a delayed dexopt of an app before launching 944 * it, to increasing the ANR timeouts in that case. 945 */ 946 boolean mDidDexOpt; 947 948 String mDebugApp = null; 949 boolean mWaitForDebugger = false; 950 boolean mDebugTransient = false; 951 String mOrigDebugApp = null; 952 boolean mOrigWaitForDebugger = false; 953 boolean mAlwaysFinishActivities = false; 954 IActivityController mController = null; 955 String mProfileApp = null; 956 ProcessRecord mProfileProc = null; 957 String mProfileFile; 958 ParcelFileDescriptor mProfileFd; 959 int mProfileType = 0; 960 boolean mAutoStopProfiler = false; 961 String mOpenGlTraceApp = null; 962 963 static class ProcessChangeItem { 964 static final int CHANGE_ACTIVITIES = 1<<0; 965 static final int CHANGE_IMPORTANCE= 1<<1; 966 int changes; 967 int uid; 968 int pid; 969 int importance; 970 boolean foregroundActivities; 971 } 972 973 final RemoteCallbackList<IProcessObserver> mProcessObservers 974 = new RemoteCallbackList<IProcessObserver>(); 975 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 976 977 final ArrayList<ProcessChangeItem> mPendingProcessChanges 978 = new ArrayList<ProcessChangeItem>(); 979 final ArrayList<ProcessChangeItem> mAvailProcessChanges 980 = new ArrayList<ProcessChangeItem>(); 981 982 /** 983 * Runtime CPU use collection thread. This object's lock is used to 984 * protect all related state. 985 */ 986 final Thread mProcessCpuThread; 987 988 /** 989 * Used to collect process stats when showing not responding dialog. 990 * Protected by mProcessCpuThread. 991 */ 992 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 993 MONITOR_THREAD_CPU_USAGE); 994 final AtomicLong mLastCpuTime = new AtomicLong(0); 995 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 996 997 long mLastWriteTime = 0; 998 999 /** 1000 * Used to retain an update lock when the foreground activity is in 1001 * immersive mode. 1002 */ 1003 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1004 1005 /** 1006 * Set to true after the system has finished booting. 1007 */ 1008 boolean mBooted = false; 1009 1010 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1011 int mProcessLimitOverride = -1; 1012 1013 WindowManagerService mWindowManager; 1014 1015 final ActivityThread mSystemThread; 1016 1017 int mCurrentUserId = 0; 1018 int[] mRelatedUserIds = new int[0]; // Accessed by ActivityStack 1019 private UserManagerService mUserManager; 1020 1021 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1022 final ProcessRecord mApp; 1023 final int mPid; 1024 final IApplicationThread mAppThread; 1025 1026 AppDeathRecipient(ProcessRecord app, int pid, 1027 IApplicationThread thread) { 1028 if (localLOGV) Slog.v( 1029 TAG, "New death recipient " + this 1030 + " for thread " + thread.asBinder()); 1031 mApp = app; 1032 mPid = pid; 1033 mAppThread = thread; 1034 } 1035 1036 @Override 1037 public void binderDied() { 1038 if (localLOGV) Slog.v( 1039 TAG, "Death received in " + this 1040 + " for thread " + mAppThread.asBinder()); 1041 synchronized(ActivityManagerService.this) { 1042 appDiedLocked(mApp, mPid, mAppThread); 1043 } 1044 } 1045 } 1046 1047 static final int SHOW_ERROR_MSG = 1; 1048 static final int SHOW_NOT_RESPONDING_MSG = 2; 1049 static final int SHOW_FACTORY_ERROR_MSG = 3; 1050 static final int UPDATE_CONFIGURATION_MSG = 4; 1051 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1052 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1053 static final int SERVICE_TIMEOUT_MSG = 12; 1054 static final int UPDATE_TIME_ZONE = 13; 1055 static final int SHOW_UID_ERROR_MSG = 14; 1056 static final int IM_FEELING_LUCKY_MSG = 15; 1057 static final int PROC_START_TIMEOUT_MSG = 20; 1058 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1059 static final int KILL_APPLICATION_MSG = 22; 1060 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1061 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1062 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1063 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1064 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1065 static final int CLEAR_DNS_CACHE_MSG = 28; 1066 static final int UPDATE_HTTP_PROXY_MSG = 29; 1067 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1068 static final int DISPATCH_PROCESSES_CHANGED = 31; 1069 static final int DISPATCH_PROCESS_DIED = 32; 1070 static final int REPORT_MEM_USAGE_MSG = 33; 1071 static final int REPORT_USER_SWITCH_MSG = 34; 1072 static final int CONTINUE_USER_SWITCH_MSG = 35; 1073 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1074 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1075 static final int PERSIST_URI_GRANTS_MSG = 38; 1076 static final int REQUEST_ALL_PSS_MSG = 39; 1077 static final int START_RELATED_USERS_MSG = 40; 1078 static final int UPDATE_TIME = 41; 1079 1080 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1081 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1082 static final int FIRST_COMPAT_MODE_MSG = 300; 1083 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1084 1085 AlertDialog mUidAlert; 1086 CompatModeDialog mCompatModeDialog; 1087 long mLastMemUsageReportTime = 0; 1088 1089 /** 1090 * Flag whether the current user is a "monkey", i.e. whether 1091 * the UI is driven by a UI automation tool. 1092 */ 1093 private boolean mUserIsMonkey; 1094 1095 final ServiceThread mHandlerThread; 1096 final MainHandler mHandler; 1097 1098 final class MainHandler extends Handler { 1099 public MainHandler(Looper looper) { 1100 super(looper, null, true); 1101 } 1102 1103 @Override 1104 public void handleMessage(Message msg) { 1105 switch (msg.what) { 1106 case SHOW_ERROR_MSG: { 1107 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1108 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1109 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1110 synchronized (ActivityManagerService.this) { 1111 ProcessRecord proc = (ProcessRecord)data.get("app"); 1112 AppErrorResult res = (AppErrorResult) data.get("result"); 1113 if (proc != null && proc.crashDialog != null) { 1114 Slog.e(TAG, "App already has crash dialog: " + proc); 1115 if (res != null) { 1116 res.set(0); 1117 } 1118 return; 1119 } 1120 if (!showBackground && UserHandle.getAppId(proc.uid) 1121 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1122 && proc.pid != MY_PID) { 1123 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1124 if (res != null) { 1125 res.set(0); 1126 } 1127 return; 1128 } 1129 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1130 Dialog d = new AppErrorDialog(mContext, 1131 ActivityManagerService.this, res, proc); 1132 d.show(); 1133 proc.crashDialog = d; 1134 } else { 1135 // The device is asleep, so just pretend that the user 1136 // saw a crash dialog and hit "force quit". 1137 if (res != null) { 1138 res.set(0); 1139 } 1140 } 1141 } 1142 1143 ensureBootCompleted(); 1144 } break; 1145 case SHOW_NOT_RESPONDING_MSG: { 1146 synchronized (ActivityManagerService.this) { 1147 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1148 ProcessRecord proc = (ProcessRecord)data.get("app"); 1149 if (proc != null && proc.anrDialog != null) { 1150 Slog.e(TAG, "App already has anr dialog: " + proc); 1151 return; 1152 } 1153 1154 Intent intent = new Intent("android.intent.action.ANR"); 1155 if (!mProcessesReady) { 1156 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1157 | Intent.FLAG_RECEIVER_FOREGROUND); 1158 } 1159 broadcastIntentLocked(null, null, intent, 1160 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1161 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1162 1163 if (mShowDialogs) { 1164 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1165 mContext, proc, (ActivityRecord)data.get("activity"), 1166 msg.arg1 != 0); 1167 d.show(); 1168 proc.anrDialog = d; 1169 } else { 1170 // Just kill the app if there is no dialog to be shown. 1171 killAppAtUsersRequest(proc, null); 1172 } 1173 } 1174 1175 ensureBootCompleted(); 1176 } break; 1177 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1178 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1179 synchronized (ActivityManagerService.this) { 1180 ProcessRecord proc = (ProcessRecord) data.get("app"); 1181 if (proc == null) { 1182 Slog.e(TAG, "App not found when showing strict mode dialog."); 1183 break; 1184 } 1185 if (proc.crashDialog != null) { 1186 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1187 return; 1188 } 1189 AppErrorResult res = (AppErrorResult) data.get("result"); 1190 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1191 Dialog d = new StrictModeViolationDialog(mContext, 1192 ActivityManagerService.this, res, proc); 1193 d.show(); 1194 proc.crashDialog = d; 1195 } else { 1196 // The device is asleep, so just pretend that the user 1197 // saw a crash dialog and hit "force quit". 1198 res.set(0); 1199 } 1200 } 1201 ensureBootCompleted(); 1202 } break; 1203 case SHOW_FACTORY_ERROR_MSG: { 1204 Dialog d = new FactoryErrorDialog( 1205 mContext, msg.getData().getCharSequence("msg")); 1206 d.show(); 1207 ensureBootCompleted(); 1208 } break; 1209 case UPDATE_CONFIGURATION_MSG: { 1210 final ContentResolver resolver = mContext.getContentResolver(); 1211 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1212 } break; 1213 case GC_BACKGROUND_PROCESSES_MSG: { 1214 synchronized (ActivityManagerService.this) { 1215 performAppGcsIfAppropriateLocked(); 1216 } 1217 } break; 1218 case WAIT_FOR_DEBUGGER_MSG: { 1219 synchronized (ActivityManagerService.this) { 1220 ProcessRecord app = (ProcessRecord)msg.obj; 1221 if (msg.arg1 != 0) { 1222 if (!app.waitedForDebugger) { 1223 Dialog d = new AppWaitingForDebuggerDialog( 1224 ActivityManagerService.this, 1225 mContext, app); 1226 app.waitDialog = d; 1227 app.waitedForDebugger = true; 1228 d.show(); 1229 } 1230 } else { 1231 if (app.waitDialog != null) { 1232 app.waitDialog.dismiss(); 1233 app.waitDialog = null; 1234 } 1235 } 1236 } 1237 } break; 1238 case SERVICE_TIMEOUT_MSG: { 1239 if (mDidDexOpt) { 1240 mDidDexOpt = false; 1241 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1242 nmsg.obj = msg.obj; 1243 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1244 return; 1245 } 1246 mServices.serviceTimeout((ProcessRecord)msg.obj); 1247 } break; 1248 case UPDATE_TIME_ZONE: { 1249 synchronized (ActivityManagerService.this) { 1250 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1251 ProcessRecord r = mLruProcesses.get(i); 1252 if (r.thread != null) { 1253 try { 1254 r.thread.updateTimeZone(); 1255 } catch (RemoteException ex) { 1256 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1257 } 1258 } 1259 } 1260 } 1261 } break; 1262 case CLEAR_DNS_CACHE_MSG: { 1263 synchronized (ActivityManagerService.this) { 1264 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1265 ProcessRecord r = mLruProcesses.get(i); 1266 if (r.thread != null) { 1267 try { 1268 r.thread.clearDnsCache(); 1269 } catch (RemoteException ex) { 1270 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1271 } 1272 } 1273 } 1274 } 1275 } break; 1276 case UPDATE_HTTP_PROXY_MSG: { 1277 ProxyProperties proxy = (ProxyProperties)msg.obj; 1278 String host = ""; 1279 String port = ""; 1280 String exclList = ""; 1281 String pacFileUrl = null; 1282 if (proxy != null) { 1283 host = proxy.getHost(); 1284 port = Integer.toString(proxy.getPort()); 1285 exclList = proxy.getExclusionList(); 1286 pacFileUrl = proxy.getPacFileUrl(); 1287 } 1288 synchronized (ActivityManagerService.this) { 1289 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1290 ProcessRecord r = mLruProcesses.get(i); 1291 if (r.thread != null) { 1292 try { 1293 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1294 } catch (RemoteException ex) { 1295 Slog.w(TAG, "Failed to update http proxy for: " + 1296 r.info.processName); 1297 } 1298 } 1299 } 1300 } 1301 } break; 1302 case SHOW_UID_ERROR_MSG: { 1303 String title = "System UIDs Inconsistent"; 1304 String text = "UIDs on the system are inconsistent, you need to wipe your" 1305 + " data partition or your device will be unstable."; 1306 Log.e(TAG, title + ": " + text); 1307 if (mShowDialogs) { 1308 // XXX This is a temporary dialog, no need to localize. 1309 AlertDialog d = new BaseErrorDialog(mContext); 1310 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1311 d.setCancelable(false); 1312 d.setTitle(title); 1313 d.setMessage(text); 1314 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1315 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1316 mUidAlert = d; 1317 d.show(); 1318 } 1319 } break; 1320 case IM_FEELING_LUCKY_MSG: { 1321 if (mUidAlert != null) { 1322 mUidAlert.dismiss(); 1323 mUidAlert = null; 1324 } 1325 } break; 1326 case PROC_START_TIMEOUT_MSG: { 1327 if (mDidDexOpt) { 1328 mDidDexOpt = false; 1329 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1330 nmsg.obj = msg.obj; 1331 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1332 return; 1333 } 1334 ProcessRecord app = (ProcessRecord)msg.obj; 1335 synchronized (ActivityManagerService.this) { 1336 processStartTimedOutLocked(app); 1337 } 1338 } break; 1339 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1340 synchronized (ActivityManagerService.this) { 1341 doPendingActivityLaunchesLocked(true); 1342 } 1343 } break; 1344 case KILL_APPLICATION_MSG: { 1345 synchronized (ActivityManagerService.this) { 1346 int appid = msg.arg1; 1347 boolean restart = (msg.arg2 == 1); 1348 Bundle bundle = (Bundle)msg.obj; 1349 String pkg = bundle.getString("pkg"); 1350 String reason = bundle.getString("reason"); 1351 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1352 false, UserHandle.USER_ALL, reason); 1353 } 1354 } break; 1355 case FINALIZE_PENDING_INTENT_MSG: { 1356 ((PendingIntentRecord)msg.obj).completeFinalize(); 1357 } break; 1358 case POST_HEAVY_NOTIFICATION_MSG: { 1359 INotificationManager inm = NotificationManager.getService(); 1360 if (inm == null) { 1361 return; 1362 } 1363 1364 ActivityRecord root = (ActivityRecord)msg.obj; 1365 ProcessRecord process = root.app; 1366 if (process == null) { 1367 return; 1368 } 1369 1370 try { 1371 Context context = mContext.createPackageContext(process.info.packageName, 0); 1372 String text = mContext.getString(R.string.heavy_weight_notification, 1373 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1374 Notification notification = new Notification(); 1375 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1376 notification.when = 0; 1377 notification.flags = Notification.FLAG_ONGOING_EVENT; 1378 notification.tickerText = text; 1379 notification.defaults = 0; // please be quiet 1380 notification.sound = null; 1381 notification.vibrate = null; 1382 notification.setLatestEventInfo(context, text, 1383 mContext.getText(R.string.heavy_weight_notification_detail), 1384 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1385 PendingIntent.FLAG_CANCEL_CURRENT, null, 1386 new UserHandle(root.userId))); 1387 1388 try { 1389 int[] outId = new int[1]; 1390 inm.enqueueNotificationWithTag("android", "android", null, 1391 R.string.heavy_weight_notification, 1392 notification, outId, root.userId); 1393 } catch (RuntimeException e) { 1394 Slog.w(ActivityManagerService.TAG, 1395 "Error showing notification for heavy-weight app", e); 1396 } catch (RemoteException e) { 1397 } 1398 } catch (NameNotFoundException e) { 1399 Slog.w(TAG, "Unable to create context for heavy notification", e); 1400 } 1401 } break; 1402 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1403 INotificationManager inm = NotificationManager.getService(); 1404 if (inm == null) { 1405 return; 1406 } 1407 try { 1408 inm.cancelNotificationWithTag("android", null, 1409 R.string.heavy_weight_notification, msg.arg1); 1410 } catch (RuntimeException e) { 1411 Slog.w(ActivityManagerService.TAG, 1412 "Error canceling notification for service", e); 1413 } catch (RemoteException e) { 1414 } 1415 } break; 1416 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1417 synchronized (ActivityManagerService.this) { 1418 checkExcessivePowerUsageLocked(true); 1419 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1420 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1421 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1422 } 1423 } break; 1424 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1425 synchronized (ActivityManagerService.this) { 1426 ActivityRecord ar = (ActivityRecord)msg.obj; 1427 if (mCompatModeDialog != null) { 1428 if (mCompatModeDialog.mAppInfo.packageName.equals( 1429 ar.info.applicationInfo.packageName)) { 1430 return; 1431 } 1432 mCompatModeDialog.dismiss(); 1433 mCompatModeDialog = null; 1434 } 1435 if (ar != null && false) { 1436 if (mCompatModePackages.getPackageAskCompatModeLocked( 1437 ar.packageName)) { 1438 int mode = mCompatModePackages.computeCompatModeLocked( 1439 ar.info.applicationInfo); 1440 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1441 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1442 mCompatModeDialog = new CompatModeDialog( 1443 ActivityManagerService.this, mContext, 1444 ar.info.applicationInfo); 1445 mCompatModeDialog.show(); 1446 } 1447 } 1448 } 1449 } 1450 break; 1451 } 1452 case DISPATCH_PROCESSES_CHANGED: { 1453 dispatchProcessesChanged(); 1454 break; 1455 } 1456 case DISPATCH_PROCESS_DIED: { 1457 final int pid = msg.arg1; 1458 final int uid = msg.arg2; 1459 dispatchProcessDied(pid, uid); 1460 break; 1461 } 1462 case REPORT_MEM_USAGE_MSG: { 1463 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1464 Thread thread = new Thread() { 1465 @Override public void run() { 1466 final SparseArray<ProcessMemInfo> infoMap 1467 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1468 for (int i=0, N=memInfos.size(); i<N; i++) { 1469 ProcessMemInfo mi = memInfos.get(i); 1470 infoMap.put(mi.pid, mi); 1471 } 1472 updateCpuStatsNow(); 1473 synchronized (mProcessCpuThread) { 1474 final int N = mProcessCpuTracker.countStats(); 1475 for (int i=0; i<N; i++) { 1476 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1477 if (st.vsize > 0) { 1478 long pss = Debug.getPss(st.pid, null); 1479 if (pss > 0) { 1480 if (infoMap.indexOfKey(st.pid) < 0) { 1481 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1482 ProcessList.NATIVE_ADJ, -1, "native", null); 1483 mi.pss = pss; 1484 memInfos.add(mi); 1485 } 1486 } 1487 } 1488 } 1489 } 1490 1491 long totalPss = 0; 1492 for (int i=0, N=memInfos.size(); i<N; i++) { 1493 ProcessMemInfo mi = memInfos.get(i); 1494 if (mi.pss == 0) { 1495 mi.pss = Debug.getPss(mi.pid, null); 1496 } 1497 totalPss += mi.pss; 1498 } 1499 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1500 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1501 if (lhs.oomAdj != rhs.oomAdj) { 1502 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1503 } 1504 if (lhs.pss != rhs.pss) { 1505 return lhs.pss < rhs.pss ? 1 : -1; 1506 } 1507 return 0; 1508 } 1509 }); 1510 1511 StringBuilder tag = new StringBuilder(128); 1512 StringBuilder stack = new StringBuilder(128); 1513 tag.append("Low on memory -- "); 1514 appendMemBucket(tag, totalPss, "total", false); 1515 appendMemBucket(stack, totalPss, "total", true); 1516 1517 StringBuilder logBuilder = new StringBuilder(1024); 1518 logBuilder.append("Low on memory:\n"); 1519 1520 boolean firstLine = true; 1521 int lastOomAdj = Integer.MIN_VALUE; 1522 for (int i=0, N=memInfos.size(); i<N; i++) { 1523 ProcessMemInfo mi = memInfos.get(i); 1524 1525 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1526 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1527 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1528 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1529 if (lastOomAdj != mi.oomAdj) { 1530 lastOomAdj = mi.oomAdj; 1531 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1532 tag.append(" / "); 1533 } 1534 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1535 if (firstLine) { 1536 stack.append(":"); 1537 firstLine = false; 1538 } 1539 stack.append("\n\t at "); 1540 } else { 1541 stack.append("$"); 1542 } 1543 } else { 1544 tag.append(" "); 1545 stack.append("$"); 1546 } 1547 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1548 appendMemBucket(tag, mi.pss, mi.name, false); 1549 } 1550 appendMemBucket(stack, mi.pss, mi.name, true); 1551 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1552 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1553 stack.append("("); 1554 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1555 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1556 stack.append(DUMP_MEM_OOM_LABEL[k]); 1557 stack.append(":"); 1558 stack.append(DUMP_MEM_OOM_ADJ[k]); 1559 } 1560 } 1561 stack.append(")"); 1562 } 1563 } 1564 1565 logBuilder.append(" "); 1566 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1567 logBuilder.append(' '); 1568 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1569 logBuilder.append(' '); 1570 ProcessList.appendRamKb(logBuilder, mi.pss); 1571 logBuilder.append(" kB: "); 1572 logBuilder.append(mi.name); 1573 logBuilder.append(" ("); 1574 logBuilder.append(mi.pid); 1575 logBuilder.append(") "); 1576 logBuilder.append(mi.adjType); 1577 logBuilder.append('\n'); 1578 if (mi.adjReason != null) { 1579 logBuilder.append(" "); 1580 logBuilder.append(mi.adjReason); 1581 logBuilder.append('\n'); 1582 } 1583 } 1584 1585 logBuilder.append(" "); 1586 ProcessList.appendRamKb(logBuilder, totalPss); 1587 logBuilder.append(" kB: TOTAL\n"); 1588 1589 long[] infos = new long[Debug.MEMINFO_COUNT]; 1590 Debug.getMemInfo(infos); 1591 logBuilder.append(" MemInfo: "); 1592 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1593 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1594 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1595 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1596 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1597 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1598 logBuilder.append(" ZRAM: "); 1599 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1600 logBuilder.append(" kB RAM, "); 1601 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1602 logBuilder.append(" kB swap total, "); 1603 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1604 logBuilder.append(" kB swap free\n"); 1605 } 1606 Slog.i(TAG, logBuilder.toString()); 1607 1608 StringBuilder dropBuilder = new StringBuilder(1024); 1609 /* 1610 StringWriter oomSw = new StringWriter(); 1611 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1612 StringWriter catSw = new StringWriter(); 1613 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1614 String[] emptyArgs = new String[] { }; 1615 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1616 oomPw.flush(); 1617 String oomString = oomSw.toString(); 1618 */ 1619 dropBuilder.append(stack); 1620 dropBuilder.append('\n'); 1621 dropBuilder.append('\n'); 1622 dropBuilder.append(logBuilder); 1623 dropBuilder.append('\n'); 1624 /* 1625 dropBuilder.append(oomString); 1626 dropBuilder.append('\n'); 1627 */ 1628 StringWriter catSw = new StringWriter(); 1629 synchronized (ActivityManagerService.this) { 1630 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1631 String[] emptyArgs = new String[] { }; 1632 catPw.println(); 1633 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1634 catPw.println(); 1635 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1636 false, false, null); 1637 catPw.println(); 1638 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1639 catPw.flush(); 1640 } 1641 dropBuilder.append(catSw.toString()); 1642 addErrorToDropBox("lowmem", null, "system_server", null, 1643 null, tag.toString(), dropBuilder.toString(), null, null); 1644 //Slog.i(TAG, "Sent to dropbox:"); 1645 //Slog.i(TAG, dropBuilder.toString()); 1646 synchronized (ActivityManagerService.this) { 1647 long now = SystemClock.uptimeMillis(); 1648 if (mLastMemUsageReportTime < now) { 1649 mLastMemUsageReportTime = now; 1650 } 1651 } 1652 } 1653 }; 1654 thread.start(); 1655 break; 1656 } 1657 case REPORT_USER_SWITCH_MSG: { 1658 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1659 break; 1660 } 1661 case CONTINUE_USER_SWITCH_MSG: { 1662 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1663 break; 1664 } 1665 case USER_SWITCH_TIMEOUT_MSG: { 1666 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1667 break; 1668 } 1669 case IMMERSIVE_MODE_LOCK_MSG: { 1670 final boolean nextState = (msg.arg1 != 0); 1671 if (mUpdateLock.isHeld() != nextState) { 1672 if (DEBUG_IMMERSIVE) { 1673 final ActivityRecord r = (ActivityRecord) msg.obj; 1674 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1675 } 1676 if (nextState) { 1677 mUpdateLock.acquire(); 1678 } else { 1679 mUpdateLock.release(); 1680 } 1681 } 1682 break; 1683 } 1684 case PERSIST_URI_GRANTS_MSG: { 1685 writeGrantedUriPermissions(); 1686 break; 1687 } 1688 case REQUEST_ALL_PSS_MSG: { 1689 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1690 break; 1691 } 1692 case START_RELATED_USERS_MSG: { 1693 synchronized (ActivityManagerService.this) { 1694 startRelatedUsersLocked(); 1695 } 1696 break; 1697 } 1698 case UPDATE_TIME: { 1699 synchronized (ActivityManagerService.this) { 1700 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1701 ProcessRecord r = mLruProcesses.get(i); 1702 if (r.thread != null) { 1703 try { 1704 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1705 } catch (RemoteException ex) { 1706 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1707 } 1708 } 1709 } 1710 } 1711 break; 1712 } 1713 } 1714 } 1715 }; 1716 1717 static final int COLLECT_PSS_BG_MSG = 1; 1718 1719 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1720 @Override 1721 public void handleMessage(Message msg) { 1722 switch (msg.what) { 1723 case COLLECT_PSS_BG_MSG: { 1724 int i=0, num=0; 1725 long start = SystemClock.uptimeMillis(); 1726 long[] tmp = new long[1]; 1727 do { 1728 ProcessRecord proc; 1729 int procState; 1730 int pid; 1731 synchronized (ActivityManagerService.this) { 1732 if (i >= mPendingPssProcesses.size()) { 1733 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1734 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1735 mPendingPssProcesses.clear(); 1736 return; 1737 } 1738 proc = mPendingPssProcesses.get(i); 1739 procState = proc.pssProcState; 1740 if (proc.thread != null && procState == proc.setProcState) { 1741 pid = proc.pid; 1742 } else { 1743 proc = null; 1744 pid = 0; 1745 } 1746 i++; 1747 } 1748 if (proc != null) { 1749 long pss = Debug.getPss(pid, tmp); 1750 synchronized (ActivityManagerService.this) { 1751 if (proc.thread != null && proc.setProcState == procState 1752 && proc.pid == pid) { 1753 num++; 1754 proc.lastPssTime = SystemClock.uptimeMillis(); 1755 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1756 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1757 + ": " + pss + " lastPss=" + proc.lastPss 1758 + " state=" + ProcessList.makeProcStateString(procState)); 1759 if (proc.initialIdlePss == 0) { 1760 proc.initialIdlePss = pss; 1761 } 1762 proc.lastPss = pss; 1763 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1764 proc.lastCachedPss = pss; 1765 } 1766 } 1767 } 1768 } 1769 } while (true); 1770 } 1771 } 1772 } 1773 }; 1774 1775 public void setSystemProcess() { 1776 try { 1777 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1778 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1779 ServiceManager.addService("meminfo", new MemBinder(this)); 1780 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1781 ServiceManager.addService("dbinfo", new DbBinder(this)); 1782 if (MONITOR_CPU_USAGE) { 1783 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1784 } 1785 ServiceManager.addService("permission", new PermissionController(this)); 1786 1787 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1788 "android", STOCK_PM_FLAGS); 1789 mSystemThread.installSystemApplicationInfo(info); 1790 1791 synchronized (this) { 1792 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1793 app.persistent = true; 1794 app.pid = MY_PID; 1795 app.maxAdj = ProcessList.SYSTEM_ADJ; 1796 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1797 mProcessNames.put(app.processName, app.uid, app); 1798 synchronized (mPidsSelfLocked) { 1799 mPidsSelfLocked.put(app.pid, app); 1800 } 1801 updateLruProcessLocked(app, false, null); 1802 updateOomAdjLocked(); 1803 } 1804 } catch (PackageManager.NameNotFoundException e) { 1805 throw new RuntimeException( 1806 "Unable to find android system package", e); 1807 } 1808 } 1809 1810 public void setWindowManager(WindowManagerService wm) { 1811 mWindowManager = wm; 1812 mStackSupervisor.setWindowManager(wm); 1813 } 1814 1815 public void startObservingNativeCrashes() { 1816 final NativeCrashListener ncl = new NativeCrashListener(this); 1817 ncl.start(); 1818 } 1819 1820 public IAppOpsService getAppOpsService() { 1821 return mAppOpsService; 1822 } 1823 1824 static class MemBinder extends Binder { 1825 ActivityManagerService mActivityManagerService; 1826 MemBinder(ActivityManagerService activityManagerService) { 1827 mActivityManagerService = activityManagerService; 1828 } 1829 1830 @Override 1831 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1832 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1833 != PackageManager.PERMISSION_GRANTED) { 1834 pw.println("Permission Denial: can't dump meminfo from from pid=" 1835 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1836 + " without permission " + android.Manifest.permission.DUMP); 1837 return; 1838 } 1839 1840 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1841 } 1842 } 1843 1844 static class GraphicsBinder extends Binder { 1845 ActivityManagerService mActivityManagerService; 1846 GraphicsBinder(ActivityManagerService activityManagerService) { 1847 mActivityManagerService = activityManagerService; 1848 } 1849 1850 @Override 1851 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1852 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1853 != PackageManager.PERMISSION_GRANTED) { 1854 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1855 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1856 + " without permission " + android.Manifest.permission.DUMP); 1857 return; 1858 } 1859 1860 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1861 } 1862 } 1863 1864 static class DbBinder extends Binder { 1865 ActivityManagerService mActivityManagerService; 1866 DbBinder(ActivityManagerService activityManagerService) { 1867 mActivityManagerService = activityManagerService; 1868 } 1869 1870 @Override 1871 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1872 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1873 != PackageManager.PERMISSION_GRANTED) { 1874 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1875 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1876 + " without permission " + android.Manifest.permission.DUMP); 1877 return; 1878 } 1879 1880 mActivityManagerService.dumpDbInfo(fd, pw, args); 1881 } 1882 } 1883 1884 static class CpuBinder extends Binder { 1885 ActivityManagerService mActivityManagerService; 1886 CpuBinder(ActivityManagerService activityManagerService) { 1887 mActivityManagerService = activityManagerService; 1888 } 1889 1890 @Override 1891 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1892 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1893 != PackageManager.PERMISSION_GRANTED) { 1894 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1895 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1896 + " without permission " + android.Manifest.permission.DUMP); 1897 return; 1898 } 1899 1900 synchronized (mActivityManagerService.mProcessCpuThread) { 1901 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1902 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1903 SystemClock.uptimeMillis())); 1904 } 1905 } 1906 } 1907 1908 public static final class Lifecycle extends SystemService { 1909 private final ActivityManagerService mService; 1910 1911 public Lifecycle(Context context) { 1912 super(context); 1913 mService = new ActivityManagerService(context); 1914 } 1915 1916 @Override 1917 public void onStart() { 1918 mService.start(); 1919 } 1920 1921 public ActivityManagerService getService() { 1922 return mService; 1923 } 1924 } 1925 1926 // Note: This method is invoked on the main thread but may need to attach various 1927 // handlers to other threads. So take care to be explicit about the looper. 1928 public ActivityManagerService(Context systemContext) { 1929 mContext = systemContext; 1930 mFactoryTest = FactoryTest.getMode(); 1931 mSystemThread = ActivityThread.currentActivityThread(); 1932 1933 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1934 1935 mHandlerThread = new ServiceThread(TAG, 1936 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1937 mHandlerThread.start(); 1938 mHandler = new MainHandler(mHandlerThread.getLooper()); 1939 1940 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1941 "foreground", BROADCAST_FG_TIMEOUT, false); 1942 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1943 "background", BROADCAST_BG_TIMEOUT, true); 1944 mBroadcastQueues[0] = mFgBroadcastQueue; 1945 mBroadcastQueues[1] = mBgBroadcastQueue; 1946 1947 mServices = new ActiveServices(this); 1948 mProviderMap = new ProviderMap(this); 1949 1950 // TODO: Move creation of battery stats service outside of activity manager service. 1951 File dataDir = Environment.getDataDirectory(); 1952 File systemDir = new File(dataDir, "system"); 1953 systemDir.mkdirs(); 1954 mBatteryStatsService = new BatteryStatsService(new File( 1955 systemDir, "batterystats.bin").toString(), mHandler); 1956 mBatteryStatsService.getActiveStatistics().readLocked(); 1957 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1958 mOnBattery = DEBUG_POWER ? true 1959 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 1960 mBatteryStatsService.getActiveStatistics().setCallback(this); 1961 1962 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 1963 1964 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 1965 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 1966 1967 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 1968 1969 // User 0 is the first and only user that runs at boot. 1970 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 1971 mUserLru.add(Integer.valueOf(0)); 1972 updateStartedUserArrayLocked(); 1973 1974 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 1975 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 1976 1977 mConfiguration.setToDefaults(); 1978 mConfiguration.setLocale(Locale.getDefault()); 1979 1980 mConfigurationSeq = mConfiguration.seq = 1; 1981 mProcessCpuTracker.init(); 1982 1983 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 1984 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 1985 mStackSupervisor = new ActivityStackSupervisor(this); 1986 1987 mProcessCpuThread = new Thread("CpuTracker") { 1988 @Override 1989 public void run() { 1990 while (true) { 1991 try { 1992 try { 1993 synchronized(this) { 1994 final long now = SystemClock.uptimeMillis(); 1995 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 1996 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 1997 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 1998 // + ", write delay=" + nextWriteDelay); 1999 if (nextWriteDelay < nextCpuDelay) { 2000 nextCpuDelay = nextWriteDelay; 2001 } 2002 if (nextCpuDelay > 0) { 2003 mProcessCpuMutexFree.set(true); 2004 this.wait(nextCpuDelay); 2005 } 2006 } 2007 } catch (InterruptedException e) { 2008 } 2009 updateCpuStatsNow(); 2010 } catch (Exception e) { 2011 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2012 } 2013 } 2014 } 2015 }; 2016 2017 Watchdog.getInstance().addMonitor(this); 2018 Watchdog.getInstance().addThread(mHandler); 2019 } 2020 2021 private void start() { 2022 mProcessCpuThread.start(); 2023 2024 mBatteryStatsService.publish(mContext); 2025 mUsageStatsService.publish(mContext); 2026 mAppOpsService.publish(mContext); 2027 startRunning(null, null, null, null); 2028 } 2029 2030 @Override 2031 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2032 throws RemoteException { 2033 if (code == SYSPROPS_TRANSACTION) { 2034 // We need to tell all apps about the system property change. 2035 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2036 synchronized(this) { 2037 final int NP = mProcessNames.getMap().size(); 2038 for (int ip=0; ip<NP; ip++) { 2039 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2040 final int NA = apps.size(); 2041 for (int ia=0; ia<NA; ia++) { 2042 ProcessRecord app = apps.valueAt(ia); 2043 if (app.thread != null) { 2044 procs.add(app.thread.asBinder()); 2045 } 2046 } 2047 } 2048 } 2049 2050 int N = procs.size(); 2051 for (int i=0; i<N; i++) { 2052 Parcel data2 = Parcel.obtain(); 2053 try { 2054 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2055 } catch (RemoteException e) { 2056 } 2057 data2.recycle(); 2058 } 2059 } 2060 try { 2061 return super.onTransact(code, data, reply, flags); 2062 } catch (RuntimeException e) { 2063 // The activity manager only throws security exceptions, so let's 2064 // log all others. 2065 if (!(e instanceof SecurityException)) { 2066 Slog.wtf(TAG, "Activity Manager Crash", e); 2067 } 2068 throw e; 2069 } 2070 } 2071 2072 void updateCpuStats() { 2073 final long now = SystemClock.uptimeMillis(); 2074 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2075 return; 2076 } 2077 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2078 synchronized (mProcessCpuThread) { 2079 mProcessCpuThread.notify(); 2080 } 2081 } 2082 } 2083 2084 void updateCpuStatsNow() { 2085 synchronized (mProcessCpuThread) { 2086 mProcessCpuMutexFree.set(false); 2087 final long now = SystemClock.uptimeMillis(); 2088 boolean haveNewCpuStats = false; 2089 2090 if (MONITOR_CPU_USAGE && 2091 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2092 mLastCpuTime.set(now); 2093 haveNewCpuStats = true; 2094 mProcessCpuTracker.update(); 2095 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2096 //Slog.i(TAG, "Total CPU usage: " 2097 // + mProcessCpu.getTotalCpuPercent() + "%"); 2098 2099 // Slog the cpu usage if the property is set. 2100 if ("true".equals(SystemProperties.get("events.cpu"))) { 2101 int user = mProcessCpuTracker.getLastUserTime(); 2102 int system = mProcessCpuTracker.getLastSystemTime(); 2103 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2104 int irq = mProcessCpuTracker.getLastIrqTime(); 2105 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2106 int idle = mProcessCpuTracker.getLastIdleTime(); 2107 2108 int total = user + system + iowait + irq + softIrq + idle; 2109 if (total == 0) total = 1; 2110 2111 EventLog.writeEvent(EventLogTags.CPU, 2112 ((user+system+iowait+irq+softIrq) * 100) / total, 2113 (user * 100) / total, 2114 (system * 100) / total, 2115 (iowait * 100) / total, 2116 (irq * 100) / total, 2117 (softIrq * 100) / total); 2118 } 2119 } 2120 2121 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2122 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2123 synchronized(bstats) { 2124 synchronized(mPidsSelfLocked) { 2125 if (haveNewCpuStats) { 2126 if (mOnBattery) { 2127 int perc = bstats.startAddingCpuLocked(); 2128 int totalUTime = 0; 2129 int totalSTime = 0; 2130 final int N = mProcessCpuTracker.countStats(); 2131 for (int i=0; i<N; i++) { 2132 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2133 if (!st.working) { 2134 continue; 2135 } 2136 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2137 int otherUTime = (st.rel_utime*perc)/100; 2138 int otherSTime = (st.rel_stime*perc)/100; 2139 totalUTime += otherUTime; 2140 totalSTime += otherSTime; 2141 if (pr != null) { 2142 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2143 if (ps == null || !ps.isActive()) { 2144 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2145 pr.info.uid, pr.processName); 2146 } 2147 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2148 st.rel_stime-otherSTime); 2149 ps.addSpeedStepTimes(cpuSpeedTimes); 2150 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2151 } else { 2152 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2153 if (ps == null || !ps.isActive()) { 2154 st.batteryStats = ps = bstats.getProcessStatsLocked( 2155 bstats.mapUid(st.uid), st.name); 2156 } 2157 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2158 st.rel_stime-otherSTime); 2159 ps.addSpeedStepTimes(cpuSpeedTimes); 2160 } 2161 } 2162 bstats.finishAddingCpuLocked(perc, totalUTime, 2163 totalSTime, cpuSpeedTimes); 2164 } 2165 } 2166 } 2167 2168 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2169 mLastWriteTime = now; 2170 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2171 } 2172 } 2173 } 2174 } 2175 2176 @Override 2177 public void batteryNeedsCpuUpdate() { 2178 updateCpuStatsNow(); 2179 } 2180 2181 @Override 2182 public void batteryPowerChanged(boolean onBattery) { 2183 // When plugging in, update the CPU stats first before changing 2184 // the plug state. 2185 updateCpuStatsNow(); 2186 synchronized (this) { 2187 synchronized(mPidsSelfLocked) { 2188 mOnBattery = DEBUG_POWER ? true : onBattery; 2189 } 2190 } 2191 } 2192 2193 /** 2194 * Initialize the application bind args. These are passed to each 2195 * process when the bindApplication() IPC is sent to the process. They're 2196 * lazily setup to make sure the services are running when they're asked for. 2197 */ 2198 private HashMap<String, IBinder> getCommonServicesLocked() { 2199 if (mAppBindArgs == null) { 2200 mAppBindArgs = new HashMap<String, IBinder>(); 2201 2202 // Setup the application init args 2203 mAppBindArgs.put("package", ServiceManager.getService("package")); 2204 mAppBindArgs.put("window", ServiceManager.getService("window")); 2205 mAppBindArgs.put(Context.ALARM_SERVICE, 2206 ServiceManager.getService(Context.ALARM_SERVICE)); 2207 } 2208 return mAppBindArgs; 2209 } 2210 2211 final void setFocusedActivityLocked(ActivityRecord r) { 2212 if (mFocusedActivity != r) { 2213 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2214 mFocusedActivity = r; 2215 mStackSupervisor.setFocusedStack(r); 2216 if (r != null) { 2217 mWindowManager.setFocusedApp(r.appToken, true); 2218 } 2219 applyUpdateLockStateLocked(r); 2220 } 2221 } 2222 2223 @Override 2224 public void setFocusedStack(int stackId) { 2225 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2226 synchronized (ActivityManagerService.this) { 2227 ActivityStack stack = mStackSupervisor.getStack(stackId); 2228 if (stack != null) { 2229 ActivityRecord r = stack.topRunningActivityLocked(null); 2230 if (r != null) { 2231 setFocusedActivityLocked(r); 2232 } 2233 } 2234 } 2235 } 2236 2237 @Override 2238 public void notifyActivityDrawn(IBinder token) { 2239 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2240 synchronized (this) { 2241 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2242 if (r != null) { 2243 r.task.stack.notifyActivityDrawnLocked(r); 2244 } 2245 } 2246 } 2247 2248 final void applyUpdateLockStateLocked(ActivityRecord r) { 2249 // Modifications to the UpdateLock state are done on our handler, outside 2250 // the activity manager's locks. The new state is determined based on the 2251 // state *now* of the relevant activity record. The object is passed to 2252 // the handler solely for logging detail, not to be consulted/modified. 2253 final boolean nextState = r != null && r.immersive; 2254 mHandler.sendMessage( 2255 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2256 } 2257 2258 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2259 Message msg = Message.obtain(); 2260 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2261 msg.obj = r.task.askedCompatMode ? null : r; 2262 mHandler.sendMessage(msg); 2263 } 2264 2265 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2266 String what, Object obj, ProcessRecord srcApp) { 2267 app.lastActivityTime = now; 2268 2269 if (app.activities.size() > 0) { 2270 // Don't want to touch dependent processes that are hosting activities. 2271 return index; 2272 } 2273 2274 int lrui = mLruProcesses.lastIndexOf(app); 2275 if (lrui < 0) { 2276 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2277 + what + " " + obj + " from " + srcApp); 2278 return index; 2279 } 2280 2281 if (lrui >= index) { 2282 // Don't want to cause this to move dependent processes *back* in the 2283 // list as if they were less frequently used. 2284 return index; 2285 } 2286 2287 if (lrui >= mLruProcessActivityStart) { 2288 // Don't want to touch dependent processes that are hosting activities. 2289 return index; 2290 } 2291 2292 mLruProcesses.remove(lrui); 2293 if (index > 0) { 2294 index--; 2295 } 2296 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2297 + " in LRU list: " + app); 2298 mLruProcesses.add(index, app); 2299 return index; 2300 } 2301 2302 final void removeLruProcessLocked(ProcessRecord app) { 2303 int lrui = mLruProcesses.lastIndexOf(app); 2304 if (lrui >= 0) { 2305 if (lrui <= mLruProcessActivityStart) { 2306 mLruProcessActivityStart--; 2307 } 2308 if (lrui <= mLruProcessServiceStart) { 2309 mLruProcessServiceStart--; 2310 } 2311 mLruProcesses.remove(lrui); 2312 } 2313 } 2314 2315 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2316 ProcessRecord client) { 2317 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities; 2318 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2319 if (!activityChange && hasActivity) { 2320 // The process has activties, so we are only going to allow activity-based 2321 // adjustments move it. It should be kept in the front of the list with other 2322 // processes that have activities, and we don't want those to change their 2323 // order except due to activity operations. 2324 return; 2325 } 2326 2327 mLruSeq++; 2328 final long now = SystemClock.uptimeMillis(); 2329 app.lastActivityTime = now; 2330 2331 // First a quick reject: if the app is already at the position we will 2332 // put it, then there is nothing to do. 2333 if (hasActivity) { 2334 final int N = mLruProcesses.size(); 2335 if (N > 0 && mLruProcesses.get(N-1) == app) { 2336 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2337 return; 2338 } 2339 } else { 2340 if (mLruProcessServiceStart > 0 2341 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2342 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2343 return; 2344 } 2345 } 2346 2347 int lrui = mLruProcesses.lastIndexOf(app); 2348 2349 if (app.persistent && lrui >= 0) { 2350 // We don't care about the position of persistent processes, as long as 2351 // they are in the list. 2352 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2353 return; 2354 } 2355 2356 /* In progress: compute new position first, so we can avoid doing work 2357 if the process is not actually going to move. Not yet working. 2358 int addIndex; 2359 int nextIndex; 2360 boolean inActivity = false, inService = false; 2361 if (hasActivity) { 2362 // Process has activities, put it at the very tipsy-top. 2363 addIndex = mLruProcesses.size(); 2364 nextIndex = mLruProcessServiceStart; 2365 inActivity = true; 2366 } else if (hasService) { 2367 // Process has services, put it at the top of the service list. 2368 addIndex = mLruProcessActivityStart; 2369 nextIndex = mLruProcessServiceStart; 2370 inActivity = true; 2371 inService = true; 2372 } else { 2373 // Process not otherwise of interest, it goes to the top of the non-service area. 2374 addIndex = mLruProcessServiceStart; 2375 if (client != null) { 2376 int clientIndex = mLruProcesses.lastIndexOf(client); 2377 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2378 + app); 2379 if (clientIndex >= 0 && addIndex > clientIndex) { 2380 addIndex = clientIndex; 2381 } 2382 } 2383 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2384 } 2385 2386 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2387 + mLruProcessActivityStart + "): " + app); 2388 */ 2389 2390 if (lrui >= 0) { 2391 if (lrui < mLruProcessActivityStart) { 2392 mLruProcessActivityStart--; 2393 } 2394 if (lrui < mLruProcessServiceStart) { 2395 mLruProcessServiceStart--; 2396 } 2397 /* 2398 if (addIndex > lrui) { 2399 addIndex--; 2400 } 2401 if (nextIndex > lrui) { 2402 nextIndex--; 2403 } 2404 */ 2405 mLruProcesses.remove(lrui); 2406 } 2407 2408 /* 2409 mLruProcesses.add(addIndex, app); 2410 if (inActivity) { 2411 mLruProcessActivityStart++; 2412 } 2413 if (inService) { 2414 mLruProcessActivityStart++; 2415 } 2416 */ 2417 2418 int nextIndex; 2419 if (hasActivity) { 2420 final int N = mLruProcesses.size(); 2421 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2422 // Process doesn't have activities, but has clients with 2423 // activities... move it up, but one below the top (the top 2424 // should always have a real activity). 2425 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2426 mLruProcesses.add(N-1, app); 2427 // To keep it from spamming the LRU list (by making a bunch of clients), 2428 // we will push down any other entries owned by the app. 2429 final int uid = app.info.uid; 2430 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2431 ProcessRecord subProc = mLruProcesses.get(i); 2432 if (subProc.info.uid == uid) { 2433 // We want to push this one down the list. If the process after 2434 // it is for the same uid, however, don't do so, because we don't 2435 // want them internally to be re-ordered. 2436 if (mLruProcesses.get(i-1).info.uid != uid) { 2437 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2438 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2439 ProcessRecord tmp = mLruProcesses.get(i); 2440 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2441 mLruProcesses.set(i-1, tmp); 2442 i--; 2443 } 2444 } else { 2445 // A gap, we can stop here. 2446 break; 2447 } 2448 } 2449 } else { 2450 // Process has activities, put it at the very tipsy-top. 2451 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2452 mLruProcesses.add(app); 2453 } 2454 nextIndex = mLruProcessServiceStart; 2455 } else if (hasService) { 2456 // Process has services, put it at the top of the service list. 2457 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2458 mLruProcesses.add(mLruProcessActivityStart, app); 2459 nextIndex = mLruProcessServiceStart; 2460 mLruProcessActivityStart++; 2461 } else { 2462 // Process not otherwise of interest, it goes to the top of the non-service area. 2463 int index = mLruProcessServiceStart; 2464 if (client != null) { 2465 // If there is a client, don't allow the process to be moved up higher 2466 // in the list than that client. 2467 int clientIndex = mLruProcesses.lastIndexOf(client); 2468 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2469 + " when updating " + app); 2470 if (clientIndex <= lrui) { 2471 // Don't allow the client index restriction to push it down farther in the 2472 // list than it already is. 2473 clientIndex = lrui; 2474 } 2475 if (clientIndex >= 0 && index > clientIndex) { 2476 index = clientIndex; 2477 } 2478 } 2479 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2480 mLruProcesses.add(index, app); 2481 nextIndex = index-1; 2482 mLruProcessActivityStart++; 2483 mLruProcessServiceStart++; 2484 } 2485 2486 // If the app is currently using a content provider or service, 2487 // bump those processes as well. 2488 for (int j=app.connections.size()-1; j>=0; j--) { 2489 ConnectionRecord cr = app.connections.valueAt(j); 2490 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2491 && cr.binding.service.app != null 2492 && cr.binding.service.app.lruSeq != mLruSeq 2493 && !cr.binding.service.app.persistent) { 2494 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2495 "service connection", cr, app); 2496 } 2497 } 2498 for (int j=app.conProviders.size()-1; j>=0; j--) { 2499 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2500 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2501 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2502 "provider reference", cpr, app); 2503 } 2504 } 2505 } 2506 2507 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2508 if (uid == Process.SYSTEM_UID) { 2509 // The system gets to run in any process. If there are multiple 2510 // processes with the same uid, just pick the first (this 2511 // should never happen). 2512 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2513 if (procs == null) return null; 2514 final int N = procs.size(); 2515 for (int i = 0; i < N; i++) { 2516 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2517 } 2518 } 2519 ProcessRecord proc = mProcessNames.get(processName, uid); 2520 if (false && proc != null && !keepIfLarge 2521 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2522 && proc.lastCachedPss >= 4000) { 2523 // Turn this condition on to cause killing to happen regularly, for testing. 2524 if (proc.baseProcessTracker != null) { 2525 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2526 } 2527 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2528 + "k from cached"); 2529 } else if (proc != null && !keepIfLarge 2530 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2531 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2532 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2533 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2534 if (proc.baseProcessTracker != null) { 2535 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2536 } 2537 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2538 + "k from cached"); 2539 } 2540 } 2541 return proc; 2542 } 2543 2544 void ensurePackageDexOpt(String packageName) { 2545 IPackageManager pm = AppGlobals.getPackageManager(); 2546 try { 2547 if (pm.performDexOpt(packageName)) { 2548 mDidDexOpt = true; 2549 } 2550 } catch (RemoteException e) { 2551 } 2552 } 2553 2554 boolean isNextTransitionForward() { 2555 int transit = mWindowManager.getPendingAppTransition(); 2556 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2557 || transit == AppTransition.TRANSIT_TASK_OPEN 2558 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2559 } 2560 2561 final ProcessRecord startProcessLocked(String processName, 2562 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2563 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2564 boolean isolated, boolean keepIfLarge) { 2565 ProcessRecord app; 2566 if (!isolated) { 2567 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2568 } else { 2569 // If this is an isolated process, it can't re-use an existing process. 2570 app = null; 2571 } 2572 // We don't have to do anything more if: 2573 // (1) There is an existing application record; and 2574 // (2) The caller doesn't think it is dead, OR there is no thread 2575 // object attached to it so we know it couldn't have crashed; and 2576 // (3) There is a pid assigned to it, so it is either starting or 2577 // already running. 2578 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2579 + " app=" + app + " knownToBeDead=" + knownToBeDead 2580 + " thread=" + (app != null ? app.thread : null) 2581 + " pid=" + (app != null ? app.pid : -1)); 2582 if (app != null && app.pid > 0) { 2583 if (!knownToBeDead || app.thread == null) { 2584 // We already have the app running, or are waiting for it to 2585 // come up (we have a pid but not yet its thread), so keep it. 2586 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2587 // If this is a new package in the process, add the package to the list 2588 app.addPackage(info.packageName, mProcessStats); 2589 return app; 2590 } 2591 2592 // An application record is attached to a previous process, 2593 // clean it up now. 2594 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2595 handleAppDiedLocked(app, true, true); 2596 } 2597 2598 String hostingNameStr = hostingName != null 2599 ? hostingName.flattenToShortString() : null; 2600 2601 if (!isolated) { 2602 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2603 // If we are in the background, then check to see if this process 2604 // is bad. If so, we will just silently fail. 2605 if (mBadProcesses.get(info.processName, info.uid) != null) { 2606 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2607 + "/" + info.processName); 2608 return null; 2609 } 2610 } else { 2611 // When the user is explicitly starting a process, then clear its 2612 // crash count so that we won't make it bad until they see at 2613 // least one crash dialog again, and make the process good again 2614 // if it had been bad. 2615 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2616 + "/" + info.processName); 2617 mProcessCrashTimes.remove(info.processName, info.uid); 2618 if (mBadProcesses.get(info.processName, info.uid) != null) { 2619 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2620 UserHandle.getUserId(info.uid), info.uid, 2621 info.processName); 2622 mBadProcesses.remove(info.processName, info.uid); 2623 if (app != null) { 2624 app.bad = false; 2625 } 2626 } 2627 } 2628 } 2629 2630 if (app == null) { 2631 app = newProcessRecordLocked(info, processName, isolated); 2632 if (app == null) { 2633 Slog.w(TAG, "Failed making new process record for " 2634 + processName + "/" + info.uid + " isolated=" + isolated); 2635 return null; 2636 } 2637 mProcessNames.put(processName, app.uid, app); 2638 if (isolated) { 2639 mIsolatedProcesses.put(app.uid, app); 2640 } 2641 } else { 2642 // If this is a new package in the process, add the package to the list 2643 app.addPackage(info.packageName, mProcessStats); 2644 } 2645 2646 // If the system is not ready yet, then hold off on starting this 2647 // process until it is. 2648 if (!mProcessesReady 2649 && !isAllowedWhileBooting(info) 2650 && !allowWhileBooting) { 2651 if (!mProcessesOnHold.contains(app)) { 2652 mProcessesOnHold.add(app); 2653 } 2654 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2655 return app; 2656 } 2657 2658 startProcessLocked(app, hostingType, hostingNameStr); 2659 return (app.pid != 0) ? app : null; 2660 } 2661 2662 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2663 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2664 } 2665 2666 private final void startProcessLocked(ProcessRecord app, 2667 String hostingType, String hostingNameStr) { 2668 if (app.pid > 0 && app.pid != MY_PID) { 2669 synchronized (mPidsSelfLocked) { 2670 mPidsSelfLocked.remove(app.pid); 2671 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2672 } 2673 app.setPid(0); 2674 } 2675 2676 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2677 "startProcessLocked removing on hold: " + app); 2678 mProcessesOnHold.remove(app); 2679 2680 updateCpuStats(); 2681 2682 try { 2683 int uid = app.uid; 2684 2685 int[] gids = null; 2686 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2687 if (!app.isolated) { 2688 int[] permGids = null; 2689 try { 2690 final PackageManager pm = mContext.getPackageManager(); 2691 permGids = pm.getPackageGids(app.info.packageName); 2692 2693 if (Environment.isExternalStorageEmulated()) { 2694 if (pm.checkPermission( 2695 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2696 app.info.packageName) == PERMISSION_GRANTED) { 2697 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2698 } else { 2699 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2700 } 2701 } 2702 } catch (PackageManager.NameNotFoundException e) { 2703 Slog.w(TAG, "Unable to retrieve gids", e); 2704 } 2705 2706 /* 2707 * Add shared application GID so applications can share some 2708 * resources like shared libraries 2709 */ 2710 if (permGids == null) { 2711 gids = new int[1]; 2712 } else { 2713 gids = new int[permGids.length + 1]; 2714 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2715 } 2716 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2717 } 2718 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2719 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2720 && mTopComponent != null 2721 && app.processName.equals(mTopComponent.getPackageName())) { 2722 uid = 0; 2723 } 2724 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2725 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2726 uid = 0; 2727 } 2728 } 2729 int debugFlags = 0; 2730 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2731 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2732 // Also turn on CheckJNI for debuggable apps. It's quite 2733 // awkward to turn on otherwise. 2734 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2735 } 2736 // Run the app in safe mode if its manifest requests so or the 2737 // system is booted in safe mode. 2738 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2739 Zygote.systemInSafeMode == true) { 2740 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2741 } 2742 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2743 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2744 } 2745 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2746 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2747 } 2748 if ("1".equals(SystemProperties.get("debug.assert"))) { 2749 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2750 } 2751 2752 // Start the process. It will either succeed and return a result containing 2753 // the PID of the new process, or else throw a RuntimeException. 2754 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2755 app.processName, uid, uid, gids, debugFlags, mountExternal, 2756 app.info.targetSdkVersion, app.info.seinfo, null); 2757 2758 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2759 synchronized (bs) { 2760 if (bs.isOnBattery()) { 2761 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2762 } 2763 } 2764 2765 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2766 UserHandle.getUserId(uid), startResult.pid, uid, 2767 app.processName, hostingType, 2768 hostingNameStr != null ? hostingNameStr : ""); 2769 2770 if (app.persistent) { 2771 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2772 } 2773 2774 StringBuilder buf = mStringBuilder; 2775 buf.setLength(0); 2776 buf.append("Start proc "); 2777 buf.append(app.processName); 2778 buf.append(" for "); 2779 buf.append(hostingType); 2780 if (hostingNameStr != null) { 2781 buf.append(" "); 2782 buf.append(hostingNameStr); 2783 } 2784 buf.append(": pid="); 2785 buf.append(startResult.pid); 2786 buf.append(" uid="); 2787 buf.append(uid); 2788 buf.append(" gids={"); 2789 if (gids != null) { 2790 for (int gi=0; gi<gids.length; gi++) { 2791 if (gi != 0) buf.append(", "); 2792 buf.append(gids[gi]); 2793 2794 } 2795 } 2796 buf.append("}"); 2797 Slog.i(TAG, buf.toString()); 2798 app.setPid(startResult.pid); 2799 app.usingWrapper = startResult.usingWrapper; 2800 app.removed = false; 2801 synchronized (mPidsSelfLocked) { 2802 this.mPidsSelfLocked.put(startResult.pid, app); 2803 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2804 msg.obj = app; 2805 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2806 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2807 } 2808 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2809 app.processName, app.info.uid); 2810 if (app.isolated) { 2811 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2812 } 2813 } catch (RuntimeException e) { 2814 // XXX do better error recovery. 2815 app.setPid(0); 2816 Slog.e(TAG, "Failure starting process " + app.processName, e); 2817 } 2818 } 2819 2820 void updateUsageStats(ActivityRecord component, boolean resumed) { 2821 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2822 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2823 if (resumed) { 2824 mUsageStatsService.noteResumeComponent(component.realActivity); 2825 synchronized (stats) { 2826 stats.noteActivityResumedLocked(component.app.uid); 2827 } 2828 } else { 2829 mUsageStatsService.notePauseComponent(component.realActivity); 2830 synchronized (stats) { 2831 stats.noteActivityPausedLocked(component.app.uid); 2832 } 2833 } 2834 } 2835 2836 Intent getHomeIntent() { 2837 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2838 intent.setComponent(mTopComponent); 2839 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2840 intent.addCategory(Intent.CATEGORY_HOME); 2841 } 2842 return intent; 2843 } 2844 2845 boolean startHomeActivityLocked(int userId) { 2846 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2847 && mTopAction == null) { 2848 // We are running in factory test mode, but unable to find 2849 // the factory test app, so just sit around displaying the 2850 // error message and don't try to start anything. 2851 return false; 2852 } 2853 Intent intent = getHomeIntent(); 2854 ActivityInfo aInfo = 2855 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2856 if (aInfo != null) { 2857 intent.setComponent(new ComponentName( 2858 aInfo.applicationInfo.packageName, aInfo.name)); 2859 // Don't do this if the home app is currently being 2860 // instrumented. 2861 aInfo = new ActivityInfo(aInfo); 2862 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2863 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2864 aInfo.applicationInfo.uid, true); 2865 if (app == null || app.instrumentationClass == null) { 2866 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2867 mStackSupervisor.startHomeActivity(intent, aInfo); 2868 } 2869 } 2870 2871 return true; 2872 } 2873 2874 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2875 ActivityInfo ai = null; 2876 ComponentName comp = intent.getComponent(); 2877 try { 2878 if (comp != null) { 2879 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2880 } else { 2881 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2882 intent, 2883 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2884 flags, userId); 2885 2886 if (info != null) { 2887 ai = info.activityInfo; 2888 } 2889 } 2890 } catch (RemoteException e) { 2891 // ignore 2892 } 2893 2894 return ai; 2895 } 2896 2897 /** 2898 * Starts the "new version setup screen" if appropriate. 2899 */ 2900 void startSetupActivityLocked() { 2901 // Only do this once per boot. 2902 if (mCheckedForSetup) { 2903 return; 2904 } 2905 2906 // We will show this screen if the current one is a different 2907 // version than the last one shown, and we are not running in 2908 // low-level factory test mode. 2909 final ContentResolver resolver = mContext.getContentResolver(); 2910 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2911 Settings.Global.getInt(resolver, 2912 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2913 mCheckedForSetup = true; 2914 2915 // See if we should be showing the platform update setup UI. 2916 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2917 List<ResolveInfo> ris = mContext.getPackageManager() 2918 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2919 2920 // We don't allow third party apps to replace this. 2921 ResolveInfo ri = null; 2922 for (int i=0; ris != null && i<ris.size(); i++) { 2923 if ((ris.get(i).activityInfo.applicationInfo.flags 2924 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2925 ri = ris.get(i); 2926 break; 2927 } 2928 } 2929 2930 if (ri != null) { 2931 String vers = ri.activityInfo.metaData != null 2932 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2933 : null; 2934 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2935 vers = ri.activityInfo.applicationInfo.metaData.getString( 2936 Intent.METADATA_SETUP_VERSION); 2937 } 2938 String lastVers = Settings.Secure.getString( 2939 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2940 if (vers != null && !vers.equals(lastVers)) { 2941 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2942 intent.setComponent(new ComponentName( 2943 ri.activityInfo.packageName, ri.activityInfo.name)); 2944 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2945 null, null, 0, 0, 0, null, 0, null, false, null, null); 2946 } 2947 } 2948 } 2949 } 2950 2951 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 2952 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 2953 } 2954 2955 void enforceNotIsolatedCaller(String caller) { 2956 if (UserHandle.isIsolated(Binder.getCallingUid())) { 2957 throw new SecurityException("Isolated process not allowed to call " + caller); 2958 } 2959 } 2960 2961 @Override 2962 public int getFrontActivityScreenCompatMode() { 2963 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 2964 synchronized (this) { 2965 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 2966 } 2967 } 2968 2969 @Override 2970 public void setFrontActivityScreenCompatMode(int mode) { 2971 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2972 "setFrontActivityScreenCompatMode"); 2973 synchronized (this) { 2974 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 2975 } 2976 } 2977 2978 @Override 2979 public int getPackageScreenCompatMode(String packageName) { 2980 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 2981 synchronized (this) { 2982 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 2983 } 2984 } 2985 2986 @Override 2987 public void setPackageScreenCompatMode(String packageName, int mode) { 2988 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 2989 "setPackageScreenCompatMode"); 2990 synchronized (this) { 2991 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 2992 } 2993 } 2994 2995 @Override 2996 public boolean getPackageAskScreenCompat(String packageName) { 2997 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 2998 synchronized (this) { 2999 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3000 } 3001 } 3002 3003 @Override 3004 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3005 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3006 "setPackageAskScreenCompat"); 3007 synchronized (this) { 3008 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3009 } 3010 } 3011 3012 private void dispatchProcessesChanged() { 3013 int N; 3014 synchronized (this) { 3015 N = mPendingProcessChanges.size(); 3016 if (mActiveProcessChanges.length < N) { 3017 mActiveProcessChanges = new ProcessChangeItem[N]; 3018 } 3019 mPendingProcessChanges.toArray(mActiveProcessChanges); 3020 mAvailProcessChanges.addAll(mPendingProcessChanges); 3021 mPendingProcessChanges.clear(); 3022 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3023 } 3024 3025 int i = mProcessObservers.beginBroadcast(); 3026 while (i > 0) { 3027 i--; 3028 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3029 if (observer != null) { 3030 try { 3031 for (int j=0; j<N; j++) { 3032 ProcessChangeItem item = mActiveProcessChanges[j]; 3033 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3034 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3035 + item.pid + " uid=" + item.uid + ": " 3036 + item.foregroundActivities); 3037 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3038 item.foregroundActivities); 3039 } 3040 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3041 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3042 + item.pid + " uid=" + item.uid + ": " + item.importance); 3043 observer.onImportanceChanged(item.pid, item.uid, 3044 item.importance); 3045 } 3046 } 3047 } catch (RemoteException e) { 3048 } 3049 } 3050 } 3051 mProcessObservers.finishBroadcast(); 3052 } 3053 3054 private void dispatchProcessDied(int pid, int uid) { 3055 int i = mProcessObservers.beginBroadcast(); 3056 while (i > 0) { 3057 i--; 3058 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3059 if (observer != null) { 3060 try { 3061 observer.onProcessDied(pid, uid); 3062 } catch (RemoteException e) { 3063 } 3064 } 3065 } 3066 mProcessObservers.finishBroadcast(); 3067 } 3068 3069 final void doPendingActivityLaunchesLocked(boolean doResume) { 3070 final int N = mPendingActivityLaunches.size(); 3071 if (N <= 0) { 3072 return; 3073 } 3074 for (int i=0; i<N; i++) { 3075 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3076 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3077 doResume && i == (N-1), null); 3078 } 3079 mPendingActivityLaunches.clear(); 3080 } 3081 3082 @Override 3083 public final int startActivity(IApplicationThread caller, String callingPackage, 3084 Intent intent, String resolvedType, IBinder resultTo, 3085 String resultWho, int requestCode, int startFlags, 3086 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3087 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3088 resultWho, requestCode, 3089 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3090 } 3091 3092 @Override 3093 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3094 Intent intent, String resolvedType, IBinder resultTo, 3095 String resultWho, int requestCode, int startFlags, 3096 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3097 enforceNotIsolatedCaller("startActivity"); 3098 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3099 false, true, "startActivity", null); 3100 // TODO: Switch to user app stacks here. 3101 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3102 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3103 null, null, options, userId, null); 3104 } 3105 3106 @Override 3107 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3108 Intent intent, String resolvedType, IBinder resultTo, 3109 String resultWho, int requestCode, int startFlags, String profileFile, 3110 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3111 enforceNotIsolatedCaller("startActivityAndWait"); 3112 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3113 false, true, "startActivityAndWait", null); 3114 WaitResult res = new WaitResult(); 3115 // TODO: Switch to user app stacks here. 3116 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3117 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3118 res, null, options, UserHandle.getCallingUserId(), null); 3119 return res; 3120 } 3121 3122 @Override 3123 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3124 Intent intent, String resolvedType, IBinder resultTo, 3125 String resultWho, int requestCode, int startFlags, Configuration config, 3126 Bundle options, int userId) { 3127 enforceNotIsolatedCaller("startActivityWithConfig"); 3128 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3129 false, true, "startActivityWithConfig", null); 3130 // TODO: Switch to user app stacks here. 3131 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3132 resolvedType, resultTo, resultWho, requestCode, startFlags, 3133 null, null, null, config, options, userId, null); 3134 return ret; 3135 } 3136 3137 @Override 3138 public int startActivityIntentSender(IApplicationThread caller, 3139 IntentSender intent, Intent fillInIntent, String resolvedType, 3140 IBinder resultTo, String resultWho, int requestCode, 3141 int flagsMask, int flagsValues, Bundle options) { 3142 enforceNotIsolatedCaller("startActivityIntentSender"); 3143 // Refuse possible leaked file descriptors 3144 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3145 throw new IllegalArgumentException("File descriptors passed in Intent"); 3146 } 3147 3148 IIntentSender sender = intent.getTarget(); 3149 if (!(sender instanceof PendingIntentRecord)) { 3150 throw new IllegalArgumentException("Bad PendingIntent object"); 3151 } 3152 3153 PendingIntentRecord pir = (PendingIntentRecord)sender; 3154 3155 synchronized (this) { 3156 // If this is coming from the currently resumed activity, it is 3157 // effectively saying that app switches are allowed at this point. 3158 final ActivityStack stack = getFocusedStack(); 3159 if (stack.mResumedActivity != null && 3160 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3161 mAppSwitchesAllowedTime = 0; 3162 } 3163 } 3164 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3165 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3166 return ret; 3167 } 3168 3169 @Override 3170 public boolean startNextMatchingActivity(IBinder callingActivity, 3171 Intent intent, Bundle options) { 3172 // Refuse possible leaked file descriptors 3173 if (intent != null && intent.hasFileDescriptors() == true) { 3174 throw new IllegalArgumentException("File descriptors passed in Intent"); 3175 } 3176 3177 synchronized (this) { 3178 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3179 if (r == null) { 3180 ActivityOptions.abort(options); 3181 return false; 3182 } 3183 if (r.app == null || r.app.thread == null) { 3184 // The caller is not running... d'oh! 3185 ActivityOptions.abort(options); 3186 return false; 3187 } 3188 intent = new Intent(intent); 3189 // The caller is not allowed to change the data. 3190 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3191 // And we are resetting to find the next component... 3192 intent.setComponent(null); 3193 3194 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3195 3196 ActivityInfo aInfo = null; 3197 try { 3198 List<ResolveInfo> resolves = 3199 AppGlobals.getPackageManager().queryIntentActivities( 3200 intent, r.resolvedType, 3201 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3202 UserHandle.getCallingUserId()); 3203 3204 // Look for the original activity in the list... 3205 final int N = resolves != null ? resolves.size() : 0; 3206 for (int i=0; i<N; i++) { 3207 ResolveInfo rInfo = resolves.get(i); 3208 if (rInfo.activityInfo.packageName.equals(r.packageName) 3209 && rInfo.activityInfo.name.equals(r.info.name)) { 3210 // We found the current one... the next matching is 3211 // after it. 3212 i++; 3213 if (i<N) { 3214 aInfo = resolves.get(i).activityInfo; 3215 } 3216 if (debug) { 3217 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3218 + "/" + r.info.name); 3219 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3220 + "/" + aInfo.name); 3221 } 3222 break; 3223 } 3224 } 3225 } catch (RemoteException e) { 3226 } 3227 3228 if (aInfo == null) { 3229 // Nobody who is next! 3230 ActivityOptions.abort(options); 3231 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3232 return false; 3233 } 3234 3235 intent.setComponent(new ComponentName( 3236 aInfo.applicationInfo.packageName, aInfo.name)); 3237 intent.setFlags(intent.getFlags()&~( 3238 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3239 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3240 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3241 Intent.FLAG_ACTIVITY_NEW_TASK)); 3242 3243 // Okay now we need to start the new activity, replacing the 3244 // currently running activity. This is a little tricky because 3245 // we want to start the new one as if the current one is finished, 3246 // but not finish the current one first so that there is no flicker. 3247 // And thus... 3248 final boolean wasFinishing = r.finishing; 3249 r.finishing = true; 3250 3251 // Propagate reply information over to the new activity. 3252 final ActivityRecord resultTo = r.resultTo; 3253 final String resultWho = r.resultWho; 3254 final int requestCode = r.requestCode; 3255 r.resultTo = null; 3256 if (resultTo != null) { 3257 resultTo.removeResultsLocked(r, resultWho, requestCode); 3258 } 3259 3260 final long origId = Binder.clearCallingIdentity(); 3261 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3262 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3263 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3264 options, false, null, null); 3265 Binder.restoreCallingIdentity(origId); 3266 3267 r.finishing = wasFinishing; 3268 if (res != ActivityManager.START_SUCCESS) { 3269 return false; 3270 } 3271 return true; 3272 } 3273 } 3274 3275 final int startActivityInPackage(int uid, String callingPackage, 3276 Intent intent, String resolvedType, IBinder resultTo, 3277 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3278 IActivityContainer container) { 3279 3280 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3281 false, true, "startActivityInPackage", null); 3282 3283 // TODO: Switch to user app stacks here. 3284 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3285 resultTo, resultWho, requestCode, startFlags, 3286 null, null, null, null, options, userId, container); 3287 return ret; 3288 } 3289 3290 @Override 3291 public final int startActivities(IApplicationThread caller, String callingPackage, 3292 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3293 int userId) { 3294 enforceNotIsolatedCaller("startActivities"); 3295 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3296 false, true, "startActivity", null); 3297 // TODO: Switch to user app stacks here. 3298 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3299 resolvedTypes, resultTo, options, userId); 3300 return ret; 3301 } 3302 3303 final int startActivitiesInPackage(int uid, String callingPackage, 3304 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3305 Bundle options, int userId) { 3306 3307 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3308 false, true, "startActivityInPackage", null); 3309 // TODO: Switch to user app stacks here. 3310 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3311 resultTo, options, userId); 3312 return ret; 3313 } 3314 3315 final void addRecentTaskLocked(TaskRecord task) { 3316 int N = mRecentTasks.size(); 3317 // Quick case: check if the top-most recent task is the same. 3318 if (N > 0 && mRecentTasks.get(0) == task) { 3319 return; 3320 } 3321 // Remove any existing entries that are the same kind of task. 3322 final Intent intent = task.intent; 3323 final boolean document = intent != null && intent.isDocument(); 3324 for (int i=0; i<N; i++) { 3325 TaskRecord tr = mRecentTasks.get(i); 3326 if (task != tr) { 3327 if (task.userId != tr.userId) { 3328 continue; 3329 } 3330 final Intent trIntent = tr.intent; 3331 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3332 (intent == null || !intent.filterEquals(trIntent))) { 3333 continue; 3334 } 3335 if (document || trIntent != null && trIntent.isDocument()) { 3336 // Document tasks do not match other tasks. 3337 continue; 3338 } 3339 } 3340 3341 // Either task and tr are the same or, their affinities match or their intents match 3342 // and neither of them is a document. 3343 tr.disposeThumbnail(); 3344 mRecentTasks.remove(i); 3345 i--; 3346 N--; 3347 if (task.intent == null) { 3348 // If the new recent task we are adding is not fully 3349 // specified, then replace it with the existing recent task. 3350 task = tr; 3351 } 3352 } 3353 if (N >= MAX_RECENT_TASKS) { 3354 mRecentTasks.remove(N-1).disposeThumbnail(); 3355 } 3356 mRecentTasks.add(0, task); 3357 } 3358 3359 @Override 3360 public void reportActivityFullyDrawn(IBinder token) { 3361 synchronized (this) { 3362 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3363 if (r == null) { 3364 return; 3365 } 3366 r.reportFullyDrawnLocked(); 3367 } 3368 } 3369 3370 @Override 3371 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3372 synchronized (this) { 3373 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3374 if (r == null) { 3375 return; 3376 } 3377 final long origId = Binder.clearCallingIdentity(); 3378 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3379 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3380 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3381 if (config != null) { 3382 r.frozenBeforeDestroy = true; 3383 if (!updateConfigurationLocked(config, r, false, false)) { 3384 mStackSupervisor.resumeTopActivitiesLocked(); 3385 } 3386 } 3387 Binder.restoreCallingIdentity(origId); 3388 } 3389 } 3390 3391 @Override 3392 public int getRequestedOrientation(IBinder token) { 3393 synchronized (this) { 3394 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3395 if (r == null) { 3396 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3397 } 3398 return mWindowManager.getAppOrientation(r.appToken); 3399 } 3400 } 3401 3402 /** 3403 * This is the internal entry point for handling Activity.finish(). 3404 * 3405 * @param token The Binder token referencing the Activity we want to finish. 3406 * @param resultCode Result code, if any, from this Activity. 3407 * @param resultData Result data (Intent), if any, from this Activity. 3408 * 3409 * @return Returns true if the activity successfully finished, or false if it is still running. 3410 */ 3411 @Override 3412 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3413 // Refuse possible leaked file descriptors 3414 if (resultData != null && resultData.hasFileDescriptors() == true) { 3415 throw new IllegalArgumentException("File descriptors passed in Intent"); 3416 } 3417 3418 synchronized(this) { 3419 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3420 if (r == null) { 3421 return true; 3422 } 3423 if (mController != null) { 3424 // Find the first activity that is not finishing. 3425 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3426 if (next != null) { 3427 // ask watcher if this is allowed 3428 boolean resumeOK = true; 3429 try { 3430 resumeOK = mController.activityResuming(next.packageName); 3431 } catch (RemoteException e) { 3432 mController = null; 3433 Watchdog.getInstance().setActivityController(null); 3434 } 3435 3436 if (!resumeOK) { 3437 return false; 3438 } 3439 } 3440 } 3441 final long origId = Binder.clearCallingIdentity(); 3442 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3443 resultData, "app-request", true); 3444 Binder.restoreCallingIdentity(origId); 3445 return res; 3446 } 3447 } 3448 3449 @Override 3450 public final void finishHeavyWeightApp() { 3451 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3452 != PackageManager.PERMISSION_GRANTED) { 3453 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3454 + Binder.getCallingPid() 3455 + ", uid=" + Binder.getCallingUid() 3456 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3457 Slog.w(TAG, msg); 3458 throw new SecurityException(msg); 3459 } 3460 3461 synchronized(this) { 3462 if (mHeavyWeightProcess == null) { 3463 return; 3464 } 3465 3466 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3467 mHeavyWeightProcess.activities); 3468 for (int i=0; i<activities.size(); i++) { 3469 ActivityRecord r = activities.get(i); 3470 if (!r.finishing) { 3471 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3472 null, "finish-heavy", true); 3473 } 3474 } 3475 3476 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3477 mHeavyWeightProcess.userId, 0)); 3478 mHeavyWeightProcess = null; 3479 } 3480 } 3481 3482 @Override 3483 public void crashApplication(int uid, int initialPid, String packageName, 3484 String message) { 3485 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3486 != PackageManager.PERMISSION_GRANTED) { 3487 String msg = "Permission Denial: crashApplication() from pid=" 3488 + Binder.getCallingPid() 3489 + ", uid=" + Binder.getCallingUid() 3490 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3491 Slog.w(TAG, msg); 3492 throw new SecurityException(msg); 3493 } 3494 3495 synchronized(this) { 3496 ProcessRecord proc = null; 3497 3498 // Figure out which process to kill. We don't trust that initialPid 3499 // still has any relation to current pids, so must scan through the 3500 // list. 3501 synchronized (mPidsSelfLocked) { 3502 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3503 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3504 if (p.uid != uid) { 3505 continue; 3506 } 3507 if (p.pid == initialPid) { 3508 proc = p; 3509 break; 3510 } 3511 if (p.pkgList.containsKey(packageName)) { 3512 proc = p; 3513 } 3514 } 3515 } 3516 3517 if (proc == null) { 3518 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3519 + " initialPid=" + initialPid 3520 + " packageName=" + packageName); 3521 return; 3522 } 3523 3524 if (proc.thread != null) { 3525 if (proc.pid == Process.myPid()) { 3526 Log.w(TAG, "crashApplication: trying to crash self!"); 3527 return; 3528 } 3529 long ident = Binder.clearCallingIdentity(); 3530 try { 3531 proc.thread.scheduleCrash(message); 3532 } catch (RemoteException e) { 3533 } 3534 Binder.restoreCallingIdentity(ident); 3535 } 3536 } 3537 } 3538 3539 @Override 3540 public final void finishSubActivity(IBinder token, String resultWho, 3541 int requestCode) { 3542 synchronized(this) { 3543 final long origId = Binder.clearCallingIdentity(); 3544 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3545 if (r != null) { 3546 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3547 } 3548 Binder.restoreCallingIdentity(origId); 3549 } 3550 } 3551 3552 @Override 3553 public boolean finishActivityAffinity(IBinder token) { 3554 synchronized(this) { 3555 final long origId = Binder.clearCallingIdentity(); 3556 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3557 boolean res = false; 3558 if (r != null) { 3559 res = r.task.stack.finishActivityAffinityLocked(r); 3560 } 3561 Binder.restoreCallingIdentity(origId); 3562 return res; 3563 } 3564 } 3565 3566 @Override 3567 public boolean willActivityBeVisible(IBinder token) { 3568 synchronized(this) { 3569 ActivityStack stack = ActivityRecord.getStackLocked(token); 3570 if (stack != null) { 3571 return stack.willActivityBeVisibleLocked(token); 3572 } 3573 return false; 3574 } 3575 } 3576 3577 @Override 3578 public void overridePendingTransition(IBinder token, String packageName, 3579 int enterAnim, int exitAnim) { 3580 synchronized(this) { 3581 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3582 if (self == null) { 3583 return; 3584 } 3585 3586 final long origId = Binder.clearCallingIdentity(); 3587 3588 if (self.state == ActivityState.RESUMED 3589 || self.state == ActivityState.PAUSING) { 3590 mWindowManager.overridePendingAppTransition(packageName, 3591 enterAnim, exitAnim, null); 3592 } 3593 3594 Binder.restoreCallingIdentity(origId); 3595 } 3596 } 3597 3598 /** 3599 * Main function for removing an existing process from the activity manager 3600 * as a result of that process going away. Clears out all connections 3601 * to the process. 3602 */ 3603 private final void handleAppDiedLocked(ProcessRecord app, 3604 boolean restarting, boolean allowRestart) { 3605 int pid = app.pid; 3606 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3607 if (!restarting) { 3608 removeLruProcessLocked(app); 3609 if (pid > 0) { 3610 ProcessList.remove(pid); 3611 } 3612 } 3613 3614 if (mProfileProc == app) { 3615 clearProfilerLocked(); 3616 } 3617 3618 // Remove this application's activities from active lists. 3619 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3620 3621 app.activities.clear(); 3622 3623 if (app.instrumentationClass != null) { 3624 Slog.w(TAG, "Crash of app " + app.processName 3625 + " running instrumentation " + app.instrumentationClass); 3626 Bundle info = new Bundle(); 3627 info.putString("shortMsg", "Process crashed."); 3628 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3629 } 3630 3631 if (!restarting) { 3632 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3633 // If there was nothing to resume, and we are not already 3634 // restarting this process, but there is a visible activity that 3635 // is hosted by the process... then make sure all visible 3636 // activities are running, taking care of restarting this 3637 // process. 3638 if (hasVisibleActivities) { 3639 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3640 } 3641 } 3642 } 3643 } 3644 3645 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3646 IBinder threadBinder = thread.asBinder(); 3647 // Find the application record. 3648 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3649 ProcessRecord rec = mLruProcesses.get(i); 3650 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3651 return i; 3652 } 3653 } 3654 return -1; 3655 } 3656 3657 final ProcessRecord getRecordForAppLocked( 3658 IApplicationThread thread) { 3659 if (thread == null) { 3660 return null; 3661 } 3662 3663 int appIndex = getLRURecordIndexForAppLocked(thread); 3664 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3665 } 3666 3667 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3668 // If there are no longer any background processes running, 3669 // and the app that died was not running instrumentation, 3670 // then tell everyone we are now low on memory. 3671 boolean haveBg = false; 3672 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3673 ProcessRecord rec = mLruProcesses.get(i); 3674 if (rec.thread != null 3675 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3676 haveBg = true; 3677 break; 3678 } 3679 } 3680 3681 if (!haveBg) { 3682 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3683 if (doReport) { 3684 long now = SystemClock.uptimeMillis(); 3685 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3686 doReport = false; 3687 } else { 3688 mLastMemUsageReportTime = now; 3689 } 3690 } 3691 final ArrayList<ProcessMemInfo> memInfos 3692 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3693 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3694 long now = SystemClock.uptimeMillis(); 3695 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3696 ProcessRecord rec = mLruProcesses.get(i); 3697 if (rec == dyingProc || rec.thread == null) { 3698 continue; 3699 } 3700 if (doReport) { 3701 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3702 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3703 } 3704 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3705 // The low memory report is overriding any current 3706 // state for a GC request. Make sure to do 3707 // heavy/important/visible/foreground processes first. 3708 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3709 rec.lastRequestedGc = 0; 3710 } else { 3711 rec.lastRequestedGc = rec.lastLowMemory; 3712 } 3713 rec.reportLowMemory = true; 3714 rec.lastLowMemory = now; 3715 mProcessesToGc.remove(rec); 3716 addProcessToGcListLocked(rec); 3717 } 3718 } 3719 if (doReport) { 3720 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3721 mHandler.sendMessage(msg); 3722 } 3723 scheduleAppGcsLocked(); 3724 } 3725 } 3726 3727 final void appDiedLocked(ProcessRecord app, int pid, 3728 IApplicationThread thread) { 3729 3730 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3731 synchronized (stats) { 3732 stats.noteProcessDiedLocked(app.info.uid, pid); 3733 } 3734 3735 // Clean up already done if the process has been re-started. 3736 if (app.pid == pid && app.thread != null && 3737 app.thread.asBinder() == thread.asBinder()) { 3738 boolean doLowMem = app.instrumentationClass == null; 3739 boolean doOomAdj = doLowMem; 3740 if (!app.killedByAm) { 3741 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3742 + ") has died."); 3743 mAllowLowerMemLevel = true; 3744 } else { 3745 // Note that we always want to do oom adj to update our state with the 3746 // new number of procs. 3747 mAllowLowerMemLevel = false; 3748 doLowMem = false; 3749 } 3750 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3751 if (DEBUG_CLEANUP) Slog.v( 3752 TAG, "Dying app: " + app + ", pid: " + pid 3753 + ", thread: " + thread.asBinder()); 3754 handleAppDiedLocked(app, false, true); 3755 3756 if (doOomAdj) { 3757 updateOomAdjLocked(); 3758 } 3759 if (doLowMem) { 3760 doLowMemReportIfNeededLocked(app); 3761 } 3762 } else if (app.pid != pid) { 3763 // A new process has already been started. 3764 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3765 + ") has died and restarted (pid " + app.pid + ")."); 3766 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3767 } else if (DEBUG_PROCESSES) { 3768 Slog.d(TAG, "Received spurious death notification for thread " 3769 + thread.asBinder()); 3770 } 3771 } 3772 3773 /** 3774 * If a stack trace dump file is configured, dump process stack traces. 3775 * @param clearTraces causes the dump file to be erased prior to the new 3776 * traces being written, if true; when false, the new traces will be 3777 * appended to any existing file content. 3778 * @param firstPids of dalvik VM processes to dump stack traces for first 3779 * @param lastPids of dalvik VM processes to dump stack traces for last 3780 * @param nativeProcs optional list of native process names to dump stack crawls 3781 * @return file containing stack traces, or null if no dump file is configured 3782 */ 3783 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3784 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3785 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3786 if (tracesPath == null || tracesPath.length() == 0) { 3787 return null; 3788 } 3789 3790 File tracesFile = new File(tracesPath); 3791 try { 3792 File tracesDir = tracesFile.getParentFile(); 3793 if (!tracesDir.exists()) { 3794 tracesFile.mkdirs(); 3795 if (!SELinux.restorecon(tracesDir)) { 3796 return null; 3797 } 3798 } 3799 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3800 3801 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3802 tracesFile.createNewFile(); 3803 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3804 } catch (IOException e) { 3805 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3806 return null; 3807 } 3808 3809 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3810 return tracesFile; 3811 } 3812 3813 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3814 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3815 // Use a FileObserver to detect when traces finish writing. 3816 // The order of traces is considered important to maintain for legibility. 3817 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3818 @Override 3819 public synchronized void onEvent(int event, String path) { notify(); } 3820 }; 3821 3822 try { 3823 observer.startWatching(); 3824 3825 // First collect all of the stacks of the most important pids. 3826 if (firstPids != null) { 3827 try { 3828 int num = firstPids.size(); 3829 for (int i = 0; i < num; i++) { 3830 synchronized (observer) { 3831 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3832 observer.wait(200); // Wait for write-close, give up after 200msec 3833 } 3834 } 3835 } catch (InterruptedException e) { 3836 Log.wtf(TAG, e); 3837 } 3838 } 3839 3840 // Next collect the stacks of the native pids 3841 if (nativeProcs != null) { 3842 int[] pids = Process.getPidsForCommands(nativeProcs); 3843 if (pids != null) { 3844 for (int pid : pids) { 3845 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3846 } 3847 } 3848 } 3849 3850 // Lastly, measure CPU usage. 3851 if (processCpuTracker != null) { 3852 processCpuTracker.init(); 3853 System.gc(); 3854 processCpuTracker.update(); 3855 try { 3856 synchronized (processCpuTracker) { 3857 processCpuTracker.wait(500); // measure over 1/2 second. 3858 } 3859 } catch (InterruptedException e) { 3860 } 3861 processCpuTracker.update(); 3862 3863 // We'll take the stack crawls of just the top apps using CPU. 3864 final int N = processCpuTracker.countWorkingStats(); 3865 int numProcs = 0; 3866 for (int i=0; i<N && numProcs<5; i++) { 3867 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3868 if (lastPids.indexOfKey(stats.pid) >= 0) { 3869 numProcs++; 3870 try { 3871 synchronized (observer) { 3872 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3873 observer.wait(200); // Wait for write-close, give up after 200msec 3874 } 3875 } catch (InterruptedException e) { 3876 Log.wtf(TAG, e); 3877 } 3878 3879 } 3880 } 3881 } 3882 } finally { 3883 observer.stopWatching(); 3884 } 3885 } 3886 3887 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3888 if (true || IS_USER_BUILD) { 3889 return; 3890 } 3891 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3892 if (tracesPath == null || tracesPath.length() == 0) { 3893 return; 3894 } 3895 3896 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3897 StrictMode.allowThreadDiskWrites(); 3898 try { 3899 final File tracesFile = new File(tracesPath); 3900 final File tracesDir = tracesFile.getParentFile(); 3901 final File tracesTmp = new File(tracesDir, "__tmp__"); 3902 try { 3903 if (!tracesDir.exists()) { 3904 tracesFile.mkdirs(); 3905 if (!SELinux.restorecon(tracesDir.getPath())) { 3906 return; 3907 } 3908 } 3909 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3910 3911 if (tracesFile.exists()) { 3912 tracesTmp.delete(); 3913 tracesFile.renameTo(tracesTmp); 3914 } 3915 StringBuilder sb = new StringBuilder(); 3916 Time tobj = new Time(); 3917 tobj.set(System.currentTimeMillis()); 3918 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3919 sb.append(": "); 3920 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3921 sb.append(" since "); 3922 sb.append(msg); 3923 FileOutputStream fos = new FileOutputStream(tracesFile); 3924 fos.write(sb.toString().getBytes()); 3925 if (app == null) { 3926 fos.write("\n*** No application process!".getBytes()); 3927 } 3928 fos.close(); 3929 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3930 } catch (IOException e) { 3931 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3932 return; 3933 } 3934 3935 if (app != null) { 3936 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3937 firstPids.add(app.pid); 3938 dumpStackTraces(tracesPath, firstPids, null, null, null); 3939 } 3940 3941 File lastTracesFile = null; 3942 File curTracesFile = null; 3943 for (int i=9; i>=0; i--) { 3944 String name = String.format(Locale.US, "slow%02d.txt", i); 3945 curTracesFile = new File(tracesDir, name); 3946 if (curTracesFile.exists()) { 3947 if (lastTracesFile != null) { 3948 curTracesFile.renameTo(lastTracesFile); 3949 } else { 3950 curTracesFile.delete(); 3951 } 3952 } 3953 lastTracesFile = curTracesFile; 3954 } 3955 tracesFile.renameTo(curTracesFile); 3956 if (tracesTmp.exists()) { 3957 tracesTmp.renameTo(tracesFile); 3958 } 3959 } finally { 3960 StrictMode.setThreadPolicy(oldPolicy); 3961 } 3962 } 3963 3964 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 3965 ActivityRecord parent, boolean aboveSystem, final String annotation) { 3966 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 3967 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 3968 3969 if (mController != null) { 3970 try { 3971 // 0 == continue, -1 = kill process immediately 3972 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 3973 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 3974 } catch (RemoteException e) { 3975 mController = null; 3976 Watchdog.getInstance().setActivityController(null); 3977 } 3978 } 3979 3980 long anrTime = SystemClock.uptimeMillis(); 3981 if (MONITOR_CPU_USAGE) { 3982 updateCpuStatsNow(); 3983 } 3984 3985 synchronized (this) { 3986 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 3987 if (mShuttingDown) { 3988 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 3989 return; 3990 } else if (app.notResponding) { 3991 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 3992 return; 3993 } else if (app.crashing) { 3994 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 3995 return; 3996 } 3997 3998 // In case we come through here for the same app before completing 3999 // this one, mark as anring now so we will bail out. 4000 app.notResponding = true; 4001 4002 // Log the ANR to the event log. 4003 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4004 app.processName, app.info.flags, annotation); 4005 4006 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4007 firstPids.add(app.pid); 4008 4009 int parentPid = app.pid; 4010 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4011 if (parentPid != app.pid) firstPids.add(parentPid); 4012 4013 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4014 4015 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4016 ProcessRecord r = mLruProcesses.get(i); 4017 if (r != null && r.thread != null) { 4018 int pid = r.pid; 4019 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4020 if (r.persistent) { 4021 firstPids.add(pid); 4022 } else { 4023 lastPids.put(pid, Boolean.TRUE); 4024 } 4025 } 4026 } 4027 } 4028 } 4029 4030 // Log the ANR to the main log. 4031 StringBuilder info = new StringBuilder(); 4032 info.setLength(0); 4033 info.append("ANR in ").append(app.processName); 4034 if (activity != null && activity.shortComponentName != null) { 4035 info.append(" (").append(activity.shortComponentName).append(")"); 4036 } 4037 info.append("\n"); 4038 info.append("PID: ").append(app.pid).append("\n"); 4039 if (annotation != null) { 4040 info.append("Reason: ").append(annotation).append("\n"); 4041 } 4042 if (parent != null && parent != activity) { 4043 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4044 } 4045 4046 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4047 4048 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4049 NATIVE_STACKS_OF_INTEREST); 4050 4051 String cpuInfo = null; 4052 if (MONITOR_CPU_USAGE) { 4053 updateCpuStatsNow(); 4054 synchronized (mProcessCpuThread) { 4055 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4056 } 4057 info.append(processCpuTracker.printCurrentLoad()); 4058 info.append(cpuInfo); 4059 } 4060 4061 info.append(processCpuTracker.printCurrentState(anrTime)); 4062 4063 Slog.e(TAG, info.toString()); 4064 if (tracesFile == null) { 4065 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4066 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4067 } 4068 4069 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4070 cpuInfo, tracesFile, null); 4071 4072 if (mController != null) { 4073 try { 4074 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4075 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4076 if (res != 0) { 4077 if (res < 0 && app.pid != MY_PID) { 4078 Process.killProcess(app.pid); 4079 } else { 4080 synchronized (this) { 4081 mServices.scheduleServiceTimeoutLocked(app); 4082 } 4083 } 4084 return; 4085 } 4086 } catch (RemoteException e) { 4087 mController = null; 4088 Watchdog.getInstance().setActivityController(null); 4089 } 4090 } 4091 4092 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4093 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4094 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4095 4096 synchronized (this) { 4097 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4098 killUnneededProcessLocked(app, "background ANR"); 4099 return; 4100 } 4101 4102 // Set the app's notResponding state, and look up the errorReportReceiver 4103 makeAppNotRespondingLocked(app, 4104 activity != null ? activity.shortComponentName : null, 4105 annotation != null ? "ANR " + annotation : "ANR", 4106 info.toString()); 4107 4108 // Bring up the infamous App Not Responding dialog 4109 Message msg = Message.obtain(); 4110 HashMap<String, Object> map = new HashMap<String, Object>(); 4111 msg.what = SHOW_NOT_RESPONDING_MSG; 4112 msg.obj = map; 4113 msg.arg1 = aboveSystem ? 1 : 0; 4114 map.put("app", app); 4115 if (activity != null) { 4116 map.put("activity", activity); 4117 } 4118 4119 mHandler.sendMessage(msg); 4120 } 4121 } 4122 4123 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4124 if (!mLaunchWarningShown) { 4125 mLaunchWarningShown = true; 4126 mHandler.post(new Runnable() { 4127 @Override 4128 public void run() { 4129 synchronized (ActivityManagerService.this) { 4130 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4131 d.show(); 4132 mHandler.postDelayed(new Runnable() { 4133 @Override 4134 public void run() { 4135 synchronized (ActivityManagerService.this) { 4136 d.dismiss(); 4137 mLaunchWarningShown = false; 4138 } 4139 } 4140 }, 4000); 4141 } 4142 } 4143 }); 4144 } 4145 } 4146 4147 @Override 4148 public boolean clearApplicationUserData(final String packageName, 4149 final IPackageDataObserver observer, int userId) { 4150 enforceNotIsolatedCaller("clearApplicationUserData"); 4151 int uid = Binder.getCallingUid(); 4152 int pid = Binder.getCallingPid(); 4153 userId = handleIncomingUser(pid, uid, 4154 userId, false, true, "clearApplicationUserData", null); 4155 long callingId = Binder.clearCallingIdentity(); 4156 try { 4157 IPackageManager pm = AppGlobals.getPackageManager(); 4158 int pkgUid = -1; 4159 synchronized(this) { 4160 try { 4161 pkgUid = pm.getPackageUid(packageName, userId); 4162 } catch (RemoteException e) { 4163 } 4164 if (pkgUid == -1) { 4165 Slog.w(TAG, "Invalid packageName: " + packageName); 4166 if (observer != null) { 4167 try { 4168 observer.onRemoveCompleted(packageName, false); 4169 } catch (RemoteException e) { 4170 Slog.i(TAG, "Observer no longer exists."); 4171 } 4172 } 4173 return false; 4174 } 4175 if (uid == pkgUid || checkComponentPermission( 4176 android.Manifest.permission.CLEAR_APP_USER_DATA, 4177 pid, uid, -1, true) 4178 == PackageManager.PERMISSION_GRANTED) { 4179 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4180 } else { 4181 throw new SecurityException("PID " + pid + " does not have permission " 4182 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4183 + " of package " + packageName); 4184 } 4185 } 4186 4187 try { 4188 // Clear application user data 4189 pm.clearApplicationUserData(packageName, observer, userId); 4190 4191 // Remove all permissions granted from/to this package 4192 removeUriPermissionsForPackageLocked(packageName, userId, true); 4193 4194 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4195 Uri.fromParts("package", packageName, null)); 4196 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4197 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4198 null, null, 0, null, null, null, false, false, userId); 4199 } catch (RemoteException e) { 4200 } 4201 } finally { 4202 Binder.restoreCallingIdentity(callingId); 4203 } 4204 return true; 4205 } 4206 4207 @Override 4208 public void killBackgroundProcesses(final String packageName, int userId) { 4209 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4210 != PackageManager.PERMISSION_GRANTED && 4211 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4212 != PackageManager.PERMISSION_GRANTED) { 4213 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4214 + Binder.getCallingPid() 4215 + ", uid=" + Binder.getCallingUid() 4216 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4217 Slog.w(TAG, msg); 4218 throw new SecurityException(msg); 4219 } 4220 4221 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4222 userId, true, true, "killBackgroundProcesses", null); 4223 long callingId = Binder.clearCallingIdentity(); 4224 try { 4225 IPackageManager pm = AppGlobals.getPackageManager(); 4226 synchronized(this) { 4227 int appId = -1; 4228 try { 4229 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4230 } catch (RemoteException e) { 4231 } 4232 if (appId == -1) { 4233 Slog.w(TAG, "Invalid packageName: " + packageName); 4234 return; 4235 } 4236 killPackageProcessesLocked(packageName, appId, userId, 4237 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4238 } 4239 } finally { 4240 Binder.restoreCallingIdentity(callingId); 4241 } 4242 } 4243 4244 @Override 4245 public void killAllBackgroundProcesses() { 4246 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4247 != PackageManager.PERMISSION_GRANTED) { 4248 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4249 + Binder.getCallingPid() 4250 + ", uid=" + Binder.getCallingUid() 4251 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4252 Slog.w(TAG, msg); 4253 throw new SecurityException(msg); 4254 } 4255 4256 long callingId = Binder.clearCallingIdentity(); 4257 try { 4258 synchronized(this) { 4259 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4260 final int NP = mProcessNames.getMap().size(); 4261 for (int ip=0; ip<NP; ip++) { 4262 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4263 final int NA = apps.size(); 4264 for (int ia=0; ia<NA; ia++) { 4265 ProcessRecord app = apps.valueAt(ia); 4266 if (app.persistent) { 4267 // we don't kill persistent processes 4268 continue; 4269 } 4270 if (app.removed) { 4271 procs.add(app); 4272 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4273 app.removed = true; 4274 procs.add(app); 4275 } 4276 } 4277 } 4278 4279 int N = procs.size(); 4280 for (int i=0; i<N; i++) { 4281 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4282 } 4283 mAllowLowerMemLevel = true; 4284 updateOomAdjLocked(); 4285 doLowMemReportIfNeededLocked(null); 4286 } 4287 } finally { 4288 Binder.restoreCallingIdentity(callingId); 4289 } 4290 } 4291 4292 @Override 4293 public void forceStopPackage(final String packageName, int userId) { 4294 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4295 != PackageManager.PERMISSION_GRANTED) { 4296 String msg = "Permission Denial: forceStopPackage() from pid=" 4297 + Binder.getCallingPid() 4298 + ", uid=" + Binder.getCallingUid() 4299 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4300 Slog.w(TAG, msg); 4301 throw new SecurityException(msg); 4302 } 4303 final int callingPid = Binder.getCallingPid(); 4304 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4305 userId, true, true, "forceStopPackage", null); 4306 long callingId = Binder.clearCallingIdentity(); 4307 try { 4308 IPackageManager pm = AppGlobals.getPackageManager(); 4309 synchronized(this) { 4310 int[] users = userId == UserHandle.USER_ALL 4311 ? getUsersLocked() : new int[] { userId }; 4312 for (int user : users) { 4313 int pkgUid = -1; 4314 try { 4315 pkgUid = pm.getPackageUid(packageName, user); 4316 } catch (RemoteException e) { 4317 } 4318 if (pkgUid == -1) { 4319 Slog.w(TAG, "Invalid packageName: " + packageName); 4320 continue; 4321 } 4322 try { 4323 pm.setPackageStoppedState(packageName, true, user); 4324 } catch (RemoteException e) { 4325 } catch (IllegalArgumentException e) { 4326 Slog.w(TAG, "Failed trying to unstop package " 4327 + packageName + ": " + e); 4328 } 4329 if (isUserRunningLocked(user, false)) { 4330 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4331 } 4332 } 4333 } 4334 } finally { 4335 Binder.restoreCallingIdentity(callingId); 4336 } 4337 } 4338 4339 /* 4340 * The pkg name and app id have to be specified. 4341 */ 4342 @Override 4343 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4344 if (pkg == null) { 4345 return; 4346 } 4347 // Make sure the uid is valid. 4348 if (appid < 0) { 4349 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4350 return; 4351 } 4352 int callerUid = Binder.getCallingUid(); 4353 // Only the system server can kill an application 4354 if (callerUid == Process.SYSTEM_UID) { 4355 // Post an aysnc message to kill the application 4356 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4357 msg.arg1 = appid; 4358 msg.arg2 = 0; 4359 Bundle bundle = new Bundle(); 4360 bundle.putString("pkg", pkg); 4361 bundle.putString("reason", reason); 4362 msg.obj = bundle; 4363 mHandler.sendMessage(msg); 4364 } else { 4365 throw new SecurityException(callerUid + " cannot kill pkg: " + 4366 pkg); 4367 } 4368 } 4369 4370 @Override 4371 public void closeSystemDialogs(String reason) { 4372 enforceNotIsolatedCaller("closeSystemDialogs"); 4373 4374 final int pid = Binder.getCallingPid(); 4375 final int uid = Binder.getCallingUid(); 4376 final long origId = Binder.clearCallingIdentity(); 4377 try { 4378 synchronized (this) { 4379 // Only allow this from foreground processes, so that background 4380 // applications can't abuse it to prevent system UI from being shown. 4381 if (uid >= Process.FIRST_APPLICATION_UID) { 4382 ProcessRecord proc; 4383 synchronized (mPidsSelfLocked) { 4384 proc = mPidsSelfLocked.get(pid); 4385 } 4386 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4387 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4388 + " from background process " + proc); 4389 return; 4390 } 4391 } 4392 closeSystemDialogsLocked(reason); 4393 } 4394 } finally { 4395 Binder.restoreCallingIdentity(origId); 4396 } 4397 } 4398 4399 void closeSystemDialogsLocked(String reason) { 4400 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4401 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4402 | Intent.FLAG_RECEIVER_FOREGROUND); 4403 if (reason != null) { 4404 intent.putExtra("reason", reason); 4405 } 4406 mWindowManager.closeSystemDialogs(reason); 4407 4408 mStackSupervisor.closeSystemDialogsLocked(); 4409 4410 broadcastIntentLocked(null, null, intent, null, 4411 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4412 Process.SYSTEM_UID, UserHandle.USER_ALL); 4413 } 4414 4415 @Override 4416 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4417 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4418 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4419 for (int i=pids.length-1; i>=0; i--) { 4420 ProcessRecord proc; 4421 int oomAdj; 4422 synchronized (this) { 4423 synchronized (mPidsSelfLocked) { 4424 proc = mPidsSelfLocked.get(pids[i]); 4425 oomAdj = proc != null ? proc.setAdj : 0; 4426 } 4427 } 4428 infos[i] = new Debug.MemoryInfo(); 4429 Debug.getMemoryInfo(pids[i], infos[i]); 4430 if (proc != null) { 4431 synchronized (this) { 4432 if (proc.thread != null && proc.setAdj == oomAdj) { 4433 // Record this for posterity if the process has been stable. 4434 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4435 infos[i].getTotalUss(), false, proc.pkgList); 4436 } 4437 } 4438 } 4439 } 4440 return infos; 4441 } 4442 4443 @Override 4444 public long[] getProcessPss(int[] pids) { 4445 enforceNotIsolatedCaller("getProcessPss"); 4446 long[] pss = new long[pids.length]; 4447 for (int i=pids.length-1; i>=0; i--) { 4448 ProcessRecord proc; 4449 int oomAdj; 4450 synchronized (this) { 4451 synchronized (mPidsSelfLocked) { 4452 proc = mPidsSelfLocked.get(pids[i]); 4453 oomAdj = proc != null ? proc.setAdj : 0; 4454 } 4455 } 4456 long[] tmpUss = new long[1]; 4457 pss[i] = Debug.getPss(pids[i], tmpUss); 4458 if (proc != null) { 4459 synchronized (this) { 4460 if (proc.thread != null && proc.setAdj == oomAdj) { 4461 // Record this for posterity if the process has been stable. 4462 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4463 } 4464 } 4465 } 4466 } 4467 return pss; 4468 } 4469 4470 @Override 4471 public void killApplicationProcess(String processName, int uid) { 4472 if (processName == null) { 4473 return; 4474 } 4475 4476 int callerUid = Binder.getCallingUid(); 4477 // Only the system server can kill an application 4478 if (callerUid == Process.SYSTEM_UID) { 4479 synchronized (this) { 4480 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4481 if (app != null && app.thread != null) { 4482 try { 4483 app.thread.scheduleSuicide(); 4484 } catch (RemoteException e) { 4485 // If the other end already died, then our work here is done. 4486 } 4487 } else { 4488 Slog.w(TAG, "Process/uid not found attempting kill of " 4489 + processName + " / " + uid); 4490 } 4491 } 4492 } else { 4493 throw new SecurityException(callerUid + " cannot kill app process: " + 4494 processName); 4495 } 4496 } 4497 4498 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4499 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4500 false, true, false, false, UserHandle.getUserId(uid), reason); 4501 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4502 Uri.fromParts("package", packageName, null)); 4503 if (!mProcessesReady) { 4504 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4505 | Intent.FLAG_RECEIVER_FOREGROUND); 4506 } 4507 intent.putExtra(Intent.EXTRA_UID, uid); 4508 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4509 broadcastIntentLocked(null, null, intent, 4510 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4511 false, false, 4512 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4513 } 4514 4515 private void forceStopUserLocked(int userId, String reason) { 4516 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4517 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4518 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4519 | Intent.FLAG_RECEIVER_FOREGROUND); 4520 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4521 broadcastIntentLocked(null, null, intent, 4522 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4523 false, false, 4524 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4525 } 4526 4527 private final boolean killPackageProcessesLocked(String packageName, int appId, 4528 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4529 boolean doit, boolean evenPersistent, String reason) { 4530 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4531 4532 // Remove all processes this package may have touched: all with the 4533 // same UID (except for the system or root user), and all whose name 4534 // matches the package name. 4535 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4536 final int NP = mProcessNames.getMap().size(); 4537 for (int ip=0; ip<NP; ip++) { 4538 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4539 final int NA = apps.size(); 4540 for (int ia=0; ia<NA; ia++) { 4541 ProcessRecord app = apps.valueAt(ia); 4542 if (app.persistent && !evenPersistent) { 4543 // we don't kill persistent processes 4544 continue; 4545 } 4546 if (app.removed) { 4547 if (doit) { 4548 procs.add(app); 4549 } 4550 continue; 4551 } 4552 4553 // Skip process if it doesn't meet our oom adj requirement. 4554 if (app.setAdj < minOomAdj) { 4555 continue; 4556 } 4557 4558 // If no package is specified, we call all processes under the 4559 // give user id. 4560 if (packageName == null) { 4561 if (app.userId != userId) { 4562 continue; 4563 } 4564 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4565 continue; 4566 } 4567 // Package has been specified, we want to hit all processes 4568 // that match it. We need to qualify this by the processes 4569 // that are running under the specified app and user ID. 4570 } else { 4571 if (UserHandle.getAppId(app.uid) != appId) { 4572 continue; 4573 } 4574 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4575 continue; 4576 } 4577 if (!app.pkgList.containsKey(packageName)) { 4578 continue; 4579 } 4580 } 4581 4582 // Process has passed all conditions, kill it! 4583 if (!doit) { 4584 return true; 4585 } 4586 app.removed = true; 4587 procs.add(app); 4588 } 4589 } 4590 4591 int N = procs.size(); 4592 for (int i=0; i<N; i++) { 4593 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4594 } 4595 updateOomAdjLocked(); 4596 return N > 0; 4597 } 4598 4599 private final boolean forceStopPackageLocked(String name, int appId, 4600 boolean callerWillRestart, boolean purgeCache, boolean doit, 4601 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4602 int i; 4603 int N; 4604 4605 if (userId == UserHandle.USER_ALL && name == null) { 4606 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4607 } 4608 4609 if (appId < 0 && name != null) { 4610 try { 4611 appId = UserHandle.getAppId( 4612 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4613 } catch (RemoteException e) { 4614 } 4615 } 4616 4617 if (doit) { 4618 if (name != null) { 4619 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4620 + " user=" + userId + ": " + reason); 4621 } else { 4622 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4623 } 4624 4625 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4626 for (int ip=pmap.size()-1; ip>=0; ip--) { 4627 SparseArray<Long> ba = pmap.valueAt(ip); 4628 for (i=ba.size()-1; i>=0; i--) { 4629 boolean remove = false; 4630 final int entUid = ba.keyAt(i); 4631 if (name != null) { 4632 if (userId == UserHandle.USER_ALL) { 4633 if (UserHandle.getAppId(entUid) == appId) { 4634 remove = true; 4635 } 4636 } else { 4637 if (entUid == UserHandle.getUid(userId, appId)) { 4638 remove = true; 4639 } 4640 } 4641 } else if (UserHandle.getUserId(entUid) == userId) { 4642 remove = true; 4643 } 4644 if (remove) { 4645 ba.removeAt(i); 4646 } 4647 } 4648 if (ba.size() == 0) { 4649 pmap.removeAt(ip); 4650 } 4651 } 4652 } 4653 4654 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4655 -100, callerWillRestart, true, doit, evenPersistent, 4656 name == null ? ("stop user " + userId) : ("stop " + name)); 4657 4658 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4659 if (!doit) { 4660 return true; 4661 } 4662 didSomething = true; 4663 } 4664 4665 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4666 if (!doit) { 4667 return true; 4668 } 4669 didSomething = true; 4670 } 4671 4672 if (name == null) { 4673 // Remove all sticky broadcasts from this user. 4674 mStickyBroadcasts.remove(userId); 4675 } 4676 4677 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4678 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4679 userId, providers)) { 4680 if (!doit) { 4681 return true; 4682 } 4683 didSomething = true; 4684 } 4685 N = providers.size(); 4686 for (i=0; i<N; i++) { 4687 removeDyingProviderLocked(null, providers.get(i), true); 4688 } 4689 4690 // Remove transient permissions granted from/to this package/user 4691 removeUriPermissionsForPackageLocked(name, userId, false); 4692 4693 if (name == null || uninstalling) { 4694 // Remove pending intents. For now we only do this when force 4695 // stopping users, because we have some problems when doing this 4696 // for packages -- app widgets are not currently cleaned up for 4697 // such packages, so they can be left with bad pending intents. 4698 if (mIntentSenderRecords.size() > 0) { 4699 Iterator<WeakReference<PendingIntentRecord>> it 4700 = mIntentSenderRecords.values().iterator(); 4701 while (it.hasNext()) { 4702 WeakReference<PendingIntentRecord> wpir = it.next(); 4703 if (wpir == null) { 4704 it.remove(); 4705 continue; 4706 } 4707 PendingIntentRecord pir = wpir.get(); 4708 if (pir == null) { 4709 it.remove(); 4710 continue; 4711 } 4712 if (name == null) { 4713 // Stopping user, remove all objects for the user. 4714 if (pir.key.userId != userId) { 4715 // Not the same user, skip it. 4716 continue; 4717 } 4718 } else { 4719 if (UserHandle.getAppId(pir.uid) != appId) { 4720 // Different app id, skip it. 4721 continue; 4722 } 4723 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4724 // Different user, skip it. 4725 continue; 4726 } 4727 if (!pir.key.packageName.equals(name)) { 4728 // Different package, skip it. 4729 continue; 4730 } 4731 } 4732 if (!doit) { 4733 return true; 4734 } 4735 didSomething = true; 4736 it.remove(); 4737 pir.canceled = true; 4738 if (pir.key.activity != null) { 4739 pir.key.activity.pendingResults.remove(pir.ref); 4740 } 4741 } 4742 } 4743 } 4744 4745 if (doit) { 4746 if (purgeCache && name != null) { 4747 AttributeCache ac = AttributeCache.instance(); 4748 if (ac != null) { 4749 ac.removePackage(name); 4750 } 4751 } 4752 if (mBooted) { 4753 mStackSupervisor.resumeTopActivitiesLocked(); 4754 mStackSupervisor.scheduleIdleLocked(); 4755 } 4756 } 4757 4758 return didSomething; 4759 } 4760 4761 private final boolean removeProcessLocked(ProcessRecord app, 4762 boolean callerWillRestart, boolean allowRestart, String reason) { 4763 final String name = app.processName; 4764 final int uid = app.uid; 4765 if (DEBUG_PROCESSES) Slog.d( 4766 TAG, "Force removing proc " + app.toShortString() + " (" + name 4767 + "/" + uid + ")"); 4768 4769 mProcessNames.remove(name, uid); 4770 mIsolatedProcesses.remove(app.uid); 4771 if (mHeavyWeightProcess == app) { 4772 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4773 mHeavyWeightProcess.userId, 0)); 4774 mHeavyWeightProcess = null; 4775 } 4776 boolean needRestart = false; 4777 if (app.pid > 0 && app.pid != MY_PID) { 4778 int pid = app.pid; 4779 synchronized (mPidsSelfLocked) { 4780 mPidsSelfLocked.remove(pid); 4781 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4782 } 4783 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4784 app.processName, app.info.uid); 4785 if (app.isolated) { 4786 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4787 } 4788 killUnneededProcessLocked(app, reason); 4789 handleAppDiedLocked(app, true, allowRestart); 4790 removeLruProcessLocked(app); 4791 4792 if (app.persistent && !app.isolated) { 4793 if (!callerWillRestart) { 4794 addAppLocked(app.info, false); 4795 } else { 4796 needRestart = true; 4797 } 4798 } 4799 } else { 4800 mRemovedProcesses.add(app); 4801 } 4802 4803 return needRestart; 4804 } 4805 4806 private final void processStartTimedOutLocked(ProcessRecord app) { 4807 final int pid = app.pid; 4808 boolean gone = false; 4809 synchronized (mPidsSelfLocked) { 4810 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4811 if (knownApp != null && knownApp.thread == null) { 4812 mPidsSelfLocked.remove(pid); 4813 gone = true; 4814 } 4815 } 4816 4817 if (gone) { 4818 Slog.w(TAG, "Process " + app + " failed to attach"); 4819 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4820 pid, app.uid, app.processName); 4821 mProcessNames.remove(app.processName, app.uid); 4822 mIsolatedProcesses.remove(app.uid); 4823 if (mHeavyWeightProcess == app) { 4824 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4825 mHeavyWeightProcess.userId, 0)); 4826 mHeavyWeightProcess = null; 4827 } 4828 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4829 app.processName, app.info.uid); 4830 if (app.isolated) { 4831 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4832 } 4833 // Take care of any launching providers waiting for this process. 4834 checkAppInLaunchingProvidersLocked(app, true); 4835 // Take care of any services that are waiting for the process. 4836 mServices.processStartTimedOutLocked(app); 4837 killUnneededProcessLocked(app, "start timeout"); 4838 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4839 Slog.w(TAG, "Unattached app died before backup, skipping"); 4840 try { 4841 IBackupManager bm = IBackupManager.Stub.asInterface( 4842 ServiceManager.getService(Context.BACKUP_SERVICE)); 4843 bm.agentDisconnected(app.info.packageName); 4844 } catch (RemoteException e) { 4845 // Can't happen; the backup manager is local 4846 } 4847 } 4848 if (isPendingBroadcastProcessLocked(pid)) { 4849 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4850 skipPendingBroadcastLocked(pid); 4851 } 4852 } else { 4853 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4854 } 4855 } 4856 4857 private final boolean attachApplicationLocked(IApplicationThread thread, 4858 int pid) { 4859 4860 // Find the application record that is being attached... either via 4861 // the pid if we are running in multiple processes, or just pull the 4862 // next app record if we are emulating process with anonymous threads. 4863 ProcessRecord app; 4864 if (pid != MY_PID && pid >= 0) { 4865 synchronized (mPidsSelfLocked) { 4866 app = mPidsSelfLocked.get(pid); 4867 } 4868 } else { 4869 app = null; 4870 } 4871 4872 if (app == null) { 4873 Slog.w(TAG, "No pending application record for pid " + pid 4874 + " (IApplicationThread " + thread + "); dropping process"); 4875 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4876 if (pid > 0 && pid != MY_PID) { 4877 Process.killProcessQuiet(pid); 4878 } else { 4879 try { 4880 thread.scheduleExit(); 4881 } catch (Exception e) { 4882 // Ignore exceptions. 4883 } 4884 } 4885 return false; 4886 } 4887 4888 // If this application record is still attached to a previous 4889 // process, clean it up now. 4890 if (app.thread != null) { 4891 handleAppDiedLocked(app, true, true); 4892 } 4893 4894 // Tell the process all about itself. 4895 4896 if (localLOGV) Slog.v( 4897 TAG, "Binding process pid " + pid + " to record " + app); 4898 4899 final String processName = app.processName; 4900 try { 4901 AppDeathRecipient adr = new AppDeathRecipient( 4902 app, pid, thread); 4903 thread.asBinder().linkToDeath(adr, 0); 4904 app.deathRecipient = adr; 4905 } catch (RemoteException e) { 4906 app.resetPackageList(mProcessStats); 4907 startProcessLocked(app, "link fail", processName); 4908 return false; 4909 } 4910 4911 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4912 4913 app.makeActive(thread, mProcessStats); 4914 app.curAdj = app.setAdj = -100; 4915 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4916 app.forcingToForeground = null; 4917 updateProcessForegroundLocked(app, false, false); 4918 app.hasShownUi = false; 4919 app.debugging = false; 4920 app.cached = false; 4921 4922 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4923 4924 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4925 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4926 4927 if (!normalMode) { 4928 Slog.i(TAG, "Launching preboot mode app: " + app); 4929 } 4930 4931 if (localLOGV) Slog.v( 4932 TAG, "New app record " + app 4933 + " thread=" + thread.asBinder() + " pid=" + pid); 4934 try { 4935 int testMode = IApplicationThread.DEBUG_OFF; 4936 if (mDebugApp != null && mDebugApp.equals(processName)) { 4937 testMode = mWaitForDebugger 4938 ? IApplicationThread.DEBUG_WAIT 4939 : IApplicationThread.DEBUG_ON; 4940 app.debugging = true; 4941 if (mDebugTransient) { 4942 mDebugApp = mOrigDebugApp; 4943 mWaitForDebugger = mOrigWaitForDebugger; 4944 } 4945 } 4946 String profileFile = app.instrumentationProfileFile; 4947 ParcelFileDescriptor profileFd = null; 4948 boolean profileAutoStop = false; 4949 if (mProfileApp != null && mProfileApp.equals(processName)) { 4950 mProfileProc = app; 4951 profileFile = mProfileFile; 4952 profileFd = mProfileFd; 4953 profileAutoStop = mAutoStopProfiler; 4954 } 4955 boolean enableOpenGlTrace = false; 4956 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 4957 enableOpenGlTrace = true; 4958 mOpenGlTraceApp = null; 4959 } 4960 4961 // If the app is being launched for restore or full backup, set it up specially 4962 boolean isRestrictedBackupMode = false; 4963 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 4964 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 4965 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 4966 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 4967 } 4968 4969 ensurePackageDexOpt(app.instrumentationInfo != null 4970 ? app.instrumentationInfo.packageName 4971 : app.info.packageName); 4972 if (app.instrumentationClass != null) { 4973 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 4974 } 4975 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 4976 + processName + " with config " + mConfiguration); 4977 ApplicationInfo appInfo = app.instrumentationInfo != null 4978 ? app.instrumentationInfo : app.info; 4979 app.compat = compatibilityInfoForPackageLocked(appInfo); 4980 if (profileFd != null) { 4981 profileFd = profileFd.dup(); 4982 } 4983 thread.bindApplication(processName, appInfo, providers, 4984 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 4985 app.instrumentationArguments, app.instrumentationWatcher, 4986 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 4987 isRestrictedBackupMode || !normalMode, app.persistent, 4988 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 4989 mCoreSettingsObserver.getCoreSettingsLocked()); 4990 updateLruProcessLocked(app, false, null); 4991 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 4992 } catch (Exception e) { 4993 // todo: Yikes! What should we do? For now we will try to 4994 // start another process, but that could easily get us in 4995 // an infinite loop of restarting processes... 4996 Slog.w(TAG, "Exception thrown during bind!", e); 4997 4998 app.resetPackageList(mProcessStats); 4999 app.unlinkDeathRecipient(); 5000 startProcessLocked(app, "bind fail", processName); 5001 return false; 5002 } 5003 5004 // Remove this record from the list of starting applications. 5005 mPersistentStartingProcesses.remove(app); 5006 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5007 "Attach application locked removing on hold: " + app); 5008 mProcessesOnHold.remove(app); 5009 5010 boolean badApp = false; 5011 boolean didSomething = false; 5012 5013 // See if the top visible activity is waiting to run in this process... 5014 if (normalMode) { 5015 try { 5016 if (mStackSupervisor.attachApplicationLocked(app)) { 5017 didSomething = true; 5018 } 5019 } catch (Exception e) { 5020 badApp = true; 5021 } 5022 } 5023 5024 // Find any services that should be running in this process... 5025 if (!badApp) { 5026 try { 5027 didSomething |= mServices.attachApplicationLocked(app, processName); 5028 } catch (Exception e) { 5029 badApp = true; 5030 } 5031 } 5032 5033 // Check if a next-broadcast receiver is in this process... 5034 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5035 try { 5036 didSomething |= sendPendingBroadcastsLocked(app); 5037 } catch (Exception e) { 5038 // If the app died trying to launch the receiver we declare it 'bad' 5039 badApp = true; 5040 } 5041 } 5042 5043 // Check whether the next backup agent is in this process... 5044 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5045 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5046 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5047 try { 5048 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5049 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5050 mBackupTarget.backupMode); 5051 } catch (Exception e) { 5052 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5053 e.printStackTrace(); 5054 } 5055 } 5056 5057 if (badApp) { 5058 // todo: Also need to kill application to deal with all 5059 // kinds of exceptions. 5060 handleAppDiedLocked(app, false, true); 5061 return false; 5062 } 5063 5064 if (!didSomething) { 5065 updateOomAdjLocked(); 5066 } 5067 5068 return true; 5069 } 5070 5071 @Override 5072 public final void attachApplication(IApplicationThread thread) { 5073 synchronized (this) { 5074 int callingPid = Binder.getCallingPid(); 5075 final long origId = Binder.clearCallingIdentity(); 5076 attachApplicationLocked(thread, callingPid); 5077 Binder.restoreCallingIdentity(origId); 5078 } 5079 } 5080 5081 @Override 5082 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5083 final long origId = Binder.clearCallingIdentity(); 5084 synchronized (this) { 5085 ActivityStack stack = ActivityRecord.getStackLocked(token); 5086 if (stack != null) { 5087 ActivityRecord r = 5088 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5089 if (stopProfiling) { 5090 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5091 try { 5092 mProfileFd.close(); 5093 } catch (IOException e) { 5094 } 5095 clearProfilerLocked(); 5096 } 5097 } 5098 } 5099 } 5100 Binder.restoreCallingIdentity(origId); 5101 } 5102 5103 void enableScreenAfterBoot() { 5104 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5105 SystemClock.uptimeMillis()); 5106 mWindowManager.enableScreenAfterBoot(); 5107 5108 synchronized (this) { 5109 updateEventDispatchingLocked(); 5110 } 5111 } 5112 5113 @Override 5114 public void showBootMessage(final CharSequence msg, final boolean always) { 5115 enforceNotIsolatedCaller("showBootMessage"); 5116 mWindowManager.showBootMessage(msg, always); 5117 } 5118 5119 @Override 5120 public void dismissKeyguardOnNextActivity() { 5121 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5122 final long token = Binder.clearCallingIdentity(); 5123 try { 5124 synchronized (this) { 5125 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5126 if (mLockScreenShown) { 5127 mLockScreenShown = false; 5128 comeOutOfSleepIfNeededLocked(); 5129 } 5130 mStackSupervisor.setDismissKeyguard(true); 5131 } 5132 } finally { 5133 Binder.restoreCallingIdentity(token); 5134 } 5135 } 5136 5137 final void finishBooting() { 5138 IntentFilter pkgFilter = new IntentFilter(); 5139 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5140 pkgFilter.addDataScheme("package"); 5141 mContext.registerReceiver(new BroadcastReceiver() { 5142 @Override 5143 public void onReceive(Context context, Intent intent) { 5144 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5145 if (pkgs != null) { 5146 for (String pkg : pkgs) { 5147 synchronized (ActivityManagerService.this) { 5148 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5149 "finished booting")) { 5150 setResultCode(Activity.RESULT_OK); 5151 return; 5152 } 5153 } 5154 } 5155 } 5156 } 5157 }, pkgFilter); 5158 5159 synchronized (this) { 5160 // Ensure that any processes we had put on hold are now started 5161 // up. 5162 final int NP = mProcessesOnHold.size(); 5163 if (NP > 0) { 5164 ArrayList<ProcessRecord> procs = 5165 new ArrayList<ProcessRecord>(mProcessesOnHold); 5166 for (int ip=0; ip<NP; ip++) { 5167 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5168 + procs.get(ip)); 5169 startProcessLocked(procs.get(ip), "on-hold", null); 5170 } 5171 } 5172 5173 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5174 // Start looking for apps that are abusing wake locks. 5175 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5176 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5177 // Tell anyone interested that we are done booting! 5178 SystemProperties.set("sys.boot_completed", "1"); 5179 SystemProperties.set("dev.bootcomplete", "1"); 5180 for (int i=0; i<mStartedUsers.size(); i++) { 5181 UserStartedState uss = mStartedUsers.valueAt(i); 5182 if (uss.mState == UserStartedState.STATE_BOOTING) { 5183 uss.mState = UserStartedState.STATE_RUNNING; 5184 final int userId = mStartedUsers.keyAt(i); 5185 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5186 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5187 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5188 broadcastIntentLocked(null, null, intent, null, 5189 new IIntentReceiver.Stub() { 5190 @Override 5191 public void performReceive(Intent intent, int resultCode, 5192 String data, Bundle extras, boolean ordered, 5193 boolean sticky, int sendingUser) { 5194 synchronized (ActivityManagerService.this) { 5195 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5196 true, false); 5197 } 5198 } 5199 }, 5200 0, null, null, 5201 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5202 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5203 userId); 5204 } 5205 } 5206 scheduleStartRelatedUsersLocked(); 5207 } 5208 } 5209 } 5210 5211 final void ensureBootCompleted() { 5212 boolean booting; 5213 boolean enableScreen; 5214 synchronized (this) { 5215 booting = mBooting; 5216 mBooting = false; 5217 enableScreen = !mBooted; 5218 mBooted = true; 5219 } 5220 5221 if (booting) { 5222 finishBooting(); 5223 } 5224 5225 if (enableScreen) { 5226 enableScreenAfterBoot(); 5227 } 5228 } 5229 5230 @Override 5231 public final void activityResumed(IBinder token) { 5232 final long origId = Binder.clearCallingIdentity(); 5233 synchronized(this) { 5234 ActivityStack stack = ActivityRecord.getStackLocked(token); 5235 if (stack != null) { 5236 ActivityRecord.activityResumedLocked(token); 5237 } 5238 } 5239 Binder.restoreCallingIdentity(origId); 5240 } 5241 5242 @Override 5243 public final void activityPaused(IBinder token) { 5244 final long origId = Binder.clearCallingIdentity(); 5245 synchronized(this) { 5246 ActivityStack stack = ActivityRecord.getStackLocked(token); 5247 if (stack != null) { 5248 stack.activityPausedLocked(token, false); 5249 } 5250 } 5251 Binder.restoreCallingIdentity(origId); 5252 } 5253 5254 @Override 5255 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5256 CharSequence description) { 5257 if (localLOGV) Slog.v( 5258 TAG, "Activity stopped: token=" + token); 5259 5260 // Refuse possible leaked file descriptors 5261 if (icicle != null && icicle.hasFileDescriptors()) { 5262 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5263 } 5264 5265 ActivityRecord r = null; 5266 5267 final long origId = Binder.clearCallingIdentity(); 5268 5269 synchronized (this) { 5270 r = ActivityRecord.isInStackLocked(token); 5271 if (r != null) { 5272 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5273 } 5274 } 5275 5276 if (r != null) { 5277 sendPendingThumbnail(r, null, null, null, false); 5278 } 5279 5280 trimApplications(); 5281 5282 Binder.restoreCallingIdentity(origId); 5283 } 5284 5285 @Override 5286 public final void activityDestroyed(IBinder token) { 5287 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5288 synchronized (this) { 5289 ActivityStack stack = ActivityRecord.getStackLocked(token); 5290 if (stack != null) { 5291 stack.activityDestroyedLocked(token); 5292 } 5293 } 5294 } 5295 5296 @Override 5297 public String getCallingPackage(IBinder token) { 5298 synchronized (this) { 5299 ActivityRecord r = getCallingRecordLocked(token); 5300 return r != null ? r.info.packageName : null; 5301 } 5302 } 5303 5304 @Override 5305 public ComponentName getCallingActivity(IBinder token) { 5306 synchronized (this) { 5307 ActivityRecord r = getCallingRecordLocked(token); 5308 return r != null ? r.intent.getComponent() : null; 5309 } 5310 } 5311 5312 private ActivityRecord getCallingRecordLocked(IBinder token) { 5313 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5314 if (r == null) { 5315 return null; 5316 } 5317 return r.resultTo; 5318 } 5319 5320 @Override 5321 public ComponentName getActivityClassForToken(IBinder token) { 5322 synchronized(this) { 5323 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5324 if (r == null) { 5325 return null; 5326 } 5327 return r.intent.getComponent(); 5328 } 5329 } 5330 5331 @Override 5332 public String getPackageForToken(IBinder token) { 5333 synchronized(this) { 5334 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5335 if (r == null) { 5336 return null; 5337 } 5338 return r.packageName; 5339 } 5340 } 5341 5342 @Override 5343 public IIntentSender getIntentSender(int type, 5344 String packageName, IBinder token, String resultWho, 5345 int requestCode, Intent[] intents, String[] resolvedTypes, 5346 int flags, Bundle options, int userId) { 5347 enforceNotIsolatedCaller("getIntentSender"); 5348 // Refuse possible leaked file descriptors 5349 if (intents != null) { 5350 if (intents.length < 1) { 5351 throw new IllegalArgumentException("Intents array length must be >= 1"); 5352 } 5353 for (int i=0; i<intents.length; i++) { 5354 Intent intent = intents[i]; 5355 if (intent != null) { 5356 if (intent.hasFileDescriptors()) { 5357 throw new IllegalArgumentException("File descriptors passed in Intent"); 5358 } 5359 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5360 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5361 throw new IllegalArgumentException( 5362 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5363 } 5364 intents[i] = new Intent(intent); 5365 } 5366 } 5367 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5368 throw new IllegalArgumentException( 5369 "Intent array length does not match resolvedTypes length"); 5370 } 5371 } 5372 if (options != null) { 5373 if (options.hasFileDescriptors()) { 5374 throw new IllegalArgumentException("File descriptors passed in options"); 5375 } 5376 } 5377 5378 synchronized(this) { 5379 int callingUid = Binder.getCallingUid(); 5380 int origUserId = userId; 5381 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5382 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5383 "getIntentSender", null); 5384 if (origUserId == UserHandle.USER_CURRENT) { 5385 // We don't want to evaluate this until the pending intent is 5386 // actually executed. However, we do want to always do the 5387 // security checking for it above. 5388 userId = UserHandle.USER_CURRENT; 5389 } 5390 try { 5391 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5392 int uid = AppGlobals.getPackageManager() 5393 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5394 if (!UserHandle.isSameApp(callingUid, uid)) { 5395 String msg = "Permission Denial: getIntentSender() from pid=" 5396 + Binder.getCallingPid() 5397 + ", uid=" + Binder.getCallingUid() 5398 + ", (need uid=" + uid + ")" 5399 + " is not allowed to send as package " + packageName; 5400 Slog.w(TAG, msg); 5401 throw new SecurityException(msg); 5402 } 5403 } 5404 5405 return getIntentSenderLocked(type, packageName, callingUid, userId, 5406 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5407 5408 } catch (RemoteException e) { 5409 throw new SecurityException(e); 5410 } 5411 } 5412 } 5413 5414 IIntentSender getIntentSenderLocked(int type, String packageName, 5415 int callingUid, int userId, IBinder token, String resultWho, 5416 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5417 Bundle options) { 5418 if (DEBUG_MU) 5419 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5420 ActivityRecord activity = null; 5421 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5422 activity = ActivityRecord.isInStackLocked(token); 5423 if (activity == null) { 5424 return null; 5425 } 5426 if (activity.finishing) { 5427 return null; 5428 } 5429 } 5430 5431 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5432 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5433 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5434 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5435 |PendingIntent.FLAG_UPDATE_CURRENT); 5436 5437 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5438 type, packageName, activity, resultWho, 5439 requestCode, intents, resolvedTypes, flags, options, userId); 5440 WeakReference<PendingIntentRecord> ref; 5441 ref = mIntentSenderRecords.get(key); 5442 PendingIntentRecord rec = ref != null ? ref.get() : null; 5443 if (rec != null) { 5444 if (!cancelCurrent) { 5445 if (updateCurrent) { 5446 if (rec.key.requestIntent != null) { 5447 rec.key.requestIntent.replaceExtras(intents != null ? 5448 intents[intents.length - 1] : null); 5449 } 5450 if (intents != null) { 5451 intents[intents.length-1] = rec.key.requestIntent; 5452 rec.key.allIntents = intents; 5453 rec.key.allResolvedTypes = resolvedTypes; 5454 } else { 5455 rec.key.allIntents = null; 5456 rec.key.allResolvedTypes = null; 5457 } 5458 } 5459 return rec; 5460 } 5461 rec.canceled = true; 5462 mIntentSenderRecords.remove(key); 5463 } 5464 if (noCreate) { 5465 return rec; 5466 } 5467 rec = new PendingIntentRecord(this, key, callingUid); 5468 mIntentSenderRecords.put(key, rec.ref); 5469 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5470 if (activity.pendingResults == null) { 5471 activity.pendingResults 5472 = new HashSet<WeakReference<PendingIntentRecord>>(); 5473 } 5474 activity.pendingResults.add(rec.ref); 5475 } 5476 return rec; 5477 } 5478 5479 @Override 5480 public void cancelIntentSender(IIntentSender sender) { 5481 if (!(sender instanceof PendingIntentRecord)) { 5482 return; 5483 } 5484 synchronized(this) { 5485 PendingIntentRecord rec = (PendingIntentRecord)sender; 5486 try { 5487 int uid = AppGlobals.getPackageManager() 5488 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5489 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5490 String msg = "Permission Denial: cancelIntentSender() from pid=" 5491 + Binder.getCallingPid() 5492 + ", uid=" + Binder.getCallingUid() 5493 + " is not allowed to cancel packges " 5494 + rec.key.packageName; 5495 Slog.w(TAG, msg); 5496 throw new SecurityException(msg); 5497 } 5498 } catch (RemoteException e) { 5499 throw new SecurityException(e); 5500 } 5501 cancelIntentSenderLocked(rec, true); 5502 } 5503 } 5504 5505 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5506 rec.canceled = true; 5507 mIntentSenderRecords.remove(rec.key); 5508 if (cleanActivity && rec.key.activity != null) { 5509 rec.key.activity.pendingResults.remove(rec.ref); 5510 } 5511 } 5512 5513 @Override 5514 public String getPackageForIntentSender(IIntentSender pendingResult) { 5515 if (!(pendingResult instanceof PendingIntentRecord)) { 5516 return null; 5517 } 5518 try { 5519 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5520 return res.key.packageName; 5521 } catch (ClassCastException e) { 5522 } 5523 return null; 5524 } 5525 5526 @Override 5527 public int getUidForIntentSender(IIntentSender sender) { 5528 if (sender instanceof PendingIntentRecord) { 5529 try { 5530 PendingIntentRecord res = (PendingIntentRecord)sender; 5531 return res.uid; 5532 } catch (ClassCastException e) { 5533 } 5534 } 5535 return -1; 5536 } 5537 5538 @Override 5539 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5540 if (!(pendingResult instanceof PendingIntentRecord)) { 5541 return false; 5542 } 5543 try { 5544 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5545 if (res.key.allIntents == null) { 5546 return false; 5547 } 5548 for (int i=0; i<res.key.allIntents.length; i++) { 5549 Intent intent = res.key.allIntents[i]; 5550 if (intent.getPackage() != null && intent.getComponent() != null) { 5551 return false; 5552 } 5553 } 5554 return true; 5555 } catch (ClassCastException e) { 5556 } 5557 return false; 5558 } 5559 5560 @Override 5561 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5562 if (!(pendingResult instanceof PendingIntentRecord)) { 5563 return false; 5564 } 5565 try { 5566 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5567 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5568 return true; 5569 } 5570 return false; 5571 } catch (ClassCastException e) { 5572 } 5573 return false; 5574 } 5575 5576 @Override 5577 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5578 if (!(pendingResult instanceof PendingIntentRecord)) { 5579 return null; 5580 } 5581 try { 5582 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5583 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5584 } catch (ClassCastException e) { 5585 } 5586 return null; 5587 } 5588 5589 @Override 5590 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5591 if (!(pendingResult instanceof PendingIntentRecord)) { 5592 return null; 5593 } 5594 try { 5595 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5596 Intent intent = res.key.requestIntent; 5597 if (intent != null) { 5598 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5599 || res.lastTagPrefix.equals(prefix))) { 5600 return res.lastTag; 5601 } 5602 res.lastTagPrefix = prefix; 5603 StringBuilder sb = new StringBuilder(128); 5604 if (prefix != null) { 5605 sb.append(prefix); 5606 } 5607 if (intent.getAction() != null) { 5608 sb.append(intent.getAction()); 5609 } else if (intent.getComponent() != null) { 5610 intent.getComponent().appendShortString(sb); 5611 } else { 5612 sb.append("?"); 5613 } 5614 return res.lastTag = sb.toString(); 5615 } 5616 } catch (ClassCastException e) { 5617 } 5618 return null; 5619 } 5620 5621 @Override 5622 public void setProcessLimit(int max) { 5623 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5624 "setProcessLimit()"); 5625 synchronized (this) { 5626 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5627 mProcessLimitOverride = max; 5628 } 5629 trimApplications(); 5630 } 5631 5632 @Override 5633 public int getProcessLimit() { 5634 synchronized (this) { 5635 return mProcessLimitOverride; 5636 } 5637 } 5638 5639 void foregroundTokenDied(ForegroundToken token) { 5640 synchronized (ActivityManagerService.this) { 5641 synchronized (mPidsSelfLocked) { 5642 ForegroundToken cur 5643 = mForegroundProcesses.get(token.pid); 5644 if (cur != token) { 5645 return; 5646 } 5647 mForegroundProcesses.remove(token.pid); 5648 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5649 if (pr == null) { 5650 return; 5651 } 5652 pr.forcingToForeground = null; 5653 updateProcessForegroundLocked(pr, false, false); 5654 } 5655 updateOomAdjLocked(); 5656 } 5657 } 5658 5659 @Override 5660 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5661 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5662 "setProcessForeground()"); 5663 synchronized(this) { 5664 boolean changed = false; 5665 5666 synchronized (mPidsSelfLocked) { 5667 ProcessRecord pr = mPidsSelfLocked.get(pid); 5668 if (pr == null && isForeground) { 5669 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5670 return; 5671 } 5672 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5673 if (oldToken != null) { 5674 oldToken.token.unlinkToDeath(oldToken, 0); 5675 mForegroundProcesses.remove(pid); 5676 if (pr != null) { 5677 pr.forcingToForeground = null; 5678 } 5679 changed = true; 5680 } 5681 if (isForeground && token != null) { 5682 ForegroundToken newToken = new ForegroundToken() { 5683 @Override 5684 public void binderDied() { 5685 foregroundTokenDied(this); 5686 } 5687 }; 5688 newToken.pid = pid; 5689 newToken.token = token; 5690 try { 5691 token.linkToDeath(newToken, 0); 5692 mForegroundProcesses.put(pid, newToken); 5693 pr.forcingToForeground = token; 5694 changed = true; 5695 } catch (RemoteException e) { 5696 // If the process died while doing this, we will later 5697 // do the cleanup with the process death link. 5698 } 5699 } 5700 } 5701 5702 if (changed) { 5703 updateOomAdjLocked(); 5704 } 5705 } 5706 } 5707 5708 // ========================================================= 5709 // PERMISSIONS 5710 // ========================================================= 5711 5712 static class PermissionController extends IPermissionController.Stub { 5713 ActivityManagerService mActivityManagerService; 5714 PermissionController(ActivityManagerService activityManagerService) { 5715 mActivityManagerService = activityManagerService; 5716 } 5717 5718 @Override 5719 public boolean checkPermission(String permission, int pid, int uid) { 5720 return mActivityManagerService.checkPermission(permission, pid, 5721 uid) == PackageManager.PERMISSION_GRANTED; 5722 } 5723 } 5724 5725 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5726 @Override 5727 public int checkComponentPermission(String permission, int pid, int uid, 5728 int owningUid, boolean exported) { 5729 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5730 owningUid, exported); 5731 } 5732 5733 @Override 5734 public Object getAMSLock() { 5735 return ActivityManagerService.this; 5736 } 5737 } 5738 5739 /** 5740 * This can be called with or without the global lock held. 5741 */ 5742 int checkComponentPermission(String permission, int pid, int uid, 5743 int owningUid, boolean exported) { 5744 // We might be performing an operation on behalf of an indirect binder 5745 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5746 // client identity accordingly before proceeding. 5747 Identity tlsIdentity = sCallerIdentity.get(); 5748 if (tlsIdentity != null) { 5749 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5750 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5751 uid = tlsIdentity.uid; 5752 pid = tlsIdentity.pid; 5753 } 5754 5755 if (pid == MY_PID) { 5756 return PackageManager.PERMISSION_GRANTED; 5757 } 5758 5759 return ActivityManager.checkComponentPermission(permission, uid, 5760 owningUid, exported); 5761 } 5762 5763 /** 5764 * As the only public entry point for permissions checking, this method 5765 * can enforce the semantic that requesting a check on a null global 5766 * permission is automatically denied. (Internally a null permission 5767 * string is used when calling {@link #checkComponentPermission} in cases 5768 * when only uid-based security is needed.) 5769 * 5770 * This can be called with or without the global lock held. 5771 */ 5772 @Override 5773 public int checkPermission(String permission, int pid, int uid) { 5774 if (permission == null) { 5775 return PackageManager.PERMISSION_DENIED; 5776 } 5777 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5778 } 5779 5780 /** 5781 * Binder IPC calls go through the public entry point. 5782 * This can be called with or without the global lock held. 5783 */ 5784 int checkCallingPermission(String permission) { 5785 return checkPermission(permission, 5786 Binder.getCallingPid(), 5787 UserHandle.getAppId(Binder.getCallingUid())); 5788 } 5789 5790 /** 5791 * This can be called with or without the global lock held. 5792 */ 5793 void enforceCallingPermission(String permission, String func) { 5794 if (checkCallingPermission(permission) 5795 == PackageManager.PERMISSION_GRANTED) { 5796 return; 5797 } 5798 5799 String msg = "Permission Denial: " + func + " from pid=" 5800 + Binder.getCallingPid() 5801 + ", uid=" + Binder.getCallingUid() 5802 + " requires " + permission; 5803 Slog.w(TAG, msg); 5804 throw new SecurityException(msg); 5805 } 5806 5807 /** 5808 * Determine if UID is holding permissions required to access {@link Uri} in 5809 * the given {@link ProviderInfo}. Final permission checking is always done 5810 * in {@link ContentProvider}. 5811 */ 5812 private final boolean checkHoldingPermissionsLocked( 5813 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) { 5814 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5815 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5816 5817 if (pi.applicationInfo.uid == uid) { 5818 return true; 5819 } else if (!pi.exported) { 5820 return false; 5821 } 5822 5823 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5824 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5825 try { 5826 // check if target holds top-level <provider> permissions 5827 if (!readMet && pi.readPermission != null 5828 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5829 readMet = true; 5830 } 5831 if (!writeMet && pi.writePermission != null 5832 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5833 writeMet = true; 5834 } 5835 5836 // track if unprotected read/write is allowed; any denied 5837 // <path-permission> below removes this ability 5838 boolean allowDefaultRead = pi.readPermission == null; 5839 boolean allowDefaultWrite = pi.writePermission == null; 5840 5841 // check if target holds any <path-permission> that match uri 5842 final PathPermission[] pps = pi.pathPermissions; 5843 if (pps != null) { 5844 final String path = uri.getPath(); 5845 int i = pps.length; 5846 while (i > 0 && (!readMet || !writeMet)) { 5847 i--; 5848 PathPermission pp = pps[i]; 5849 if (pp.match(path)) { 5850 if (!readMet) { 5851 final String pprperm = pp.getReadPermission(); 5852 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5853 + pprperm + " for " + pp.getPath() 5854 + ": match=" + pp.match(path) 5855 + " check=" + pm.checkUidPermission(pprperm, uid)); 5856 if (pprperm != null) { 5857 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5858 readMet = true; 5859 } else { 5860 allowDefaultRead = false; 5861 } 5862 } 5863 } 5864 if (!writeMet) { 5865 final String ppwperm = pp.getWritePermission(); 5866 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5867 + ppwperm + " for " + pp.getPath() 5868 + ": match=" + pp.match(path) 5869 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5870 if (ppwperm != null) { 5871 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5872 writeMet = true; 5873 } else { 5874 allowDefaultWrite = false; 5875 } 5876 } 5877 } 5878 } 5879 } 5880 } 5881 5882 // grant unprotected <provider> read/write, if not blocked by 5883 // <path-permission> above 5884 if (allowDefaultRead) readMet = true; 5885 if (allowDefaultWrite) writeMet = true; 5886 5887 } catch (RemoteException e) { 5888 return false; 5889 } 5890 5891 return readMet && writeMet; 5892 } 5893 5894 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5895 ProviderInfo pi = null; 5896 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5897 if (cpr != null) { 5898 pi = cpr.info; 5899 } else { 5900 try { 5901 pi = AppGlobals.getPackageManager().resolveContentProvider( 5902 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5903 } catch (RemoteException ex) { 5904 } 5905 } 5906 return pi; 5907 } 5908 5909 private UriPermission findUriPermissionLocked(int targetUid, Uri uri) { 5910 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5911 if (targetUris != null) { 5912 return targetUris.get(uri); 5913 } else { 5914 return null; 5915 } 5916 } 5917 5918 private UriPermission findOrCreateUriPermissionLocked( 5919 String sourcePkg, String targetPkg, int targetUid, Uri uri) { 5920 ArrayMap<Uri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5921 if (targetUris == null) { 5922 targetUris = Maps.newArrayMap(); 5923 mGrantedUriPermissions.put(targetUid, targetUris); 5924 } 5925 5926 UriPermission perm = targetUris.get(uri); 5927 if (perm == null) { 5928 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5929 targetUris.put(uri, perm); 5930 } 5931 5932 return perm; 5933 } 5934 5935 private final boolean checkUriPermissionLocked( 5936 Uri uri, int uid, int modeFlags, int minStrength) { 5937 // Root gets to do everything. 5938 if (uid == 0) { 5939 return true; 5940 } 5941 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5942 if (perms == null) return false; 5943 UriPermission perm = perms.get(uri); 5944 if (perm == null) return false; 5945 return perm.getStrength(modeFlags) >= minStrength; 5946 } 5947 5948 @Override 5949 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) { 5950 enforceNotIsolatedCaller("checkUriPermission"); 5951 5952 // Another redirected-binder-call permissions check as in 5953 // {@link checkComponentPermission}. 5954 Identity tlsIdentity = sCallerIdentity.get(); 5955 if (tlsIdentity != null) { 5956 uid = tlsIdentity.uid; 5957 pid = tlsIdentity.pid; 5958 } 5959 5960 // Our own process gets to do everything. 5961 if (pid == MY_PID) { 5962 return PackageManager.PERMISSION_GRANTED; 5963 } 5964 synchronized(this) { 5965 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 5966 ? PackageManager.PERMISSION_GRANTED 5967 : PackageManager.PERMISSION_DENIED; 5968 } 5969 } 5970 5971 /** 5972 * Check if the targetPkg can be granted permission to access uri by 5973 * the callingUid using the given modeFlags. Throws a security exception 5974 * if callingUid is not allowed to do this. Returns the uid of the target 5975 * if the URI permission grant should be performed; returns -1 if it is not 5976 * needed (for example targetPkg already has permission to access the URI). 5977 * If you already know the uid of the target, you can supply it in 5978 * lastTargetUid else set that to -1. 5979 */ 5980 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 5981 Uri uri, int modeFlags, int lastTargetUid) { 5982 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 5983 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 5984 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 5985 if (modeFlags == 0) { 5986 return -1; 5987 } 5988 5989 if (targetPkg != null) { 5990 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5991 "Checking grant " + targetPkg + " permission to " + uri); 5992 } 5993 5994 final IPackageManager pm = AppGlobals.getPackageManager(); 5995 5996 // If this is not a content: uri, we can't do anything with it. 5997 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 5998 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5999 "Can't grant URI permission for non-content URI: " + uri); 6000 return -1; 6001 } 6002 6003 final String authority = uri.getAuthority(); 6004 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6005 if (pi == null) { 6006 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6007 return -1; 6008 } 6009 6010 int targetUid = lastTargetUid; 6011 if (targetUid < 0 && targetPkg != null) { 6012 try { 6013 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6014 if (targetUid < 0) { 6015 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6016 "Can't grant URI permission no uid for: " + targetPkg); 6017 return -1; 6018 } 6019 } catch (RemoteException ex) { 6020 return -1; 6021 } 6022 } 6023 6024 if (targetUid >= 0) { 6025 // First... does the target actually need this permission? 6026 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6027 // No need to grant the target this permission. 6028 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6029 "Target " + targetPkg + " already has full permission to " + uri); 6030 return -1; 6031 } 6032 } else { 6033 // First... there is no target package, so can anyone access it? 6034 boolean allowed = pi.exported; 6035 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6036 if (pi.readPermission != null) { 6037 allowed = false; 6038 } 6039 } 6040 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6041 if (pi.writePermission != null) { 6042 allowed = false; 6043 } 6044 } 6045 if (allowed) { 6046 return -1; 6047 } 6048 } 6049 6050 // Second... is the provider allowing granting of URI permissions? 6051 if (!pi.grantUriPermissions) { 6052 throw new SecurityException("Provider " + pi.packageName 6053 + "/" + pi.name 6054 + " does not allow granting of Uri permissions (uri " 6055 + uri + ")"); 6056 } 6057 if (pi.uriPermissionPatterns != null) { 6058 final int N = pi.uriPermissionPatterns.length; 6059 boolean allowed = false; 6060 for (int i=0; i<N; i++) { 6061 if (pi.uriPermissionPatterns[i] != null 6062 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6063 allowed = true; 6064 break; 6065 } 6066 } 6067 if (!allowed) { 6068 throw new SecurityException("Provider " + pi.packageName 6069 + "/" + pi.name 6070 + " does not allow granting of permission to path of Uri " 6071 + uri); 6072 } 6073 } 6074 6075 // Third... does the caller itself have permission to access 6076 // this uri? 6077 if (callingUid != Process.myUid()) { 6078 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6079 // Require they hold a strong enough Uri permission 6080 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6081 : UriPermission.STRENGTH_OWNED; 6082 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6083 throw new SecurityException("Uid " + callingUid 6084 + " does not have permission to uri " + uri); 6085 } 6086 } 6087 } 6088 6089 return targetUid; 6090 } 6091 6092 @Override 6093 public int checkGrantUriPermission(int callingUid, String targetPkg, 6094 Uri uri, int modeFlags) { 6095 enforceNotIsolatedCaller("checkGrantUriPermission"); 6096 synchronized(this) { 6097 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6098 } 6099 } 6100 6101 void grantUriPermissionUncheckedLocked( 6102 int targetUid, String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) { 6103 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6104 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6105 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6106 if (modeFlags == 0) { 6107 return; 6108 } 6109 6110 // So here we are: the caller has the assumed permission 6111 // to the uri, and the target doesn't. Let's now give this to 6112 // the target. 6113 6114 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6115 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6116 6117 final String authority = uri.getAuthority(); 6118 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6119 if (pi == null) { 6120 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6121 return; 6122 } 6123 6124 final UriPermission perm = findOrCreateUriPermissionLocked( 6125 pi.packageName, targetPkg, targetUid, uri); 6126 perm.grantModes(modeFlags, persistable, owner); 6127 } 6128 6129 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6130 int modeFlags, UriPermissionOwner owner) { 6131 if (targetPkg == null) { 6132 throw new NullPointerException("targetPkg"); 6133 } 6134 6135 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6136 if (targetUid < 0) { 6137 return; 6138 } 6139 6140 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6141 } 6142 6143 static class NeededUriGrants extends ArrayList<Uri> { 6144 final String targetPkg; 6145 final int targetUid; 6146 final int flags; 6147 6148 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6149 this.targetPkg = targetPkg; 6150 this.targetUid = targetUid; 6151 this.flags = flags; 6152 } 6153 } 6154 6155 /** 6156 * Like checkGrantUriPermissionLocked, but takes an Intent. 6157 */ 6158 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6159 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6160 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6161 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6162 + " clip=" + (intent != null ? intent.getClipData() : null) 6163 + " from " + intent + "; flags=0x" 6164 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6165 6166 if (targetPkg == null) { 6167 throw new NullPointerException("targetPkg"); 6168 } 6169 6170 if (intent == null) { 6171 return null; 6172 } 6173 Uri data = intent.getData(); 6174 ClipData clip = intent.getClipData(); 6175 if (data == null && clip == null) { 6176 return null; 6177 } 6178 6179 if (data != null) { 6180 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6181 mode, needed != null ? needed.targetUid : -1); 6182 if (targetUid > 0) { 6183 if (needed == null) { 6184 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6185 } 6186 needed.add(data); 6187 } 6188 } 6189 if (clip != null) { 6190 for (int i=0; i<clip.getItemCount(); i++) { 6191 Uri uri = clip.getItemAt(i).getUri(); 6192 if (uri != null) { 6193 int targetUid = -1; 6194 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6195 mode, needed != null ? needed.targetUid : -1); 6196 if (targetUid > 0) { 6197 if (needed == null) { 6198 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6199 } 6200 needed.add(uri); 6201 } 6202 } else { 6203 Intent clipIntent = clip.getItemAt(i).getIntent(); 6204 if (clipIntent != null) { 6205 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6206 callingUid, targetPkg, clipIntent, mode, needed); 6207 if (newNeeded != null) { 6208 needed = newNeeded; 6209 } 6210 } 6211 } 6212 } 6213 } 6214 6215 return needed; 6216 } 6217 6218 /** 6219 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6220 */ 6221 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6222 UriPermissionOwner owner) { 6223 if (needed != null) { 6224 for (int i=0; i<needed.size(); i++) { 6225 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6226 needed.get(i), needed.flags, owner); 6227 } 6228 } 6229 } 6230 6231 void grantUriPermissionFromIntentLocked(int callingUid, 6232 String targetPkg, Intent intent, UriPermissionOwner owner) { 6233 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6234 intent, intent != null ? intent.getFlags() : 0, null); 6235 if (needed == null) { 6236 return; 6237 } 6238 6239 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6240 } 6241 6242 @Override 6243 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6244 Uri uri, int modeFlags) { 6245 enforceNotIsolatedCaller("grantUriPermission"); 6246 synchronized(this) { 6247 final ProcessRecord r = getRecordForAppLocked(caller); 6248 if (r == null) { 6249 throw new SecurityException("Unable to find app for caller " 6250 + caller 6251 + " when granting permission to uri " + uri); 6252 } 6253 if (targetPkg == null) { 6254 throw new IllegalArgumentException("null target"); 6255 } 6256 if (uri == null) { 6257 throw new IllegalArgumentException("null uri"); 6258 } 6259 6260 // Persistable only supported through Intents 6261 Preconditions.checkFlagsArgument(modeFlags, 6262 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6263 6264 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, 6265 null); 6266 } 6267 } 6268 6269 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6270 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION 6271 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) { 6272 ArrayMap<Uri, UriPermission> perms 6273 = mGrantedUriPermissions.get(perm.targetUid); 6274 if (perms != null) { 6275 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6276 "Removing " + perm.targetUid + " permission to " + perm.uri); 6277 perms.remove(perm.uri); 6278 if (perms.size() == 0) { 6279 mGrantedUriPermissions.remove(perm.targetUid); 6280 } 6281 } 6282 } 6283 } 6284 6285 private void revokeUriPermissionLocked(int callingUid, Uri uri, int modeFlags) { 6286 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6287 6288 final IPackageManager pm = AppGlobals.getPackageManager(); 6289 final String authority = uri.getAuthority(); 6290 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6291 if (pi == null) { 6292 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6293 return; 6294 } 6295 6296 // Does the caller have this permission on the URI? 6297 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6298 // Right now, if you are not the original owner of the permission, 6299 // you are not allowed to revoke it. 6300 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6301 throw new SecurityException("Uid " + callingUid 6302 + " does not have permission to uri " + uri); 6303 //} 6304 } 6305 6306 boolean persistChanged = false; 6307 6308 // Go through all of the permissions and remove any that match. 6309 final List<String> SEGMENTS = uri.getPathSegments(); 6310 if (SEGMENTS != null) { 6311 final int NS = SEGMENTS.size(); 6312 int N = mGrantedUriPermissions.size(); 6313 for (int i=0; i<N; i++) { 6314 ArrayMap<Uri, UriPermission> perms 6315 = mGrantedUriPermissions.valueAt(i); 6316 Iterator<UriPermission> it = perms.values().iterator(); 6317 toploop: 6318 while (it.hasNext()) { 6319 UriPermission perm = it.next(); 6320 Uri targetUri = perm.uri; 6321 if (!authority.equals(targetUri.getAuthority())) { 6322 continue; 6323 } 6324 List<String> targetSegments = targetUri.getPathSegments(); 6325 if (targetSegments == null) { 6326 continue; 6327 } 6328 if (targetSegments.size() < NS) { 6329 continue; 6330 } 6331 for (int j=0; j<NS; j++) { 6332 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) { 6333 continue toploop; 6334 } 6335 } 6336 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6337 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6338 persistChanged |= perm.clearModes(modeFlags, true); 6339 if (perm.modeFlags == 0) { 6340 it.remove(); 6341 } 6342 } 6343 if (perms.size() == 0) { 6344 mGrantedUriPermissions.remove( 6345 mGrantedUriPermissions.keyAt(i)); 6346 N--; 6347 i--; 6348 } 6349 } 6350 } 6351 6352 if (persistChanged) { 6353 schedulePersistUriGrants(); 6354 } 6355 } 6356 6357 @Override 6358 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6359 int modeFlags) { 6360 enforceNotIsolatedCaller("revokeUriPermission"); 6361 synchronized(this) { 6362 final ProcessRecord r = getRecordForAppLocked(caller); 6363 if (r == null) { 6364 throw new SecurityException("Unable to find app for caller " 6365 + caller 6366 + " when revoking permission to uri " + uri); 6367 } 6368 if (uri == null) { 6369 Slog.w(TAG, "revokeUriPermission: null uri"); 6370 return; 6371 } 6372 6373 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION 6374 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6375 if (modeFlags == 0) { 6376 return; 6377 } 6378 6379 final IPackageManager pm = AppGlobals.getPackageManager(); 6380 final String authority = uri.getAuthority(); 6381 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6382 if (pi == null) { 6383 Slog.w(TAG, "No content provider found for permission revoke: " 6384 + uri.toSafeString()); 6385 return; 6386 } 6387 6388 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6389 } 6390 } 6391 6392 /** 6393 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6394 * given package. 6395 * 6396 * @param packageName Package name to match, or {@code null} to apply to all 6397 * packages. 6398 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6399 * to all users. 6400 * @param persistable If persistable grants should be removed. 6401 */ 6402 private void removeUriPermissionsForPackageLocked( 6403 String packageName, int userHandle, boolean persistable) { 6404 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6405 throw new IllegalArgumentException("Must narrow by either package or user"); 6406 } 6407 6408 boolean persistChanged = false; 6409 6410 final int size = mGrantedUriPermissions.size(); 6411 for (int i = 0; i < size; i++) { 6412 // Only inspect grants matching user 6413 if (userHandle == UserHandle.USER_ALL 6414 || userHandle == UserHandle.getUserId(mGrantedUriPermissions.keyAt(i))) { 6415 final Iterator<UriPermission> it = mGrantedUriPermissions.valueAt(i) 6416 .values().iterator(); 6417 while (it.hasNext()) { 6418 final UriPermission perm = it.next(); 6419 6420 // Only inspect grants matching package 6421 if (packageName == null || perm.sourcePkg.equals(packageName) 6422 || perm.targetPkg.equals(packageName)) { 6423 persistChanged |= perm.clearModes(~0, persistable); 6424 6425 // Only remove when no modes remain; any persisted grants 6426 // will keep this alive. 6427 if (perm.modeFlags == 0) { 6428 it.remove(); 6429 } 6430 } 6431 } 6432 } 6433 } 6434 6435 if (persistChanged) { 6436 schedulePersistUriGrants(); 6437 } 6438 } 6439 6440 @Override 6441 public IBinder newUriPermissionOwner(String name) { 6442 enforceNotIsolatedCaller("newUriPermissionOwner"); 6443 synchronized(this) { 6444 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6445 return owner.getExternalTokenLocked(); 6446 } 6447 } 6448 6449 @Override 6450 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6451 Uri uri, int modeFlags) { 6452 synchronized(this) { 6453 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6454 if (owner == null) { 6455 throw new IllegalArgumentException("Unknown owner: " + token); 6456 } 6457 if (fromUid != Binder.getCallingUid()) { 6458 if (Binder.getCallingUid() != Process.myUid()) { 6459 // Only system code can grant URI permissions on behalf 6460 // of other users. 6461 throw new SecurityException("nice try"); 6462 } 6463 } 6464 if (targetPkg == null) { 6465 throw new IllegalArgumentException("null target"); 6466 } 6467 if (uri == null) { 6468 throw new IllegalArgumentException("null uri"); 6469 } 6470 6471 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6472 } 6473 } 6474 6475 @Override 6476 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6477 synchronized(this) { 6478 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6479 if (owner == null) { 6480 throw new IllegalArgumentException("Unknown owner: " + token); 6481 } 6482 6483 if (uri == null) { 6484 owner.removeUriPermissionsLocked(mode); 6485 } else { 6486 owner.removeUriPermissionLocked(uri, mode); 6487 } 6488 } 6489 } 6490 6491 private void schedulePersistUriGrants() { 6492 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6493 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6494 10 * DateUtils.SECOND_IN_MILLIS); 6495 } 6496 } 6497 6498 private void writeGrantedUriPermissions() { 6499 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6500 6501 // Snapshot permissions so we can persist without lock 6502 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6503 synchronized (this) { 6504 final int size = mGrantedUriPermissions.size(); 6505 for (int i = 0 ; i < size; i++) { 6506 for (UriPermission perm : mGrantedUriPermissions.valueAt(i).values()) { 6507 if (perm.persistedModeFlags != 0) { 6508 persist.add(perm.snapshot()); 6509 } 6510 } 6511 } 6512 } 6513 6514 FileOutputStream fos = null; 6515 try { 6516 fos = mGrantFile.startWrite(); 6517 6518 XmlSerializer out = new FastXmlSerializer(); 6519 out.setOutput(fos, "utf-8"); 6520 out.startDocument(null, true); 6521 out.startTag(null, TAG_URI_GRANTS); 6522 for (UriPermission.Snapshot perm : persist) { 6523 out.startTag(null, TAG_URI_GRANT); 6524 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6525 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6526 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6527 out.attribute(null, ATTR_URI, String.valueOf(perm.uri)); 6528 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6529 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6530 out.endTag(null, TAG_URI_GRANT); 6531 } 6532 out.endTag(null, TAG_URI_GRANTS); 6533 out.endDocument(); 6534 6535 mGrantFile.finishWrite(fos); 6536 } catch (IOException e) { 6537 if (fos != null) { 6538 mGrantFile.failWrite(fos); 6539 } 6540 } 6541 } 6542 6543 private void readGrantedUriPermissionsLocked() { 6544 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6545 6546 final long now = System.currentTimeMillis(); 6547 6548 FileInputStream fis = null; 6549 try { 6550 fis = mGrantFile.openRead(); 6551 final XmlPullParser in = Xml.newPullParser(); 6552 in.setInput(fis, null); 6553 6554 int type; 6555 while ((type = in.next()) != END_DOCUMENT) { 6556 final String tag = in.getName(); 6557 if (type == START_TAG) { 6558 if (TAG_URI_GRANT.equals(tag)) { 6559 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6560 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6561 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6562 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6563 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6564 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6565 6566 // Sanity check that provider still belongs to source package 6567 final ProviderInfo pi = getProviderInfoLocked( 6568 uri.getAuthority(), userHandle); 6569 if (pi != null && sourcePkg.equals(pi.packageName)) { 6570 int targetUid = -1; 6571 try { 6572 targetUid = AppGlobals.getPackageManager() 6573 .getPackageUid(targetPkg, userHandle); 6574 } catch (RemoteException e) { 6575 } 6576 if (targetUid != -1) { 6577 final UriPermission perm = findOrCreateUriPermissionLocked( 6578 sourcePkg, targetPkg, targetUid, uri); 6579 perm.initPersistedModes(modeFlags, createdTime); 6580 } 6581 } else { 6582 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6583 + " but instead found " + pi); 6584 } 6585 } 6586 } 6587 } 6588 } catch (FileNotFoundException e) { 6589 // Missing grants is okay 6590 } catch (IOException e) { 6591 Log.wtf(TAG, "Failed reading Uri grants", e); 6592 } catch (XmlPullParserException e) { 6593 Log.wtf(TAG, "Failed reading Uri grants", e); 6594 } finally { 6595 IoUtils.closeQuietly(fis); 6596 } 6597 } 6598 6599 @Override 6600 public void takePersistableUriPermission(Uri uri, int modeFlags) { 6601 enforceNotIsolatedCaller("takePersistableUriPermission"); 6602 6603 Preconditions.checkFlagsArgument(modeFlags, 6604 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6605 6606 synchronized (this) { 6607 final int callingUid = Binder.getCallingUid(); 6608 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6609 if (perm == null) { 6610 throw new SecurityException("No permission grant found for UID " + callingUid 6611 + " and Uri " + uri.toSafeString()); 6612 } 6613 6614 boolean persistChanged = perm.takePersistableModes(modeFlags); 6615 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6616 6617 if (persistChanged) { 6618 schedulePersistUriGrants(); 6619 } 6620 } 6621 } 6622 6623 @Override 6624 public void releasePersistableUriPermission(Uri uri, int modeFlags) { 6625 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6626 6627 Preconditions.checkFlagsArgument(modeFlags, 6628 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6629 6630 synchronized (this) { 6631 final int callingUid = Binder.getCallingUid(); 6632 6633 final UriPermission perm = findUriPermissionLocked(callingUid, uri); 6634 if (perm == null) { 6635 Slog.w(TAG, "No permission grant found for UID " + callingUid + " and Uri " 6636 + uri.toSafeString()); 6637 return; 6638 } 6639 6640 final boolean persistChanged = perm.releasePersistableModes(modeFlags); 6641 removeUriPermissionIfNeededLocked(perm); 6642 if (persistChanged) { 6643 schedulePersistUriGrants(); 6644 } 6645 } 6646 } 6647 6648 /** 6649 * Prune any older {@link UriPermission} for the given UID until outstanding 6650 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6651 * 6652 * @return if any mutations occured that require persisting. 6653 */ 6654 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6655 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6656 if (perms == null) return false; 6657 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6658 6659 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6660 for (UriPermission perm : perms.values()) { 6661 if (perm.persistedModeFlags != 0) { 6662 persisted.add(perm); 6663 } 6664 } 6665 6666 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6667 if (trimCount <= 0) return false; 6668 6669 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6670 for (int i = 0; i < trimCount; i++) { 6671 final UriPermission perm = persisted.get(i); 6672 6673 if (DEBUG_URI_PERMISSION) { 6674 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6675 } 6676 6677 perm.releasePersistableModes(~0); 6678 removeUriPermissionIfNeededLocked(perm); 6679 } 6680 6681 return true; 6682 } 6683 6684 @Override 6685 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6686 String packageName, boolean incoming) { 6687 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6688 Preconditions.checkNotNull(packageName, "packageName"); 6689 6690 final int callingUid = Binder.getCallingUid(); 6691 final IPackageManager pm = AppGlobals.getPackageManager(); 6692 try { 6693 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6694 if (packageUid != callingUid) { 6695 throw new SecurityException( 6696 "Package " + packageName + " does not belong to calling UID " + callingUid); 6697 } 6698 } catch (RemoteException e) { 6699 throw new SecurityException("Failed to verify package name ownership"); 6700 } 6701 6702 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6703 synchronized (this) { 6704 if (incoming) { 6705 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 6706 if (perms == null) { 6707 Slog.w(TAG, "No permission grants found for " + packageName); 6708 } else { 6709 final int size = perms.size(); 6710 for (int i = 0; i < size; i++) { 6711 final UriPermission perm = perms.valueAt(i); 6712 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6713 result.add(perm.buildPersistedPublicApiObject()); 6714 } 6715 } 6716 } 6717 } else { 6718 final int size = mGrantedUriPermissions.size(); 6719 for (int i = 0; i < size; i++) { 6720 final ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6721 final int permsSize = perms.size(); 6722 for (int j = 0; j < permsSize; j++) { 6723 final UriPermission perm = perms.valueAt(j); 6724 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6725 result.add(perm.buildPersistedPublicApiObject()); 6726 } 6727 } 6728 } 6729 } 6730 } 6731 return new ParceledListSlice<android.content.UriPermission>(result); 6732 } 6733 6734 @Override 6735 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6736 synchronized (this) { 6737 ProcessRecord app = 6738 who != null ? getRecordForAppLocked(who) : null; 6739 if (app == null) return; 6740 6741 Message msg = Message.obtain(); 6742 msg.what = WAIT_FOR_DEBUGGER_MSG; 6743 msg.obj = app; 6744 msg.arg1 = waiting ? 1 : 0; 6745 mHandler.sendMessage(msg); 6746 } 6747 } 6748 6749 @Override 6750 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6751 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6752 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6753 outInfo.availMem = Process.getFreeMemory(); 6754 outInfo.totalMem = Process.getTotalMemory(); 6755 outInfo.threshold = homeAppMem; 6756 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6757 outInfo.hiddenAppThreshold = cachedAppMem; 6758 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6759 ProcessList.SERVICE_ADJ); 6760 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6761 ProcessList.VISIBLE_APP_ADJ); 6762 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6763 ProcessList.FOREGROUND_APP_ADJ); 6764 } 6765 6766 // ========================================================= 6767 // TASK MANAGEMENT 6768 // ========================================================= 6769 6770 @Override 6771 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6772 IThumbnailReceiver receiver) { 6773 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6774 6775 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6776 ActivityRecord topRecord = null; 6777 6778 synchronized(this) { 6779 if (localLOGV) Slog.v( 6780 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6781 + ", receiver=" + receiver); 6782 6783 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6784 != PackageManager.PERMISSION_GRANTED) { 6785 if (receiver != null) { 6786 // If the caller wants to wait for pending thumbnails, 6787 // it ain't gonna get them. 6788 try { 6789 receiver.finished(); 6790 } catch (RemoteException ex) { 6791 } 6792 } 6793 String msg = "Permission Denial: getTasks() from pid=" 6794 + Binder.getCallingPid() 6795 + ", uid=" + Binder.getCallingUid() 6796 + " requires " + android.Manifest.permission.GET_TASKS; 6797 Slog.w(TAG, msg); 6798 throw new SecurityException(msg); 6799 } 6800 6801 // TODO: Improve with MRU list from all ActivityStacks. 6802 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6803 6804 if (!pending.pendingRecords.isEmpty()) { 6805 mPendingThumbnails.add(pending); 6806 } 6807 } 6808 6809 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6810 6811 if (topRecord != null) { 6812 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6813 try { 6814 IApplicationThread topThumbnail = topRecord.app.thread; 6815 topThumbnail.requestThumbnail(topRecord.appToken); 6816 } catch (Exception e) { 6817 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6818 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6819 } 6820 } 6821 6822 if (pending == null && receiver != null) { 6823 // In this case all thumbnails were available and the client 6824 // is being asked to be told when the remaining ones come in... 6825 // which is unusually, since the top-most currently running 6826 // activity should never have a canned thumbnail! Oh well. 6827 try { 6828 receiver.finished(); 6829 } catch (RemoteException ex) { 6830 } 6831 } 6832 6833 return list; 6834 } 6835 6836 TaskRecord getMostRecentTask() { 6837 return mRecentTasks.get(0); 6838 } 6839 6840 @Override 6841 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6842 int flags, int userId) { 6843 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6844 false, true, "getRecentTasks", null); 6845 6846 synchronized (this) { 6847 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6848 "getRecentTasks()"); 6849 final boolean detailed = checkCallingPermission( 6850 android.Manifest.permission.GET_DETAILED_TASKS) 6851 == PackageManager.PERMISSION_GRANTED; 6852 6853 IPackageManager pm = AppGlobals.getPackageManager(); 6854 6855 final int N = mRecentTasks.size(); 6856 ArrayList<ActivityManager.RecentTaskInfo> res 6857 = new ArrayList<ActivityManager.RecentTaskInfo>( 6858 maxNum < N ? maxNum : N); 6859 6860 final Set<Integer> includedUsers; 6861 if ((flags & ActivityManager.RECENT_INCLUDE_RELATED) != 0) { 6862 includedUsers = getRelatedUsersLocked(userId); 6863 } else { 6864 includedUsers = new HashSet<Integer>(); 6865 } 6866 includedUsers.add(Integer.valueOf(userId)); 6867 for (int i=0; i<N && maxNum > 0; i++) { 6868 TaskRecord tr = mRecentTasks.get(i); 6869 // Only add calling user or related users recent tasks 6870 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 6871 6872 // Return the entry if desired by the caller. We always return 6873 // the first entry, because callers always expect this to be the 6874 // foreground app. We may filter others if the caller has 6875 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6876 // we should exclude the entry. 6877 6878 if (i == 0 6879 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6880 || (tr.intent == null) 6881 || ((tr.intent.getFlags() 6882 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6883 ActivityManager.RecentTaskInfo rti 6884 = new ActivityManager.RecentTaskInfo(); 6885 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6886 rti.persistentId = tr.taskId; 6887 rti.baseIntent = new Intent( 6888 tr.intent != null ? tr.intent : tr.affinityIntent); 6889 if (!detailed) { 6890 rti.baseIntent.replaceExtras((Bundle)null); 6891 } 6892 rti.origActivity = tr.origActivity; 6893 rti.description = tr.lastDescription; 6894 rti.stackId = tr.stack.mStackId; 6895 rti.userId = tr.userId; 6896 6897 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6898 // Check whether this activity is currently available. 6899 try { 6900 if (rti.origActivity != null) { 6901 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6902 == null) { 6903 continue; 6904 } 6905 } else if (rti.baseIntent != null) { 6906 if (pm.queryIntentActivities(rti.baseIntent, 6907 null, 0, userId) == null) { 6908 continue; 6909 } 6910 } 6911 } catch (RemoteException e) { 6912 // Will never happen. 6913 } 6914 } 6915 6916 res.add(rti); 6917 maxNum--; 6918 } 6919 } 6920 return res; 6921 } 6922 } 6923 6924 private TaskRecord recentTaskForIdLocked(int id) { 6925 final int N = mRecentTasks.size(); 6926 for (int i=0; i<N; i++) { 6927 TaskRecord tr = mRecentTasks.get(i); 6928 if (tr.taskId == id) { 6929 return tr; 6930 } 6931 } 6932 return null; 6933 } 6934 6935 @Override 6936 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 6937 synchronized (this) { 6938 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6939 "getTaskThumbnails()"); 6940 TaskRecord tr = recentTaskForIdLocked(id); 6941 if (tr != null) { 6942 return tr.getTaskThumbnailsLocked(); 6943 } 6944 } 6945 return null; 6946 } 6947 6948 @Override 6949 public Bitmap getTaskTopThumbnail(int id) { 6950 synchronized (this) { 6951 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 6952 "getTaskTopThumbnail()"); 6953 TaskRecord tr = recentTaskForIdLocked(id); 6954 if (tr != null) { 6955 return tr.getTaskTopThumbnailLocked(); 6956 } 6957 } 6958 return null; 6959 } 6960 6961 @Override 6962 public boolean removeSubTask(int taskId, int subTaskIndex) { 6963 synchronized (this) { 6964 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 6965 "removeSubTask()"); 6966 long ident = Binder.clearCallingIdentity(); 6967 try { 6968 TaskRecord tr = recentTaskForIdLocked(taskId); 6969 if (tr != null) { 6970 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 6971 } 6972 return false; 6973 } finally { 6974 Binder.restoreCallingIdentity(ident); 6975 } 6976 } 6977 } 6978 6979 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 6980 if (!pr.killedByAm) { 6981 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 6982 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 6983 pr.processName, pr.setAdj, reason); 6984 pr.killedByAm = true; 6985 Process.killProcessQuiet(pr.pid); 6986 } 6987 } 6988 6989 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 6990 tr.disposeThumbnail(); 6991 mRecentTasks.remove(tr); 6992 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 6993 Intent baseIntent = new Intent( 6994 tr.intent != null ? tr.intent : tr.affinityIntent); 6995 ComponentName component = baseIntent.getComponent(); 6996 if (component == null) { 6997 Slog.w(TAG, "Now component for base intent of task: " + tr); 6998 return; 6999 } 7000 7001 // Find any running services associated with this app. 7002 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7003 7004 if (killProcesses) { 7005 // Find any running processes associated with this app. 7006 final String pkg = component.getPackageName(); 7007 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7008 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7009 for (int i=0; i<pmap.size(); i++) { 7010 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7011 for (int j=0; j<uids.size(); j++) { 7012 ProcessRecord proc = uids.valueAt(j); 7013 if (proc.userId != tr.userId) { 7014 continue; 7015 } 7016 if (!proc.pkgList.containsKey(pkg)) { 7017 continue; 7018 } 7019 procs.add(proc); 7020 } 7021 } 7022 7023 // Kill the running processes. 7024 for (int i=0; i<procs.size(); i++) { 7025 ProcessRecord pr = procs.get(i); 7026 if (pr == mHomeProcess) { 7027 // Don't kill the home process along with tasks from the same package. 7028 continue; 7029 } 7030 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7031 killUnneededProcessLocked(pr, "remove task"); 7032 } else { 7033 pr.waitingToKill = "remove task"; 7034 } 7035 } 7036 } 7037 } 7038 7039 @Override 7040 public boolean removeTask(int taskId, int flags) { 7041 synchronized (this) { 7042 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7043 "removeTask()"); 7044 long ident = Binder.clearCallingIdentity(); 7045 try { 7046 TaskRecord tr = recentTaskForIdLocked(taskId); 7047 if (tr != null) { 7048 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7049 if (r != null) { 7050 cleanUpRemovedTaskLocked(tr, flags); 7051 return true; 7052 } 7053 if (tr.mActivities.size() == 0) { 7054 // Caller is just removing a recent task that is 7055 // not actively running. That is easy! 7056 cleanUpRemovedTaskLocked(tr, flags); 7057 return true; 7058 } 7059 Slog.w(TAG, "removeTask: task " + taskId 7060 + " does not have activities to remove, " 7061 + " but numActivities=" + tr.numActivities 7062 + ": " + tr); 7063 } 7064 } finally { 7065 Binder.restoreCallingIdentity(ident); 7066 } 7067 } 7068 return false; 7069 } 7070 7071 /** 7072 * TODO: Add mController hook 7073 */ 7074 @Override 7075 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7076 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7077 "moveTaskToFront()"); 7078 7079 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7080 synchronized(this) { 7081 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7082 Binder.getCallingUid(), "Task to front")) { 7083 ActivityOptions.abort(options); 7084 return; 7085 } 7086 final long origId = Binder.clearCallingIdentity(); 7087 try { 7088 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7089 if (task == null) { 7090 return; 7091 } 7092 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7093 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7094 return; 7095 } 7096 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7097 } finally { 7098 Binder.restoreCallingIdentity(origId); 7099 } 7100 ActivityOptions.abort(options); 7101 } 7102 } 7103 7104 @Override 7105 public void moveTaskToBack(int taskId) { 7106 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7107 "moveTaskToBack()"); 7108 7109 synchronized(this) { 7110 TaskRecord tr = recentTaskForIdLocked(taskId); 7111 if (tr != null) { 7112 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7113 ActivityStack stack = tr.stack; 7114 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7115 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7116 Binder.getCallingUid(), "Task to back")) { 7117 return; 7118 } 7119 } 7120 final long origId = Binder.clearCallingIdentity(); 7121 try { 7122 stack.moveTaskToBackLocked(taskId, null); 7123 } finally { 7124 Binder.restoreCallingIdentity(origId); 7125 } 7126 } 7127 } 7128 } 7129 7130 /** 7131 * Moves an activity, and all of the other activities within the same task, to the bottom 7132 * of the history stack. The activity's order within the task is unchanged. 7133 * 7134 * @param token A reference to the activity we wish to move 7135 * @param nonRoot If false then this only works if the activity is the root 7136 * of a task; if true it will work for any activity in a task. 7137 * @return Returns true if the move completed, false if not. 7138 */ 7139 @Override 7140 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7141 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7142 synchronized(this) { 7143 final long origId = Binder.clearCallingIdentity(); 7144 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7145 if (taskId >= 0) { 7146 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7147 } 7148 Binder.restoreCallingIdentity(origId); 7149 } 7150 return false; 7151 } 7152 7153 @Override 7154 public void moveTaskBackwards(int task) { 7155 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7156 "moveTaskBackwards()"); 7157 7158 synchronized(this) { 7159 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7160 Binder.getCallingUid(), "Task backwards")) { 7161 return; 7162 } 7163 final long origId = Binder.clearCallingIdentity(); 7164 moveTaskBackwardsLocked(task); 7165 Binder.restoreCallingIdentity(origId); 7166 } 7167 } 7168 7169 private final void moveTaskBackwardsLocked(int task) { 7170 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7171 } 7172 7173 @Override 7174 public IBinder getHomeActivityToken() throws RemoteException { 7175 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7176 "getHomeActivityToken()"); 7177 synchronized (this) { 7178 return mStackSupervisor.getHomeActivityToken(); 7179 } 7180 } 7181 7182 @Override 7183 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7184 IActivityContainerCallback callback) throws RemoteException { 7185 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7186 "createActivityContainer()"); 7187 synchronized (this) { 7188 if (parentActivityToken == null) { 7189 throw new IllegalArgumentException("parent token must not be null"); 7190 } 7191 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7192 if (r == null) { 7193 return null; 7194 } 7195 return mStackSupervisor.createActivityContainer(r, callback); 7196 } 7197 } 7198 7199 @Override 7200 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7201 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7202 "deleteActivityContainer()"); 7203 synchronized (this) { 7204 mStackSupervisor.deleteActivityContainer(container); 7205 } 7206 } 7207 7208 @Override 7209 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7210 throws RemoteException { 7211 synchronized (this) { 7212 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7213 if (stack != null) { 7214 return stack.mActivityContainer; 7215 } 7216 return null; 7217 } 7218 } 7219 7220 @Override 7221 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7222 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7223 "moveTaskToStack()"); 7224 if (stackId == HOME_STACK_ID) { 7225 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7226 new RuntimeException("here").fillInStackTrace()); 7227 } 7228 synchronized (this) { 7229 long ident = Binder.clearCallingIdentity(); 7230 try { 7231 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7232 + stackId + " toTop=" + toTop); 7233 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7234 } finally { 7235 Binder.restoreCallingIdentity(ident); 7236 } 7237 } 7238 } 7239 7240 @Override 7241 public void resizeStack(int stackBoxId, Rect bounds) { 7242 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7243 "resizeStackBox()"); 7244 long ident = Binder.clearCallingIdentity(); 7245 try { 7246 mWindowManager.resizeStack(stackBoxId, bounds); 7247 } finally { 7248 Binder.restoreCallingIdentity(ident); 7249 } 7250 } 7251 7252 @Override 7253 public List<StackInfo> getAllStackInfos() { 7254 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7255 "getAllStackInfos()"); 7256 long ident = Binder.clearCallingIdentity(); 7257 try { 7258 synchronized (this) { 7259 return mStackSupervisor.getAllStackInfosLocked(); 7260 } 7261 } finally { 7262 Binder.restoreCallingIdentity(ident); 7263 } 7264 } 7265 7266 @Override 7267 public StackInfo getStackInfo(int stackId) { 7268 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7269 "getStackInfo()"); 7270 long ident = Binder.clearCallingIdentity(); 7271 try { 7272 synchronized (this) { 7273 return mStackSupervisor.getStackInfoLocked(stackId); 7274 } 7275 } finally { 7276 Binder.restoreCallingIdentity(ident); 7277 } 7278 } 7279 7280 @Override 7281 public boolean isInHomeStack(int taskId) { 7282 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7283 "getStackInfo()"); 7284 long ident = Binder.clearCallingIdentity(); 7285 try { 7286 synchronized (this) { 7287 TaskRecord tr = recentTaskForIdLocked(taskId); 7288 if (tr != null) { 7289 return tr.stack.isHomeStack(); 7290 } 7291 } 7292 } finally { 7293 Binder.restoreCallingIdentity(ident); 7294 } 7295 return false; 7296 } 7297 7298 @Override 7299 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7300 synchronized(this) { 7301 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7302 } 7303 } 7304 7305 private boolean isLockTaskAuthorized(ComponentName name) { 7306// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7307// "startLockTaskMode()"); 7308// DevicePolicyManager dpm = (DevicePolicyManager) 7309// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7310// return dpm != null && dpm.isLockTaskPermitted(name); 7311 return true; 7312 } 7313 7314 private void startLockTaskMode(TaskRecord task) { 7315 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7316 return; 7317 } 7318 long ident = Binder.clearCallingIdentity(); 7319 try { 7320 synchronized (this) { 7321 // Since we lost lock on task, make sure it is still there. 7322 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7323 if (task != null) { 7324 mStackSupervisor.setLockTaskModeLocked(task); 7325 } 7326 } 7327 } finally { 7328 Binder.restoreCallingIdentity(ident); 7329 } 7330 } 7331 7332 @Override 7333 public void startLockTaskMode(int taskId) { 7334 long ident = Binder.clearCallingIdentity(); 7335 try { 7336 final TaskRecord task; 7337 synchronized (this) { 7338 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7339 } 7340 if (task != null) { 7341 startLockTaskMode(task); 7342 } 7343 } finally { 7344 Binder.restoreCallingIdentity(ident); 7345 } 7346 } 7347 7348 @Override 7349 public void startLockTaskMode(IBinder token) { 7350 long ident = Binder.clearCallingIdentity(); 7351 try { 7352 final TaskRecord task; 7353 synchronized (this) { 7354 final ActivityRecord r = ActivityRecord.forToken(token); 7355 if (r == null) { 7356 return; 7357 } 7358 task = r.task; 7359 } 7360 if (task != null) { 7361 startLockTaskMode(task); 7362 } 7363 } finally { 7364 Binder.restoreCallingIdentity(ident); 7365 } 7366 } 7367 7368 @Override 7369 public void stopLockTaskMode() { 7370// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7371// "stopLockTaskMode()"); 7372 synchronized (this) { 7373 mStackSupervisor.setLockTaskModeLocked(null); 7374 } 7375 } 7376 7377 @Override 7378 public boolean isInLockTaskMode() { 7379 synchronized (this) { 7380 return mStackSupervisor.isInLockTaskMode(); 7381 } 7382 } 7383 7384 // ========================================================= 7385 // THUMBNAILS 7386 // ========================================================= 7387 7388 public void reportThumbnail(IBinder token, 7389 Bitmap thumbnail, CharSequence description) { 7390 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7391 final long origId = Binder.clearCallingIdentity(); 7392 sendPendingThumbnail(null, token, thumbnail, description, true); 7393 Binder.restoreCallingIdentity(origId); 7394 } 7395 7396 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7397 Bitmap thumbnail, CharSequence description, boolean always) { 7398 TaskRecord task; 7399 ArrayList<PendingThumbnailsRecord> receivers = null; 7400 7401 //System.out.println("Send pending thumbnail: " + r); 7402 7403 synchronized(this) { 7404 if (r == null) { 7405 r = ActivityRecord.isInStackLocked(token); 7406 if (r == null) { 7407 return; 7408 } 7409 } 7410 if (thumbnail == null && r.thumbHolder != null) { 7411 thumbnail = r.thumbHolder.lastThumbnail; 7412 description = r.thumbHolder.lastDescription; 7413 } 7414 if (thumbnail == null && !always) { 7415 // If there is no thumbnail, and this entry is not actually 7416 // going away, then abort for now and pick up the next 7417 // thumbnail we get. 7418 return; 7419 } 7420 task = r.task; 7421 7422 int N = mPendingThumbnails.size(); 7423 int i=0; 7424 while (i<N) { 7425 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7426 //System.out.println("Looking in " + pr.pendingRecords); 7427 if (pr.pendingRecords.remove(r)) { 7428 if (receivers == null) { 7429 receivers = new ArrayList<PendingThumbnailsRecord>(); 7430 } 7431 receivers.add(pr); 7432 if (pr.pendingRecords.size() == 0) { 7433 pr.finished = true; 7434 mPendingThumbnails.remove(i); 7435 N--; 7436 continue; 7437 } 7438 } 7439 i++; 7440 } 7441 } 7442 7443 if (receivers != null) { 7444 final int N = receivers.size(); 7445 for (int i=0; i<N; i++) { 7446 try { 7447 PendingThumbnailsRecord pr = receivers.get(i); 7448 pr.receiver.newThumbnail( 7449 task != null ? task.taskId : -1, thumbnail, description); 7450 if (pr.finished) { 7451 pr.receiver.finished(); 7452 } 7453 } catch (Exception e) { 7454 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7455 } 7456 } 7457 } 7458 } 7459 7460 // ========================================================= 7461 // CONTENT PROVIDERS 7462 // ========================================================= 7463 7464 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7465 List<ProviderInfo> providers = null; 7466 try { 7467 providers = AppGlobals.getPackageManager(). 7468 queryContentProviders(app.processName, app.uid, 7469 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7470 } catch (RemoteException ex) { 7471 } 7472 if (DEBUG_MU) 7473 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7474 int userId = app.userId; 7475 if (providers != null) { 7476 int N = providers.size(); 7477 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7478 for (int i=0; i<N; i++) { 7479 ProviderInfo cpi = 7480 (ProviderInfo)providers.get(i); 7481 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7482 cpi.name, cpi.flags); 7483 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7484 // This is a singleton provider, but a user besides the 7485 // default user is asking to initialize a process it runs 7486 // in... well, no, it doesn't actually run in this process, 7487 // it runs in the process of the default user. Get rid of it. 7488 providers.remove(i); 7489 N--; 7490 i--; 7491 continue; 7492 } 7493 7494 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7495 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7496 if (cpr == null) { 7497 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7498 mProviderMap.putProviderByClass(comp, cpr); 7499 } 7500 if (DEBUG_MU) 7501 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7502 app.pubProviders.put(cpi.name, cpr); 7503 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7504 // Don't add this if it is a platform component that is marked 7505 // to run in multiple processes, because this is actually 7506 // part of the framework so doesn't make sense to track as a 7507 // separate apk in the process. 7508 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7509 } 7510 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7511 } 7512 } 7513 return providers; 7514 } 7515 7516 /** 7517 * Check if {@link ProcessRecord} has a possible chance at accessing the 7518 * given {@link ProviderInfo}. Final permission checking is always done 7519 * in {@link ContentProvider}. 7520 */ 7521 private final String checkContentProviderPermissionLocked( 7522 ProviderInfo cpi, ProcessRecord r) { 7523 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7524 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7525 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7526 cpi.applicationInfo.uid, cpi.exported) 7527 == PackageManager.PERMISSION_GRANTED) { 7528 return null; 7529 } 7530 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7531 cpi.applicationInfo.uid, cpi.exported) 7532 == PackageManager.PERMISSION_GRANTED) { 7533 return null; 7534 } 7535 7536 PathPermission[] pps = cpi.pathPermissions; 7537 if (pps != null) { 7538 int i = pps.length; 7539 while (i > 0) { 7540 i--; 7541 PathPermission pp = pps[i]; 7542 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7543 cpi.applicationInfo.uid, cpi.exported) 7544 == PackageManager.PERMISSION_GRANTED) { 7545 return null; 7546 } 7547 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7548 cpi.applicationInfo.uid, cpi.exported) 7549 == PackageManager.PERMISSION_GRANTED) { 7550 return null; 7551 } 7552 } 7553 } 7554 7555 ArrayMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7556 if (perms != null) { 7557 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) { 7558 if (uri.getKey().getAuthority().equals(cpi.authority)) { 7559 return null; 7560 } 7561 } 7562 } 7563 7564 String msg; 7565 if (!cpi.exported) { 7566 msg = "Permission Denial: opening provider " + cpi.name 7567 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7568 + ", uid=" + callingUid + ") that is not exported from uid " 7569 + cpi.applicationInfo.uid; 7570 } else { 7571 msg = "Permission Denial: opening provider " + cpi.name 7572 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7573 + ", uid=" + callingUid + ") requires " 7574 + cpi.readPermission + " or " + cpi.writePermission; 7575 } 7576 Slog.w(TAG, msg); 7577 return msg; 7578 } 7579 7580 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7581 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7582 if (r != null) { 7583 for (int i=0; i<r.conProviders.size(); i++) { 7584 ContentProviderConnection conn = r.conProviders.get(i); 7585 if (conn.provider == cpr) { 7586 if (DEBUG_PROVIDER) Slog.v(TAG, 7587 "Adding provider requested by " 7588 + r.processName + " from process " 7589 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7590 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7591 if (stable) { 7592 conn.stableCount++; 7593 conn.numStableIncs++; 7594 } else { 7595 conn.unstableCount++; 7596 conn.numUnstableIncs++; 7597 } 7598 return conn; 7599 } 7600 } 7601 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7602 if (stable) { 7603 conn.stableCount = 1; 7604 conn.numStableIncs = 1; 7605 } else { 7606 conn.unstableCount = 1; 7607 conn.numUnstableIncs = 1; 7608 } 7609 cpr.connections.add(conn); 7610 r.conProviders.add(conn); 7611 return conn; 7612 } 7613 cpr.addExternalProcessHandleLocked(externalProcessToken); 7614 return null; 7615 } 7616 7617 boolean decProviderCountLocked(ContentProviderConnection conn, 7618 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7619 if (conn != null) { 7620 cpr = conn.provider; 7621 if (DEBUG_PROVIDER) Slog.v(TAG, 7622 "Removing provider requested by " 7623 + conn.client.processName + " from process " 7624 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7625 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7626 if (stable) { 7627 conn.stableCount--; 7628 } else { 7629 conn.unstableCount--; 7630 } 7631 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7632 cpr.connections.remove(conn); 7633 conn.client.conProviders.remove(conn); 7634 return true; 7635 } 7636 return false; 7637 } 7638 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7639 return false; 7640 } 7641 7642 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7643 String name, IBinder token, boolean stable, int userId) { 7644 ContentProviderRecord cpr; 7645 ContentProviderConnection conn = null; 7646 ProviderInfo cpi = null; 7647 7648 synchronized(this) { 7649 ProcessRecord r = null; 7650 if (caller != null) { 7651 r = getRecordForAppLocked(caller); 7652 if (r == null) { 7653 throw new SecurityException( 7654 "Unable to find app for caller " + caller 7655 + " (pid=" + Binder.getCallingPid() 7656 + ") when getting content provider " + name); 7657 } 7658 } 7659 7660 // First check if this content provider has been published... 7661 cpr = mProviderMap.getProviderByName(name, userId); 7662 boolean providerRunning = cpr != null; 7663 if (providerRunning) { 7664 cpi = cpr.info; 7665 String msg; 7666 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7667 throw new SecurityException(msg); 7668 } 7669 7670 if (r != null && cpr.canRunHere(r)) { 7671 // This provider has been published or is in the process 7672 // of being published... but it is also allowed to run 7673 // in the caller's process, so don't make a connection 7674 // and just let the caller instantiate its own instance. 7675 ContentProviderHolder holder = cpr.newHolder(null); 7676 // don't give caller the provider object, it needs 7677 // to make its own. 7678 holder.provider = null; 7679 return holder; 7680 } 7681 7682 final long origId = Binder.clearCallingIdentity(); 7683 7684 // In this case the provider instance already exists, so we can 7685 // return it right away. 7686 conn = incProviderCountLocked(r, cpr, token, stable); 7687 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7688 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7689 // If this is a perceptible app accessing the provider, 7690 // make sure to count it as being accessed and thus 7691 // back up on the LRU list. This is good because 7692 // content providers are often expensive to start. 7693 updateLruProcessLocked(cpr.proc, false, null); 7694 } 7695 } 7696 7697 if (cpr.proc != null) { 7698 if (false) { 7699 if (cpr.name.flattenToShortString().equals( 7700 "com.android.providers.calendar/.CalendarProvider2")) { 7701 Slog.v(TAG, "****************** KILLING " 7702 + cpr.name.flattenToShortString()); 7703 Process.killProcess(cpr.proc.pid); 7704 } 7705 } 7706 boolean success = updateOomAdjLocked(cpr.proc); 7707 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7708 // NOTE: there is still a race here where a signal could be 7709 // pending on the process even though we managed to update its 7710 // adj level. Not sure what to do about this, but at least 7711 // the race is now smaller. 7712 if (!success) { 7713 // Uh oh... it looks like the provider's process 7714 // has been killed on us. We need to wait for a new 7715 // process to be started, and make sure its death 7716 // doesn't kill our process. 7717 Slog.i(TAG, 7718 "Existing provider " + cpr.name.flattenToShortString() 7719 + " is crashing; detaching " + r); 7720 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7721 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7722 if (!lastRef) { 7723 // This wasn't the last ref our process had on 7724 // the provider... we have now been killed, bail. 7725 return null; 7726 } 7727 providerRunning = false; 7728 conn = null; 7729 } 7730 } 7731 7732 Binder.restoreCallingIdentity(origId); 7733 } 7734 7735 boolean singleton; 7736 if (!providerRunning) { 7737 try { 7738 cpi = AppGlobals.getPackageManager(). 7739 resolveContentProvider(name, 7740 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7741 } catch (RemoteException ex) { 7742 } 7743 if (cpi == null) { 7744 return null; 7745 } 7746 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7747 cpi.name, cpi.flags); 7748 if (singleton) { 7749 userId = 0; 7750 } 7751 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7752 7753 String msg; 7754 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7755 throw new SecurityException(msg); 7756 } 7757 7758 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7759 && !cpi.processName.equals("system")) { 7760 // If this content provider does not run in the system 7761 // process, and the system is not yet ready to run other 7762 // processes, then fail fast instead of hanging. 7763 throw new IllegalArgumentException( 7764 "Attempt to launch content provider before system ready"); 7765 } 7766 7767 // Make sure that the user who owns this provider is started. If not, 7768 // we don't want to allow it to run. 7769 if (mStartedUsers.get(userId) == null) { 7770 Slog.w(TAG, "Unable to launch app " 7771 + cpi.applicationInfo.packageName + "/" 7772 + cpi.applicationInfo.uid + " for provider " 7773 + name + ": user " + userId + " is stopped"); 7774 return null; 7775 } 7776 7777 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7778 cpr = mProviderMap.getProviderByClass(comp, userId); 7779 final boolean firstClass = cpr == null; 7780 if (firstClass) { 7781 try { 7782 ApplicationInfo ai = 7783 AppGlobals.getPackageManager(). 7784 getApplicationInfo( 7785 cpi.applicationInfo.packageName, 7786 STOCK_PM_FLAGS, userId); 7787 if (ai == null) { 7788 Slog.w(TAG, "No package info for content provider " 7789 + cpi.name); 7790 return null; 7791 } 7792 ai = getAppInfoForUser(ai, userId); 7793 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7794 } catch (RemoteException ex) { 7795 // pm is in same process, this will never happen. 7796 } 7797 } 7798 7799 if (r != null && cpr.canRunHere(r)) { 7800 // If this is a multiprocess provider, then just return its 7801 // info and allow the caller to instantiate it. Only do 7802 // this if the provider is the same user as the caller's 7803 // process, or can run as root (so can be in any process). 7804 return cpr.newHolder(null); 7805 } 7806 7807 if (DEBUG_PROVIDER) { 7808 RuntimeException e = new RuntimeException("here"); 7809 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7810 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7811 } 7812 7813 // This is single process, and our app is now connecting to it. 7814 // See if we are already in the process of launching this 7815 // provider. 7816 final int N = mLaunchingProviders.size(); 7817 int i; 7818 for (i=0; i<N; i++) { 7819 if (mLaunchingProviders.get(i) == cpr) { 7820 break; 7821 } 7822 } 7823 7824 // If the provider is not already being launched, then get it 7825 // started. 7826 if (i >= N) { 7827 final long origId = Binder.clearCallingIdentity(); 7828 7829 try { 7830 // Content provider is now in use, its package can't be stopped. 7831 try { 7832 AppGlobals.getPackageManager().setPackageStoppedState( 7833 cpr.appInfo.packageName, false, userId); 7834 } catch (RemoteException e) { 7835 } catch (IllegalArgumentException e) { 7836 Slog.w(TAG, "Failed trying to unstop package " 7837 + cpr.appInfo.packageName + ": " + e); 7838 } 7839 7840 // Use existing process if already started 7841 ProcessRecord proc = getProcessRecordLocked( 7842 cpi.processName, cpr.appInfo.uid, false); 7843 if (proc != null && proc.thread != null) { 7844 if (DEBUG_PROVIDER) { 7845 Slog.d(TAG, "Installing in existing process " + proc); 7846 } 7847 proc.pubProviders.put(cpi.name, cpr); 7848 try { 7849 proc.thread.scheduleInstallProvider(cpi); 7850 } catch (RemoteException e) { 7851 } 7852 } else { 7853 proc = startProcessLocked(cpi.processName, 7854 cpr.appInfo, false, 0, "content provider", 7855 new ComponentName(cpi.applicationInfo.packageName, 7856 cpi.name), false, false, false); 7857 if (proc == null) { 7858 Slog.w(TAG, "Unable to launch app " 7859 + cpi.applicationInfo.packageName + "/" 7860 + cpi.applicationInfo.uid + " for provider " 7861 + name + ": process is bad"); 7862 return null; 7863 } 7864 } 7865 cpr.launchingApp = proc; 7866 mLaunchingProviders.add(cpr); 7867 } finally { 7868 Binder.restoreCallingIdentity(origId); 7869 } 7870 } 7871 7872 // Make sure the provider is published (the same provider class 7873 // may be published under multiple names). 7874 if (firstClass) { 7875 mProviderMap.putProviderByClass(comp, cpr); 7876 } 7877 7878 mProviderMap.putProviderByName(name, cpr); 7879 conn = incProviderCountLocked(r, cpr, token, stable); 7880 if (conn != null) { 7881 conn.waiting = true; 7882 } 7883 } 7884 } 7885 7886 // Wait for the provider to be published... 7887 synchronized (cpr) { 7888 while (cpr.provider == null) { 7889 if (cpr.launchingApp == null) { 7890 Slog.w(TAG, "Unable to launch app " 7891 + cpi.applicationInfo.packageName + "/" 7892 + cpi.applicationInfo.uid + " for provider " 7893 + name + ": launching app became null"); 7894 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 7895 UserHandle.getUserId(cpi.applicationInfo.uid), 7896 cpi.applicationInfo.packageName, 7897 cpi.applicationInfo.uid, name); 7898 return null; 7899 } 7900 try { 7901 if (DEBUG_MU) { 7902 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 7903 + cpr.launchingApp); 7904 } 7905 if (conn != null) { 7906 conn.waiting = true; 7907 } 7908 cpr.wait(); 7909 } catch (InterruptedException ex) { 7910 } finally { 7911 if (conn != null) { 7912 conn.waiting = false; 7913 } 7914 } 7915 } 7916 } 7917 return cpr != null ? cpr.newHolder(conn) : null; 7918 } 7919 7920 public final ContentProviderHolder getContentProvider( 7921 IApplicationThread caller, String name, int userId, boolean stable) { 7922 enforceNotIsolatedCaller("getContentProvider"); 7923 if (caller == null) { 7924 String msg = "null IApplicationThread when getting content provider " 7925 + name; 7926 Slog.w(TAG, msg); 7927 throw new SecurityException(msg); 7928 } 7929 7930 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7931 false, true, "getContentProvider", null); 7932 return getContentProviderImpl(caller, name, null, stable, userId); 7933 } 7934 7935 public ContentProviderHolder getContentProviderExternal( 7936 String name, int userId, IBinder token) { 7937 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7938 "Do not have permission in call getContentProviderExternal()"); 7939 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 7940 false, true, "getContentProvider", null); 7941 return getContentProviderExternalUnchecked(name, token, userId); 7942 } 7943 7944 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 7945 IBinder token, int userId) { 7946 return getContentProviderImpl(null, name, token, true, userId); 7947 } 7948 7949 /** 7950 * Drop a content provider from a ProcessRecord's bookkeeping 7951 */ 7952 public void removeContentProvider(IBinder connection, boolean stable) { 7953 enforceNotIsolatedCaller("removeContentProvider"); 7954 long ident = Binder.clearCallingIdentity(); 7955 try { 7956 synchronized (this) { 7957 ContentProviderConnection conn; 7958 try { 7959 conn = (ContentProviderConnection)connection; 7960 } catch (ClassCastException e) { 7961 String msg ="removeContentProvider: " + connection 7962 + " not a ContentProviderConnection"; 7963 Slog.w(TAG, msg); 7964 throw new IllegalArgumentException(msg); 7965 } 7966 if (conn == null) { 7967 throw new NullPointerException("connection is null"); 7968 } 7969 if (decProviderCountLocked(conn, null, null, stable)) { 7970 updateOomAdjLocked(); 7971 } 7972 } 7973 } finally { 7974 Binder.restoreCallingIdentity(ident); 7975 } 7976 } 7977 7978 public void removeContentProviderExternal(String name, IBinder token) { 7979 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 7980 "Do not have permission in call removeContentProviderExternal()"); 7981 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 7982 } 7983 7984 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 7985 synchronized (this) { 7986 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 7987 if(cpr == null) { 7988 //remove from mProvidersByClass 7989 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 7990 return; 7991 } 7992 7993 //update content provider record entry info 7994 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 7995 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 7996 if (localCpr.hasExternalProcessHandles()) { 7997 if (localCpr.removeExternalProcessHandleLocked(token)) { 7998 updateOomAdjLocked(); 7999 } else { 8000 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8001 + " with no external reference for token: " 8002 + token + "."); 8003 } 8004 } else { 8005 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8006 + " with no external references."); 8007 } 8008 } 8009 } 8010 8011 public final void publishContentProviders(IApplicationThread caller, 8012 List<ContentProviderHolder> providers) { 8013 if (providers == null) { 8014 return; 8015 } 8016 8017 enforceNotIsolatedCaller("publishContentProviders"); 8018 synchronized (this) { 8019 final ProcessRecord r = getRecordForAppLocked(caller); 8020 if (DEBUG_MU) 8021 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8022 if (r == null) { 8023 throw new SecurityException( 8024 "Unable to find app for caller " + caller 8025 + " (pid=" + Binder.getCallingPid() 8026 + ") when publishing content providers"); 8027 } 8028 8029 final long origId = Binder.clearCallingIdentity(); 8030 8031 final int N = providers.size(); 8032 for (int i=0; i<N; i++) { 8033 ContentProviderHolder src = providers.get(i); 8034 if (src == null || src.info == null || src.provider == null) { 8035 continue; 8036 } 8037 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8038 if (DEBUG_MU) 8039 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8040 if (dst != null) { 8041 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8042 mProviderMap.putProviderByClass(comp, dst); 8043 String names[] = dst.info.authority.split(";"); 8044 for (int j = 0; j < names.length; j++) { 8045 mProviderMap.putProviderByName(names[j], dst); 8046 } 8047 8048 int NL = mLaunchingProviders.size(); 8049 int j; 8050 for (j=0; j<NL; j++) { 8051 if (mLaunchingProviders.get(j) == dst) { 8052 mLaunchingProviders.remove(j); 8053 j--; 8054 NL--; 8055 } 8056 } 8057 synchronized (dst) { 8058 dst.provider = src.provider; 8059 dst.proc = r; 8060 dst.notifyAll(); 8061 } 8062 updateOomAdjLocked(r); 8063 } 8064 } 8065 8066 Binder.restoreCallingIdentity(origId); 8067 } 8068 } 8069 8070 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8071 ContentProviderConnection conn; 8072 try { 8073 conn = (ContentProviderConnection)connection; 8074 } catch (ClassCastException e) { 8075 String msg ="refContentProvider: " + connection 8076 + " not a ContentProviderConnection"; 8077 Slog.w(TAG, msg); 8078 throw new IllegalArgumentException(msg); 8079 } 8080 if (conn == null) { 8081 throw new NullPointerException("connection is null"); 8082 } 8083 8084 synchronized (this) { 8085 if (stable > 0) { 8086 conn.numStableIncs += stable; 8087 } 8088 stable = conn.stableCount + stable; 8089 if (stable < 0) { 8090 throw new IllegalStateException("stableCount < 0: " + stable); 8091 } 8092 8093 if (unstable > 0) { 8094 conn.numUnstableIncs += unstable; 8095 } 8096 unstable = conn.unstableCount + unstable; 8097 if (unstable < 0) { 8098 throw new IllegalStateException("unstableCount < 0: " + unstable); 8099 } 8100 8101 if ((stable+unstable) <= 0) { 8102 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8103 + stable + " unstable=" + unstable); 8104 } 8105 conn.stableCount = stable; 8106 conn.unstableCount = unstable; 8107 return !conn.dead; 8108 } 8109 } 8110 8111 public void unstableProviderDied(IBinder connection) { 8112 ContentProviderConnection conn; 8113 try { 8114 conn = (ContentProviderConnection)connection; 8115 } catch (ClassCastException e) { 8116 String msg ="refContentProvider: " + connection 8117 + " not a ContentProviderConnection"; 8118 Slog.w(TAG, msg); 8119 throw new IllegalArgumentException(msg); 8120 } 8121 if (conn == null) { 8122 throw new NullPointerException("connection is null"); 8123 } 8124 8125 // Safely retrieve the content provider associated with the connection. 8126 IContentProvider provider; 8127 synchronized (this) { 8128 provider = conn.provider.provider; 8129 } 8130 8131 if (provider == null) { 8132 // Um, yeah, we're way ahead of you. 8133 return; 8134 } 8135 8136 // Make sure the caller is being honest with us. 8137 if (provider.asBinder().pingBinder()) { 8138 // Er, no, still looks good to us. 8139 synchronized (this) { 8140 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8141 + " says " + conn + " died, but we don't agree"); 8142 return; 8143 } 8144 } 8145 8146 // Well look at that! It's dead! 8147 synchronized (this) { 8148 if (conn.provider.provider != provider) { 8149 // But something changed... good enough. 8150 return; 8151 } 8152 8153 ProcessRecord proc = conn.provider.proc; 8154 if (proc == null || proc.thread == null) { 8155 // Seems like the process is already cleaned up. 8156 return; 8157 } 8158 8159 // As far as we're concerned, this is just like receiving a 8160 // death notification... just a bit prematurely. 8161 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8162 + ") early provider death"); 8163 final long ident = Binder.clearCallingIdentity(); 8164 try { 8165 appDiedLocked(proc, proc.pid, proc.thread); 8166 } finally { 8167 Binder.restoreCallingIdentity(ident); 8168 } 8169 } 8170 } 8171 8172 @Override 8173 public void appNotRespondingViaProvider(IBinder connection) { 8174 enforceCallingPermission( 8175 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8176 8177 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8178 if (conn == null) { 8179 Slog.w(TAG, "ContentProviderConnection is null"); 8180 return; 8181 } 8182 8183 final ProcessRecord host = conn.provider.proc; 8184 if (host == null) { 8185 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8186 return; 8187 } 8188 8189 final long token = Binder.clearCallingIdentity(); 8190 try { 8191 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8192 } finally { 8193 Binder.restoreCallingIdentity(token); 8194 } 8195 } 8196 8197 public final void installSystemProviders() { 8198 List<ProviderInfo> providers; 8199 synchronized (this) { 8200 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8201 providers = generateApplicationProvidersLocked(app); 8202 if (providers != null) { 8203 for (int i=providers.size()-1; i>=0; i--) { 8204 ProviderInfo pi = (ProviderInfo)providers.get(i); 8205 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8206 Slog.w(TAG, "Not installing system proc provider " + pi.name 8207 + ": not system .apk"); 8208 providers.remove(i); 8209 } 8210 } 8211 } 8212 } 8213 if (providers != null) { 8214 mSystemThread.installSystemProviders(providers); 8215 } 8216 8217 mCoreSettingsObserver = new CoreSettingsObserver(this); 8218 8219 mUsageStatsService.monitorPackages(); 8220 } 8221 8222 /** 8223 * Allows app to retrieve the MIME type of a URI without having permission 8224 * to access its content provider. 8225 * 8226 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8227 * 8228 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8229 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8230 */ 8231 public String getProviderMimeType(Uri uri, int userId) { 8232 enforceNotIsolatedCaller("getProviderMimeType"); 8233 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8234 userId, false, true, "getProviderMimeType", null); 8235 final String name = uri.getAuthority(); 8236 final long ident = Binder.clearCallingIdentity(); 8237 ContentProviderHolder holder = null; 8238 8239 try { 8240 holder = getContentProviderExternalUnchecked(name, null, userId); 8241 if (holder != null) { 8242 return holder.provider.getType(uri); 8243 } 8244 } catch (RemoteException e) { 8245 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8246 return null; 8247 } finally { 8248 if (holder != null) { 8249 removeContentProviderExternalUnchecked(name, null, userId); 8250 } 8251 Binder.restoreCallingIdentity(ident); 8252 } 8253 8254 return null; 8255 } 8256 8257 // ========================================================= 8258 // GLOBAL MANAGEMENT 8259 // ========================================================= 8260 8261 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8262 boolean isolated) { 8263 String proc = customProcess != null ? customProcess : info.processName; 8264 BatteryStatsImpl.Uid.Proc ps = null; 8265 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8266 int uid = info.uid; 8267 if (isolated) { 8268 int userId = UserHandle.getUserId(uid); 8269 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8270 while (true) { 8271 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8272 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8273 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8274 } 8275 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8276 mNextIsolatedProcessUid++; 8277 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8278 // No process for this uid, use it. 8279 break; 8280 } 8281 stepsLeft--; 8282 if (stepsLeft <= 0) { 8283 return null; 8284 } 8285 } 8286 } 8287 return new ProcessRecord(stats, info, proc, uid); 8288 } 8289 8290 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8291 ProcessRecord app; 8292 if (!isolated) { 8293 app = getProcessRecordLocked(info.processName, info.uid, true); 8294 } else { 8295 app = null; 8296 } 8297 8298 if (app == null) { 8299 app = newProcessRecordLocked(info, null, isolated); 8300 mProcessNames.put(info.processName, app.uid, app); 8301 if (isolated) { 8302 mIsolatedProcesses.put(app.uid, app); 8303 } 8304 updateLruProcessLocked(app, false, null); 8305 updateOomAdjLocked(); 8306 } 8307 8308 // This package really, really can not be stopped. 8309 try { 8310 AppGlobals.getPackageManager().setPackageStoppedState( 8311 info.packageName, false, UserHandle.getUserId(app.uid)); 8312 } catch (RemoteException e) { 8313 } catch (IllegalArgumentException e) { 8314 Slog.w(TAG, "Failed trying to unstop package " 8315 + info.packageName + ": " + e); 8316 } 8317 8318 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8319 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8320 app.persistent = true; 8321 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8322 } 8323 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8324 mPersistentStartingProcesses.add(app); 8325 startProcessLocked(app, "added application", app.processName); 8326 } 8327 8328 return app; 8329 } 8330 8331 public void unhandledBack() { 8332 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8333 "unhandledBack()"); 8334 8335 synchronized(this) { 8336 final long origId = Binder.clearCallingIdentity(); 8337 try { 8338 getFocusedStack().unhandledBackLocked(); 8339 } finally { 8340 Binder.restoreCallingIdentity(origId); 8341 } 8342 } 8343 } 8344 8345 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8346 enforceNotIsolatedCaller("openContentUri"); 8347 final int userId = UserHandle.getCallingUserId(); 8348 String name = uri.getAuthority(); 8349 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8350 ParcelFileDescriptor pfd = null; 8351 if (cph != null) { 8352 // We record the binder invoker's uid in thread-local storage before 8353 // going to the content provider to open the file. Later, in the code 8354 // that handles all permissions checks, we look for this uid and use 8355 // that rather than the Activity Manager's own uid. The effect is that 8356 // we do the check against the caller's permissions even though it looks 8357 // to the content provider like the Activity Manager itself is making 8358 // the request. 8359 sCallerIdentity.set(new Identity( 8360 Binder.getCallingPid(), Binder.getCallingUid())); 8361 try { 8362 pfd = cph.provider.openFile(null, uri, "r", null); 8363 } catch (FileNotFoundException e) { 8364 // do nothing; pfd will be returned null 8365 } finally { 8366 // Ensure that whatever happens, we clean up the identity state 8367 sCallerIdentity.remove(); 8368 } 8369 8370 // We've got the fd now, so we're done with the provider. 8371 removeContentProviderExternalUnchecked(name, null, userId); 8372 } else { 8373 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8374 } 8375 return pfd; 8376 } 8377 8378 // Actually is sleeping or shutting down or whatever else in the future 8379 // is an inactive state. 8380 public boolean isSleepingOrShuttingDown() { 8381 return mSleeping || mShuttingDown; 8382 } 8383 8384 public void goingToSleep() { 8385 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8386 != PackageManager.PERMISSION_GRANTED) { 8387 throw new SecurityException("Requires permission " 8388 + android.Manifest.permission.DEVICE_POWER); 8389 } 8390 8391 synchronized(this) { 8392 mWentToSleep = true; 8393 updateEventDispatchingLocked(); 8394 8395 if (!mSleeping) { 8396 mSleeping = true; 8397 mStackSupervisor.goingToSleepLocked(); 8398 8399 // Initialize the wake times of all processes. 8400 checkExcessivePowerUsageLocked(false); 8401 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8402 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8403 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8404 } 8405 } 8406 } 8407 8408 @Override 8409 public boolean shutdown(int timeout) { 8410 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8411 != PackageManager.PERMISSION_GRANTED) { 8412 throw new SecurityException("Requires permission " 8413 + android.Manifest.permission.SHUTDOWN); 8414 } 8415 8416 boolean timedout = false; 8417 8418 synchronized(this) { 8419 mShuttingDown = true; 8420 updateEventDispatchingLocked(); 8421 timedout = mStackSupervisor.shutdownLocked(timeout); 8422 } 8423 8424 mAppOpsService.shutdown(); 8425 mUsageStatsService.shutdown(); 8426 mBatteryStatsService.shutdown(); 8427 synchronized (this) { 8428 mProcessStats.shutdownLocked(); 8429 } 8430 8431 return timedout; 8432 } 8433 8434 public final void activitySlept(IBinder token) { 8435 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8436 8437 final long origId = Binder.clearCallingIdentity(); 8438 8439 synchronized (this) { 8440 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8441 if (r != null) { 8442 mStackSupervisor.activitySleptLocked(r); 8443 } 8444 } 8445 8446 Binder.restoreCallingIdentity(origId); 8447 } 8448 8449 void logLockScreen(String msg) { 8450 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8451 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8452 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8453 mStackSupervisor.mDismissKeyguardOnNextActivity); 8454 } 8455 8456 private void comeOutOfSleepIfNeededLocked() { 8457 if (!mWentToSleep && !mLockScreenShown) { 8458 if (mSleeping) { 8459 mSleeping = false; 8460 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8461 } 8462 } 8463 } 8464 8465 public void wakingUp() { 8466 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8467 != PackageManager.PERMISSION_GRANTED) { 8468 throw new SecurityException("Requires permission " 8469 + android.Manifest.permission.DEVICE_POWER); 8470 } 8471 8472 synchronized(this) { 8473 mWentToSleep = false; 8474 updateEventDispatchingLocked(); 8475 comeOutOfSleepIfNeededLocked(); 8476 } 8477 } 8478 8479 private void updateEventDispatchingLocked() { 8480 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8481 } 8482 8483 public void setLockScreenShown(boolean shown) { 8484 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8485 != PackageManager.PERMISSION_GRANTED) { 8486 throw new SecurityException("Requires permission " 8487 + android.Manifest.permission.DEVICE_POWER); 8488 } 8489 8490 synchronized(this) { 8491 long ident = Binder.clearCallingIdentity(); 8492 try { 8493 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8494 mLockScreenShown = shown; 8495 comeOutOfSleepIfNeededLocked(); 8496 } finally { 8497 Binder.restoreCallingIdentity(ident); 8498 } 8499 } 8500 } 8501 8502 public void stopAppSwitches() { 8503 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8504 != PackageManager.PERMISSION_GRANTED) { 8505 throw new SecurityException("Requires permission " 8506 + android.Manifest.permission.STOP_APP_SWITCHES); 8507 } 8508 8509 synchronized(this) { 8510 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8511 + APP_SWITCH_DELAY_TIME; 8512 mDidAppSwitch = false; 8513 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8514 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8515 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8516 } 8517 } 8518 8519 public void resumeAppSwitches() { 8520 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8521 != PackageManager.PERMISSION_GRANTED) { 8522 throw new SecurityException("Requires permission " 8523 + android.Manifest.permission.STOP_APP_SWITCHES); 8524 } 8525 8526 synchronized(this) { 8527 // Note that we don't execute any pending app switches... we will 8528 // let those wait until either the timeout, or the next start 8529 // activity request. 8530 mAppSwitchesAllowedTime = 0; 8531 } 8532 } 8533 8534 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8535 String name) { 8536 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8537 return true; 8538 } 8539 8540 final int perm = checkComponentPermission( 8541 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8542 callingUid, -1, true); 8543 if (perm == PackageManager.PERMISSION_GRANTED) { 8544 return true; 8545 } 8546 8547 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8548 return false; 8549 } 8550 8551 public void setDebugApp(String packageName, boolean waitForDebugger, 8552 boolean persistent) { 8553 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8554 "setDebugApp()"); 8555 8556 long ident = Binder.clearCallingIdentity(); 8557 try { 8558 // Note that this is not really thread safe if there are multiple 8559 // callers into it at the same time, but that's not a situation we 8560 // care about. 8561 if (persistent) { 8562 final ContentResolver resolver = mContext.getContentResolver(); 8563 Settings.Global.putString( 8564 resolver, Settings.Global.DEBUG_APP, 8565 packageName); 8566 Settings.Global.putInt( 8567 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8568 waitForDebugger ? 1 : 0); 8569 } 8570 8571 synchronized (this) { 8572 if (!persistent) { 8573 mOrigDebugApp = mDebugApp; 8574 mOrigWaitForDebugger = mWaitForDebugger; 8575 } 8576 mDebugApp = packageName; 8577 mWaitForDebugger = waitForDebugger; 8578 mDebugTransient = !persistent; 8579 if (packageName != null) { 8580 forceStopPackageLocked(packageName, -1, false, false, true, true, 8581 false, UserHandle.USER_ALL, "set debug app"); 8582 } 8583 } 8584 } finally { 8585 Binder.restoreCallingIdentity(ident); 8586 } 8587 } 8588 8589 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8590 synchronized (this) { 8591 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8592 if (!isDebuggable) { 8593 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8594 throw new SecurityException("Process not debuggable: " + app.packageName); 8595 } 8596 } 8597 8598 mOpenGlTraceApp = processName; 8599 } 8600 } 8601 8602 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8603 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8604 synchronized (this) { 8605 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8606 if (!isDebuggable) { 8607 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8608 throw new SecurityException("Process not debuggable: " + app.packageName); 8609 } 8610 } 8611 mProfileApp = processName; 8612 mProfileFile = profileFile; 8613 if (mProfileFd != null) { 8614 try { 8615 mProfileFd.close(); 8616 } catch (IOException e) { 8617 } 8618 mProfileFd = null; 8619 } 8620 mProfileFd = profileFd; 8621 mProfileType = 0; 8622 mAutoStopProfiler = autoStopProfiler; 8623 } 8624 } 8625 8626 @Override 8627 public void setAlwaysFinish(boolean enabled) { 8628 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8629 "setAlwaysFinish()"); 8630 8631 Settings.Global.putInt( 8632 mContext.getContentResolver(), 8633 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8634 8635 synchronized (this) { 8636 mAlwaysFinishActivities = enabled; 8637 } 8638 } 8639 8640 @Override 8641 public void setActivityController(IActivityController controller) { 8642 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8643 "setActivityController()"); 8644 synchronized (this) { 8645 mController = controller; 8646 Watchdog.getInstance().setActivityController(controller); 8647 } 8648 } 8649 8650 @Override 8651 public void setUserIsMonkey(boolean userIsMonkey) { 8652 synchronized (this) { 8653 synchronized (mPidsSelfLocked) { 8654 final int callingPid = Binder.getCallingPid(); 8655 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8656 if (precessRecord == null) { 8657 throw new SecurityException("Unknown process: " + callingPid); 8658 } 8659 if (precessRecord.instrumentationUiAutomationConnection == null) { 8660 throw new SecurityException("Only an instrumentation process " 8661 + "with a UiAutomation can call setUserIsMonkey"); 8662 } 8663 } 8664 mUserIsMonkey = userIsMonkey; 8665 } 8666 } 8667 8668 @Override 8669 public boolean isUserAMonkey() { 8670 synchronized (this) { 8671 // If there is a controller also implies the user is a monkey. 8672 return (mUserIsMonkey || mController != null); 8673 } 8674 } 8675 8676 public void requestBugReport() { 8677 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8678 SystemProperties.set("ctl.start", "bugreport"); 8679 } 8680 8681 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8682 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8683 } 8684 8685 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8686 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8687 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8688 } 8689 return KEY_DISPATCHING_TIMEOUT; 8690 } 8691 8692 @Override 8693 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8694 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8695 != PackageManager.PERMISSION_GRANTED) { 8696 throw new SecurityException("Requires permission " 8697 + android.Manifest.permission.FILTER_EVENTS); 8698 } 8699 ProcessRecord proc; 8700 long timeout; 8701 synchronized (this) { 8702 synchronized (mPidsSelfLocked) { 8703 proc = mPidsSelfLocked.get(pid); 8704 } 8705 timeout = getInputDispatchingTimeoutLocked(proc); 8706 } 8707 8708 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8709 return -1; 8710 } 8711 8712 return timeout; 8713 } 8714 8715 /** 8716 * Handle input dispatching timeouts. 8717 * Returns whether input dispatching should be aborted or not. 8718 */ 8719 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8720 final ActivityRecord activity, final ActivityRecord parent, 8721 final boolean aboveSystem, String reason) { 8722 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8723 != PackageManager.PERMISSION_GRANTED) { 8724 throw new SecurityException("Requires permission " 8725 + android.Manifest.permission.FILTER_EVENTS); 8726 } 8727 8728 final String annotation; 8729 if (reason == null) { 8730 annotation = "Input dispatching timed out"; 8731 } else { 8732 annotation = "Input dispatching timed out (" + reason + ")"; 8733 } 8734 8735 if (proc != null) { 8736 synchronized (this) { 8737 if (proc.debugging) { 8738 return false; 8739 } 8740 8741 if (mDidDexOpt) { 8742 // Give more time since we were dexopting. 8743 mDidDexOpt = false; 8744 return false; 8745 } 8746 8747 if (proc.instrumentationClass != null) { 8748 Bundle info = new Bundle(); 8749 info.putString("shortMsg", "keyDispatchingTimedOut"); 8750 info.putString("longMsg", annotation); 8751 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8752 return true; 8753 } 8754 } 8755 mHandler.post(new Runnable() { 8756 @Override 8757 public void run() { 8758 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8759 } 8760 }); 8761 } 8762 8763 return true; 8764 } 8765 8766 public Bundle getAssistContextExtras(int requestType) { 8767 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8768 "getAssistContextExtras()"); 8769 PendingAssistExtras pae; 8770 Bundle extras = new Bundle(); 8771 synchronized (this) { 8772 ActivityRecord activity = getFocusedStack().mResumedActivity; 8773 if (activity == null) { 8774 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8775 return null; 8776 } 8777 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8778 if (activity.app == null || activity.app.thread == null) { 8779 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8780 return extras; 8781 } 8782 if (activity.app.pid == Binder.getCallingPid()) { 8783 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8784 return extras; 8785 } 8786 pae = new PendingAssistExtras(activity); 8787 try { 8788 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8789 requestType); 8790 mPendingAssistExtras.add(pae); 8791 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8792 } catch (RemoteException e) { 8793 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8794 return extras; 8795 } 8796 } 8797 synchronized (pae) { 8798 while (!pae.haveResult) { 8799 try { 8800 pae.wait(); 8801 } catch (InterruptedException e) { 8802 } 8803 } 8804 if (pae.result != null) { 8805 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8806 } 8807 } 8808 synchronized (this) { 8809 mPendingAssistExtras.remove(pae); 8810 mHandler.removeCallbacks(pae); 8811 } 8812 return extras; 8813 } 8814 8815 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8816 PendingAssistExtras pae = (PendingAssistExtras)token; 8817 synchronized (pae) { 8818 pae.result = extras; 8819 pae.haveResult = true; 8820 pae.notifyAll(); 8821 } 8822 } 8823 8824 public void registerProcessObserver(IProcessObserver observer) { 8825 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8826 "registerProcessObserver()"); 8827 synchronized (this) { 8828 mProcessObservers.register(observer); 8829 } 8830 } 8831 8832 @Override 8833 public void unregisterProcessObserver(IProcessObserver observer) { 8834 synchronized (this) { 8835 mProcessObservers.unregister(observer); 8836 } 8837 } 8838 8839 @Override 8840 public boolean convertFromTranslucent(IBinder token) { 8841 final long origId = Binder.clearCallingIdentity(); 8842 try { 8843 synchronized (this) { 8844 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8845 if (r == null) { 8846 return false; 8847 } 8848 if (r.changeWindowTranslucency(true)) { 8849 mWindowManager.setAppFullscreen(token, true); 8850 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8851 return true; 8852 } 8853 return false; 8854 } 8855 } finally { 8856 Binder.restoreCallingIdentity(origId); 8857 } 8858 } 8859 8860 @Override 8861 public boolean convertToTranslucent(IBinder token) { 8862 final long origId = Binder.clearCallingIdentity(); 8863 try { 8864 synchronized (this) { 8865 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8866 if (r == null) { 8867 return false; 8868 } 8869 if (r.changeWindowTranslucency(false)) { 8870 r.task.stack.convertToTranslucent(r); 8871 mWindowManager.setAppFullscreen(token, false); 8872 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8873 return true; 8874 } 8875 return false; 8876 } 8877 } finally { 8878 Binder.restoreCallingIdentity(origId); 8879 } 8880 } 8881 8882 @Override 8883 public void setImmersive(IBinder token, boolean immersive) { 8884 synchronized(this) { 8885 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8886 if (r == null) { 8887 throw new IllegalArgumentException(); 8888 } 8889 r.immersive = immersive; 8890 8891 // update associated state if we're frontmost 8892 if (r == mFocusedActivity) { 8893 if (DEBUG_IMMERSIVE) { 8894 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8895 } 8896 applyUpdateLockStateLocked(r); 8897 } 8898 } 8899 } 8900 8901 @Override 8902 public boolean isImmersive(IBinder token) { 8903 synchronized (this) { 8904 ActivityRecord r = ActivityRecord.isInStackLocked(token); 8905 if (r == null) { 8906 throw new IllegalArgumentException(); 8907 } 8908 return r.immersive; 8909 } 8910 } 8911 8912 public boolean isTopActivityImmersive() { 8913 enforceNotIsolatedCaller("startActivity"); 8914 synchronized (this) { 8915 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 8916 return (r != null) ? r.immersive : false; 8917 } 8918 } 8919 8920 public final void enterSafeMode() { 8921 synchronized(this) { 8922 // It only makes sense to do this before the system is ready 8923 // and started launching other packages. 8924 if (!mSystemReady) { 8925 try { 8926 AppGlobals.getPackageManager().enterSafeMode(); 8927 } catch (RemoteException e) { 8928 } 8929 } 8930 } 8931 } 8932 8933 public final void showSafeModeOverlay() { 8934 View v = LayoutInflater.from(mContext).inflate( 8935 com.android.internal.R.layout.safe_mode, null); 8936 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 8937 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 8938 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 8939 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 8940 lp.gravity = Gravity.BOTTOM | Gravity.START; 8941 lp.format = v.getBackground().getOpacity(); 8942 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 8943 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 8944 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 8945 ((WindowManager)mContext.getSystemService( 8946 Context.WINDOW_SERVICE)).addView(v, lp); 8947 } 8948 8949 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 8950 if (!(sender instanceof PendingIntentRecord)) { 8951 return; 8952 } 8953 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8954 synchronized (stats) { 8955 if (mBatteryStatsService.isOnBattery()) { 8956 mBatteryStatsService.enforceCallingPermission(); 8957 PendingIntentRecord rec = (PendingIntentRecord)sender; 8958 int MY_UID = Binder.getCallingUid(); 8959 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 8960 BatteryStatsImpl.Uid.Pkg pkg = 8961 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 8962 sourcePkg != null ? sourcePkg : rec.key.packageName); 8963 pkg.incWakeupsLocked(); 8964 } 8965 } 8966 } 8967 8968 public boolean killPids(int[] pids, String pReason, boolean secure) { 8969 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 8970 throw new SecurityException("killPids only available to the system"); 8971 } 8972 String reason = (pReason == null) ? "Unknown" : pReason; 8973 // XXX Note: don't acquire main activity lock here, because the window 8974 // manager calls in with its locks held. 8975 8976 boolean killed = false; 8977 synchronized (mPidsSelfLocked) { 8978 int[] types = new int[pids.length]; 8979 int worstType = 0; 8980 for (int i=0; i<pids.length; i++) { 8981 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 8982 if (proc != null) { 8983 int type = proc.setAdj; 8984 types[i] = type; 8985 if (type > worstType) { 8986 worstType = type; 8987 } 8988 } 8989 } 8990 8991 // If the worst oom_adj is somewhere in the cached proc LRU range, 8992 // then constrain it so we will kill all cached procs. 8993 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 8994 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 8995 worstType = ProcessList.CACHED_APP_MIN_ADJ; 8996 } 8997 8998 // If this is not a secure call, don't let it kill processes that 8999 // are important. 9000 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9001 worstType = ProcessList.SERVICE_ADJ; 9002 } 9003 9004 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9005 for (int i=0; i<pids.length; i++) { 9006 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9007 if (proc == null) { 9008 continue; 9009 } 9010 int adj = proc.setAdj; 9011 if (adj >= worstType && !proc.killedByAm) { 9012 killUnneededProcessLocked(proc, reason); 9013 killed = true; 9014 } 9015 } 9016 } 9017 return killed; 9018 } 9019 9020 @Override 9021 public void killUid(int uid, String reason) { 9022 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9023 throw new SecurityException("killUid only available to the system"); 9024 } 9025 synchronized (this) { 9026 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9027 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9028 reason != null ? reason : "kill uid"); 9029 } 9030 } 9031 9032 @Override 9033 public boolean killProcessesBelowForeground(String reason) { 9034 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9035 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9036 } 9037 9038 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9039 } 9040 9041 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9042 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9043 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9044 } 9045 9046 boolean killed = false; 9047 synchronized (mPidsSelfLocked) { 9048 final int size = mPidsSelfLocked.size(); 9049 for (int i = 0; i < size; i++) { 9050 final int pid = mPidsSelfLocked.keyAt(i); 9051 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9052 if (proc == null) continue; 9053 9054 final int adj = proc.setAdj; 9055 if (adj > belowAdj && !proc.killedByAm) { 9056 killUnneededProcessLocked(proc, reason); 9057 killed = true; 9058 } 9059 } 9060 } 9061 return killed; 9062 } 9063 9064 @Override 9065 public void hang(final IBinder who, boolean allowRestart) { 9066 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9067 != PackageManager.PERMISSION_GRANTED) { 9068 throw new SecurityException("Requires permission " 9069 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9070 } 9071 9072 final IBinder.DeathRecipient death = new DeathRecipient() { 9073 @Override 9074 public void binderDied() { 9075 synchronized (this) { 9076 notifyAll(); 9077 } 9078 } 9079 }; 9080 9081 try { 9082 who.linkToDeath(death, 0); 9083 } catch (RemoteException e) { 9084 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9085 return; 9086 } 9087 9088 synchronized (this) { 9089 Watchdog.getInstance().setAllowRestart(allowRestart); 9090 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9091 synchronized (death) { 9092 while (who.isBinderAlive()) { 9093 try { 9094 death.wait(); 9095 } catch (InterruptedException e) { 9096 } 9097 } 9098 } 9099 Watchdog.getInstance().setAllowRestart(true); 9100 } 9101 } 9102 9103 @Override 9104 public void restart() { 9105 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9106 != PackageManager.PERMISSION_GRANTED) { 9107 throw new SecurityException("Requires permission " 9108 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9109 } 9110 9111 Log.i(TAG, "Sending shutdown broadcast..."); 9112 9113 BroadcastReceiver br = new BroadcastReceiver() { 9114 @Override public void onReceive(Context context, Intent intent) { 9115 // Now the broadcast is done, finish up the low-level shutdown. 9116 Log.i(TAG, "Shutting down activity manager..."); 9117 shutdown(10000); 9118 Log.i(TAG, "Shutdown complete, restarting!"); 9119 Process.killProcess(Process.myPid()); 9120 System.exit(10); 9121 } 9122 }; 9123 9124 // First send the high-level shut down broadcast. 9125 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9126 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9127 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9128 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9129 mContext.sendOrderedBroadcastAsUser(intent, 9130 UserHandle.ALL, null, br, mHandler, 0, null, null); 9131 */ 9132 br.onReceive(mContext, intent); 9133 } 9134 9135 private long getLowRamTimeSinceIdle(long now) { 9136 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9137 } 9138 9139 @Override 9140 public void performIdleMaintenance() { 9141 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9142 != PackageManager.PERMISSION_GRANTED) { 9143 throw new SecurityException("Requires permission " 9144 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9145 } 9146 9147 synchronized (this) { 9148 final long now = SystemClock.uptimeMillis(); 9149 final long timeSinceLastIdle = now - mLastIdleTime; 9150 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9151 mLastIdleTime = now; 9152 mLowRamTimeSinceLastIdle = 0; 9153 if (mLowRamStartTime != 0) { 9154 mLowRamStartTime = now; 9155 } 9156 9157 StringBuilder sb = new StringBuilder(128); 9158 sb.append("Idle maintenance over "); 9159 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9160 sb.append(" low RAM for "); 9161 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9162 Slog.i(TAG, sb.toString()); 9163 9164 // If at least 1/3 of our time since the last idle period has been spent 9165 // with RAM low, then we want to kill processes. 9166 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9167 9168 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9169 ProcessRecord proc = mLruProcesses.get(i); 9170 if (proc.notCachedSinceIdle) { 9171 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9172 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9173 if (doKilling && proc.initialIdlePss != 0 9174 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9175 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9176 + " from " + proc.initialIdlePss + ")"); 9177 } 9178 } 9179 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9180 proc.notCachedSinceIdle = true; 9181 proc.initialIdlePss = 0; 9182 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9183 mSleeping, now); 9184 } 9185 } 9186 9187 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9188 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9189 } 9190 } 9191 9192 public final void startRunning(String pkg, String cls, String action, 9193 String data) { 9194 synchronized(this) { 9195 if (mStartRunning) { 9196 return; 9197 } 9198 mStartRunning = true; 9199 mTopComponent = pkg != null && cls != null 9200 ? new ComponentName(pkg, cls) : null; 9201 mTopAction = action != null ? action : Intent.ACTION_MAIN; 9202 mTopData = data; 9203 if (!mSystemReady) { 9204 return; 9205 } 9206 } 9207 9208 systemReady(null); 9209 } 9210 9211 private void retrieveSettings() { 9212 final ContentResolver resolver = mContext.getContentResolver(); 9213 String debugApp = Settings.Global.getString( 9214 resolver, Settings.Global.DEBUG_APP); 9215 boolean waitForDebugger = Settings.Global.getInt( 9216 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9217 boolean alwaysFinishActivities = Settings.Global.getInt( 9218 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9219 boolean forceRtl = Settings.Global.getInt( 9220 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9221 // Transfer any global setting for forcing RTL layout, into a System Property 9222 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9223 9224 Configuration configuration = new Configuration(); 9225 Settings.System.getConfiguration(resolver, configuration); 9226 if (forceRtl) { 9227 // This will take care of setting the correct layout direction flags 9228 configuration.setLayoutDirection(configuration.locale); 9229 } 9230 9231 synchronized (this) { 9232 mDebugApp = mOrigDebugApp = debugApp; 9233 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9234 mAlwaysFinishActivities = alwaysFinishActivities; 9235 // This happens before any activities are started, so we can 9236 // change mConfiguration in-place. 9237 updateConfigurationLocked(configuration, null, false, true); 9238 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9239 } 9240 } 9241 9242 public boolean testIsSystemReady() { 9243 // no need to synchronize(this) just to read & return the value 9244 return mSystemReady; 9245 } 9246 9247 private static File getCalledPreBootReceiversFile() { 9248 File dataDir = Environment.getDataDirectory(); 9249 File systemDir = new File(dataDir, "system"); 9250 File fname = new File(systemDir, "called_pre_boots.dat"); 9251 return fname; 9252 } 9253 9254 static final int LAST_DONE_VERSION = 10000; 9255 9256 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9257 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9258 File file = getCalledPreBootReceiversFile(); 9259 FileInputStream fis = null; 9260 try { 9261 fis = new FileInputStream(file); 9262 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9263 int fvers = dis.readInt(); 9264 if (fvers == LAST_DONE_VERSION) { 9265 String vers = dis.readUTF(); 9266 String codename = dis.readUTF(); 9267 String build = dis.readUTF(); 9268 if (android.os.Build.VERSION.RELEASE.equals(vers) 9269 && android.os.Build.VERSION.CODENAME.equals(codename) 9270 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9271 int num = dis.readInt(); 9272 while (num > 0) { 9273 num--; 9274 String pkg = dis.readUTF(); 9275 String cls = dis.readUTF(); 9276 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9277 } 9278 } 9279 } 9280 } catch (FileNotFoundException e) { 9281 } catch (IOException e) { 9282 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9283 } finally { 9284 if (fis != null) { 9285 try { 9286 fis.close(); 9287 } catch (IOException e) { 9288 } 9289 } 9290 } 9291 return lastDoneReceivers; 9292 } 9293 9294 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9295 File file = getCalledPreBootReceiversFile(); 9296 FileOutputStream fos = null; 9297 DataOutputStream dos = null; 9298 try { 9299 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9300 fos = new FileOutputStream(file); 9301 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9302 dos.writeInt(LAST_DONE_VERSION); 9303 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9304 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9305 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9306 dos.writeInt(list.size()); 9307 for (int i=0; i<list.size(); i++) { 9308 dos.writeUTF(list.get(i).getPackageName()); 9309 dos.writeUTF(list.get(i).getClassName()); 9310 } 9311 } catch (IOException e) { 9312 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9313 file.delete(); 9314 } finally { 9315 FileUtils.sync(fos); 9316 if (dos != null) { 9317 try { 9318 dos.close(); 9319 } catch (IOException e) { 9320 // TODO Auto-generated catch block 9321 e.printStackTrace(); 9322 } 9323 } 9324 } 9325 } 9326 9327 public void systemReady(final Runnable goingCallback) { 9328 synchronized(this) { 9329 if (mSystemReady) { 9330 if (goingCallback != null) goingCallback.run(); 9331 return; 9332 } 9333 9334 // Check to see if there are any update receivers to run. 9335 if (!mDidUpdate) { 9336 if (mWaitingUpdate) { 9337 return; 9338 } 9339 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9340 List<ResolveInfo> ris = null; 9341 try { 9342 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9343 intent, null, 0, 0); 9344 } catch (RemoteException e) { 9345 } 9346 if (ris != null) { 9347 for (int i=ris.size()-1; i>=0; i--) { 9348 if ((ris.get(i).activityInfo.applicationInfo.flags 9349 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9350 ris.remove(i); 9351 } 9352 } 9353 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9354 9355 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9356 9357 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9358 for (int i=0; i<ris.size(); i++) { 9359 ActivityInfo ai = ris.get(i).activityInfo; 9360 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9361 if (lastDoneReceivers.contains(comp)) { 9362 // We already did the pre boot receiver for this app with the current 9363 // platform version, so don't do it again... 9364 ris.remove(i); 9365 i--; 9366 // ...however, do keep it as one that has been done, so we don't 9367 // forget about it when rewriting the file of last done receivers. 9368 doneReceivers.add(comp); 9369 } 9370 } 9371 9372 final int[] users = getUsersLocked(); 9373 for (int i=0; i<ris.size(); i++) { 9374 ActivityInfo ai = ris.get(i).activityInfo; 9375 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9376 doneReceivers.add(comp); 9377 intent.setComponent(comp); 9378 for (int j=0; j<users.length; j++) { 9379 IIntentReceiver finisher = null; 9380 if (i == ris.size()-1 && j == users.length-1) { 9381 finisher = new IIntentReceiver.Stub() { 9382 public void performReceive(Intent intent, int resultCode, 9383 String data, Bundle extras, boolean ordered, 9384 boolean sticky, int sendingUser) { 9385 // The raw IIntentReceiver interface is called 9386 // with the AM lock held, so redispatch to 9387 // execute our code without the lock. 9388 mHandler.post(new Runnable() { 9389 public void run() { 9390 synchronized (ActivityManagerService.this) { 9391 mDidUpdate = true; 9392 } 9393 writeLastDonePreBootReceivers(doneReceivers); 9394 showBootMessage(mContext.getText( 9395 R.string.android_upgrading_complete), 9396 false); 9397 systemReady(goingCallback); 9398 } 9399 }); 9400 } 9401 }; 9402 } 9403 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9404 + " for user " + users[j]); 9405 broadcastIntentLocked(null, null, intent, null, finisher, 9406 0, null, null, null, AppOpsManager.OP_NONE, 9407 true, false, MY_PID, Process.SYSTEM_UID, 9408 users[j]); 9409 if (finisher != null) { 9410 mWaitingUpdate = true; 9411 } 9412 } 9413 } 9414 } 9415 if (mWaitingUpdate) { 9416 return; 9417 } 9418 mDidUpdate = true; 9419 } 9420 9421 mAppOpsService.systemReady(); 9422 mSystemReady = true; 9423 if (!mStartRunning) { 9424 return; 9425 } 9426 } 9427 9428 ArrayList<ProcessRecord> procsToKill = null; 9429 synchronized(mPidsSelfLocked) { 9430 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9431 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9432 if (!isAllowedWhileBooting(proc.info)){ 9433 if (procsToKill == null) { 9434 procsToKill = new ArrayList<ProcessRecord>(); 9435 } 9436 procsToKill.add(proc); 9437 } 9438 } 9439 } 9440 9441 synchronized(this) { 9442 if (procsToKill != null) { 9443 for (int i=procsToKill.size()-1; i>=0; i--) { 9444 ProcessRecord proc = procsToKill.get(i); 9445 Slog.i(TAG, "Removing system update proc: " + proc); 9446 removeProcessLocked(proc, true, false, "system update done"); 9447 } 9448 } 9449 9450 // Now that we have cleaned up any update processes, we 9451 // are ready to start launching real processes and know that 9452 // we won't trample on them any more. 9453 mProcessesReady = true; 9454 } 9455 9456 Slog.i(TAG, "System now ready"); 9457 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9458 SystemClock.uptimeMillis()); 9459 9460 synchronized(this) { 9461 // Make sure we have no pre-ready processes sitting around. 9462 9463 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9464 ResolveInfo ri = mContext.getPackageManager() 9465 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9466 STOCK_PM_FLAGS); 9467 CharSequence errorMsg = null; 9468 if (ri != null) { 9469 ActivityInfo ai = ri.activityInfo; 9470 ApplicationInfo app = ai.applicationInfo; 9471 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9472 mTopAction = Intent.ACTION_FACTORY_TEST; 9473 mTopData = null; 9474 mTopComponent = new ComponentName(app.packageName, 9475 ai.name); 9476 } else { 9477 errorMsg = mContext.getResources().getText( 9478 com.android.internal.R.string.factorytest_not_system); 9479 } 9480 } else { 9481 errorMsg = mContext.getResources().getText( 9482 com.android.internal.R.string.factorytest_no_action); 9483 } 9484 if (errorMsg != null) { 9485 mTopAction = null; 9486 mTopData = null; 9487 mTopComponent = null; 9488 Message msg = Message.obtain(); 9489 msg.what = SHOW_FACTORY_ERROR_MSG; 9490 msg.getData().putCharSequence("msg", errorMsg); 9491 mHandler.sendMessage(msg); 9492 } 9493 } 9494 } 9495 9496 retrieveSettings(); 9497 9498 synchronized (this) { 9499 readGrantedUriPermissionsLocked(); 9500 } 9501 9502 if (goingCallback != null) goingCallback.run(); 9503 9504 synchronized (this) { 9505 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9506 try { 9507 List apps = AppGlobals.getPackageManager(). 9508 getPersistentApplications(STOCK_PM_FLAGS); 9509 if (apps != null) { 9510 int N = apps.size(); 9511 int i; 9512 for (i=0; i<N; i++) { 9513 ApplicationInfo info 9514 = (ApplicationInfo)apps.get(i); 9515 if (info != null && 9516 !info.packageName.equals("android")) { 9517 addAppLocked(info, false); 9518 } 9519 } 9520 } 9521 } catch (RemoteException ex) { 9522 // pm is in same process, this will never happen. 9523 } 9524 } 9525 9526 // Start up initial activity. 9527 mBooting = true; 9528 9529 try { 9530 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9531 Message msg = Message.obtain(); 9532 msg.what = SHOW_UID_ERROR_MSG; 9533 mHandler.sendMessage(msg); 9534 } 9535 } catch (RemoteException e) { 9536 } 9537 9538 long ident = Binder.clearCallingIdentity(); 9539 try { 9540 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9541 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9542 | Intent.FLAG_RECEIVER_FOREGROUND); 9543 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9544 broadcastIntentLocked(null, null, intent, 9545 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9546 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9547 intent = new Intent(Intent.ACTION_USER_STARTING); 9548 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9549 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9550 broadcastIntentLocked(null, null, intent, 9551 null, new IIntentReceiver.Stub() { 9552 @Override 9553 public void performReceive(Intent intent, int resultCode, String data, 9554 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9555 throws RemoteException { 9556 } 9557 }, 0, null, null, 9558 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9559 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9560 } finally { 9561 Binder.restoreCallingIdentity(ident); 9562 } 9563 mStackSupervisor.resumeTopActivitiesLocked(); 9564 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9565 } 9566 } 9567 9568 private boolean makeAppCrashingLocked(ProcessRecord app, 9569 String shortMsg, String longMsg, String stackTrace) { 9570 app.crashing = true; 9571 app.crashingReport = generateProcessError(app, 9572 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9573 startAppProblemLocked(app); 9574 app.stopFreezingAllLocked(); 9575 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9576 } 9577 9578 private void makeAppNotRespondingLocked(ProcessRecord app, 9579 String activity, String shortMsg, String longMsg) { 9580 app.notResponding = true; 9581 app.notRespondingReport = generateProcessError(app, 9582 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9583 activity, shortMsg, longMsg, null); 9584 startAppProblemLocked(app); 9585 app.stopFreezingAllLocked(); 9586 } 9587 9588 /** 9589 * Generate a process error record, suitable for attachment to a ProcessRecord. 9590 * 9591 * @param app The ProcessRecord in which the error occurred. 9592 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9593 * ActivityManager.AppErrorStateInfo 9594 * @param activity The activity associated with the crash, if known. 9595 * @param shortMsg Short message describing the crash. 9596 * @param longMsg Long message describing the crash. 9597 * @param stackTrace Full crash stack trace, may be null. 9598 * 9599 * @return Returns a fully-formed AppErrorStateInfo record. 9600 */ 9601 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9602 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9603 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9604 9605 report.condition = condition; 9606 report.processName = app.processName; 9607 report.pid = app.pid; 9608 report.uid = app.info.uid; 9609 report.tag = activity; 9610 report.shortMsg = shortMsg; 9611 report.longMsg = longMsg; 9612 report.stackTrace = stackTrace; 9613 9614 return report; 9615 } 9616 9617 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9618 synchronized (this) { 9619 app.crashing = false; 9620 app.crashingReport = null; 9621 app.notResponding = false; 9622 app.notRespondingReport = null; 9623 if (app.anrDialog == fromDialog) { 9624 app.anrDialog = null; 9625 } 9626 if (app.waitDialog == fromDialog) { 9627 app.waitDialog = null; 9628 } 9629 if (app.pid > 0 && app.pid != MY_PID) { 9630 handleAppCrashLocked(app, null, null, null); 9631 killUnneededProcessLocked(app, "user request after error"); 9632 } 9633 } 9634 } 9635 9636 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9637 String stackTrace) { 9638 long now = SystemClock.uptimeMillis(); 9639 9640 Long crashTime; 9641 if (!app.isolated) { 9642 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9643 } else { 9644 crashTime = null; 9645 } 9646 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9647 // This process loses! 9648 Slog.w(TAG, "Process " + app.info.processName 9649 + " has crashed too many times: killing!"); 9650 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9651 app.userId, app.info.processName, app.uid); 9652 mStackSupervisor.handleAppCrashLocked(app); 9653 if (!app.persistent) { 9654 // We don't want to start this process again until the user 9655 // explicitly does so... but for persistent process, we really 9656 // need to keep it running. If a persistent process is actually 9657 // repeatedly crashing, then badness for everyone. 9658 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9659 app.info.processName); 9660 if (!app.isolated) { 9661 // XXX We don't have a way to mark isolated processes 9662 // as bad, since they don't have a peristent identity. 9663 mBadProcesses.put(app.info.processName, app.uid, 9664 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9665 mProcessCrashTimes.remove(app.info.processName, app.uid); 9666 } 9667 app.bad = true; 9668 app.removed = true; 9669 // Don't let services in this process be restarted and potentially 9670 // annoy the user repeatedly. Unless it is persistent, since those 9671 // processes run critical code. 9672 removeProcessLocked(app, false, false, "crash"); 9673 mStackSupervisor.resumeTopActivitiesLocked(); 9674 return false; 9675 } 9676 mStackSupervisor.resumeTopActivitiesLocked(); 9677 } else { 9678 mStackSupervisor.finishTopRunningActivityLocked(app); 9679 } 9680 9681 // Bump up the crash count of any services currently running in the proc. 9682 for (int i=app.services.size()-1; i>=0; i--) { 9683 // Any services running in the application need to be placed 9684 // back in the pending list. 9685 ServiceRecord sr = app.services.valueAt(i); 9686 sr.crashCount++; 9687 } 9688 9689 // If the crashing process is what we consider to be the "home process" and it has been 9690 // replaced by a third-party app, clear the package preferred activities from packages 9691 // with a home activity running in the process to prevent a repeatedly crashing app 9692 // from blocking the user to manually clear the list. 9693 final ArrayList<ActivityRecord> activities = app.activities; 9694 if (app == mHomeProcess && activities.size() > 0 9695 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9696 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9697 final ActivityRecord r = activities.get(activityNdx); 9698 if (r.isHomeActivity()) { 9699 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9700 try { 9701 ActivityThread.getPackageManager() 9702 .clearPackagePreferredActivities(r.packageName); 9703 } catch (RemoteException c) { 9704 // pm is in same process, this will never happen. 9705 } 9706 } 9707 } 9708 } 9709 9710 if (!app.isolated) { 9711 // XXX Can't keep track of crash times for isolated processes, 9712 // because they don't have a perisistent identity. 9713 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9714 } 9715 9716 return true; 9717 } 9718 9719 void startAppProblemLocked(ProcessRecord app) { 9720 if (app.userId == mCurrentUserId) { 9721 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9722 mContext, app.info.packageName, app.info.flags); 9723 } else { 9724 // If this app is not running under the current user, then we 9725 // can't give it a report button because that would require 9726 // launching the report UI under a different user. 9727 app.errorReportReceiver = null; 9728 } 9729 skipCurrentReceiverLocked(app); 9730 } 9731 9732 void skipCurrentReceiverLocked(ProcessRecord app) { 9733 for (BroadcastQueue queue : mBroadcastQueues) { 9734 queue.skipCurrentReceiverLocked(app); 9735 } 9736 } 9737 9738 /** 9739 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9740 * The application process will exit immediately after this call returns. 9741 * @param app object of the crashing app, null for the system server 9742 * @param crashInfo describing the exception 9743 */ 9744 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9745 ProcessRecord r = findAppProcess(app, "Crash"); 9746 final String processName = app == null ? "system_server" 9747 : (r == null ? "unknown" : r.processName); 9748 9749 handleApplicationCrashInner("crash", r, processName, crashInfo); 9750 } 9751 9752 /* Native crash reporting uses this inner version because it needs to be somewhat 9753 * decoupled from the AM-managed cleanup lifecycle 9754 */ 9755 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9756 ApplicationErrorReport.CrashInfo crashInfo) { 9757 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9758 UserHandle.getUserId(Binder.getCallingUid()), processName, 9759 r == null ? -1 : r.info.flags, 9760 crashInfo.exceptionClassName, 9761 crashInfo.exceptionMessage, 9762 crashInfo.throwFileName, 9763 crashInfo.throwLineNumber); 9764 9765 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9766 9767 crashApplication(r, crashInfo); 9768 } 9769 9770 public void handleApplicationStrictModeViolation( 9771 IBinder app, 9772 int violationMask, 9773 StrictMode.ViolationInfo info) { 9774 ProcessRecord r = findAppProcess(app, "StrictMode"); 9775 if (r == null) { 9776 return; 9777 } 9778 9779 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9780 Integer stackFingerprint = info.hashCode(); 9781 boolean logIt = true; 9782 synchronized (mAlreadyLoggedViolatedStacks) { 9783 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9784 logIt = false; 9785 // TODO: sub-sample into EventLog for these, with 9786 // the info.durationMillis? Then we'd get 9787 // the relative pain numbers, without logging all 9788 // the stack traces repeatedly. We'd want to do 9789 // likewise in the client code, which also does 9790 // dup suppression, before the Binder call. 9791 } else { 9792 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9793 mAlreadyLoggedViolatedStacks.clear(); 9794 } 9795 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9796 } 9797 } 9798 if (logIt) { 9799 logStrictModeViolationToDropBox(r, info); 9800 } 9801 } 9802 9803 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9804 AppErrorResult result = new AppErrorResult(); 9805 synchronized (this) { 9806 final long origId = Binder.clearCallingIdentity(); 9807 9808 Message msg = Message.obtain(); 9809 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9810 HashMap<String, Object> data = new HashMap<String, Object>(); 9811 data.put("result", result); 9812 data.put("app", r); 9813 data.put("violationMask", violationMask); 9814 data.put("info", info); 9815 msg.obj = data; 9816 mHandler.sendMessage(msg); 9817 9818 Binder.restoreCallingIdentity(origId); 9819 } 9820 int res = result.get(); 9821 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9822 } 9823 } 9824 9825 // Depending on the policy in effect, there could be a bunch of 9826 // these in quick succession so we try to batch these together to 9827 // minimize disk writes, number of dropbox entries, and maximize 9828 // compression, by having more fewer, larger records. 9829 private void logStrictModeViolationToDropBox( 9830 ProcessRecord process, 9831 StrictMode.ViolationInfo info) { 9832 if (info == null) { 9833 return; 9834 } 9835 final boolean isSystemApp = process == null || 9836 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9837 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9838 final String processName = process == null ? "unknown" : process.processName; 9839 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9840 final DropBoxManager dbox = (DropBoxManager) 9841 mContext.getSystemService(Context.DROPBOX_SERVICE); 9842 9843 // Exit early if the dropbox isn't configured to accept this report type. 9844 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9845 9846 boolean bufferWasEmpty; 9847 boolean needsFlush; 9848 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9849 synchronized (sb) { 9850 bufferWasEmpty = sb.length() == 0; 9851 appendDropBoxProcessHeaders(process, processName, sb); 9852 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9853 sb.append("System-App: ").append(isSystemApp).append("\n"); 9854 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9855 if (info.violationNumThisLoop != 0) { 9856 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9857 } 9858 if (info.numAnimationsRunning != 0) { 9859 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9860 } 9861 if (info.broadcastIntentAction != null) { 9862 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9863 } 9864 if (info.durationMillis != -1) { 9865 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9866 } 9867 if (info.numInstances != -1) { 9868 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9869 } 9870 if (info.tags != null) { 9871 for (String tag : info.tags) { 9872 sb.append("Span-Tag: ").append(tag).append("\n"); 9873 } 9874 } 9875 sb.append("\n"); 9876 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9877 sb.append(info.crashInfo.stackTrace); 9878 } 9879 sb.append("\n"); 9880 9881 // Only buffer up to ~64k. Various logging bits truncate 9882 // things at 128k. 9883 needsFlush = (sb.length() > 64 * 1024); 9884 } 9885 9886 // Flush immediately if the buffer's grown too large, or this 9887 // is a non-system app. Non-system apps are isolated with a 9888 // different tag & policy and not batched. 9889 // 9890 // Batching is useful during internal testing with 9891 // StrictMode settings turned up high. Without batching, 9892 // thousands of separate files could be created on boot. 9893 if (!isSystemApp || needsFlush) { 9894 new Thread("Error dump: " + dropboxTag) { 9895 @Override 9896 public void run() { 9897 String report; 9898 synchronized (sb) { 9899 report = sb.toString(); 9900 sb.delete(0, sb.length()); 9901 sb.trimToSize(); 9902 } 9903 if (report.length() != 0) { 9904 dbox.addText(dropboxTag, report); 9905 } 9906 } 9907 }.start(); 9908 return; 9909 } 9910 9911 // System app batching: 9912 if (!bufferWasEmpty) { 9913 // An existing dropbox-writing thread is outstanding, so 9914 // we don't need to start it up. The existing thread will 9915 // catch the buffer appends we just did. 9916 return; 9917 } 9918 9919 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 9920 // (After this point, we shouldn't access AMS internal data structures.) 9921 new Thread("Error dump: " + dropboxTag) { 9922 @Override 9923 public void run() { 9924 // 5 second sleep to let stacks arrive and be batched together 9925 try { 9926 Thread.sleep(5000); // 5 seconds 9927 } catch (InterruptedException e) {} 9928 9929 String errorReport; 9930 synchronized (mStrictModeBuffer) { 9931 errorReport = mStrictModeBuffer.toString(); 9932 if (errorReport.length() == 0) { 9933 return; 9934 } 9935 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 9936 mStrictModeBuffer.trimToSize(); 9937 } 9938 dbox.addText(dropboxTag, errorReport); 9939 } 9940 }.start(); 9941 } 9942 9943 /** 9944 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 9945 * @param app object of the crashing app, null for the system server 9946 * @param tag reported by the caller 9947 * @param crashInfo describing the context of the error 9948 * @return true if the process should exit immediately (WTF is fatal) 9949 */ 9950 public boolean handleApplicationWtf(IBinder app, String tag, 9951 ApplicationErrorReport.CrashInfo crashInfo) { 9952 ProcessRecord r = findAppProcess(app, "WTF"); 9953 final String processName = app == null ? "system_server" 9954 : (r == null ? "unknown" : r.processName); 9955 9956 EventLog.writeEvent(EventLogTags.AM_WTF, 9957 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 9958 processName, 9959 r == null ? -1 : r.info.flags, 9960 tag, crashInfo.exceptionMessage); 9961 9962 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 9963 9964 if (r != null && r.pid != Process.myPid() && 9965 Settings.Global.getInt(mContext.getContentResolver(), 9966 Settings.Global.WTF_IS_FATAL, 0) != 0) { 9967 crashApplication(r, crashInfo); 9968 return true; 9969 } else { 9970 return false; 9971 } 9972 } 9973 9974 /** 9975 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 9976 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 9977 */ 9978 private ProcessRecord findAppProcess(IBinder app, String reason) { 9979 if (app == null) { 9980 return null; 9981 } 9982 9983 synchronized (this) { 9984 final int NP = mProcessNames.getMap().size(); 9985 for (int ip=0; ip<NP; ip++) { 9986 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 9987 final int NA = apps.size(); 9988 for (int ia=0; ia<NA; ia++) { 9989 ProcessRecord p = apps.valueAt(ia); 9990 if (p.thread != null && p.thread.asBinder() == app) { 9991 return p; 9992 } 9993 } 9994 } 9995 9996 Slog.w(TAG, "Can't find mystery application for " + reason 9997 + " from pid=" + Binder.getCallingPid() 9998 + " uid=" + Binder.getCallingUid() + ": " + app); 9999 return null; 10000 } 10001 } 10002 10003 /** 10004 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10005 * to append various headers to the dropbox log text. 10006 */ 10007 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10008 StringBuilder sb) { 10009 // Watchdog thread ends up invoking this function (with 10010 // a null ProcessRecord) to add the stack file to dropbox. 10011 // Do not acquire a lock on this (am) in such cases, as it 10012 // could cause a potential deadlock, if and when watchdog 10013 // is invoked due to unavailability of lock on am and it 10014 // would prevent watchdog from killing system_server. 10015 if (process == null) { 10016 sb.append("Process: ").append(processName).append("\n"); 10017 return; 10018 } 10019 // Note: ProcessRecord 'process' is guarded by the service 10020 // instance. (notably process.pkgList, which could otherwise change 10021 // concurrently during execution of this method) 10022 synchronized (this) { 10023 sb.append("Process: ").append(processName).append("\n"); 10024 int flags = process.info.flags; 10025 IPackageManager pm = AppGlobals.getPackageManager(); 10026 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10027 for (int ip=0; ip<process.pkgList.size(); ip++) { 10028 String pkg = process.pkgList.keyAt(ip); 10029 sb.append("Package: ").append(pkg); 10030 try { 10031 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10032 if (pi != null) { 10033 sb.append(" v").append(pi.versionCode); 10034 if (pi.versionName != null) { 10035 sb.append(" (").append(pi.versionName).append(")"); 10036 } 10037 } 10038 } catch (RemoteException e) { 10039 Slog.e(TAG, "Error getting package info: " + pkg, e); 10040 } 10041 sb.append("\n"); 10042 } 10043 } 10044 } 10045 10046 private static String processClass(ProcessRecord process) { 10047 if (process == null || process.pid == MY_PID) { 10048 return "system_server"; 10049 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10050 return "system_app"; 10051 } else { 10052 return "data_app"; 10053 } 10054 } 10055 10056 /** 10057 * Write a description of an error (crash, WTF, ANR) to the drop box. 10058 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10059 * @param process which caused the error, null means the system server 10060 * @param activity which triggered the error, null if unknown 10061 * @param parent activity related to the error, null if unknown 10062 * @param subject line related to the error, null if absent 10063 * @param report in long form describing the error, null if absent 10064 * @param logFile to include in the report, null if none 10065 * @param crashInfo giving an application stack trace, null if absent 10066 */ 10067 public void addErrorToDropBox(String eventType, 10068 ProcessRecord process, String processName, ActivityRecord activity, 10069 ActivityRecord parent, String subject, 10070 final String report, final File logFile, 10071 final ApplicationErrorReport.CrashInfo crashInfo) { 10072 // NOTE -- this must never acquire the ActivityManagerService lock, 10073 // otherwise the watchdog may be prevented from resetting the system. 10074 10075 final String dropboxTag = processClass(process) + "_" + eventType; 10076 final DropBoxManager dbox = (DropBoxManager) 10077 mContext.getSystemService(Context.DROPBOX_SERVICE); 10078 10079 // Exit early if the dropbox isn't configured to accept this report type. 10080 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10081 10082 final StringBuilder sb = new StringBuilder(1024); 10083 appendDropBoxProcessHeaders(process, processName, sb); 10084 if (activity != null) { 10085 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10086 } 10087 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10088 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10089 } 10090 if (parent != null && parent != activity) { 10091 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10092 } 10093 if (subject != null) { 10094 sb.append("Subject: ").append(subject).append("\n"); 10095 } 10096 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10097 if (Debug.isDebuggerConnected()) { 10098 sb.append("Debugger: Connected\n"); 10099 } 10100 sb.append("\n"); 10101 10102 // Do the rest in a worker thread to avoid blocking the caller on I/O 10103 // (After this point, we shouldn't access AMS internal data structures.) 10104 Thread worker = new Thread("Error dump: " + dropboxTag) { 10105 @Override 10106 public void run() { 10107 if (report != null) { 10108 sb.append(report); 10109 } 10110 if (logFile != null) { 10111 try { 10112 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10113 "\n\n[[TRUNCATED]]")); 10114 } catch (IOException e) { 10115 Slog.e(TAG, "Error reading " + logFile, e); 10116 } 10117 } 10118 if (crashInfo != null && crashInfo.stackTrace != null) { 10119 sb.append(crashInfo.stackTrace); 10120 } 10121 10122 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10123 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10124 if (lines > 0) { 10125 sb.append("\n"); 10126 10127 // Merge several logcat streams, and take the last N lines 10128 InputStreamReader input = null; 10129 try { 10130 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10131 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10132 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10133 10134 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10135 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10136 input = new InputStreamReader(logcat.getInputStream()); 10137 10138 int num; 10139 char[] buf = new char[8192]; 10140 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10141 } catch (IOException e) { 10142 Slog.e(TAG, "Error running logcat", e); 10143 } finally { 10144 if (input != null) try { input.close(); } catch (IOException e) {} 10145 } 10146 } 10147 10148 dbox.addText(dropboxTag, sb.toString()); 10149 } 10150 }; 10151 10152 if (process == null) { 10153 // If process is null, we are being called from some internal code 10154 // and may be about to die -- run this synchronously. 10155 worker.run(); 10156 } else { 10157 worker.start(); 10158 } 10159 } 10160 10161 /** 10162 * Bring up the "unexpected error" dialog box for a crashing app. 10163 * Deal with edge cases (intercepts from instrumented applications, 10164 * ActivityController, error intent receivers, that sort of thing). 10165 * @param r the application crashing 10166 * @param crashInfo describing the failure 10167 */ 10168 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10169 long timeMillis = System.currentTimeMillis(); 10170 String shortMsg = crashInfo.exceptionClassName; 10171 String longMsg = crashInfo.exceptionMessage; 10172 String stackTrace = crashInfo.stackTrace; 10173 if (shortMsg != null && longMsg != null) { 10174 longMsg = shortMsg + ": " + longMsg; 10175 } else if (shortMsg != null) { 10176 longMsg = shortMsg; 10177 } 10178 10179 AppErrorResult result = new AppErrorResult(); 10180 synchronized (this) { 10181 if (mController != null) { 10182 try { 10183 String name = r != null ? r.processName : null; 10184 int pid = r != null ? r.pid : Binder.getCallingPid(); 10185 if (!mController.appCrashed(name, pid, 10186 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10187 Slog.w(TAG, "Force-killing crashed app " + name 10188 + " at watcher's request"); 10189 Process.killProcess(pid); 10190 return; 10191 } 10192 } catch (RemoteException e) { 10193 mController = null; 10194 Watchdog.getInstance().setActivityController(null); 10195 } 10196 } 10197 10198 final long origId = Binder.clearCallingIdentity(); 10199 10200 // If this process is running instrumentation, finish it. 10201 if (r != null && r.instrumentationClass != null) { 10202 Slog.w(TAG, "Error in app " + r.processName 10203 + " running instrumentation " + r.instrumentationClass + ":"); 10204 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10205 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10206 Bundle info = new Bundle(); 10207 info.putString("shortMsg", shortMsg); 10208 info.putString("longMsg", longMsg); 10209 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10210 Binder.restoreCallingIdentity(origId); 10211 return; 10212 } 10213 10214 // If we can't identify the process or it's already exceeded its crash quota, 10215 // quit right away without showing a crash dialog. 10216 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10217 Binder.restoreCallingIdentity(origId); 10218 return; 10219 } 10220 10221 Message msg = Message.obtain(); 10222 msg.what = SHOW_ERROR_MSG; 10223 HashMap data = new HashMap(); 10224 data.put("result", result); 10225 data.put("app", r); 10226 msg.obj = data; 10227 mHandler.sendMessage(msg); 10228 10229 Binder.restoreCallingIdentity(origId); 10230 } 10231 10232 int res = result.get(); 10233 10234 Intent appErrorIntent = null; 10235 synchronized (this) { 10236 if (r != null && !r.isolated) { 10237 // XXX Can't keep track of crash time for isolated processes, 10238 // since they don't have a persistent identity. 10239 mProcessCrashTimes.put(r.info.processName, r.uid, 10240 SystemClock.uptimeMillis()); 10241 } 10242 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10243 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10244 } 10245 } 10246 10247 if (appErrorIntent != null) { 10248 try { 10249 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10250 } catch (ActivityNotFoundException e) { 10251 Slog.w(TAG, "bug report receiver dissappeared", e); 10252 } 10253 } 10254 } 10255 10256 Intent createAppErrorIntentLocked(ProcessRecord r, 10257 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10258 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10259 if (report == null) { 10260 return null; 10261 } 10262 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10263 result.setComponent(r.errorReportReceiver); 10264 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10265 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10266 return result; 10267 } 10268 10269 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10270 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10271 if (r.errorReportReceiver == null) { 10272 return null; 10273 } 10274 10275 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10276 return null; 10277 } 10278 10279 ApplicationErrorReport report = new ApplicationErrorReport(); 10280 report.packageName = r.info.packageName; 10281 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10282 report.processName = r.processName; 10283 report.time = timeMillis; 10284 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10285 10286 if (r.crashing || r.forceCrashReport) { 10287 report.type = ApplicationErrorReport.TYPE_CRASH; 10288 report.crashInfo = crashInfo; 10289 } else if (r.notResponding) { 10290 report.type = ApplicationErrorReport.TYPE_ANR; 10291 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10292 10293 report.anrInfo.activity = r.notRespondingReport.tag; 10294 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10295 report.anrInfo.info = r.notRespondingReport.longMsg; 10296 } 10297 10298 return report; 10299 } 10300 10301 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10302 enforceNotIsolatedCaller("getProcessesInErrorState"); 10303 // assume our apps are happy - lazy create the list 10304 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10305 10306 final boolean allUsers = ActivityManager.checkUidPermission( 10307 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10308 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10309 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10310 10311 synchronized (this) { 10312 10313 // iterate across all processes 10314 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10315 ProcessRecord app = mLruProcesses.get(i); 10316 if (!allUsers && app.userId != userId) { 10317 continue; 10318 } 10319 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10320 // This one's in trouble, so we'll generate a report for it 10321 // crashes are higher priority (in case there's a crash *and* an anr) 10322 ActivityManager.ProcessErrorStateInfo report = null; 10323 if (app.crashing) { 10324 report = app.crashingReport; 10325 } else if (app.notResponding) { 10326 report = app.notRespondingReport; 10327 } 10328 10329 if (report != null) { 10330 if (errList == null) { 10331 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10332 } 10333 errList.add(report); 10334 } else { 10335 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10336 " crashing = " + app.crashing + 10337 " notResponding = " + app.notResponding); 10338 } 10339 } 10340 } 10341 } 10342 10343 return errList; 10344 } 10345 10346 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10347 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10348 if (currApp != null) { 10349 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10350 } 10351 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10352 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10353 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10354 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10355 if (currApp != null) { 10356 currApp.lru = 0; 10357 } 10358 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10359 } else if (adj >= ProcessList.SERVICE_ADJ) { 10360 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10361 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10362 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10363 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10364 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10365 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10366 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10367 } else { 10368 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10369 } 10370 } 10371 10372 private void fillInProcMemInfo(ProcessRecord app, 10373 ActivityManager.RunningAppProcessInfo outInfo) { 10374 outInfo.pid = app.pid; 10375 outInfo.uid = app.info.uid; 10376 if (mHeavyWeightProcess == app) { 10377 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10378 } 10379 if (app.persistent) { 10380 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10381 } 10382 if (app.activities.size() > 0) { 10383 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10384 } 10385 outInfo.lastTrimLevel = app.trimMemoryLevel; 10386 int adj = app.curAdj; 10387 outInfo.importance = oomAdjToImportance(adj, outInfo); 10388 outInfo.importanceReasonCode = app.adjTypeCode; 10389 } 10390 10391 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10392 enforceNotIsolatedCaller("getRunningAppProcesses"); 10393 // Lazy instantiation of list 10394 List<ActivityManager.RunningAppProcessInfo> runList = null; 10395 final boolean allUsers = ActivityManager.checkUidPermission( 10396 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10397 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10398 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10399 synchronized (this) { 10400 // Iterate across all processes 10401 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10402 ProcessRecord app = mLruProcesses.get(i); 10403 if (!allUsers && app.userId != userId) { 10404 continue; 10405 } 10406 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10407 // Generate process state info for running application 10408 ActivityManager.RunningAppProcessInfo currApp = 10409 new ActivityManager.RunningAppProcessInfo(app.processName, 10410 app.pid, app.getPackageList()); 10411 fillInProcMemInfo(app, currApp); 10412 if (app.adjSource instanceof ProcessRecord) { 10413 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10414 currApp.importanceReasonImportance = oomAdjToImportance( 10415 app.adjSourceOom, null); 10416 } else if (app.adjSource instanceof ActivityRecord) { 10417 ActivityRecord r = (ActivityRecord)app.adjSource; 10418 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10419 } 10420 if (app.adjTarget instanceof ComponentName) { 10421 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10422 } 10423 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10424 // + " lru=" + currApp.lru); 10425 if (runList == null) { 10426 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10427 } 10428 runList.add(currApp); 10429 } 10430 } 10431 } 10432 return runList; 10433 } 10434 10435 public List<ApplicationInfo> getRunningExternalApplications() { 10436 enforceNotIsolatedCaller("getRunningExternalApplications"); 10437 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10438 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10439 if (runningApps != null && runningApps.size() > 0) { 10440 Set<String> extList = new HashSet<String>(); 10441 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10442 if (app.pkgList != null) { 10443 for (String pkg : app.pkgList) { 10444 extList.add(pkg); 10445 } 10446 } 10447 } 10448 IPackageManager pm = AppGlobals.getPackageManager(); 10449 for (String pkg : extList) { 10450 try { 10451 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10452 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10453 retList.add(info); 10454 } 10455 } catch (RemoteException e) { 10456 } 10457 } 10458 } 10459 return retList; 10460 } 10461 10462 @Override 10463 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10464 enforceNotIsolatedCaller("getMyMemoryState"); 10465 synchronized (this) { 10466 ProcessRecord proc; 10467 synchronized (mPidsSelfLocked) { 10468 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10469 } 10470 fillInProcMemInfo(proc, outInfo); 10471 } 10472 } 10473 10474 @Override 10475 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10476 if (checkCallingPermission(android.Manifest.permission.DUMP) 10477 != PackageManager.PERMISSION_GRANTED) { 10478 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10479 + Binder.getCallingPid() 10480 + ", uid=" + Binder.getCallingUid() 10481 + " without permission " 10482 + android.Manifest.permission.DUMP); 10483 return; 10484 } 10485 10486 boolean dumpAll = false; 10487 boolean dumpClient = false; 10488 String dumpPackage = null; 10489 10490 int opti = 0; 10491 while (opti < args.length) { 10492 String opt = args[opti]; 10493 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10494 break; 10495 } 10496 opti++; 10497 if ("-a".equals(opt)) { 10498 dumpAll = true; 10499 } else if ("-c".equals(opt)) { 10500 dumpClient = true; 10501 } else if ("-h".equals(opt)) { 10502 pw.println("Activity manager dump options:"); 10503 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10504 pw.println(" cmd may be one of:"); 10505 pw.println(" a[ctivities]: activity stack state"); 10506 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10507 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10508 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10509 pw.println(" o[om]: out of memory management"); 10510 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10511 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10512 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10513 pw.println(" service [COMP_SPEC]: service client-side state"); 10514 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10515 pw.println(" all: dump all activities"); 10516 pw.println(" top: dump the top activity"); 10517 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10518 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10519 pw.println(" a partial substring in a component name, a"); 10520 pw.println(" hex object identifier."); 10521 pw.println(" -a: include all available server state."); 10522 pw.println(" -c: include client state."); 10523 return; 10524 } else { 10525 pw.println("Unknown argument: " + opt + "; use -h for help"); 10526 } 10527 } 10528 10529 long origId = Binder.clearCallingIdentity(); 10530 boolean more = false; 10531 // Is the caller requesting to dump a particular piece of data? 10532 if (opti < args.length) { 10533 String cmd = args[opti]; 10534 opti++; 10535 if ("activities".equals(cmd) || "a".equals(cmd)) { 10536 synchronized (this) { 10537 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10538 } 10539 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10540 String[] newArgs; 10541 String name; 10542 if (opti >= args.length) { 10543 name = null; 10544 newArgs = EMPTY_STRING_ARRAY; 10545 } else { 10546 name = args[opti]; 10547 opti++; 10548 newArgs = new String[args.length - opti]; 10549 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10550 args.length - opti); 10551 } 10552 synchronized (this) { 10553 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10554 } 10555 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10556 String[] newArgs; 10557 String name; 10558 if (opti >= args.length) { 10559 name = null; 10560 newArgs = EMPTY_STRING_ARRAY; 10561 } else { 10562 name = args[opti]; 10563 opti++; 10564 newArgs = new String[args.length - opti]; 10565 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10566 args.length - opti); 10567 } 10568 synchronized (this) { 10569 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10570 } 10571 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10572 String[] newArgs; 10573 String name; 10574 if (opti >= args.length) { 10575 name = null; 10576 newArgs = EMPTY_STRING_ARRAY; 10577 } else { 10578 name = args[opti]; 10579 opti++; 10580 newArgs = new String[args.length - opti]; 10581 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10582 args.length - opti); 10583 } 10584 synchronized (this) { 10585 dumpProcessesLocked(fd, pw, args, opti, true, name); 10586 } 10587 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10588 synchronized (this) { 10589 dumpOomLocked(fd, pw, args, opti, true); 10590 } 10591 } else if ("provider".equals(cmd)) { 10592 String[] newArgs; 10593 String name; 10594 if (opti >= args.length) { 10595 name = null; 10596 newArgs = EMPTY_STRING_ARRAY; 10597 } else { 10598 name = args[opti]; 10599 opti++; 10600 newArgs = new String[args.length - opti]; 10601 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10602 } 10603 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10604 pw.println("No providers match: " + name); 10605 pw.println("Use -h for help."); 10606 } 10607 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10608 synchronized (this) { 10609 dumpProvidersLocked(fd, pw, args, opti, true, null); 10610 } 10611 } else if ("service".equals(cmd)) { 10612 String[] newArgs; 10613 String name; 10614 if (opti >= args.length) { 10615 name = null; 10616 newArgs = EMPTY_STRING_ARRAY; 10617 } else { 10618 name = args[opti]; 10619 opti++; 10620 newArgs = new String[args.length - opti]; 10621 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10622 args.length - opti); 10623 } 10624 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10625 pw.println("No services match: " + name); 10626 pw.println("Use -h for help."); 10627 } 10628 } else if ("package".equals(cmd)) { 10629 String[] newArgs; 10630 if (opti >= args.length) { 10631 pw.println("package: no package name specified"); 10632 pw.println("Use -h for help."); 10633 } else { 10634 dumpPackage = args[opti]; 10635 opti++; 10636 newArgs = new String[args.length - opti]; 10637 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10638 args.length - opti); 10639 args = newArgs; 10640 opti = 0; 10641 more = true; 10642 } 10643 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10644 synchronized (this) { 10645 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10646 } 10647 } else { 10648 // Dumping a single activity? 10649 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10650 pw.println("Bad activity command, or no activities match: " + cmd); 10651 pw.println("Use -h for help."); 10652 } 10653 } 10654 if (!more) { 10655 Binder.restoreCallingIdentity(origId); 10656 return; 10657 } 10658 } 10659 10660 // No piece of data specified, dump everything. 10661 synchronized (this) { 10662 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10663 pw.println(); 10664 if (dumpAll) { 10665 pw.println("-------------------------------------------------------------------------------"); 10666 } 10667 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10668 pw.println(); 10669 if (dumpAll) { 10670 pw.println("-------------------------------------------------------------------------------"); 10671 } 10672 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10673 pw.println(); 10674 if (dumpAll) { 10675 pw.println("-------------------------------------------------------------------------------"); 10676 } 10677 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10678 pw.println(); 10679 if (dumpAll) { 10680 pw.println("-------------------------------------------------------------------------------"); 10681 } 10682 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10683 pw.println(); 10684 if (dumpAll) { 10685 pw.println("-------------------------------------------------------------------------------"); 10686 } 10687 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10688 } 10689 Binder.restoreCallingIdentity(origId); 10690 } 10691 10692 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10693 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10694 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10695 10696 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10697 dumpPackage); 10698 boolean needSep = printedAnything; 10699 10700 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10701 dumpPackage, needSep, " mFocusedActivity: "); 10702 if (printed) { 10703 printedAnything = true; 10704 needSep = false; 10705 } 10706 10707 if (dumpPackage == null) { 10708 if (needSep) { 10709 pw.println(); 10710 } 10711 needSep = true; 10712 printedAnything = true; 10713 mStackSupervisor.dump(pw, " "); 10714 } 10715 10716 if (mRecentTasks.size() > 0) { 10717 boolean printedHeader = false; 10718 10719 final int N = mRecentTasks.size(); 10720 for (int i=0; i<N; i++) { 10721 TaskRecord tr = mRecentTasks.get(i); 10722 if (dumpPackage != null) { 10723 if (tr.realActivity == null || 10724 !dumpPackage.equals(tr.realActivity)) { 10725 continue; 10726 } 10727 } 10728 if (!printedHeader) { 10729 if (needSep) { 10730 pw.println(); 10731 } 10732 pw.println(" Recent tasks:"); 10733 printedHeader = true; 10734 printedAnything = true; 10735 } 10736 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10737 pw.println(tr); 10738 if (dumpAll) { 10739 mRecentTasks.get(i).dump(pw, " "); 10740 } 10741 } 10742 } 10743 10744 if (!printedAnything) { 10745 pw.println(" (nothing)"); 10746 } 10747 } 10748 10749 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10750 int opti, boolean dumpAll, String dumpPackage) { 10751 boolean needSep = false; 10752 boolean printedAnything = false; 10753 int numPers = 0; 10754 10755 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10756 10757 if (dumpAll) { 10758 final int NP = mProcessNames.getMap().size(); 10759 for (int ip=0; ip<NP; ip++) { 10760 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10761 final int NA = procs.size(); 10762 for (int ia=0; ia<NA; ia++) { 10763 ProcessRecord r = procs.valueAt(ia); 10764 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10765 continue; 10766 } 10767 if (!needSep) { 10768 pw.println(" All known processes:"); 10769 needSep = true; 10770 printedAnything = true; 10771 } 10772 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10773 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10774 pw.print(" "); pw.println(r); 10775 r.dump(pw, " "); 10776 if (r.persistent) { 10777 numPers++; 10778 } 10779 } 10780 } 10781 } 10782 10783 if (mIsolatedProcesses.size() > 0) { 10784 boolean printed = false; 10785 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10786 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10787 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10788 continue; 10789 } 10790 if (!printed) { 10791 if (needSep) { 10792 pw.println(); 10793 } 10794 pw.println(" Isolated process list (sorted by uid):"); 10795 printedAnything = true; 10796 printed = true; 10797 needSep = true; 10798 } 10799 pw.println(String.format("%sIsolated #%2d: %s", 10800 " ", i, r.toString())); 10801 } 10802 } 10803 10804 if (mLruProcesses.size() > 0) { 10805 if (needSep) { 10806 pw.println(); 10807 } 10808 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10809 pw.print(" total, non-act at "); 10810 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10811 pw.print(", non-svc at "); 10812 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10813 pw.println("):"); 10814 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10815 needSep = true; 10816 printedAnything = true; 10817 } 10818 10819 if (dumpAll || dumpPackage != null) { 10820 synchronized (mPidsSelfLocked) { 10821 boolean printed = false; 10822 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10823 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10824 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10825 continue; 10826 } 10827 if (!printed) { 10828 if (needSep) pw.println(); 10829 needSep = true; 10830 pw.println(" PID mappings:"); 10831 printed = true; 10832 printedAnything = true; 10833 } 10834 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10835 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10836 } 10837 } 10838 } 10839 10840 if (mForegroundProcesses.size() > 0) { 10841 synchronized (mPidsSelfLocked) { 10842 boolean printed = false; 10843 for (int i=0; i<mForegroundProcesses.size(); i++) { 10844 ProcessRecord r = mPidsSelfLocked.get( 10845 mForegroundProcesses.valueAt(i).pid); 10846 if (dumpPackage != null && (r == null 10847 || !r.pkgList.containsKey(dumpPackage))) { 10848 continue; 10849 } 10850 if (!printed) { 10851 if (needSep) pw.println(); 10852 needSep = true; 10853 pw.println(" Foreground Processes:"); 10854 printed = true; 10855 printedAnything = true; 10856 } 10857 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10858 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10859 } 10860 } 10861 } 10862 10863 if (mPersistentStartingProcesses.size() > 0) { 10864 if (needSep) pw.println(); 10865 needSep = true; 10866 printedAnything = true; 10867 pw.println(" Persisent processes that are starting:"); 10868 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10869 "Starting Norm", "Restarting PERS", dumpPackage); 10870 } 10871 10872 if (mRemovedProcesses.size() > 0) { 10873 if (needSep) pw.println(); 10874 needSep = true; 10875 printedAnything = true; 10876 pw.println(" Processes that are being removed:"); 10877 dumpProcessList(pw, this, mRemovedProcesses, " ", 10878 "Removed Norm", "Removed PERS", dumpPackage); 10879 } 10880 10881 if (mProcessesOnHold.size() > 0) { 10882 if (needSep) pw.println(); 10883 needSep = true; 10884 printedAnything = true; 10885 pw.println(" Processes that are on old until the system is ready:"); 10886 dumpProcessList(pw, this, mProcessesOnHold, " ", 10887 "OnHold Norm", "OnHold PERS", dumpPackage); 10888 } 10889 10890 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10891 10892 if (mProcessCrashTimes.getMap().size() > 0) { 10893 boolean printed = false; 10894 long now = SystemClock.uptimeMillis(); 10895 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10896 final int NP = pmap.size(); 10897 for (int ip=0; ip<NP; ip++) { 10898 String pname = pmap.keyAt(ip); 10899 SparseArray<Long> uids = pmap.valueAt(ip); 10900 final int N = uids.size(); 10901 for (int i=0; i<N; i++) { 10902 int puid = uids.keyAt(i); 10903 ProcessRecord r = mProcessNames.get(pname, puid); 10904 if (dumpPackage != null && (r == null 10905 || !r.pkgList.containsKey(dumpPackage))) { 10906 continue; 10907 } 10908 if (!printed) { 10909 if (needSep) pw.println(); 10910 needSep = true; 10911 pw.println(" Time since processes crashed:"); 10912 printed = true; 10913 printedAnything = true; 10914 } 10915 pw.print(" Process "); pw.print(pname); 10916 pw.print(" uid "); pw.print(puid); 10917 pw.print(": last crashed "); 10918 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10919 pw.println(" ago"); 10920 } 10921 } 10922 } 10923 10924 if (mBadProcesses.getMap().size() > 0) { 10925 boolean printed = false; 10926 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 10927 final int NP = pmap.size(); 10928 for (int ip=0; ip<NP; ip++) { 10929 String pname = pmap.keyAt(ip); 10930 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 10931 final int N = uids.size(); 10932 for (int i=0; i<N; i++) { 10933 int puid = uids.keyAt(i); 10934 ProcessRecord r = mProcessNames.get(pname, puid); 10935 if (dumpPackage != null && (r == null 10936 || !r.pkgList.containsKey(dumpPackage))) { 10937 continue; 10938 } 10939 if (!printed) { 10940 if (needSep) pw.println(); 10941 needSep = true; 10942 pw.println(" Bad processes:"); 10943 printedAnything = true; 10944 } 10945 BadProcessInfo info = uids.valueAt(i); 10946 pw.print(" Bad process "); pw.print(pname); 10947 pw.print(" uid "); pw.print(puid); 10948 pw.print(": crashed at time "); pw.println(info.time); 10949 if (info.shortMsg != null) { 10950 pw.print(" Short msg: "); pw.println(info.shortMsg); 10951 } 10952 if (info.longMsg != null) { 10953 pw.print(" Long msg: "); pw.println(info.longMsg); 10954 } 10955 if (info.stack != null) { 10956 pw.println(" Stack:"); 10957 int lastPos = 0; 10958 for (int pos=0; pos<info.stack.length(); pos++) { 10959 if (info.stack.charAt(pos) == '\n') { 10960 pw.print(" "); 10961 pw.write(info.stack, lastPos, pos-lastPos); 10962 pw.println(); 10963 lastPos = pos+1; 10964 } 10965 } 10966 if (lastPos < info.stack.length()) { 10967 pw.print(" "); 10968 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 10969 pw.println(); 10970 } 10971 } 10972 } 10973 } 10974 } 10975 10976 if (dumpPackage == null) { 10977 pw.println(); 10978 needSep = false; 10979 pw.println(" mStartedUsers:"); 10980 for (int i=0; i<mStartedUsers.size(); i++) { 10981 UserStartedState uss = mStartedUsers.valueAt(i); 10982 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 10983 pw.print(": "); uss.dump("", pw); 10984 } 10985 pw.print(" mStartedUserArray: ["); 10986 for (int i=0; i<mStartedUserArray.length; i++) { 10987 if (i > 0) pw.print(", "); 10988 pw.print(mStartedUserArray[i]); 10989 } 10990 pw.println("]"); 10991 pw.print(" mUserLru: ["); 10992 for (int i=0; i<mUserLru.size(); i++) { 10993 if (i > 0) pw.print(", "); 10994 pw.print(mUserLru.get(i)); 10995 } 10996 pw.println("]"); 10997 if (dumpAll) { 10998 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 10999 } 11000 } 11001 if (mHomeProcess != null && (dumpPackage == null 11002 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11003 if (needSep) { 11004 pw.println(); 11005 needSep = false; 11006 } 11007 pw.println(" mHomeProcess: " + mHomeProcess); 11008 } 11009 if (mPreviousProcess != null && (dumpPackage == null 11010 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11011 if (needSep) { 11012 pw.println(); 11013 needSep = false; 11014 } 11015 pw.println(" mPreviousProcess: " + mPreviousProcess); 11016 } 11017 if (dumpAll) { 11018 StringBuilder sb = new StringBuilder(128); 11019 sb.append(" mPreviousProcessVisibleTime: "); 11020 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11021 pw.println(sb); 11022 } 11023 if (mHeavyWeightProcess != null && (dumpPackage == null 11024 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11025 if (needSep) { 11026 pw.println(); 11027 needSep = false; 11028 } 11029 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11030 } 11031 if (dumpPackage == null) { 11032 pw.println(" mConfiguration: " + mConfiguration); 11033 } 11034 if (dumpAll) { 11035 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11036 if (mCompatModePackages.getPackages().size() > 0) { 11037 boolean printed = false; 11038 for (Map.Entry<String, Integer> entry 11039 : mCompatModePackages.getPackages().entrySet()) { 11040 String pkg = entry.getKey(); 11041 int mode = entry.getValue(); 11042 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11043 continue; 11044 } 11045 if (!printed) { 11046 pw.println(" mScreenCompatPackages:"); 11047 printed = true; 11048 } 11049 pw.print(" "); pw.print(pkg); pw.print(": "); 11050 pw.print(mode); pw.println(); 11051 } 11052 } 11053 } 11054 if (dumpPackage == null) { 11055 if (mSleeping || mWentToSleep || mLockScreenShown) { 11056 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11057 + " mLockScreenShown " + mLockScreenShown); 11058 } 11059 if (mShuttingDown) { 11060 pw.println(" mShuttingDown=" + mShuttingDown); 11061 } 11062 } 11063 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11064 || mOrigWaitForDebugger) { 11065 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11066 || dumpPackage.equals(mOrigDebugApp)) { 11067 if (needSep) { 11068 pw.println(); 11069 needSep = false; 11070 } 11071 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11072 + " mDebugTransient=" + mDebugTransient 11073 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11074 } 11075 } 11076 if (mOpenGlTraceApp != null) { 11077 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11078 if (needSep) { 11079 pw.println(); 11080 needSep = false; 11081 } 11082 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11083 } 11084 } 11085 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11086 || mProfileFd != null) { 11087 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11088 if (needSep) { 11089 pw.println(); 11090 needSep = false; 11091 } 11092 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11093 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11094 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11095 + mAutoStopProfiler); 11096 } 11097 } 11098 if (dumpPackage == null) { 11099 if (mAlwaysFinishActivities || mController != null) { 11100 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11101 + " mController=" + mController); 11102 } 11103 if (dumpAll) { 11104 pw.println(" Total persistent processes: " + numPers); 11105 pw.println(" mStartRunning=" + mStartRunning 11106 + " mProcessesReady=" + mProcessesReady 11107 + " mSystemReady=" + mSystemReady); 11108 pw.println(" mBooting=" + mBooting 11109 + " mBooted=" + mBooted 11110 + " mFactoryTest=" + mFactoryTest); 11111 pw.print(" mLastPowerCheckRealtime="); 11112 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11113 pw.println(""); 11114 pw.print(" mLastPowerCheckUptime="); 11115 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11116 pw.println(""); 11117 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11118 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11119 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11120 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11121 + " (" + mLruProcesses.size() + " total)" 11122 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11123 + " mNumServiceProcs=" + mNumServiceProcs 11124 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11125 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11126 + " mLastMemoryLevel" + mLastMemoryLevel 11127 + " mLastNumProcesses" + mLastNumProcesses); 11128 long now = SystemClock.uptimeMillis(); 11129 pw.print(" mLastIdleTime="); 11130 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11131 pw.print(" mLowRamSinceLastIdle="); 11132 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11133 pw.println(); 11134 } 11135 } 11136 11137 if (!printedAnything) { 11138 pw.println(" (nothing)"); 11139 } 11140 } 11141 11142 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11143 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11144 if (mProcessesToGc.size() > 0) { 11145 boolean printed = false; 11146 long now = SystemClock.uptimeMillis(); 11147 for (int i=0; i<mProcessesToGc.size(); i++) { 11148 ProcessRecord proc = mProcessesToGc.get(i); 11149 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11150 continue; 11151 } 11152 if (!printed) { 11153 if (needSep) pw.println(); 11154 needSep = true; 11155 pw.println(" Processes that are waiting to GC:"); 11156 printed = true; 11157 } 11158 pw.print(" Process "); pw.println(proc); 11159 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11160 pw.print(", last gced="); 11161 pw.print(now-proc.lastRequestedGc); 11162 pw.print(" ms ago, last lowMem="); 11163 pw.print(now-proc.lastLowMemory); 11164 pw.println(" ms ago"); 11165 11166 } 11167 } 11168 return needSep; 11169 } 11170 11171 void printOomLevel(PrintWriter pw, String name, int adj) { 11172 pw.print(" "); 11173 if (adj >= 0) { 11174 pw.print(' '); 11175 if (adj < 10) pw.print(' '); 11176 } else { 11177 if (adj > -10) pw.print(' '); 11178 } 11179 pw.print(adj); 11180 pw.print(": "); 11181 pw.print(name); 11182 pw.print(" ("); 11183 pw.print(mProcessList.getMemLevel(adj)/1024); 11184 pw.println(" kB)"); 11185 } 11186 11187 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11188 int opti, boolean dumpAll) { 11189 boolean needSep = false; 11190 11191 if (mLruProcesses.size() > 0) { 11192 if (needSep) pw.println(); 11193 needSep = true; 11194 pw.println(" OOM levels:"); 11195 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11196 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11197 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11198 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11199 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11200 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11201 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11202 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11203 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11204 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11205 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11206 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11207 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11208 11209 if (needSep) pw.println(); 11210 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11211 pw.print(" total, non-act at "); 11212 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11213 pw.print(", non-svc at "); 11214 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11215 pw.println("):"); 11216 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11217 needSep = true; 11218 } 11219 11220 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11221 11222 pw.println(); 11223 pw.println(" mHomeProcess: " + mHomeProcess); 11224 pw.println(" mPreviousProcess: " + mPreviousProcess); 11225 if (mHeavyWeightProcess != null) { 11226 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11227 } 11228 11229 return true; 11230 } 11231 11232 /** 11233 * There are three ways to call this: 11234 * - no provider specified: dump all the providers 11235 * - a flattened component name that matched an existing provider was specified as the 11236 * first arg: dump that one provider 11237 * - the first arg isn't the flattened component name of an existing provider: 11238 * dump all providers whose component contains the first arg as a substring 11239 */ 11240 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11241 int opti, boolean dumpAll) { 11242 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11243 } 11244 11245 static class ItemMatcher { 11246 ArrayList<ComponentName> components; 11247 ArrayList<String> strings; 11248 ArrayList<Integer> objects; 11249 boolean all; 11250 11251 ItemMatcher() { 11252 all = true; 11253 } 11254 11255 void build(String name) { 11256 ComponentName componentName = ComponentName.unflattenFromString(name); 11257 if (componentName != null) { 11258 if (components == null) { 11259 components = new ArrayList<ComponentName>(); 11260 } 11261 components.add(componentName); 11262 all = false; 11263 } else { 11264 int objectId = 0; 11265 // Not a '/' separated full component name; maybe an object ID? 11266 try { 11267 objectId = Integer.parseInt(name, 16); 11268 if (objects == null) { 11269 objects = new ArrayList<Integer>(); 11270 } 11271 objects.add(objectId); 11272 all = false; 11273 } catch (RuntimeException e) { 11274 // Not an integer; just do string match. 11275 if (strings == null) { 11276 strings = new ArrayList<String>(); 11277 } 11278 strings.add(name); 11279 all = false; 11280 } 11281 } 11282 } 11283 11284 int build(String[] args, int opti) { 11285 for (; opti<args.length; opti++) { 11286 String name = args[opti]; 11287 if ("--".equals(name)) { 11288 return opti+1; 11289 } 11290 build(name); 11291 } 11292 return opti; 11293 } 11294 11295 boolean match(Object object, ComponentName comp) { 11296 if (all) { 11297 return true; 11298 } 11299 if (components != null) { 11300 for (int i=0; i<components.size(); i++) { 11301 if (components.get(i).equals(comp)) { 11302 return true; 11303 } 11304 } 11305 } 11306 if (objects != null) { 11307 for (int i=0; i<objects.size(); i++) { 11308 if (System.identityHashCode(object) == objects.get(i)) { 11309 return true; 11310 } 11311 } 11312 } 11313 if (strings != null) { 11314 String flat = comp.flattenToString(); 11315 for (int i=0; i<strings.size(); i++) { 11316 if (flat.contains(strings.get(i))) { 11317 return true; 11318 } 11319 } 11320 } 11321 return false; 11322 } 11323 } 11324 11325 /** 11326 * There are three things that cmd can be: 11327 * - a flattened component name that matches an existing activity 11328 * - the cmd arg isn't the flattened component name of an existing activity: 11329 * dump all activity whose component contains the cmd as a substring 11330 * - A hex number of the ActivityRecord object instance. 11331 */ 11332 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11333 int opti, boolean dumpAll) { 11334 ArrayList<ActivityRecord> activities; 11335 11336 synchronized (this) { 11337 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11338 } 11339 11340 if (activities.size() <= 0) { 11341 return false; 11342 } 11343 11344 String[] newArgs = new String[args.length - opti]; 11345 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11346 11347 TaskRecord lastTask = null; 11348 boolean needSep = false; 11349 for (int i=activities.size()-1; i>=0; i--) { 11350 ActivityRecord r = activities.get(i); 11351 if (needSep) { 11352 pw.println(); 11353 } 11354 needSep = true; 11355 synchronized (this) { 11356 if (lastTask != r.task) { 11357 lastTask = r.task; 11358 pw.print("TASK "); pw.print(lastTask.affinity); 11359 pw.print(" id="); pw.println(lastTask.taskId); 11360 if (dumpAll) { 11361 lastTask.dump(pw, " "); 11362 } 11363 } 11364 } 11365 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11366 } 11367 return true; 11368 } 11369 11370 /** 11371 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11372 * there is a thread associated with the activity. 11373 */ 11374 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11375 final ActivityRecord r, String[] args, boolean dumpAll) { 11376 String innerPrefix = prefix + " "; 11377 synchronized (this) { 11378 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11379 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11380 pw.print(" pid="); 11381 if (r.app != null) pw.println(r.app.pid); 11382 else pw.println("(not running)"); 11383 if (dumpAll) { 11384 r.dump(pw, innerPrefix); 11385 } 11386 } 11387 if (r.app != null && r.app.thread != null) { 11388 // flush anything that is already in the PrintWriter since the thread is going 11389 // to write to the file descriptor directly 11390 pw.flush(); 11391 try { 11392 TransferPipe tp = new TransferPipe(); 11393 try { 11394 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11395 r.appToken, innerPrefix, args); 11396 tp.go(fd); 11397 } finally { 11398 tp.kill(); 11399 } 11400 } catch (IOException e) { 11401 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11402 } catch (RemoteException e) { 11403 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11404 } 11405 } 11406 } 11407 11408 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11409 int opti, boolean dumpAll, String dumpPackage) { 11410 boolean needSep = false; 11411 boolean onlyHistory = false; 11412 boolean printedAnything = false; 11413 11414 if ("history".equals(dumpPackage)) { 11415 if (opti < args.length && "-s".equals(args[opti])) { 11416 dumpAll = false; 11417 } 11418 onlyHistory = true; 11419 dumpPackage = null; 11420 } 11421 11422 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11423 if (!onlyHistory && dumpAll) { 11424 if (mRegisteredReceivers.size() > 0) { 11425 boolean printed = false; 11426 Iterator it = mRegisteredReceivers.values().iterator(); 11427 while (it.hasNext()) { 11428 ReceiverList r = (ReceiverList)it.next(); 11429 if (dumpPackage != null && (r.app == null || 11430 !dumpPackage.equals(r.app.info.packageName))) { 11431 continue; 11432 } 11433 if (!printed) { 11434 pw.println(" Registered Receivers:"); 11435 needSep = true; 11436 printed = true; 11437 printedAnything = true; 11438 } 11439 pw.print(" * "); pw.println(r); 11440 r.dump(pw, " "); 11441 } 11442 } 11443 11444 if (mReceiverResolver.dump(pw, needSep ? 11445 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11446 " ", dumpPackage, false)) { 11447 needSep = true; 11448 printedAnything = true; 11449 } 11450 } 11451 11452 for (BroadcastQueue q : mBroadcastQueues) { 11453 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11454 printedAnything |= needSep; 11455 } 11456 11457 needSep = true; 11458 11459 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11460 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11461 if (needSep) { 11462 pw.println(); 11463 } 11464 needSep = true; 11465 printedAnything = true; 11466 pw.print(" Sticky broadcasts for user "); 11467 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11468 StringBuilder sb = new StringBuilder(128); 11469 for (Map.Entry<String, ArrayList<Intent>> ent 11470 : mStickyBroadcasts.valueAt(user).entrySet()) { 11471 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11472 if (dumpAll) { 11473 pw.println(":"); 11474 ArrayList<Intent> intents = ent.getValue(); 11475 final int N = intents.size(); 11476 for (int i=0; i<N; i++) { 11477 sb.setLength(0); 11478 sb.append(" Intent: "); 11479 intents.get(i).toShortString(sb, false, true, false, false); 11480 pw.println(sb.toString()); 11481 Bundle bundle = intents.get(i).getExtras(); 11482 if (bundle != null) { 11483 pw.print(" "); 11484 pw.println(bundle.toString()); 11485 } 11486 } 11487 } else { 11488 pw.println(""); 11489 } 11490 } 11491 } 11492 } 11493 11494 if (!onlyHistory && dumpAll) { 11495 pw.println(); 11496 for (BroadcastQueue queue : mBroadcastQueues) { 11497 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11498 + queue.mBroadcastsScheduled); 11499 } 11500 pw.println(" mHandler:"); 11501 mHandler.dump(new PrintWriterPrinter(pw), " "); 11502 needSep = true; 11503 printedAnything = true; 11504 } 11505 11506 if (!printedAnything) { 11507 pw.println(" (nothing)"); 11508 } 11509 } 11510 11511 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11512 int opti, boolean dumpAll, String dumpPackage) { 11513 boolean needSep; 11514 boolean printedAnything = false; 11515 11516 ItemMatcher matcher = new ItemMatcher(); 11517 matcher.build(args, opti); 11518 11519 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11520 11521 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11522 printedAnything |= needSep; 11523 11524 if (mLaunchingProviders.size() > 0) { 11525 boolean printed = false; 11526 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11527 ContentProviderRecord r = mLaunchingProviders.get(i); 11528 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11529 continue; 11530 } 11531 if (!printed) { 11532 if (needSep) pw.println(); 11533 needSep = true; 11534 pw.println(" Launching content providers:"); 11535 printed = true; 11536 printedAnything = true; 11537 } 11538 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11539 pw.println(r); 11540 } 11541 } 11542 11543 if (mGrantedUriPermissions.size() > 0) { 11544 boolean printed = false; 11545 int dumpUid = -2; 11546 if (dumpPackage != null) { 11547 try { 11548 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11549 } catch (NameNotFoundException e) { 11550 dumpUid = -1; 11551 } 11552 } 11553 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11554 int uid = mGrantedUriPermissions.keyAt(i); 11555 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11556 continue; 11557 } 11558 ArrayMap<Uri, UriPermission> perms 11559 = mGrantedUriPermissions.valueAt(i); 11560 if (!printed) { 11561 if (needSep) pw.println(); 11562 needSep = true; 11563 pw.println(" Granted Uri Permissions:"); 11564 printed = true; 11565 printedAnything = true; 11566 } 11567 pw.print(" * UID "); pw.print(uid); 11568 pw.println(" holds:"); 11569 for (UriPermission perm : perms.values()) { 11570 pw.print(" "); pw.println(perm); 11571 if (dumpAll) { 11572 perm.dump(pw, " "); 11573 } 11574 } 11575 } 11576 } 11577 11578 if (!printedAnything) { 11579 pw.println(" (nothing)"); 11580 } 11581 } 11582 11583 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11584 int opti, boolean dumpAll, String dumpPackage) { 11585 boolean printed = false; 11586 11587 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11588 11589 if (mIntentSenderRecords.size() > 0) { 11590 Iterator<WeakReference<PendingIntentRecord>> it 11591 = mIntentSenderRecords.values().iterator(); 11592 while (it.hasNext()) { 11593 WeakReference<PendingIntentRecord> ref = it.next(); 11594 PendingIntentRecord rec = ref != null ? ref.get(): null; 11595 if (dumpPackage != null && (rec == null 11596 || !dumpPackage.equals(rec.key.packageName))) { 11597 continue; 11598 } 11599 printed = true; 11600 if (rec != null) { 11601 pw.print(" * "); pw.println(rec); 11602 if (dumpAll) { 11603 rec.dump(pw, " "); 11604 } 11605 } else { 11606 pw.print(" * "); pw.println(ref); 11607 } 11608 } 11609 } 11610 11611 if (!printed) { 11612 pw.println(" (nothing)"); 11613 } 11614 } 11615 11616 private static final int dumpProcessList(PrintWriter pw, 11617 ActivityManagerService service, List list, 11618 String prefix, String normalLabel, String persistentLabel, 11619 String dumpPackage) { 11620 int numPers = 0; 11621 final int N = list.size()-1; 11622 for (int i=N; i>=0; i--) { 11623 ProcessRecord r = (ProcessRecord)list.get(i); 11624 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11625 continue; 11626 } 11627 pw.println(String.format("%s%s #%2d: %s", 11628 prefix, (r.persistent ? persistentLabel : normalLabel), 11629 i, r.toString())); 11630 if (r.persistent) { 11631 numPers++; 11632 } 11633 } 11634 return numPers; 11635 } 11636 11637 private static final boolean dumpProcessOomList(PrintWriter pw, 11638 ActivityManagerService service, List<ProcessRecord> origList, 11639 String prefix, String normalLabel, String persistentLabel, 11640 boolean inclDetails, String dumpPackage) { 11641 11642 ArrayList<Pair<ProcessRecord, Integer>> list 11643 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11644 for (int i=0; i<origList.size(); i++) { 11645 ProcessRecord r = origList.get(i); 11646 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11647 continue; 11648 } 11649 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11650 } 11651 11652 if (list.size() <= 0) { 11653 return false; 11654 } 11655 11656 Comparator<Pair<ProcessRecord, Integer>> comparator 11657 = new Comparator<Pair<ProcessRecord, Integer>>() { 11658 @Override 11659 public int compare(Pair<ProcessRecord, Integer> object1, 11660 Pair<ProcessRecord, Integer> object2) { 11661 if (object1.first.setAdj != object2.first.setAdj) { 11662 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11663 } 11664 if (object1.second.intValue() != object2.second.intValue()) { 11665 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11666 } 11667 return 0; 11668 } 11669 }; 11670 11671 Collections.sort(list, comparator); 11672 11673 final long curRealtime = SystemClock.elapsedRealtime(); 11674 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11675 final long curUptime = SystemClock.uptimeMillis(); 11676 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11677 11678 for (int i=list.size()-1; i>=0; i--) { 11679 ProcessRecord r = list.get(i).first; 11680 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11681 char schedGroup; 11682 switch (r.setSchedGroup) { 11683 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11684 schedGroup = 'B'; 11685 break; 11686 case Process.THREAD_GROUP_DEFAULT: 11687 schedGroup = 'F'; 11688 break; 11689 default: 11690 schedGroup = '?'; 11691 break; 11692 } 11693 char foreground; 11694 if (r.foregroundActivities) { 11695 foreground = 'A'; 11696 } else if (r.foregroundServices) { 11697 foreground = 'S'; 11698 } else { 11699 foreground = ' '; 11700 } 11701 String procState = ProcessList.makeProcStateString(r.curProcState); 11702 pw.print(prefix); 11703 pw.print(r.persistent ? persistentLabel : normalLabel); 11704 pw.print(" #"); 11705 int num = (origList.size()-1)-list.get(i).second; 11706 if (num < 10) pw.print(' '); 11707 pw.print(num); 11708 pw.print(": "); 11709 pw.print(oomAdj); 11710 pw.print(' '); 11711 pw.print(schedGroup); 11712 pw.print('/'); 11713 pw.print(foreground); 11714 pw.print('/'); 11715 pw.print(procState); 11716 pw.print(" trm:"); 11717 if (r.trimMemoryLevel < 10) pw.print(' '); 11718 pw.print(r.trimMemoryLevel); 11719 pw.print(' '); 11720 pw.print(r.toShortString()); 11721 pw.print(" ("); 11722 pw.print(r.adjType); 11723 pw.println(')'); 11724 if (r.adjSource != null || r.adjTarget != null) { 11725 pw.print(prefix); 11726 pw.print(" "); 11727 if (r.adjTarget instanceof ComponentName) { 11728 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11729 } else if (r.adjTarget != null) { 11730 pw.print(r.adjTarget.toString()); 11731 } else { 11732 pw.print("{null}"); 11733 } 11734 pw.print("<="); 11735 if (r.adjSource instanceof ProcessRecord) { 11736 pw.print("Proc{"); 11737 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11738 pw.println("}"); 11739 } else if (r.adjSource != null) { 11740 pw.println(r.adjSource.toString()); 11741 } else { 11742 pw.println("{null}"); 11743 } 11744 } 11745 if (inclDetails) { 11746 pw.print(prefix); 11747 pw.print(" "); 11748 pw.print("oom: max="); pw.print(r.maxAdj); 11749 pw.print(" curRaw="); pw.print(r.curRawAdj); 11750 pw.print(" setRaw="); pw.print(r.setRawAdj); 11751 pw.print(" cur="); pw.print(r.curAdj); 11752 pw.print(" set="); pw.println(r.setAdj); 11753 pw.print(prefix); 11754 pw.print(" "); 11755 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11756 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11757 pw.print(" lastPss="); pw.print(r.lastPss); 11758 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11759 pw.print(prefix); 11760 pw.print(" "); 11761 pw.print("keeping="); pw.print(r.keeping); 11762 pw.print(" cached="); pw.print(r.cached); 11763 pw.print(" empty="); pw.print(r.empty); 11764 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11765 11766 if (!r.keeping) { 11767 if (r.lastWakeTime != 0) { 11768 long wtime; 11769 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11770 synchronized (stats) { 11771 wtime = stats.getProcessWakeTime(r.info.uid, 11772 r.pid, curRealtime); 11773 } 11774 long timeUsed = wtime - r.lastWakeTime; 11775 pw.print(prefix); 11776 pw.print(" "); 11777 pw.print("keep awake over "); 11778 TimeUtils.formatDuration(realtimeSince, pw); 11779 pw.print(" used "); 11780 TimeUtils.formatDuration(timeUsed, pw); 11781 pw.print(" ("); 11782 pw.print((timeUsed*100)/realtimeSince); 11783 pw.println("%)"); 11784 } 11785 if (r.lastCpuTime != 0) { 11786 long timeUsed = r.curCpuTime - r.lastCpuTime; 11787 pw.print(prefix); 11788 pw.print(" "); 11789 pw.print("run cpu over "); 11790 TimeUtils.formatDuration(uptimeSince, pw); 11791 pw.print(" used "); 11792 TimeUtils.formatDuration(timeUsed, pw); 11793 pw.print(" ("); 11794 pw.print((timeUsed*100)/uptimeSince); 11795 pw.println("%)"); 11796 } 11797 } 11798 } 11799 } 11800 return true; 11801 } 11802 11803 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11804 ArrayList<ProcessRecord> procs; 11805 synchronized (this) { 11806 if (args != null && args.length > start 11807 && args[start].charAt(0) != '-') { 11808 procs = new ArrayList<ProcessRecord>(); 11809 int pid = -1; 11810 try { 11811 pid = Integer.parseInt(args[start]); 11812 } catch (NumberFormatException e) { 11813 } 11814 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11815 ProcessRecord proc = mLruProcesses.get(i); 11816 if (proc.pid == pid) { 11817 procs.add(proc); 11818 } else if (proc.processName.equals(args[start])) { 11819 procs.add(proc); 11820 } 11821 } 11822 if (procs.size() <= 0) { 11823 return null; 11824 } 11825 } else { 11826 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11827 } 11828 } 11829 return procs; 11830 } 11831 11832 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11833 PrintWriter pw, String[] args) { 11834 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11835 if (procs == null) { 11836 pw.println("No process found for: " + args[0]); 11837 return; 11838 } 11839 11840 long uptime = SystemClock.uptimeMillis(); 11841 long realtime = SystemClock.elapsedRealtime(); 11842 pw.println("Applications Graphics Acceleration Info:"); 11843 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11844 11845 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11846 ProcessRecord r = procs.get(i); 11847 if (r.thread != null) { 11848 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11849 pw.flush(); 11850 try { 11851 TransferPipe tp = new TransferPipe(); 11852 try { 11853 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11854 tp.go(fd); 11855 } finally { 11856 tp.kill(); 11857 } 11858 } catch (IOException e) { 11859 pw.println("Failure while dumping the app: " + r); 11860 pw.flush(); 11861 } catch (RemoteException e) { 11862 pw.println("Got a RemoteException while dumping the app " + r); 11863 pw.flush(); 11864 } 11865 } 11866 } 11867 } 11868 11869 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11870 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11871 if (procs == null) { 11872 pw.println("No process found for: " + args[0]); 11873 return; 11874 } 11875 11876 pw.println("Applications Database Info:"); 11877 11878 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11879 ProcessRecord r = procs.get(i); 11880 if (r.thread != null) { 11881 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11882 pw.flush(); 11883 try { 11884 TransferPipe tp = new TransferPipe(); 11885 try { 11886 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11887 tp.go(fd); 11888 } finally { 11889 tp.kill(); 11890 } 11891 } catch (IOException e) { 11892 pw.println("Failure while dumping the app: " + r); 11893 pw.flush(); 11894 } catch (RemoteException e) { 11895 pw.println("Got a RemoteException while dumping the app " + r); 11896 pw.flush(); 11897 } 11898 } 11899 } 11900 } 11901 11902 final static class MemItem { 11903 final boolean isProc; 11904 final String label; 11905 final String shortLabel; 11906 final long pss; 11907 final int id; 11908 final boolean hasActivities; 11909 ArrayList<MemItem> subitems; 11910 11911 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11912 boolean _hasActivities) { 11913 isProc = true; 11914 label = _label; 11915 shortLabel = _shortLabel; 11916 pss = _pss; 11917 id = _id; 11918 hasActivities = _hasActivities; 11919 } 11920 11921 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11922 isProc = false; 11923 label = _label; 11924 shortLabel = _shortLabel; 11925 pss = _pss; 11926 id = _id; 11927 hasActivities = false; 11928 } 11929 } 11930 11931 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 11932 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 11933 if (sort && !isCompact) { 11934 Collections.sort(items, new Comparator<MemItem>() { 11935 @Override 11936 public int compare(MemItem lhs, MemItem rhs) { 11937 if (lhs.pss < rhs.pss) { 11938 return 1; 11939 } else if (lhs.pss > rhs.pss) { 11940 return -1; 11941 } 11942 return 0; 11943 } 11944 }); 11945 } 11946 11947 for (int i=0; i<items.size(); i++) { 11948 MemItem mi = items.get(i); 11949 if (!isCompact) { 11950 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 11951 } else if (mi.isProc) { 11952 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 11953 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 11954 pw.println(mi.hasActivities ? ",a" : ",e"); 11955 } else { 11956 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 11957 pw.println(mi.pss); 11958 } 11959 if (mi.subitems != null) { 11960 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 11961 true, isCompact); 11962 } 11963 } 11964 } 11965 11966 // These are in KB. 11967 static final long[] DUMP_MEM_BUCKETS = new long[] { 11968 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 11969 120*1024, 160*1024, 200*1024, 11970 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 11971 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 11972 }; 11973 11974 static final void appendMemBucket(StringBuilder out, long memKB, String label, 11975 boolean stackLike) { 11976 int start = label.lastIndexOf('.'); 11977 if (start >= 0) start++; 11978 else start = 0; 11979 int end = label.length(); 11980 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 11981 if (DUMP_MEM_BUCKETS[i] >= memKB) { 11982 long bucket = DUMP_MEM_BUCKETS[i]/1024; 11983 out.append(bucket); 11984 out.append(stackLike ? "MB." : "MB "); 11985 out.append(label, start, end); 11986 return; 11987 } 11988 } 11989 out.append(memKB/1024); 11990 out.append(stackLike ? "MB." : "MB "); 11991 out.append(label, start, end); 11992 } 11993 11994 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 11995 ProcessList.NATIVE_ADJ, 11996 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 11997 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 11998 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 11999 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12000 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12001 }; 12002 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12003 "Native", 12004 "System", "Persistent", "Foreground", 12005 "Visible", "Perceptible", 12006 "Heavy Weight", "Backup", 12007 "A Services", "Home", 12008 "Previous", "B Services", "Cached" 12009 }; 12010 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12011 "native", 12012 "sys", "pers", "fore", 12013 "vis", "percept", 12014 "heavy", "backup", 12015 "servicea", "home", 12016 "prev", "serviceb", "cached" 12017 }; 12018 12019 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12020 long realtime, boolean isCheckinRequest, boolean isCompact) { 12021 if (isCheckinRequest || isCompact) { 12022 // short checkin version 12023 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12024 } else { 12025 pw.println("Applications Memory Usage (kB):"); 12026 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12027 } 12028 } 12029 12030 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12031 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12032 boolean dumpDetails = false; 12033 boolean dumpFullDetails = false; 12034 boolean dumpDalvik = false; 12035 boolean oomOnly = false; 12036 boolean isCompact = false; 12037 boolean localOnly = false; 12038 12039 int opti = 0; 12040 while (opti < args.length) { 12041 String opt = args[opti]; 12042 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12043 break; 12044 } 12045 opti++; 12046 if ("-a".equals(opt)) { 12047 dumpDetails = true; 12048 dumpFullDetails = true; 12049 dumpDalvik = true; 12050 } else if ("-d".equals(opt)) { 12051 dumpDalvik = true; 12052 } else if ("-c".equals(opt)) { 12053 isCompact = true; 12054 } else if ("--oom".equals(opt)) { 12055 oomOnly = true; 12056 } else if ("--local".equals(opt)) { 12057 localOnly = true; 12058 } else if ("-h".equals(opt)) { 12059 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12060 pw.println(" -a: include all available information for each process."); 12061 pw.println(" -d: include dalvik details when dumping process details."); 12062 pw.println(" -c: dump in a compact machine-parseable representation."); 12063 pw.println(" --oom: only show processes organized by oom adj."); 12064 pw.println(" --local: only collect details locally, don't call process."); 12065 pw.println("If [process] is specified it can be the name or "); 12066 pw.println("pid of a specific process to dump."); 12067 return; 12068 } else { 12069 pw.println("Unknown argument: " + opt + "; use -h for help"); 12070 } 12071 } 12072 12073 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12074 long uptime = SystemClock.uptimeMillis(); 12075 long realtime = SystemClock.elapsedRealtime(); 12076 final long[] tmpLong = new long[1]; 12077 12078 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12079 if (procs == null) { 12080 // No Java processes. Maybe they want to print a native process. 12081 if (args != null && args.length > opti 12082 && args[opti].charAt(0) != '-') { 12083 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12084 = new ArrayList<ProcessCpuTracker.Stats>(); 12085 updateCpuStatsNow(); 12086 int findPid = -1; 12087 try { 12088 findPid = Integer.parseInt(args[opti]); 12089 } catch (NumberFormatException e) { 12090 } 12091 synchronized (mProcessCpuThread) { 12092 final int N = mProcessCpuTracker.countStats(); 12093 for (int i=0; i<N; i++) { 12094 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12095 if (st.pid == findPid || (st.baseName != null 12096 && st.baseName.equals(args[opti]))) { 12097 nativeProcs.add(st); 12098 } 12099 } 12100 } 12101 if (nativeProcs.size() > 0) { 12102 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12103 isCompact); 12104 Debug.MemoryInfo mi = null; 12105 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12106 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12107 final int pid = r.pid; 12108 if (!isCheckinRequest && dumpDetails) { 12109 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12110 } 12111 if (mi == null) { 12112 mi = new Debug.MemoryInfo(); 12113 } 12114 if (dumpDetails || (!brief && !oomOnly)) { 12115 Debug.getMemoryInfo(pid, mi); 12116 } else { 12117 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12118 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12119 } 12120 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12121 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12122 if (isCheckinRequest) { 12123 pw.println(); 12124 } 12125 } 12126 return; 12127 } 12128 } 12129 pw.println("No process found for: " + args[opti]); 12130 return; 12131 } 12132 12133 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12134 dumpDetails = true; 12135 } 12136 12137 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12138 12139 String[] innerArgs = new String[args.length-opti]; 12140 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12141 12142 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12143 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12144 long nativePss=0, dalvikPss=0, otherPss=0; 12145 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12146 12147 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12148 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12149 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12150 12151 long totalPss = 0; 12152 long cachedPss = 0; 12153 12154 Debug.MemoryInfo mi = null; 12155 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12156 final ProcessRecord r = procs.get(i); 12157 final IApplicationThread thread; 12158 final int pid; 12159 final int oomAdj; 12160 final boolean hasActivities; 12161 synchronized (this) { 12162 thread = r.thread; 12163 pid = r.pid; 12164 oomAdj = r.getSetAdjWithServices(); 12165 hasActivities = r.activities.size() > 0; 12166 } 12167 if (thread != null) { 12168 if (!isCheckinRequest && dumpDetails) { 12169 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12170 } 12171 if (mi == null) { 12172 mi = new Debug.MemoryInfo(); 12173 } 12174 if (dumpDetails || (!brief && !oomOnly)) { 12175 Debug.getMemoryInfo(pid, mi); 12176 } else { 12177 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12178 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12179 } 12180 if (dumpDetails) { 12181 if (localOnly) { 12182 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12183 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12184 if (isCheckinRequest) { 12185 pw.println(); 12186 } 12187 } else { 12188 try { 12189 pw.flush(); 12190 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12191 dumpDalvik, innerArgs); 12192 } catch (RemoteException e) { 12193 if (!isCheckinRequest) { 12194 pw.println("Got RemoteException!"); 12195 pw.flush(); 12196 } 12197 } 12198 } 12199 } 12200 12201 final long myTotalPss = mi.getTotalPss(); 12202 final long myTotalUss = mi.getTotalUss(); 12203 12204 synchronized (this) { 12205 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12206 // Record this for posterity if the process has been stable. 12207 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12208 } 12209 } 12210 12211 if (!isCheckinRequest && mi != null) { 12212 totalPss += myTotalPss; 12213 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12214 (hasActivities ? " / activities)" : ")"), 12215 r.processName, myTotalPss, pid, hasActivities); 12216 procMems.add(pssItem); 12217 procMemsMap.put(pid, pssItem); 12218 12219 nativePss += mi.nativePss; 12220 dalvikPss += mi.dalvikPss; 12221 otherPss += mi.otherPss; 12222 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12223 long mem = mi.getOtherPss(j); 12224 miscPss[j] += mem; 12225 otherPss -= mem; 12226 } 12227 12228 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12229 cachedPss += myTotalPss; 12230 } 12231 12232 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12233 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12234 || oomIndex == (oomPss.length-1)) { 12235 oomPss[oomIndex] += myTotalPss; 12236 if (oomProcs[oomIndex] == null) { 12237 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12238 } 12239 oomProcs[oomIndex].add(pssItem); 12240 break; 12241 } 12242 } 12243 } 12244 } 12245 } 12246 12247 if (!isCheckinRequest && procs.size() > 1) { 12248 // If we are showing aggregations, also look for native processes to 12249 // include so that our aggregations are more accurate. 12250 updateCpuStatsNow(); 12251 synchronized (mProcessCpuThread) { 12252 final int N = mProcessCpuTracker.countStats(); 12253 for (int i=0; i<N; i++) { 12254 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12255 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12256 if (mi == null) { 12257 mi = new Debug.MemoryInfo(); 12258 } 12259 if (!brief && !oomOnly) { 12260 Debug.getMemoryInfo(st.pid, mi); 12261 } else { 12262 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12263 mi.nativePrivateDirty = (int)tmpLong[0]; 12264 } 12265 12266 final long myTotalPss = mi.getTotalPss(); 12267 totalPss += myTotalPss; 12268 12269 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12270 st.name, myTotalPss, st.pid, false); 12271 procMems.add(pssItem); 12272 12273 nativePss += mi.nativePss; 12274 dalvikPss += mi.dalvikPss; 12275 otherPss += mi.otherPss; 12276 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12277 long mem = mi.getOtherPss(j); 12278 miscPss[j] += mem; 12279 otherPss -= mem; 12280 } 12281 oomPss[0] += myTotalPss; 12282 if (oomProcs[0] == null) { 12283 oomProcs[0] = new ArrayList<MemItem>(); 12284 } 12285 oomProcs[0].add(pssItem); 12286 } 12287 } 12288 } 12289 12290 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12291 12292 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12293 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12294 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12295 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12296 String label = Debug.MemoryInfo.getOtherLabel(j); 12297 catMems.add(new MemItem(label, label, miscPss[j], j)); 12298 } 12299 12300 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12301 for (int j=0; j<oomPss.length; j++) { 12302 if (oomPss[j] != 0) { 12303 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12304 : DUMP_MEM_OOM_LABEL[j]; 12305 MemItem item = new MemItem(label, label, oomPss[j], 12306 DUMP_MEM_OOM_ADJ[j]); 12307 item.subitems = oomProcs[j]; 12308 oomMems.add(item); 12309 } 12310 } 12311 12312 if (!brief && !oomOnly && !isCompact) { 12313 pw.println(); 12314 pw.println("Total PSS by process:"); 12315 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12316 pw.println(); 12317 } 12318 if (!isCompact) { 12319 pw.println("Total PSS by OOM adjustment:"); 12320 } 12321 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12322 if (!brief && !oomOnly) { 12323 PrintWriter out = categoryPw != null ? categoryPw : pw; 12324 if (!isCompact) { 12325 out.println(); 12326 out.println("Total PSS by category:"); 12327 } 12328 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12329 } 12330 if (!isCompact) { 12331 pw.println(); 12332 } 12333 MemInfoReader memInfo = new MemInfoReader(); 12334 memInfo.readMemInfo(); 12335 if (!brief) { 12336 if (!isCompact) { 12337 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12338 pw.print(" kB (status "); 12339 switch (mLastMemoryLevel) { 12340 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12341 pw.println("normal)"); 12342 break; 12343 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12344 pw.println("moderate)"); 12345 break; 12346 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12347 pw.println("low)"); 12348 break; 12349 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12350 pw.println("critical)"); 12351 break; 12352 default: 12353 pw.print(mLastMemoryLevel); 12354 pw.println(")"); 12355 break; 12356 } 12357 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12358 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12359 pw.print(cachedPss); pw.print(" cached pss + "); 12360 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12361 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12362 } else { 12363 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12364 pw.print(cachedPss + memInfo.getCachedSizeKb() 12365 + memInfo.getFreeSizeKb()); pw.print(","); 12366 pw.println(totalPss - cachedPss); 12367 } 12368 } 12369 if (!isCompact) { 12370 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12371 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12372 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12373 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12374 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12375 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12376 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12377 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12378 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12379 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12380 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12381 } 12382 if (!brief) { 12383 if (memInfo.getZramTotalSizeKb() != 0) { 12384 if (!isCompact) { 12385 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12386 pw.print(" kB physical used for "); 12387 pw.print(memInfo.getSwapTotalSizeKb() 12388 - memInfo.getSwapFreeSizeKb()); 12389 pw.print(" kB in swap ("); 12390 pw.print(memInfo.getSwapTotalSizeKb()); 12391 pw.println(" kB total swap)"); 12392 } else { 12393 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12394 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12395 pw.println(memInfo.getSwapFreeSizeKb()); 12396 } 12397 } 12398 final int[] SINGLE_LONG_FORMAT = new int[] { 12399 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12400 }; 12401 long[] longOut = new long[1]; 12402 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12403 SINGLE_LONG_FORMAT, null, longOut, null); 12404 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12405 longOut[0] = 0; 12406 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12407 SINGLE_LONG_FORMAT, null, longOut, null); 12408 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12409 longOut[0] = 0; 12410 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12411 SINGLE_LONG_FORMAT, null, longOut, null); 12412 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12413 longOut[0] = 0; 12414 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12415 SINGLE_LONG_FORMAT, null, longOut, null); 12416 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12417 if (!isCompact) { 12418 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12419 pw.print(" KSM: "); pw.print(sharing); 12420 pw.print(" kB saved from shared "); 12421 pw.print(shared); pw.println(" kB"); 12422 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12423 pw.print(voltile); pw.println(" kB volatile"); 12424 } 12425 pw.print(" Tuning: "); 12426 pw.print(ActivityManager.staticGetMemoryClass()); 12427 pw.print(" (large "); 12428 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12429 pw.print("), oom "); 12430 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12431 pw.print(" kB"); 12432 pw.print(", restore limit "); 12433 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12434 pw.print(" kB"); 12435 if (ActivityManager.isLowRamDeviceStatic()) { 12436 pw.print(" (low-ram)"); 12437 } 12438 if (ActivityManager.isHighEndGfx()) { 12439 pw.print(" (high-end-gfx)"); 12440 } 12441 pw.println(); 12442 } else { 12443 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12444 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12445 pw.println(voltile); 12446 pw.print("tuning,"); 12447 pw.print(ActivityManager.staticGetMemoryClass()); 12448 pw.print(','); 12449 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12450 pw.print(','); 12451 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12452 if (ActivityManager.isLowRamDeviceStatic()) { 12453 pw.print(",low-ram"); 12454 } 12455 if (ActivityManager.isHighEndGfx()) { 12456 pw.print(",high-end-gfx"); 12457 } 12458 pw.println(); 12459 } 12460 } 12461 } 12462 } 12463 12464 /** 12465 * Searches array of arguments for the specified string 12466 * @param args array of argument strings 12467 * @param value value to search for 12468 * @return true if the value is contained in the array 12469 */ 12470 private static boolean scanArgs(String[] args, String value) { 12471 if (args != null) { 12472 for (String arg : args) { 12473 if (value.equals(arg)) { 12474 return true; 12475 } 12476 } 12477 } 12478 return false; 12479 } 12480 12481 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12482 ContentProviderRecord cpr, boolean always) { 12483 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12484 12485 if (!inLaunching || always) { 12486 synchronized (cpr) { 12487 cpr.launchingApp = null; 12488 cpr.notifyAll(); 12489 } 12490 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12491 String names[] = cpr.info.authority.split(";"); 12492 for (int j = 0; j < names.length; j++) { 12493 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12494 } 12495 } 12496 12497 for (int i=0; i<cpr.connections.size(); i++) { 12498 ContentProviderConnection conn = cpr.connections.get(i); 12499 if (conn.waiting) { 12500 // If this connection is waiting for the provider, then we don't 12501 // need to mess with its process unless we are always removing 12502 // or for some reason the provider is not currently launching. 12503 if (inLaunching && !always) { 12504 continue; 12505 } 12506 } 12507 ProcessRecord capp = conn.client; 12508 conn.dead = true; 12509 if (conn.stableCount > 0) { 12510 if (!capp.persistent && capp.thread != null 12511 && capp.pid != 0 12512 && capp.pid != MY_PID) { 12513 killUnneededProcessLocked(capp, "depends on provider " 12514 + cpr.name.flattenToShortString() 12515 + " in dying proc " + (proc != null ? proc.processName : "??")); 12516 } 12517 } else if (capp.thread != null && conn.provider.provider != null) { 12518 try { 12519 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12520 } catch (RemoteException e) { 12521 } 12522 // In the protocol here, we don't expect the client to correctly 12523 // clean up this connection, we'll just remove it. 12524 cpr.connections.remove(i); 12525 conn.client.conProviders.remove(conn); 12526 } 12527 } 12528 12529 if (inLaunching && always) { 12530 mLaunchingProviders.remove(cpr); 12531 } 12532 return inLaunching; 12533 } 12534 12535 /** 12536 * Main code for cleaning up a process when it has gone away. This is 12537 * called both as a result of the process dying, or directly when stopping 12538 * a process when running in single process mode. 12539 */ 12540 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12541 boolean restarting, boolean allowRestart, int index) { 12542 if (index >= 0) { 12543 removeLruProcessLocked(app); 12544 ProcessList.remove(app.pid); 12545 } 12546 12547 mProcessesToGc.remove(app); 12548 mPendingPssProcesses.remove(app); 12549 12550 // Dismiss any open dialogs. 12551 if (app.crashDialog != null && !app.forceCrashReport) { 12552 app.crashDialog.dismiss(); 12553 app.crashDialog = null; 12554 } 12555 if (app.anrDialog != null) { 12556 app.anrDialog.dismiss(); 12557 app.anrDialog = null; 12558 } 12559 if (app.waitDialog != null) { 12560 app.waitDialog.dismiss(); 12561 app.waitDialog = null; 12562 } 12563 12564 app.crashing = false; 12565 app.notResponding = false; 12566 12567 app.resetPackageList(mProcessStats); 12568 app.unlinkDeathRecipient(); 12569 app.makeInactive(mProcessStats); 12570 app.forcingToForeground = null; 12571 updateProcessForegroundLocked(app, false, false); 12572 app.foregroundActivities = false; 12573 app.hasShownUi = false; 12574 app.hasAboveClient = false; 12575 12576 mServices.killServicesLocked(app, allowRestart); 12577 12578 boolean restart = false; 12579 12580 // Remove published content providers. 12581 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12582 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12583 final boolean always = app.bad || !allowRestart; 12584 if (removeDyingProviderLocked(app, cpr, always) || always) { 12585 // We left the provider in the launching list, need to 12586 // restart it. 12587 restart = true; 12588 } 12589 12590 cpr.provider = null; 12591 cpr.proc = null; 12592 } 12593 app.pubProviders.clear(); 12594 12595 // Take care of any launching providers waiting for this process. 12596 if (checkAppInLaunchingProvidersLocked(app, false)) { 12597 restart = true; 12598 } 12599 12600 // Unregister from connected content providers. 12601 if (!app.conProviders.isEmpty()) { 12602 for (int i=0; i<app.conProviders.size(); i++) { 12603 ContentProviderConnection conn = app.conProviders.get(i); 12604 conn.provider.connections.remove(conn); 12605 } 12606 app.conProviders.clear(); 12607 } 12608 12609 // At this point there may be remaining entries in mLaunchingProviders 12610 // where we were the only one waiting, so they are no longer of use. 12611 // Look for these and clean up if found. 12612 // XXX Commented out for now. Trying to figure out a way to reproduce 12613 // the actual situation to identify what is actually going on. 12614 if (false) { 12615 for (int i=0; i<mLaunchingProviders.size(); i++) { 12616 ContentProviderRecord cpr = (ContentProviderRecord) 12617 mLaunchingProviders.get(i); 12618 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12619 synchronized (cpr) { 12620 cpr.launchingApp = null; 12621 cpr.notifyAll(); 12622 } 12623 } 12624 } 12625 } 12626 12627 skipCurrentReceiverLocked(app); 12628 12629 // Unregister any receivers. 12630 for (int i=app.receivers.size()-1; i>=0; i--) { 12631 removeReceiverLocked(app.receivers.valueAt(i)); 12632 } 12633 app.receivers.clear(); 12634 12635 // If the app is undergoing backup, tell the backup manager about it 12636 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12637 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12638 + mBackupTarget.appInfo + " died during backup"); 12639 try { 12640 IBackupManager bm = IBackupManager.Stub.asInterface( 12641 ServiceManager.getService(Context.BACKUP_SERVICE)); 12642 bm.agentDisconnected(app.info.packageName); 12643 } catch (RemoteException e) { 12644 // can't happen; backup manager is local 12645 } 12646 } 12647 12648 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12649 ProcessChangeItem item = mPendingProcessChanges.get(i); 12650 if (item.pid == app.pid) { 12651 mPendingProcessChanges.remove(i); 12652 mAvailProcessChanges.add(item); 12653 } 12654 } 12655 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12656 12657 // If the caller is restarting this app, then leave it in its 12658 // current lists and let the caller take care of it. 12659 if (restarting) { 12660 return; 12661 } 12662 12663 if (!app.persistent || app.isolated) { 12664 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12665 "Removing non-persistent process during cleanup: " + app); 12666 mProcessNames.remove(app.processName, app.uid); 12667 mIsolatedProcesses.remove(app.uid); 12668 if (mHeavyWeightProcess == app) { 12669 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12670 mHeavyWeightProcess.userId, 0)); 12671 mHeavyWeightProcess = null; 12672 } 12673 } else if (!app.removed) { 12674 // This app is persistent, so we need to keep its record around. 12675 // If it is not already on the pending app list, add it there 12676 // and start a new process for it. 12677 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12678 mPersistentStartingProcesses.add(app); 12679 restart = true; 12680 } 12681 } 12682 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12683 "Clean-up removing on hold: " + app); 12684 mProcessesOnHold.remove(app); 12685 12686 if (app == mHomeProcess) { 12687 mHomeProcess = null; 12688 } 12689 if (app == mPreviousProcess) { 12690 mPreviousProcess = null; 12691 } 12692 12693 if (restart && !app.isolated) { 12694 // We have components that still need to be running in the 12695 // process, so re-launch it. 12696 mProcessNames.put(app.processName, app.uid, app); 12697 startProcessLocked(app, "restart", app.processName); 12698 } else if (app.pid > 0 && app.pid != MY_PID) { 12699 // Goodbye! 12700 boolean removed; 12701 synchronized (mPidsSelfLocked) { 12702 mPidsSelfLocked.remove(app.pid); 12703 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12704 } 12705 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12706 app.processName, app.info.uid); 12707 if (app.isolated) { 12708 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12709 } 12710 app.setPid(0); 12711 } 12712 } 12713 12714 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12715 // Look through the content providers we are waiting to have launched, 12716 // and if any run in this process then either schedule a restart of 12717 // the process or kill the client waiting for it if this process has 12718 // gone bad. 12719 int NL = mLaunchingProviders.size(); 12720 boolean restart = false; 12721 for (int i=0; i<NL; i++) { 12722 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12723 if (cpr.launchingApp == app) { 12724 if (!alwaysBad && !app.bad) { 12725 restart = true; 12726 } else { 12727 removeDyingProviderLocked(app, cpr, true); 12728 // cpr should have been removed from mLaunchingProviders 12729 NL = mLaunchingProviders.size(); 12730 i--; 12731 } 12732 } 12733 } 12734 return restart; 12735 } 12736 12737 // ========================================================= 12738 // SERVICES 12739 // ========================================================= 12740 12741 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12742 int flags) { 12743 enforceNotIsolatedCaller("getServices"); 12744 synchronized (this) { 12745 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12746 } 12747 } 12748 12749 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12750 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12751 synchronized (this) { 12752 return mServices.getRunningServiceControlPanelLocked(name); 12753 } 12754 } 12755 12756 public ComponentName startService(IApplicationThread caller, Intent service, 12757 String resolvedType, int userId) { 12758 enforceNotIsolatedCaller("startService"); 12759 // Refuse possible leaked file descriptors 12760 if (service != null && service.hasFileDescriptors() == true) { 12761 throw new IllegalArgumentException("File descriptors passed in Intent"); 12762 } 12763 12764 if (DEBUG_SERVICE) 12765 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12766 synchronized(this) { 12767 final int callingPid = Binder.getCallingPid(); 12768 final int callingUid = Binder.getCallingUid(); 12769 final long origId = Binder.clearCallingIdentity(); 12770 ComponentName res = mServices.startServiceLocked(caller, service, 12771 resolvedType, callingPid, callingUid, userId); 12772 Binder.restoreCallingIdentity(origId); 12773 return res; 12774 } 12775 } 12776 12777 ComponentName startServiceInPackage(int uid, 12778 Intent service, String resolvedType, int userId) { 12779 synchronized(this) { 12780 if (DEBUG_SERVICE) 12781 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12782 final long origId = Binder.clearCallingIdentity(); 12783 ComponentName res = mServices.startServiceLocked(null, service, 12784 resolvedType, -1, uid, userId); 12785 Binder.restoreCallingIdentity(origId); 12786 return res; 12787 } 12788 } 12789 12790 public int stopService(IApplicationThread caller, Intent service, 12791 String resolvedType, int userId) { 12792 enforceNotIsolatedCaller("stopService"); 12793 // Refuse possible leaked file descriptors 12794 if (service != null && service.hasFileDescriptors() == true) { 12795 throw new IllegalArgumentException("File descriptors passed in Intent"); 12796 } 12797 12798 synchronized(this) { 12799 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12800 } 12801 } 12802 12803 public IBinder peekService(Intent service, String resolvedType) { 12804 enforceNotIsolatedCaller("peekService"); 12805 // Refuse possible leaked file descriptors 12806 if (service != null && service.hasFileDescriptors() == true) { 12807 throw new IllegalArgumentException("File descriptors passed in Intent"); 12808 } 12809 synchronized(this) { 12810 return mServices.peekServiceLocked(service, resolvedType); 12811 } 12812 } 12813 12814 public boolean stopServiceToken(ComponentName className, IBinder token, 12815 int startId) { 12816 synchronized(this) { 12817 return mServices.stopServiceTokenLocked(className, token, startId); 12818 } 12819 } 12820 12821 public void setServiceForeground(ComponentName className, IBinder token, 12822 int id, Notification notification, boolean removeNotification) { 12823 synchronized(this) { 12824 mServices.setServiceForegroundLocked(className, token, id, notification, 12825 removeNotification); 12826 } 12827 } 12828 12829 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12830 boolean requireFull, String name, String callerPackage) { 12831 final int callingUserId = UserHandle.getUserId(callingUid); 12832 if (callingUserId != userId) { 12833 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12834 if ((requireFull || checkComponentPermission( 12835 android.Manifest.permission.INTERACT_ACROSS_USERS, 12836 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12837 && checkComponentPermission( 12838 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12839 callingPid, callingUid, -1, true) 12840 != PackageManager.PERMISSION_GRANTED) { 12841 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12842 // In this case, they would like to just execute as their 12843 // owner user instead of failing. 12844 userId = callingUserId; 12845 } else { 12846 StringBuilder builder = new StringBuilder(128); 12847 builder.append("Permission Denial: "); 12848 builder.append(name); 12849 if (callerPackage != null) { 12850 builder.append(" from "); 12851 builder.append(callerPackage); 12852 } 12853 builder.append(" asks to run as user "); 12854 builder.append(userId); 12855 builder.append(" but is calling from user "); 12856 builder.append(UserHandle.getUserId(callingUid)); 12857 builder.append("; this requires "); 12858 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12859 if (!requireFull) { 12860 builder.append(" or "); 12861 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12862 } 12863 String msg = builder.toString(); 12864 Slog.w(TAG, msg); 12865 throw new SecurityException(msg); 12866 } 12867 } 12868 } 12869 if (userId == UserHandle.USER_CURRENT 12870 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12871 // Note that we may be accessing this outside of a lock... 12872 // shouldn't be a big deal, if this is being called outside 12873 // of a locked context there is intrinsically a race with 12874 // the value the caller will receive and someone else changing it. 12875 userId = mCurrentUserId; 12876 } 12877 if (!allowAll && userId < 0) { 12878 throw new IllegalArgumentException( 12879 "Call does not support special user #" + userId); 12880 } 12881 } 12882 return userId; 12883 } 12884 12885 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12886 String className, int flags) { 12887 boolean result = false; 12888 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12889 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12890 if (ActivityManager.checkUidPermission( 12891 android.Manifest.permission.INTERACT_ACROSS_USERS, 12892 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12893 ComponentName comp = new ComponentName(aInfo.packageName, className); 12894 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12895 + " requests FLAG_SINGLE_USER, but app does not hold " 12896 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12897 Slog.w(TAG, msg); 12898 throw new SecurityException(msg); 12899 } 12900 result = true; 12901 } 12902 } else if (componentProcessName == aInfo.packageName) { 12903 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12904 } else if ("system".equals(componentProcessName)) { 12905 result = true; 12906 } 12907 if (DEBUG_MU) { 12908 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12909 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12910 } 12911 return result; 12912 } 12913 12914 public int bindService(IApplicationThread caller, IBinder token, 12915 Intent service, String resolvedType, 12916 IServiceConnection connection, int flags, int userId) { 12917 enforceNotIsolatedCaller("bindService"); 12918 // Refuse possible leaked file descriptors 12919 if (service != null && service.hasFileDescriptors() == true) { 12920 throw new IllegalArgumentException("File descriptors passed in Intent"); 12921 } 12922 12923 synchronized(this) { 12924 return mServices.bindServiceLocked(caller, token, service, resolvedType, 12925 connection, flags, userId); 12926 } 12927 } 12928 12929 public boolean unbindService(IServiceConnection connection) { 12930 synchronized (this) { 12931 return mServices.unbindServiceLocked(connection); 12932 } 12933 } 12934 12935 public void publishService(IBinder token, Intent intent, IBinder service) { 12936 // Refuse possible leaked file descriptors 12937 if (intent != null && intent.hasFileDescriptors() == true) { 12938 throw new IllegalArgumentException("File descriptors passed in Intent"); 12939 } 12940 12941 synchronized(this) { 12942 if (!(token instanceof ServiceRecord)) { 12943 throw new IllegalArgumentException("Invalid service token"); 12944 } 12945 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 12946 } 12947 } 12948 12949 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 12950 // Refuse possible leaked file descriptors 12951 if (intent != null && intent.hasFileDescriptors() == true) { 12952 throw new IllegalArgumentException("File descriptors passed in Intent"); 12953 } 12954 12955 synchronized(this) { 12956 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 12957 } 12958 } 12959 12960 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 12961 synchronized(this) { 12962 if (!(token instanceof ServiceRecord)) { 12963 throw new IllegalArgumentException("Invalid service token"); 12964 } 12965 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 12966 } 12967 } 12968 12969 // ========================================================= 12970 // BACKUP AND RESTORE 12971 // ========================================================= 12972 12973 // Cause the target app to be launched if necessary and its backup agent 12974 // instantiated. The backup agent will invoke backupAgentCreated() on the 12975 // activity manager to announce its creation. 12976 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 12977 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 12978 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 12979 12980 synchronized(this) { 12981 // !!! TODO: currently no check here that we're already bound 12982 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 12983 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 12984 synchronized (stats) { 12985 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 12986 } 12987 12988 // Backup agent is now in use, its package can't be stopped. 12989 try { 12990 AppGlobals.getPackageManager().setPackageStoppedState( 12991 app.packageName, false, UserHandle.getUserId(app.uid)); 12992 } catch (RemoteException e) { 12993 } catch (IllegalArgumentException e) { 12994 Slog.w(TAG, "Failed trying to unstop package " 12995 + app.packageName + ": " + e); 12996 } 12997 12998 BackupRecord r = new BackupRecord(ss, app, backupMode); 12999 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13000 ? new ComponentName(app.packageName, app.backupAgentName) 13001 : new ComponentName("android", "FullBackupAgent"); 13002 // startProcessLocked() returns existing proc's record if it's already running 13003 ProcessRecord proc = startProcessLocked(app.processName, app, 13004 false, 0, "backup", hostingName, false, false, false); 13005 if (proc == null) { 13006 Slog.e(TAG, "Unable to start backup agent process " + r); 13007 return false; 13008 } 13009 13010 r.app = proc; 13011 mBackupTarget = r; 13012 mBackupAppName = app.packageName; 13013 13014 // Try not to kill the process during backup 13015 updateOomAdjLocked(proc); 13016 13017 // If the process is already attached, schedule the creation of the backup agent now. 13018 // If it is not yet live, this will be done when it attaches to the framework. 13019 if (proc.thread != null) { 13020 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13021 try { 13022 proc.thread.scheduleCreateBackupAgent(app, 13023 compatibilityInfoForPackageLocked(app), backupMode); 13024 } catch (RemoteException e) { 13025 // Will time out on the backup manager side 13026 } 13027 } else { 13028 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13029 } 13030 // Invariants: at this point, the target app process exists and the application 13031 // is either already running or in the process of coming up. mBackupTarget and 13032 // mBackupAppName describe the app, so that when it binds back to the AM we 13033 // know that it's scheduled for a backup-agent operation. 13034 } 13035 13036 return true; 13037 } 13038 13039 @Override 13040 public void clearPendingBackup() { 13041 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13042 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13043 13044 synchronized (this) { 13045 mBackupTarget = null; 13046 mBackupAppName = null; 13047 } 13048 } 13049 13050 // A backup agent has just come up 13051 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13052 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13053 + " = " + agent); 13054 13055 synchronized(this) { 13056 if (!agentPackageName.equals(mBackupAppName)) { 13057 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13058 return; 13059 } 13060 } 13061 13062 long oldIdent = Binder.clearCallingIdentity(); 13063 try { 13064 IBackupManager bm = IBackupManager.Stub.asInterface( 13065 ServiceManager.getService(Context.BACKUP_SERVICE)); 13066 bm.agentConnected(agentPackageName, agent); 13067 } catch (RemoteException e) { 13068 // can't happen; the backup manager service is local 13069 } catch (Exception e) { 13070 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13071 e.printStackTrace(); 13072 } finally { 13073 Binder.restoreCallingIdentity(oldIdent); 13074 } 13075 } 13076 13077 // done with this agent 13078 public void unbindBackupAgent(ApplicationInfo appInfo) { 13079 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13080 if (appInfo == null) { 13081 Slog.w(TAG, "unbind backup agent for null app"); 13082 return; 13083 } 13084 13085 synchronized(this) { 13086 try { 13087 if (mBackupAppName == null) { 13088 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13089 return; 13090 } 13091 13092 if (!mBackupAppName.equals(appInfo.packageName)) { 13093 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13094 return; 13095 } 13096 13097 // Not backing this app up any more; reset its OOM adjustment 13098 final ProcessRecord proc = mBackupTarget.app; 13099 updateOomAdjLocked(proc); 13100 13101 // If the app crashed during backup, 'thread' will be null here 13102 if (proc.thread != null) { 13103 try { 13104 proc.thread.scheduleDestroyBackupAgent(appInfo, 13105 compatibilityInfoForPackageLocked(appInfo)); 13106 } catch (Exception e) { 13107 Slog.e(TAG, "Exception when unbinding backup agent:"); 13108 e.printStackTrace(); 13109 } 13110 } 13111 } finally { 13112 mBackupTarget = null; 13113 mBackupAppName = null; 13114 } 13115 } 13116 } 13117 // ========================================================= 13118 // BROADCASTS 13119 // ========================================================= 13120 13121 private final List getStickiesLocked(String action, IntentFilter filter, 13122 List cur, int userId) { 13123 final ContentResolver resolver = mContext.getContentResolver(); 13124 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13125 if (stickies == null) { 13126 return cur; 13127 } 13128 final ArrayList<Intent> list = stickies.get(action); 13129 if (list == null) { 13130 return cur; 13131 } 13132 int N = list.size(); 13133 for (int i=0; i<N; i++) { 13134 Intent intent = list.get(i); 13135 if (filter.match(resolver, intent, true, TAG) >= 0) { 13136 if (cur == null) { 13137 cur = new ArrayList<Intent>(); 13138 } 13139 cur.add(intent); 13140 } 13141 } 13142 return cur; 13143 } 13144 13145 boolean isPendingBroadcastProcessLocked(int pid) { 13146 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13147 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13148 } 13149 13150 void skipPendingBroadcastLocked(int pid) { 13151 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13152 for (BroadcastQueue queue : mBroadcastQueues) { 13153 queue.skipPendingBroadcastLocked(pid); 13154 } 13155 } 13156 13157 // The app just attached; send any pending broadcasts that it should receive 13158 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13159 boolean didSomething = false; 13160 for (BroadcastQueue queue : mBroadcastQueues) { 13161 didSomething |= queue.sendPendingBroadcastsLocked(app); 13162 } 13163 return didSomething; 13164 } 13165 13166 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13167 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13168 enforceNotIsolatedCaller("registerReceiver"); 13169 int callingUid; 13170 int callingPid; 13171 synchronized(this) { 13172 ProcessRecord callerApp = null; 13173 if (caller != null) { 13174 callerApp = getRecordForAppLocked(caller); 13175 if (callerApp == null) { 13176 throw new SecurityException( 13177 "Unable to find app for caller " + caller 13178 + " (pid=" + Binder.getCallingPid() 13179 + ") when registering receiver " + receiver); 13180 } 13181 if (callerApp.info.uid != Process.SYSTEM_UID && 13182 !callerApp.pkgList.containsKey(callerPackage) && 13183 !"android".equals(callerPackage)) { 13184 throw new SecurityException("Given caller package " + callerPackage 13185 + " is not running in process " + callerApp); 13186 } 13187 callingUid = callerApp.info.uid; 13188 callingPid = callerApp.pid; 13189 } else { 13190 callerPackage = null; 13191 callingUid = Binder.getCallingUid(); 13192 callingPid = Binder.getCallingPid(); 13193 } 13194 13195 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13196 true, true, "registerReceiver", callerPackage); 13197 13198 List allSticky = null; 13199 13200 // Look for any matching sticky broadcasts... 13201 Iterator actions = filter.actionsIterator(); 13202 if (actions != null) { 13203 while (actions.hasNext()) { 13204 String action = (String)actions.next(); 13205 allSticky = getStickiesLocked(action, filter, allSticky, 13206 UserHandle.USER_ALL); 13207 allSticky = getStickiesLocked(action, filter, allSticky, 13208 UserHandle.getUserId(callingUid)); 13209 } 13210 } else { 13211 allSticky = getStickiesLocked(null, filter, allSticky, 13212 UserHandle.USER_ALL); 13213 allSticky = getStickiesLocked(null, filter, allSticky, 13214 UserHandle.getUserId(callingUid)); 13215 } 13216 13217 // The first sticky in the list is returned directly back to 13218 // the client. 13219 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13220 13221 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13222 + ": " + sticky); 13223 13224 if (receiver == null) { 13225 return sticky; 13226 } 13227 13228 ReceiverList rl 13229 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13230 if (rl == null) { 13231 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13232 userId, receiver); 13233 if (rl.app != null) { 13234 rl.app.receivers.add(rl); 13235 } else { 13236 try { 13237 receiver.asBinder().linkToDeath(rl, 0); 13238 } catch (RemoteException e) { 13239 return sticky; 13240 } 13241 rl.linkedToDeath = true; 13242 } 13243 mRegisteredReceivers.put(receiver.asBinder(), rl); 13244 } else if (rl.uid != callingUid) { 13245 throw new IllegalArgumentException( 13246 "Receiver requested to register for uid " + callingUid 13247 + " was previously registered for uid " + rl.uid); 13248 } else if (rl.pid != callingPid) { 13249 throw new IllegalArgumentException( 13250 "Receiver requested to register for pid " + callingPid 13251 + " was previously registered for pid " + rl.pid); 13252 } else if (rl.userId != userId) { 13253 throw new IllegalArgumentException( 13254 "Receiver requested to register for user " + userId 13255 + " was previously registered for user " + rl.userId); 13256 } 13257 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13258 permission, callingUid, userId); 13259 rl.add(bf); 13260 if (!bf.debugCheck()) { 13261 Slog.w(TAG, "==> For Dynamic broadast"); 13262 } 13263 mReceiverResolver.addFilter(bf); 13264 13265 // Enqueue broadcasts for all existing stickies that match 13266 // this filter. 13267 if (allSticky != null) { 13268 ArrayList receivers = new ArrayList(); 13269 receivers.add(bf); 13270 13271 int N = allSticky.size(); 13272 for (int i=0; i<N; i++) { 13273 Intent intent = (Intent)allSticky.get(i); 13274 BroadcastQueue queue = broadcastQueueForIntent(intent); 13275 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13276 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13277 null, null, false, true, true, -1); 13278 queue.enqueueParallelBroadcastLocked(r); 13279 queue.scheduleBroadcastsLocked(); 13280 } 13281 } 13282 13283 return sticky; 13284 } 13285 } 13286 13287 public void unregisterReceiver(IIntentReceiver receiver) { 13288 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13289 13290 final long origId = Binder.clearCallingIdentity(); 13291 try { 13292 boolean doTrim = false; 13293 13294 synchronized(this) { 13295 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13296 if (rl != null) { 13297 if (rl.curBroadcast != null) { 13298 BroadcastRecord r = rl.curBroadcast; 13299 final boolean doNext = finishReceiverLocked( 13300 receiver.asBinder(), r.resultCode, r.resultData, 13301 r.resultExtras, r.resultAbort); 13302 if (doNext) { 13303 doTrim = true; 13304 r.queue.processNextBroadcast(false); 13305 } 13306 } 13307 13308 if (rl.app != null) { 13309 rl.app.receivers.remove(rl); 13310 } 13311 removeReceiverLocked(rl); 13312 if (rl.linkedToDeath) { 13313 rl.linkedToDeath = false; 13314 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13315 } 13316 } 13317 } 13318 13319 // If we actually concluded any broadcasts, we might now be able 13320 // to trim the recipients' apps from our working set 13321 if (doTrim) { 13322 trimApplications(); 13323 return; 13324 } 13325 13326 } finally { 13327 Binder.restoreCallingIdentity(origId); 13328 } 13329 } 13330 13331 void removeReceiverLocked(ReceiverList rl) { 13332 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13333 int N = rl.size(); 13334 for (int i=0; i<N; i++) { 13335 mReceiverResolver.removeFilter(rl.get(i)); 13336 } 13337 } 13338 13339 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13340 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13341 ProcessRecord r = mLruProcesses.get(i); 13342 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13343 try { 13344 r.thread.dispatchPackageBroadcast(cmd, packages); 13345 } catch (RemoteException ex) { 13346 } 13347 } 13348 } 13349 } 13350 13351 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13352 int[] users) { 13353 List<ResolveInfo> receivers = null; 13354 try { 13355 HashSet<ComponentName> singleUserReceivers = null; 13356 boolean scannedFirstReceivers = false; 13357 for (int user : users) { 13358 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13359 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13360 if (user != 0 && newReceivers != null) { 13361 // If this is not the primary user, we need to check for 13362 // any receivers that should be filtered out. 13363 for (int i=0; i<newReceivers.size(); i++) { 13364 ResolveInfo ri = newReceivers.get(i); 13365 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13366 newReceivers.remove(i); 13367 i--; 13368 } 13369 } 13370 } 13371 if (newReceivers != null && newReceivers.size() == 0) { 13372 newReceivers = null; 13373 } 13374 if (receivers == null) { 13375 receivers = newReceivers; 13376 } else if (newReceivers != null) { 13377 // We need to concatenate the additional receivers 13378 // found with what we have do far. This would be easy, 13379 // but we also need to de-dup any receivers that are 13380 // singleUser. 13381 if (!scannedFirstReceivers) { 13382 // Collect any single user receivers we had already retrieved. 13383 scannedFirstReceivers = true; 13384 for (int i=0; i<receivers.size(); i++) { 13385 ResolveInfo ri = receivers.get(i); 13386 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13387 ComponentName cn = new ComponentName( 13388 ri.activityInfo.packageName, ri.activityInfo.name); 13389 if (singleUserReceivers == null) { 13390 singleUserReceivers = new HashSet<ComponentName>(); 13391 } 13392 singleUserReceivers.add(cn); 13393 } 13394 } 13395 } 13396 // Add the new results to the existing results, tracking 13397 // and de-dupping single user receivers. 13398 for (int i=0; i<newReceivers.size(); i++) { 13399 ResolveInfo ri = newReceivers.get(i); 13400 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13401 ComponentName cn = new ComponentName( 13402 ri.activityInfo.packageName, ri.activityInfo.name); 13403 if (singleUserReceivers == null) { 13404 singleUserReceivers = new HashSet<ComponentName>(); 13405 } 13406 if (!singleUserReceivers.contains(cn)) { 13407 singleUserReceivers.add(cn); 13408 receivers.add(ri); 13409 } 13410 } else { 13411 receivers.add(ri); 13412 } 13413 } 13414 } 13415 } 13416 } catch (RemoteException ex) { 13417 // pm is in same process, this will never happen. 13418 } 13419 return receivers; 13420 } 13421 13422 private final int broadcastIntentLocked(ProcessRecord callerApp, 13423 String callerPackage, Intent intent, String resolvedType, 13424 IIntentReceiver resultTo, int resultCode, String resultData, 13425 Bundle map, String requiredPermission, int appOp, 13426 boolean ordered, boolean sticky, int callingPid, int callingUid, 13427 int userId) { 13428 intent = new Intent(intent); 13429 13430 // By default broadcasts do not go to stopped apps. 13431 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13432 13433 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13434 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13435 + " ordered=" + ordered + " userid=" + userId); 13436 if ((resultTo != null) && !ordered) { 13437 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13438 } 13439 13440 userId = handleIncomingUser(callingPid, callingUid, userId, 13441 true, false, "broadcast", callerPackage); 13442 13443 // Make sure that the user who is receiving this broadcast is started. 13444 // If not, we will just skip it. 13445 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13446 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13447 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13448 Slog.w(TAG, "Skipping broadcast of " + intent 13449 + ": user " + userId + " is stopped"); 13450 return ActivityManager.BROADCAST_SUCCESS; 13451 } 13452 } 13453 13454 /* 13455 * Prevent non-system code (defined here to be non-persistent 13456 * processes) from sending protected broadcasts. 13457 */ 13458 int callingAppId = UserHandle.getAppId(callingUid); 13459 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13460 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13461 callingUid == 0) { 13462 // Always okay. 13463 } else if (callerApp == null || !callerApp.persistent) { 13464 try { 13465 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13466 intent.getAction())) { 13467 String msg = "Permission Denial: not allowed to send broadcast " 13468 + intent.getAction() + " from pid=" 13469 + callingPid + ", uid=" + callingUid; 13470 Slog.w(TAG, msg); 13471 throw new SecurityException(msg); 13472 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13473 // Special case for compatibility: we don't want apps to send this, 13474 // but historically it has not been protected and apps may be using it 13475 // to poke their own app widget. So, instead of making it protected, 13476 // just limit it to the caller. 13477 if (callerApp == null) { 13478 String msg = "Permission Denial: not allowed to send broadcast " 13479 + intent.getAction() + " from unknown caller."; 13480 Slog.w(TAG, msg); 13481 throw new SecurityException(msg); 13482 } else if (intent.getComponent() != null) { 13483 // They are good enough to send to an explicit component... verify 13484 // it is being sent to the calling app. 13485 if (!intent.getComponent().getPackageName().equals( 13486 callerApp.info.packageName)) { 13487 String msg = "Permission Denial: not allowed to send broadcast " 13488 + intent.getAction() + " to " 13489 + intent.getComponent().getPackageName() + " from " 13490 + callerApp.info.packageName; 13491 Slog.w(TAG, msg); 13492 throw new SecurityException(msg); 13493 } 13494 } else { 13495 // Limit broadcast to their own package. 13496 intent.setPackage(callerApp.info.packageName); 13497 } 13498 } 13499 } catch (RemoteException e) { 13500 Slog.w(TAG, "Remote exception", e); 13501 return ActivityManager.BROADCAST_SUCCESS; 13502 } 13503 } 13504 13505 // Handle special intents: if this broadcast is from the package 13506 // manager about a package being removed, we need to remove all of 13507 // its activities from the history stack. 13508 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13509 intent.getAction()); 13510 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13511 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13512 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13513 || uidRemoved) { 13514 if (checkComponentPermission( 13515 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13516 callingPid, callingUid, -1, true) 13517 == PackageManager.PERMISSION_GRANTED) { 13518 if (uidRemoved) { 13519 final Bundle intentExtras = intent.getExtras(); 13520 final int uid = intentExtras != null 13521 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13522 if (uid >= 0) { 13523 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13524 synchronized (bs) { 13525 bs.removeUidStatsLocked(uid); 13526 } 13527 mAppOpsService.uidRemoved(uid); 13528 } 13529 } else { 13530 // If resources are unavailable just force stop all 13531 // those packages and flush the attribute cache as well. 13532 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13533 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13534 if (list != null && (list.length > 0)) { 13535 for (String pkg : list) { 13536 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13537 "storage unmount"); 13538 } 13539 sendPackageBroadcastLocked( 13540 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13541 } 13542 } else { 13543 Uri data = intent.getData(); 13544 String ssp; 13545 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13546 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13547 intent.getAction()); 13548 boolean fullUninstall = removed && 13549 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13550 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13551 forceStopPackageLocked(ssp, UserHandle.getAppId( 13552 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13553 false, fullUninstall, userId, 13554 removed ? "pkg removed" : "pkg changed"); 13555 } 13556 if (removed) { 13557 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13558 new String[] {ssp}, userId); 13559 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13560 mAppOpsService.packageRemoved( 13561 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13562 13563 // Remove all permissions granted from/to this package 13564 removeUriPermissionsForPackageLocked(ssp, userId, true); 13565 } 13566 } 13567 } 13568 } 13569 } 13570 } else { 13571 String msg = "Permission Denial: " + intent.getAction() 13572 + " broadcast from " + callerPackage + " (pid=" + callingPid 13573 + ", uid=" + callingUid + ")" 13574 + " requires " 13575 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13576 Slog.w(TAG, msg); 13577 throw new SecurityException(msg); 13578 } 13579 13580 // Special case for adding a package: by default turn on compatibility 13581 // mode. 13582 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13583 Uri data = intent.getData(); 13584 String ssp; 13585 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13586 mCompatModePackages.handlePackageAddedLocked(ssp, 13587 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13588 } 13589 } 13590 13591 /* 13592 * If this is the time zone changed action, queue up a message that will reset the timezone 13593 * of all currently running processes. This message will get queued up before the broadcast 13594 * happens. 13595 */ 13596 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13597 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13598 } 13599 13600 /* 13601 * If the user set the time, let all running processes know. 13602 */ 13603 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13604 final int is24Hour = intent.getBooleanExtra( 13605 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13606 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13607 } 13608 13609 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13610 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13611 } 13612 13613 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13614 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13615 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13616 } 13617 13618 // Add to the sticky list if requested. 13619 if (sticky) { 13620 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13621 callingPid, callingUid) 13622 != PackageManager.PERMISSION_GRANTED) { 13623 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13624 + callingPid + ", uid=" + callingUid 13625 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13626 Slog.w(TAG, msg); 13627 throw new SecurityException(msg); 13628 } 13629 if (requiredPermission != null) { 13630 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13631 + " and enforce permission " + requiredPermission); 13632 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13633 } 13634 if (intent.getComponent() != null) { 13635 throw new SecurityException( 13636 "Sticky broadcasts can't target a specific component"); 13637 } 13638 // We use userId directly here, since the "all" target is maintained 13639 // as a separate set of sticky broadcasts. 13640 if (userId != UserHandle.USER_ALL) { 13641 // But first, if this is not a broadcast to all users, then 13642 // make sure it doesn't conflict with an existing broadcast to 13643 // all users. 13644 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13645 UserHandle.USER_ALL); 13646 if (stickies != null) { 13647 ArrayList<Intent> list = stickies.get(intent.getAction()); 13648 if (list != null) { 13649 int N = list.size(); 13650 int i; 13651 for (i=0; i<N; i++) { 13652 if (intent.filterEquals(list.get(i))) { 13653 throw new IllegalArgumentException( 13654 "Sticky broadcast " + intent + " for user " 13655 + userId + " conflicts with existing global broadcast"); 13656 } 13657 } 13658 } 13659 } 13660 } 13661 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13662 if (stickies == null) { 13663 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13664 mStickyBroadcasts.put(userId, stickies); 13665 } 13666 ArrayList<Intent> list = stickies.get(intent.getAction()); 13667 if (list == null) { 13668 list = new ArrayList<Intent>(); 13669 stickies.put(intent.getAction(), list); 13670 } 13671 int N = list.size(); 13672 int i; 13673 for (i=0; i<N; i++) { 13674 if (intent.filterEquals(list.get(i))) { 13675 // This sticky already exists, replace it. 13676 list.set(i, new Intent(intent)); 13677 break; 13678 } 13679 } 13680 if (i >= N) { 13681 list.add(new Intent(intent)); 13682 } 13683 } 13684 13685 int[] users; 13686 if (userId == UserHandle.USER_ALL) { 13687 // Caller wants broadcast to go to all started users. 13688 users = mStartedUserArray; 13689 } else { 13690 // Caller wants broadcast to go to one specific user. 13691 users = new int[] {userId}; 13692 } 13693 13694 // Figure out who all will receive this broadcast. 13695 List receivers = null; 13696 List<BroadcastFilter> registeredReceivers = null; 13697 // Need to resolve the intent to interested receivers... 13698 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13699 == 0) { 13700 receivers = collectReceiverComponents(intent, resolvedType, users); 13701 } 13702 if (intent.getComponent() == null) { 13703 registeredReceivers = mReceiverResolver.queryIntent(intent, 13704 resolvedType, false, userId); 13705 } 13706 13707 final boolean replacePending = 13708 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13709 13710 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13711 + " replacePending=" + replacePending); 13712 13713 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13714 if (!ordered && NR > 0) { 13715 // If we are not serializing this broadcast, then send the 13716 // registered receivers separately so they don't wait for the 13717 // components to be launched. 13718 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13719 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13720 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13721 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13722 ordered, sticky, false, userId); 13723 if (DEBUG_BROADCAST) Slog.v( 13724 TAG, "Enqueueing parallel broadcast " + r); 13725 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13726 if (!replaced) { 13727 queue.enqueueParallelBroadcastLocked(r); 13728 queue.scheduleBroadcastsLocked(); 13729 } 13730 registeredReceivers = null; 13731 NR = 0; 13732 } 13733 13734 // Merge into one list. 13735 int ir = 0; 13736 if (receivers != null) { 13737 // A special case for PACKAGE_ADDED: do not allow the package 13738 // being added to see this broadcast. This prevents them from 13739 // using this as a back door to get run as soon as they are 13740 // installed. Maybe in the future we want to have a special install 13741 // broadcast or such for apps, but we'd like to deliberately make 13742 // this decision. 13743 String skipPackages[] = null; 13744 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13745 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13746 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13747 Uri data = intent.getData(); 13748 if (data != null) { 13749 String pkgName = data.getSchemeSpecificPart(); 13750 if (pkgName != null) { 13751 skipPackages = new String[] { pkgName }; 13752 } 13753 } 13754 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13755 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13756 } 13757 if (skipPackages != null && (skipPackages.length > 0)) { 13758 for (String skipPackage : skipPackages) { 13759 if (skipPackage != null) { 13760 int NT = receivers.size(); 13761 for (int it=0; it<NT; it++) { 13762 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13763 if (curt.activityInfo.packageName.equals(skipPackage)) { 13764 receivers.remove(it); 13765 it--; 13766 NT--; 13767 } 13768 } 13769 } 13770 } 13771 } 13772 13773 int NT = receivers != null ? receivers.size() : 0; 13774 int it = 0; 13775 ResolveInfo curt = null; 13776 BroadcastFilter curr = null; 13777 while (it < NT && ir < NR) { 13778 if (curt == null) { 13779 curt = (ResolveInfo)receivers.get(it); 13780 } 13781 if (curr == null) { 13782 curr = registeredReceivers.get(ir); 13783 } 13784 if (curr.getPriority() >= curt.priority) { 13785 // Insert this broadcast record into the final list. 13786 receivers.add(it, curr); 13787 ir++; 13788 curr = null; 13789 it++; 13790 NT++; 13791 } else { 13792 // Skip to the next ResolveInfo in the final list. 13793 it++; 13794 curt = null; 13795 } 13796 } 13797 } 13798 while (ir < NR) { 13799 if (receivers == null) { 13800 receivers = new ArrayList(); 13801 } 13802 receivers.add(registeredReceivers.get(ir)); 13803 ir++; 13804 } 13805 13806 if ((receivers != null && receivers.size() > 0) 13807 || resultTo != null) { 13808 BroadcastQueue queue = broadcastQueueForIntent(intent); 13809 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13810 callerPackage, callingPid, callingUid, resolvedType, 13811 requiredPermission, appOp, receivers, resultTo, resultCode, 13812 resultData, map, ordered, sticky, false, userId); 13813 if (DEBUG_BROADCAST) Slog.v( 13814 TAG, "Enqueueing ordered broadcast " + r 13815 + ": prev had " + queue.mOrderedBroadcasts.size()); 13816 if (DEBUG_BROADCAST) { 13817 int seq = r.intent.getIntExtra("seq", -1); 13818 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13819 } 13820 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13821 if (!replaced) { 13822 queue.enqueueOrderedBroadcastLocked(r); 13823 queue.scheduleBroadcastsLocked(); 13824 } 13825 } 13826 13827 return ActivityManager.BROADCAST_SUCCESS; 13828 } 13829 13830 final Intent verifyBroadcastLocked(Intent intent) { 13831 // Refuse possible leaked file descriptors 13832 if (intent != null && intent.hasFileDescriptors() == true) { 13833 throw new IllegalArgumentException("File descriptors passed in Intent"); 13834 } 13835 13836 int flags = intent.getFlags(); 13837 13838 if (!mProcessesReady) { 13839 // if the caller really truly claims to know what they're doing, go 13840 // ahead and allow the broadcast without launching any receivers 13841 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13842 intent = new Intent(intent); 13843 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13844 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13845 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13846 + " before boot completion"); 13847 throw new IllegalStateException("Cannot broadcast before boot completed"); 13848 } 13849 } 13850 13851 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13852 throw new IllegalArgumentException( 13853 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13854 } 13855 13856 return intent; 13857 } 13858 13859 public final int broadcastIntent(IApplicationThread caller, 13860 Intent intent, String resolvedType, IIntentReceiver resultTo, 13861 int resultCode, String resultData, Bundle map, 13862 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13863 enforceNotIsolatedCaller("broadcastIntent"); 13864 synchronized(this) { 13865 intent = verifyBroadcastLocked(intent); 13866 13867 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13868 final int callingPid = Binder.getCallingPid(); 13869 final int callingUid = Binder.getCallingUid(); 13870 final long origId = Binder.clearCallingIdentity(); 13871 int res = broadcastIntentLocked(callerApp, 13872 callerApp != null ? callerApp.info.packageName : null, 13873 intent, resolvedType, resultTo, 13874 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13875 callingPid, callingUid, userId); 13876 Binder.restoreCallingIdentity(origId); 13877 return res; 13878 } 13879 } 13880 13881 int broadcastIntentInPackage(String packageName, int uid, 13882 Intent intent, String resolvedType, IIntentReceiver resultTo, 13883 int resultCode, String resultData, Bundle map, 13884 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13885 synchronized(this) { 13886 intent = verifyBroadcastLocked(intent); 13887 13888 final long origId = Binder.clearCallingIdentity(); 13889 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13890 resultTo, resultCode, resultData, map, requiredPermission, 13891 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13892 Binder.restoreCallingIdentity(origId); 13893 return res; 13894 } 13895 } 13896 13897 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13898 // Refuse possible leaked file descriptors 13899 if (intent != null && intent.hasFileDescriptors() == true) { 13900 throw new IllegalArgumentException("File descriptors passed in Intent"); 13901 } 13902 13903 userId = handleIncomingUser(Binder.getCallingPid(), 13904 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13905 13906 synchronized(this) { 13907 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13908 != PackageManager.PERMISSION_GRANTED) { 13909 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13910 + Binder.getCallingPid() 13911 + ", uid=" + Binder.getCallingUid() 13912 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13913 Slog.w(TAG, msg); 13914 throw new SecurityException(msg); 13915 } 13916 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13917 if (stickies != null) { 13918 ArrayList<Intent> list = stickies.get(intent.getAction()); 13919 if (list != null) { 13920 int N = list.size(); 13921 int i; 13922 for (i=0; i<N; i++) { 13923 if (intent.filterEquals(list.get(i))) { 13924 list.remove(i); 13925 break; 13926 } 13927 } 13928 if (list.size() <= 0) { 13929 stickies.remove(intent.getAction()); 13930 } 13931 } 13932 if (stickies.size() <= 0) { 13933 mStickyBroadcasts.remove(userId); 13934 } 13935 } 13936 } 13937 } 13938 13939 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 13940 String resultData, Bundle resultExtras, boolean resultAbort) { 13941 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 13942 if (r == null) { 13943 Slog.w(TAG, "finishReceiver called but not found on queue"); 13944 return false; 13945 } 13946 13947 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 13948 } 13949 13950 void backgroundServicesFinishedLocked(int userId) { 13951 for (BroadcastQueue queue : mBroadcastQueues) { 13952 queue.backgroundServicesFinishedLocked(userId); 13953 } 13954 } 13955 13956 public void finishReceiver(IBinder who, int resultCode, String resultData, 13957 Bundle resultExtras, boolean resultAbort) { 13958 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 13959 13960 // Refuse possible leaked file descriptors 13961 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 13962 throw new IllegalArgumentException("File descriptors passed in Bundle"); 13963 } 13964 13965 final long origId = Binder.clearCallingIdentity(); 13966 try { 13967 boolean doNext = false; 13968 BroadcastRecord r; 13969 13970 synchronized(this) { 13971 r = broadcastRecordForReceiverLocked(who); 13972 if (r != null) { 13973 doNext = r.queue.finishReceiverLocked(r, resultCode, 13974 resultData, resultExtras, resultAbort, true); 13975 } 13976 } 13977 13978 if (doNext) { 13979 r.queue.processNextBroadcast(false); 13980 } 13981 trimApplications(); 13982 } finally { 13983 Binder.restoreCallingIdentity(origId); 13984 } 13985 } 13986 13987 // ========================================================= 13988 // INSTRUMENTATION 13989 // ========================================================= 13990 13991 public boolean startInstrumentation(ComponentName className, 13992 String profileFile, int flags, Bundle arguments, 13993 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 13994 int userId) { 13995 enforceNotIsolatedCaller("startInstrumentation"); 13996 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 13997 userId, false, true, "startInstrumentation", null); 13998 // Refuse possible leaked file descriptors 13999 if (arguments != null && arguments.hasFileDescriptors()) { 14000 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14001 } 14002 14003 synchronized(this) { 14004 InstrumentationInfo ii = null; 14005 ApplicationInfo ai = null; 14006 try { 14007 ii = mContext.getPackageManager().getInstrumentationInfo( 14008 className, STOCK_PM_FLAGS); 14009 ai = AppGlobals.getPackageManager().getApplicationInfo( 14010 ii.targetPackage, STOCK_PM_FLAGS, userId); 14011 } catch (PackageManager.NameNotFoundException e) { 14012 } catch (RemoteException e) { 14013 } 14014 if (ii == null) { 14015 reportStartInstrumentationFailure(watcher, className, 14016 "Unable to find instrumentation info for: " + className); 14017 return false; 14018 } 14019 if (ai == null) { 14020 reportStartInstrumentationFailure(watcher, className, 14021 "Unable to find instrumentation target package: " + ii.targetPackage); 14022 return false; 14023 } 14024 14025 int match = mContext.getPackageManager().checkSignatures( 14026 ii.targetPackage, ii.packageName); 14027 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14028 String msg = "Permission Denial: starting instrumentation " 14029 + className + " from pid=" 14030 + Binder.getCallingPid() 14031 + ", uid=" + Binder.getCallingPid() 14032 + " not allowed because package " + ii.packageName 14033 + " does not have a signature matching the target " 14034 + ii.targetPackage; 14035 reportStartInstrumentationFailure(watcher, className, msg); 14036 throw new SecurityException(msg); 14037 } 14038 14039 final long origId = Binder.clearCallingIdentity(); 14040 // Instrumentation can kill and relaunch even persistent processes 14041 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14042 "start instr"); 14043 ProcessRecord app = addAppLocked(ai, false); 14044 app.instrumentationClass = className; 14045 app.instrumentationInfo = ai; 14046 app.instrumentationProfileFile = profileFile; 14047 app.instrumentationArguments = arguments; 14048 app.instrumentationWatcher = watcher; 14049 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14050 app.instrumentationResultClass = className; 14051 Binder.restoreCallingIdentity(origId); 14052 } 14053 14054 return true; 14055 } 14056 14057 /** 14058 * Report errors that occur while attempting to start Instrumentation. Always writes the 14059 * error to the logs, but if somebody is watching, send the report there too. This enables 14060 * the "am" command to report errors with more information. 14061 * 14062 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14063 * @param cn The component name of the instrumentation. 14064 * @param report The error report. 14065 */ 14066 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14067 ComponentName cn, String report) { 14068 Slog.w(TAG, report); 14069 try { 14070 if (watcher != null) { 14071 Bundle results = new Bundle(); 14072 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14073 results.putString("Error", report); 14074 watcher.instrumentationStatus(cn, -1, results); 14075 } 14076 } catch (RemoteException e) { 14077 Slog.w(TAG, e); 14078 } 14079 } 14080 14081 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14082 if (app.instrumentationWatcher != null) { 14083 try { 14084 // NOTE: IInstrumentationWatcher *must* be oneway here 14085 app.instrumentationWatcher.instrumentationFinished( 14086 app.instrumentationClass, 14087 resultCode, 14088 results); 14089 } catch (RemoteException e) { 14090 } 14091 } 14092 if (app.instrumentationUiAutomationConnection != null) { 14093 try { 14094 app.instrumentationUiAutomationConnection.shutdown(); 14095 } catch (RemoteException re) { 14096 /* ignore */ 14097 } 14098 // Only a UiAutomation can set this flag and now that 14099 // it is finished we make sure it is reset to its default. 14100 mUserIsMonkey = false; 14101 } 14102 app.instrumentationWatcher = null; 14103 app.instrumentationUiAutomationConnection = null; 14104 app.instrumentationClass = null; 14105 app.instrumentationInfo = null; 14106 app.instrumentationProfileFile = null; 14107 app.instrumentationArguments = null; 14108 14109 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14110 "finished inst"); 14111 } 14112 14113 public void finishInstrumentation(IApplicationThread target, 14114 int resultCode, Bundle results) { 14115 int userId = UserHandle.getCallingUserId(); 14116 // Refuse possible leaked file descriptors 14117 if (results != null && results.hasFileDescriptors()) { 14118 throw new IllegalArgumentException("File descriptors passed in Intent"); 14119 } 14120 14121 synchronized(this) { 14122 ProcessRecord app = getRecordForAppLocked(target); 14123 if (app == null) { 14124 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14125 return; 14126 } 14127 final long origId = Binder.clearCallingIdentity(); 14128 finishInstrumentationLocked(app, resultCode, results); 14129 Binder.restoreCallingIdentity(origId); 14130 } 14131 } 14132 14133 // ========================================================= 14134 // CONFIGURATION 14135 // ========================================================= 14136 14137 public ConfigurationInfo getDeviceConfigurationInfo() { 14138 ConfigurationInfo config = new ConfigurationInfo(); 14139 synchronized (this) { 14140 config.reqTouchScreen = mConfiguration.touchscreen; 14141 config.reqKeyboardType = mConfiguration.keyboard; 14142 config.reqNavigation = mConfiguration.navigation; 14143 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14144 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14145 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14146 } 14147 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14148 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14149 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14150 } 14151 config.reqGlEsVersion = GL_ES_VERSION; 14152 } 14153 return config; 14154 } 14155 14156 ActivityStack getFocusedStack() { 14157 return mStackSupervisor.getFocusedStack(); 14158 } 14159 14160 public Configuration getConfiguration() { 14161 Configuration ci; 14162 synchronized(this) { 14163 ci = new Configuration(mConfiguration); 14164 } 14165 return ci; 14166 } 14167 14168 public void updatePersistentConfiguration(Configuration values) { 14169 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14170 "updateConfiguration()"); 14171 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14172 "updateConfiguration()"); 14173 if (values == null) { 14174 throw new NullPointerException("Configuration must not be null"); 14175 } 14176 14177 synchronized(this) { 14178 final long origId = Binder.clearCallingIdentity(); 14179 updateConfigurationLocked(values, null, true, false); 14180 Binder.restoreCallingIdentity(origId); 14181 } 14182 } 14183 14184 public void updateConfiguration(Configuration values) { 14185 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14186 "updateConfiguration()"); 14187 14188 synchronized(this) { 14189 if (values == null && mWindowManager != null) { 14190 // sentinel: fetch the current configuration from the window manager 14191 values = mWindowManager.computeNewConfiguration(); 14192 } 14193 14194 if (mWindowManager != null) { 14195 mProcessList.applyDisplaySize(mWindowManager); 14196 } 14197 14198 final long origId = Binder.clearCallingIdentity(); 14199 if (values != null) { 14200 Settings.System.clearConfiguration(values); 14201 } 14202 updateConfigurationLocked(values, null, false, false); 14203 Binder.restoreCallingIdentity(origId); 14204 } 14205 } 14206 14207 /** 14208 * Do either or both things: (1) change the current configuration, and (2) 14209 * make sure the given activity is running with the (now) current 14210 * configuration. Returns true if the activity has been left running, or 14211 * false if <var>starting</var> is being destroyed to match the new 14212 * configuration. 14213 * @param persistent TODO 14214 */ 14215 boolean updateConfigurationLocked(Configuration values, 14216 ActivityRecord starting, boolean persistent, boolean initLocale) { 14217 int changes = 0; 14218 14219 if (values != null) { 14220 Configuration newConfig = new Configuration(mConfiguration); 14221 changes = newConfig.updateFrom(values); 14222 if (changes != 0) { 14223 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14224 Slog.i(TAG, "Updating configuration to: " + values); 14225 } 14226 14227 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14228 14229 if (values.locale != null && !initLocale) { 14230 saveLocaleLocked(values.locale, 14231 !values.locale.equals(mConfiguration.locale), 14232 values.userSetLocale); 14233 } 14234 14235 mConfigurationSeq++; 14236 if (mConfigurationSeq <= 0) { 14237 mConfigurationSeq = 1; 14238 } 14239 newConfig.seq = mConfigurationSeq; 14240 mConfiguration = newConfig; 14241 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14242 14243 final Configuration configCopy = new Configuration(mConfiguration); 14244 14245 // TODO: If our config changes, should we auto dismiss any currently 14246 // showing dialogs? 14247 mShowDialogs = shouldShowDialogs(newConfig); 14248 14249 AttributeCache ac = AttributeCache.instance(); 14250 if (ac != null) { 14251 ac.updateConfiguration(configCopy); 14252 } 14253 14254 // Make sure all resources in our process are updated 14255 // right now, so that anyone who is going to retrieve 14256 // resource values after we return will be sure to get 14257 // the new ones. This is especially important during 14258 // boot, where the first config change needs to guarantee 14259 // all resources have that config before following boot 14260 // code is executed. 14261 mSystemThread.applyConfigurationToResources(configCopy); 14262 14263 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14264 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14265 msg.obj = new Configuration(configCopy); 14266 mHandler.sendMessage(msg); 14267 } 14268 14269 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14270 ProcessRecord app = mLruProcesses.get(i); 14271 try { 14272 if (app.thread != null) { 14273 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14274 + app.processName + " new config " + mConfiguration); 14275 app.thread.scheduleConfigurationChanged(configCopy); 14276 } 14277 } catch (Exception e) { 14278 } 14279 } 14280 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14281 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14282 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14283 | Intent.FLAG_RECEIVER_FOREGROUND); 14284 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14285 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14286 Process.SYSTEM_UID, UserHandle.USER_ALL); 14287 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14288 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14289 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14290 broadcastIntentLocked(null, null, intent, 14291 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14292 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14293 } 14294 } 14295 } 14296 14297 boolean kept = true; 14298 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14299 // mainStack is null during startup. 14300 if (mainStack != null) { 14301 if (changes != 0 && starting == null) { 14302 // If the configuration changed, and the caller is not already 14303 // in the process of starting an activity, then find the top 14304 // activity to check if its configuration needs to change. 14305 starting = mainStack.topRunningActivityLocked(null); 14306 } 14307 14308 if (starting != null) { 14309 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14310 // And we need to make sure at this point that all other activities 14311 // are made visible with the correct configuration. 14312 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14313 } 14314 } 14315 14316 if (values != null && mWindowManager != null) { 14317 mWindowManager.setNewConfiguration(mConfiguration); 14318 } 14319 14320 return kept; 14321 } 14322 14323 /** 14324 * Decide based on the configuration whether we should shouw the ANR, 14325 * crash, etc dialogs. The idea is that if there is no affordnace to 14326 * press the on-screen buttons, we shouldn't show the dialog. 14327 * 14328 * A thought: SystemUI might also want to get told about this, the Power 14329 * dialog / global actions also might want different behaviors. 14330 */ 14331 private static final boolean shouldShowDialogs(Configuration config) { 14332 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14333 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14334 } 14335 14336 /** 14337 * Save the locale. You must be inside a synchronized (this) block. 14338 */ 14339 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14340 if(isDiff) { 14341 SystemProperties.set("user.language", l.getLanguage()); 14342 SystemProperties.set("user.region", l.getCountry()); 14343 } 14344 14345 if(isPersist) { 14346 SystemProperties.set("persist.sys.language", l.getLanguage()); 14347 SystemProperties.set("persist.sys.country", l.getCountry()); 14348 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14349 } 14350 } 14351 14352 @Override 14353 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14354 ActivityRecord srec = ActivityRecord.forToken(token); 14355 return srec != null && srec.task.affinity != null && 14356 srec.task.affinity.equals(destAffinity); 14357 } 14358 14359 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14360 Intent resultData) { 14361 14362 synchronized (this) { 14363 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14364 if (stack != null) { 14365 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14366 } 14367 return false; 14368 } 14369 } 14370 14371 public int getLaunchedFromUid(IBinder activityToken) { 14372 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14373 if (srec == null) { 14374 return -1; 14375 } 14376 return srec.launchedFromUid; 14377 } 14378 14379 public String getLaunchedFromPackage(IBinder activityToken) { 14380 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14381 if (srec == null) { 14382 return null; 14383 } 14384 return srec.launchedFromPackage; 14385 } 14386 14387 // ========================================================= 14388 // LIFETIME MANAGEMENT 14389 // ========================================================= 14390 14391 // Returns which broadcast queue the app is the current [or imminent] receiver 14392 // on, or 'null' if the app is not an active broadcast recipient. 14393 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14394 BroadcastRecord r = app.curReceiver; 14395 if (r != null) { 14396 return r.queue; 14397 } 14398 14399 // It's not the current receiver, but it might be starting up to become one 14400 synchronized (this) { 14401 for (BroadcastQueue queue : mBroadcastQueues) { 14402 r = queue.mPendingBroadcast; 14403 if (r != null && r.curApp == app) { 14404 // found it; report which queue it's in 14405 return queue; 14406 } 14407 } 14408 } 14409 14410 return null; 14411 } 14412 14413 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14414 boolean doingAll, long now) { 14415 if (mAdjSeq == app.adjSeq) { 14416 // This adjustment has already been computed. 14417 return app.curRawAdj; 14418 } 14419 14420 if (app.thread == null) { 14421 app.adjSeq = mAdjSeq; 14422 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14423 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14424 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14425 } 14426 14427 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14428 app.adjSource = null; 14429 app.adjTarget = null; 14430 app.empty = false; 14431 app.cached = false; 14432 14433 final int activitiesSize = app.activities.size(); 14434 14435 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14436 // The max adjustment doesn't allow this app to be anything 14437 // below foreground, so it is not worth doing work for it. 14438 app.adjType = "fixed"; 14439 app.adjSeq = mAdjSeq; 14440 app.curRawAdj = app.maxAdj; 14441 app.foregroundActivities = false; 14442 app.keeping = true; 14443 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14444 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14445 // System process can do UI, and when they do we want to have 14446 // them trim their memory after the user leaves the UI. To 14447 // facilitate this, here we need to determine whether or not it 14448 // is currently showing UI. 14449 app.systemNoUi = true; 14450 if (app == TOP_APP) { 14451 app.systemNoUi = false; 14452 } else if (activitiesSize > 0) { 14453 for (int j = 0; j < activitiesSize; j++) { 14454 final ActivityRecord r = app.activities.get(j); 14455 if (r.visible) { 14456 app.systemNoUi = false; 14457 } 14458 } 14459 } 14460 if (!app.systemNoUi) { 14461 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14462 } 14463 return (app.curAdj=app.maxAdj); 14464 } 14465 14466 app.keeping = false; 14467 app.systemNoUi = false; 14468 14469 // Determine the importance of the process, starting with most 14470 // important to least, and assign an appropriate OOM adjustment. 14471 int adj; 14472 int schedGroup; 14473 int procState; 14474 boolean foregroundActivities = false; 14475 boolean interesting = false; 14476 BroadcastQueue queue; 14477 if (app == TOP_APP) { 14478 // The last app on the list is the foreground app. 14479 adj = ProcessList.FOREGROUND_APP_ADJ; 14480 schedGroup = Process.THREAD_GROUP_DEFAULT; 14481 app.adjType = "top-activity"; 14482 foregroundActivities = true; 14483 interesting = true; 14484 procState = ActivityManager.PROCESS_STATE_TOP; 14485 } else if (app.instrumentationClass != null) { 14486 // Don't want to kill running instrumentation. 14487 adj = ProcessList.FOREGROUND_APP_ADJ; 14488 schedGroup = Process.THREAD_GROUP_DEFAULT; 14489 app.adjType = "instrumentation"; 14490 interesting = true; 14491 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14492 } else if ((queue = isReceivingBroadcast(app)) != null) { 14493 // An app that is currently receiving a broadcast also 14494 // counts as being in the foreground for OOM killer purposes. 14495 // It's placed in a sched group based on the nature of the 14496 // broadcast as reflected by which queue it's active in. 14497 adj = ProcessList.FOREGROUND_APP_ADJ; 14498 schedGroup = (queue == mFgBroadcastQueue) 14499 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14500 app.adjType = "broadcast"; 14501 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14502 } else if (app.executingServices.size() > 0) { 14503 // An app that is currently executing a service callback also 14504 // counts as being in the foreground. 14505 adj = ProcessList.FOREGROUND_APP_ADJ; 14506 schedGroup = app.execServicesFg ? 14507 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14508 app.adjType = "exec-service"; 14509 procState = ActivityManager.PROCESS_STATE_SERVICE; 14510 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14511 } else { 14512 // As far as we know the process is empty. We may change our mind later. 14513 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14514 // At this point we don't actually know the adjustment. Use the cached adj 14515 // value that the caller wants us to. 14516 adj = cachedAdj; 14517 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14518 app.cached = true; 14519 app.empty = true; 14520 app.adjType = "cch-empty"; 14521 } 14522 14523 // Examine all activities if not already foreground. 14524 if (!foregroundActivities && activitiesSize > 0) { 14525 for (int j = 0; j < activitiesSize; j++) { 14526 final ActivityRecord r = app.activities.get(j); 14527 if (r.app != app) { 14528 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14529 + app + "?!?"); 14530 continue; 14531 } 14532 if (r.visible) { 14533 // App has a visible activity; only upgrade adjustment. 14534 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14535 adj = ProcessList.VISIBLE_APP_ADJ; 14536 app.adjType = "visible"; 14537 } 14538 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14539 procState = ActivityManager.PROCESS_STATE_TOP; 14540 } 14541 schedGroup = Process.THREAD_GROUP_DEFAULT; 14542 app.cached = false; 14543 app.empty = false; 14544 foregroundActivities = true; 14545 break; 14546 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14547 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14548 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14549 app.adjType = "pausing"; 14550 } 14551 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14552 procState = ActivityManager.PROCESS_STATE_TOP; 14553 } 14554 schedGroup = Process.THREAD_GROUP_DEFAULT; 14555 app.cached = false; 14556 app.empty = false; 14557 foregroundActivities = true; 14558 } else if (r.state == ActivityState.STOPPING) { 14559 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14560 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14561 app.adjType = "stopping"; 14562 } 14563 // For the process state, we will at this point consider the 14564 // process to be cached. It will be cached either as an activity 14565 // or empty depending on whether the activity is finishing. We do 14566 // this so that we can treat the process as cached for purposes of 14567 // memory trimming (determing current memory level, trim command to 14568 // send to process) since there can be an arbitrary number of stopping 14569 // processes and they should soon all go into the cached state. 14570 if (!r.finishing) { 14571 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14572 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14573 } 14574 } 14575 app.cached = false; 14576 app.empty = false; 14577 foregroundActivities = true; 14578 } else { 14579 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14580 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14581 app.adjType = "cch-act"; 14582 } 14583 } 14584 } 14585 } 14586 14587 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14588 if (app.foregroundServices) { 14589 // The user is aware of this app, so make it visible. 14590 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14591 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14592 app.cached = false; 14593 app.adjType = "fg-service"; 14594 schedGroup = Process.THREAD_GROUP_DEFAULT; 14595 } else if (app.forcingToForeground != null) { 14596 // The user is aware of this app, so make it visible. 14597 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14598 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14599 app.cached = false; 14600 app.adjType = "force-fg"; 14601 app.adjSource = app.forcingToForeground; 14602 schedGroup = Process.THREAD_GROUP_DEFAULT; 14603 } 14604 } 14605 14606 if (app.foregroundServices) { 14607 interesting = true; 14608 } 14609 14610 if (app == mHeavyWeightProcess) { 14611 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14612 // We don't want to kill the current heavy-weight process. 14613 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14614 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14615 app.cached = false; 14616 app.adjType = "heavy"; 14617 } 14618 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14619 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14620 } 14621 } 14622 14623 if (app == mHomeProcess) { 14624 if (adj > ProcessList.HOME_APP_ADJ) { 14625 // This process is hosting what we currently consider to be the 14626 // home app, so we don't want to let it go into the background. 14627 adj = ProcessList.HOME_APP_ADJ; 14628 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14629 app.cached = false; 14630 app.adjType = "home"; 14631 } 14632 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14633 procState = ActivityManager.PROCESS_STATE_HOME; 14634 } 14635 } 14636 14637 if (app == mPreviousProcess && app.activities.size() > 0) { 14638 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14639 // This was the previous process that showed UI to the user. 14640 // We want to try to keep it around more aggressively, to give 14641 // a good experience around switching between two apps. 14642 adj = ProcessList.PREVIOUS_APP_ADJ; 14643 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14644 app.cached = false; 14645 app.adjType = "previous"; 14646 } 14647 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14648 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14649 } 14650 } 14651 14652 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14653 + " reason=" + app.adjType); 14654 14655 // By default, we use the computed adjustment. It may be changed if 14656 // there are applications dependent on our services or providers, but 14657 // this gives us a baseline and makes sure we don't get into an 14658 // infinite recursion. 14659 app.adjSeq = mAdjSeq; 14660 app.curRawAdj = adj; 14661 app.hasStartedServices = false; 14662 14663 if (mBackupTarget != null && app == mBackupTarget.app) { 14664 // If possible we want to avoid killing apps while they're being backed up 14665 if (adj > ProcessList.BACKUP_APP_ADJ) { 14666 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14667 adj = ProcessList.BACKUP_APP_ADJ; 14668 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14669 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14670 } 14671 app.adjType = "backup"; 14672 app.cached = false; 14673 } 14674 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14675 procState = ActivityManager.PROCESS_STATE_BACKUP; 14676 } 14677 } 14678 14679 boolean mayBeTop = false; 14680 14681 for (int is = app.services.size()-1; 14682 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14683 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14684 || procState > ActivityManager.PROCESS_STATE_TOP); 14685 is--) { 14686 ServiceRecord s = app.services.valueAt(is); 14687 if (s.startRequested) { 14688 app.hasStartedServices = true; 14689 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14690 procState = ActivityManager.PROCESS_STATE_SERVICE; 14691 } 14692 if (app.hasShownUi && app != mHomeProcess) { 14693 // If this process has shown some UI, let it immediately 14694 // go to the LRU list because it may be pretty heavy with 14695 // UI stuff. We'll tag it with a label just to help 14696 // debug and understand what is going on. 14697 if (adj > ProcessList.SERVICE_ADJ) { 14698 app.adjType = "cch-started-ui-services"; 14699 } 14700 } else { 14701 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14702 // This service has seen some activity within 14703 // recent memory, so we will keep its process ahead 14704 // of the background processes. 14705 if (adj > ProcessList.SERVICE_ADJ) { 14706 adj = ProcessList.SERVICE_ADJ; 14707 app.adjType = "started-services"; 14708 app.cached = false; 14709 } 14710 } 14711 // If we have let the service slide into the background 14712 // state, still have some text describing what it is doing 14713 // even though the service no longer has an impact. 14714 if (adj > ProcessList.SERVICE_ADJ) { 14715 app.adjType = "cch-started-services"; 14716 } 14717 } 14718 // Don't kill this process because it is doing work; it 14719 // has said it is doing work. 14720 app.keeping = true; 14721 } 14722 for (int conni = s.connections.size()-1; 14723 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14724 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14725 || procState > ActivityManager.PROCESS_STATE_TOP); 14726 conni--) { 14727 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14728 for (int i = 0; 14729 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14730 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14731 || procState > ActivityManager.PROCESS_STATE_TOP); 14732 i++) { 14733 // XXX should compute this based on the max of 14734 // all connected clients. 14735 ConnectionRecord cr = clist.get(i); 14736 if (cr.binding.client == app) { 14737 // Binding to ourself is not interesting. 14738 continue; 14739 } 14740 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14741 ProcessRecord client = cr.binding.client; 14742 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14743 TOP_APP, doingAll, now); 14744 int clientProcState = client.curProcState; 14745 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14746 // If the other app is cached for any reason, for purposes here 14747 // we are going to consider it empty. The specific cached state 14748 // doesn't propagate except under certain conditions. 14749 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14750 } 14751 String adjType = null; 14752 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14753 // Not doing bind OOM management, so treat 14754 // this guy more like a started service. 14755 if (app.hasShownUi && app != mHomeProcess) { 14756 // If this process has shown some UI, let it immediately 14757 // go to the LRU list because it may be pretty heavy with 14758 // UI stuff. We'll tag it with a label just to help 14759 // debug and understand what is going on. 14760 if (adj > clientAdj) { 14761 adjType = "cch-bound-ui-services"; 14762 } 14763 app.cached = false; 14764 clientAdj = adj; 14765 clientProcState = procState; 14766 } else { 14767 if (now >= (s.lastActivity 14768 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14769 // This service has not seen activity within 14770 // recent memory, so allow it to drop to the 14771 // LRU list if there is no other reason to keep 14772 // it around. We'll also tag it with a label just 14773 // to help debug and undertand what is going on. 14774 if (adj > clientAdj) { 14775 adjType = "cch-bound-services"; 14776 } 14777 clientAdj = adj; 14778 } 14779 } 14780 } 14781 if (adj > clientAdj) { 14782 // If this process has recently shown UI, and 14783 // the process that is binding to it is less 14784 // important than being visible, then we don't 14785 // care about the binding as much as we care 14786 // about letting this process get into the LRU 14787 // list to be killed and restarted if needed for 14788 // memory. 14789 if (app.hasShownUi && app != mHomeProcess 14790 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14791 adjType = "cch-bound-ui-services"; 14792 } else { 14793 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14794 |Context.BIND_IMPORTANT)) != 0) { 14795 adj = clientAdj; 14796 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14797 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14798 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14799 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14800 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14801 adj = clientAdj; 14802 } else { 14803 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14804 adj = ProcessList.VISIBLE_APP_ADJ; 14805 } 14806 } 14807 if (!client.cached) { 14808 app.cached = false; 14809 } 14810 if (client.keeping) { 14811 app.keeping = true; 14812 } 14813 adjType = "service"; 14814 } 14815 } 14816 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14817 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14818 schedGroup = Process.THREAD_GROUP_DEFAULT; 14819 } 14820 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14821 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14822 // Special handling of clients who are in the top state. 14823 // We *may* want to consider this process to be in the 14824 // top state as well, but only if there is not another 14825 // reason for it to be running. Being on the top is a 14826 // special state, meaning you are specifically running 14827 // for the current top app. If the process is already 14828 // running in the background for some other reason, it 14829 // is more important to continue considering it to be 14830 // in the background state. 14831 mayBeTop = true; 14832 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14833 } else { 14834 // Special handling for above-top states (persistent 14835 // processes). These should not bring the current process 14836 // into the top state, since they are not on top. Instead 14837 // give them the best state after that. 14838 clientProcState = 14839 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14840 } 14841 } 14842 } else { 14843 if (clientProcState < 14844 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14845 clientProcState = 14846 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14847 } 14848 } 14849 if (procState > clientProcState) { 14850 procState = clientProcState; 14851 } 14852 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14853 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14854 app.pendingUiClean = true; 14855 } 14856 if (adjType != null) { 14857 app.adjType = adjType; 14858 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14859 .REASON_SERVICE_IN_USE; 14860 app.adjSource = cr.binding.client; 14861 app.adjSourceOom = clientAdj; 14862 app.adjTarget = s.name; 14863 } 14864 } 14865 final ActivityRecord a = cr.activity; 14866 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14867 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14868 (a.visible || a.state == ActivityState.RESUMED 14869 || a.state == ActivityState.PAUSING)) { 14870 adj = ProcessList.FOREGROUND_APP_ADJ; 14871 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14872 schedGroup = Process.THREAD_GROUP_DEFAULT; 14873 } 14874 app.cached = false; 14875 app.adjType = "service"; 14876 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14877 .REASON_SERVICE_IN_USE; 14878 app.adjSource = a; 14879 app.adjSourceOom = adj; 14880 app.adjTarget = s.name; 14881 } 14882 } 14883 } 14884 } 14885 } 14886 14887 for (int provi = app.pubProviders.size()-1; 14888 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14889 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14890 || procState > ActivityManager.PROCESS_STATE_TOP); 14891 provi--) { 14892 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14893 for (int i = cpr.connections.size()-1; 14894 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14895 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14896 || procState > ActivityManager.PROCESS_STATE_TOP); 14897 i--) { 14898 ContentProviderConnection conn = cpr.connections.get(i); 14899 ProcessRecord client = conn.client; 14900 if (client == app) { 14901 // Being our own client is not interesting. 14902 continue; 14903 } 14904 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14905 int clientProcState = client.curProcState; 14906 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14907 // If the other app is cached for any reason, for purposes here 14908 // we are going to consider it empty. 14909 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14910 } 14911 if (adj > clientAdj) { 14912 if (app.hasShownUi && app != mHomeProcess 14913 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14914 app.adjType = "cch-ui-provider"; 14915 } else { 14916 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14917 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 14918 app.adjType = "provider"; 14919 } 14920 app.cached &= client.cached; 14921 app.keeping |= client.keeping; 14922 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14923 .REASON_PROVIDER_IN_USE; 14924 app.adjSource = client; 14925 app.adjSourceOom = clientAdj; 14926 app.adjTarget = cpr.name; 14927 } 14928 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14929 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14930 // Special handling of clients who are in the top state. 14931 // We *may* want to consider this process to be in the 14932 // top state as well, but only if there is not another 14933 // reason for it to be running. Being on the top is a 14934 // special state, meaning you are specifically running 14935 // for the current top app. If the process is already 14936 // running in the background for some other reason, it 14937 // is more important to continue considering it to be 14938 // in the background state. 14939 mayBeTop = true; 14940 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14941 } else { 14942 // Special handling for above-top states (persistent 14943 // processes). These should not bring the current process 14944 // into the top state, since they are not on top. Instead 14945 // give them the best state after that. 14946 clientProcState = 14947 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14948 } 14949 } 14950 if (procState > clientProcState) { 14951 procState = clientProcState; 14952 } 14953 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14954 schedGroup = Process.THREAD_GROUP_DEFAULT; 14955 } 14956 } 14957 // If the provider has external (non-framework) process 14958 // dependencies, ensure that its adjustment is at least 14959 // FOREGROUND_APP_ADJ. 14960 if (cpr.hasExternalProcessHandles()) { 14961 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 14962 adj = ProcessList.FOREGROUND_APP_ADJ; 14963 schedGroup = Process.THREAD_GROUP_DEFAULT; 14964 app.cached = false; 14965 app.keeping = true; 14966 app.adjType = "provider"; 14967 app.adjTarget = cpr.name; 14968 } 14969 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 14970 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14971 } 14972 } 14973 } 14974 14975 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 14976 // A client of one of our services or providers is in the top state. We 14977 // *may* want to be in the top state, but not if we are already running in 14978 // the background for some other reason. For the decision here, we are going 14979 // to pick out a few specific states that we want to remain in when a client 14980 // is top (states that tend to be longer-term) and otherwise allow it to go 14981 // to the top state. 14982 switch (procState) { 14983 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 14984 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 14985 case ActivityManager.PROCESS_STATE_SERVICE: 14986 // These all are longer-term states, so pull them up to the top 14987 // of the background states, but not all the way to the top state. 14988 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14989 break; 14990 default: 14991 // Otherwise, top is a better choice, so take it. 14992 procState = ActivityManager.PROCESS_STATE_TOP; 14993 break; 14994 } 14995 } 14996 14997 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY && app.hasClientActivities) { 14998 // This is a cached process, but with client activities. Mark it so. 14999 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15000 app.adjType = "cch-client-act"; 15001 } 15002 15003 if (adj == ProcessList.SERVICE_ADJ) { 15004 if (doingAll) { 15005 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15006 mNewNumServiceProcs++; 15007 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15008 if (!app.serviceb) { 15009 // This service isn't far enough down on the LRU list to 15010 // normally be a B service, but if we are low on RAM and it 15011 // is large we want to force it down since we would prefer to 15012 // keep launcher over it. 15013 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15014 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15015 app.serviceHighRam = true; 15016 app.serviceb = true; 15017 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15018 } else { 15019 mNewNumAServiceProcs++; 15020 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15021 } 15022 } else { 15023 app.serviceHighRam = false; 15024 } 15025 } 15026 if (app.serviceb) { 15027 adj = ProcessList.SERVICE_B_ADJ; 15028 } 15029 } 15030 15031 app.curRawAdj = adj; 15032 15033 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15034 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15035 if (adj > app.maxAdj) { 15036 adj = app.maxAdj; 15037 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15038 schedGroup = Process.THREAD_GROUP_DEFAULT; 15039 } 15040 } 15041 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15042 app.keeping = true; 15043 } 15044 15045 // Do final modification to adj. Everything we do between here and applying 15046 // the final setAdj must be done in this function, because we will also use 15047 // it when computing the final cached adj later. Note that we don't need to 15048 // worry about this for max adj above, since max adj will always be used to 15049 // keep it out of the cached vaues. 15050 adj = app.modifyRawOomAdj(adj); 15051 15052 app.curProcState = procState; 15053 15054 int importance = app.memImportance; 15055 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15056 app.curAdj = adj; 15057 app.curSchedGroup = schedGroup; 15058 if (!interesting) { 15059 // For this reporting, if there is not something explicitly 15060 // interesting in this process then we will push it to the 15061 // background importance. 15062 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15063 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15064 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15065 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15066 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15067 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15068 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15069 } else if (adj >= ProcessList.SERVICE_ADJ) { 15070 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15071 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15072 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15073 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15074 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15075 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15076 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15077 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15078 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15079 } else { 15080 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15081 } 15082 } 15083 15084 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15085 if (foregroundActivities != app.foregroundActivities) { 15086 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15087 } 15088 if (changes != 0) { 15089 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15090 app.memImportance = importance; 15091 app.foregroundActivities = foregroundActivities; 15092 int i = mPendingProcessChanges.size()-1; 15093 ProcessChangeItem item = null; 15094 while (i >= 0) { 15095 item = mPendingProcessChanges.get(i); 15096 if (item.pid == app.pid) { 15097 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15098 break; 15099 } 15100 i--; 15101 } 15102 if (i < 0) { 15103 // No existing item in pending changes; need a new one. 15104 final int NA = mAvailProcessChanges.size(); 15105 if (NA > 0) { 15106 item = mAvailProcessChanges.remove(NA-1); 15107 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15108 } else { 15109 item = new ProcessChangeItem(); 15110 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15111 } 15112 item.changes = 0; 15113 item.pid = app.pid; 15114 item.uid = app.info.uid; 15115 if (mPendingProcessChanges.size() == 0) { 15116 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15117 "*** Enqueueing dispatch processes changed!"); 15118 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15119 } 15120 mPendingProcessChanges.add(item); 15121 } 15122 item.changes |= changes; 15123 item.importance = importance; 15124 item.foregroundActivities = foregroundActivities; 15125 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15126 + Integer.toHexString(System.identityHashCode(item)) 15127 + " " + app.toShortString() + ": changes=" + item.changes 15128 + " importance=" + item.importance 15129 + " foreground=" + item.foregroundActivities 15130 + " type=" + app.adjType + " source=" + app.adjSource 15131 + " target=" + app.adjTarget); 15132 } 15133 15134 return app.curRawAdj; 15135 } 15136 15137 /** 15138 * Schedule PSS collection of a process. 15139 */ 15140 void requestPssLocked(ProcessRecord proc, int procState) { 15141 if (mPendingPssProcesses.contains(proc)) { 15142 return; 15143 } 15144 if (mPendingPssProcesses.size() == 0) { 15145 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15146 } 15147 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15148 proc.pssProcState = procState; 15149 mPendingPssProcesses.add(proc); 15150 } 15151 15152 /** 15153 * Schedule PSS collection of all processes. 15154 */ 15155 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15156 if (!always) { 15157 if (now < (mLastFullPssTime + 15158 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15159 return; 15160 } 15161 } 15162 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15163 mLastFullPssTime = now; 15164 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15165 mPendingPssProcesses.clear(); 15166 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15167 ProcessRecord app = mLruProcesses.get(i); 15168 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15169 app.pssProcState = app.setProcState; 15170 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15171 mSleeping, now); 15172 mPendingPssProcesses.add(app); 15173 } 15174 } 15175 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15176 } 15177 15178 /** 15179 * Ask a given process to GC right now. 15180 */ 15181 final void performAppGcLocked(ProcessRecord app) { 15182 try { 15183 app.lastRequestedGc = SystemClock.uptimeMillis(); 15184 if (app.thread != null) { 15185 if (app.reportLowMemory) { 15186 app.reportLowMemory = false; 15187 app.thread.scheduleLowMemory(); 15188 } else { 15189 app.thread.processInBackground(); 15190 } 15191 } 15192 } catch (Exception e) { 15193 // whatever. 15194 } 15195 } 15196 15197 /** 15198 * Returns true if things are idle enough to perform GCs. 15199 */ 15200 private final boolean canGcNowLocked() { 15201 boolean processingBroadcasts = false; 15202 for (BroadcastQueue q : mBroadcastQueues) { 15203 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15204 processingBroadcasts = true; 15205 } 15206 } 15207 return !processingBroadcasts 15208 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15209 } 15210 15211 /** 15212 * Perform GCs on all processes that are waiting for it, but only 15213 * if things are idle. 15214 */ 15215 final void performAppGcsLocked() { 15216 final int N = mProcessesToGc.size(); 15217 if (N <= 0) { 15218 return; 15219 } 15220 if (canGcNowLocked()) { 15221 while (mProcessesToGc.size() > 0) { 15222 ProcessRecord proc = mProcessesToGc.remove(0); 15223 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15224 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15225 <= SystemClock.uptimeMillis()) { 15226 // To avoid spamming the system, we will GC processes one 15227 // at a time, waiting a few seconds between each. 15228 performAppGcLocked(proc); 15229 scheduleAppGcsLocked(); 15230 return; 15231 } else { 15232 // It hasn't been long enough since we last GCed this 15233 // process... put it in the list to wait for its time. 15234 addProcessToGcListLocked(proc); 15235 break; 15236 } 15237 } 15238 } 15239 15240 scheduleAppGcsLocked(); 15241 } 15242 } 15243 15244 /** 15245 * If all looks good, perform GCs on all processes waiting for them. 15246 */ 15247 final void performAppGcsIfAppropriateLocked() { 15248 if (canGcNowLocked()) { 15249 performAppGcsLocked(); 15250 return; 15251 } 15252 // Still not idle, wait some more. 15253 scheduleAppGcsLocked(); 15254 } 15255 15256 /** 15257 * Schedule the execution of all pending app GCs. 15258 */ 15259 final void scheduleAppGcsLocked() { 15260 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15261 15262 if (mProcessesToGc.size() > 0) { 15263 // Schedule a GC for the time to the next process. 15264 ProcessRecord proc = mProcessesToGc.get(0); 15265 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15266 15267 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15268 long now = SystemClock.uptimeMillis(); 15269 if (when < (now+GC_TIMEOUT)) { 15270 when = now + GC_TIMEOUT; 15271 } 15272 mHandler.sendMessageAtTime(msg, when); 15273 } 15274 } 15275 15276 /** 15277 * Add a process to the array of processes waiting to be GCed. Keeps the 15278 * list in sorted order by the last GC time. The process can't already be 15279 * on the list. 15280 */ 15281 final void addProcessToGcListLocked(ProcessRecord proc) { 15282 boolean added = false; 15283 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15284 if (mProcessesToGc.get(i).lastRequestedGc < 15285 proc.lastRequestedGc) { 15286 added = true; 15287 mProcessesToGc.add(i+1, proc); 15288 break; 15289 } 15290 } 15291 if (!added) { 15292 mProcessesToGc.add(0, proc); 15293 } 15294 } 15295 15296 /** 15297 * Set up to ask a process to GC itself. This will either do it 15298 * immediately, or put it on the list of processes to gc the next 15299 * time things are idle. 15300 */ 15301 final void scheduleAppGcLocked(ProcessRecord app) { 15302 long now = SystemClock.uptimeMillis(); 15303 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15304 return; 15305 } 15306 if (!mProcessesToGc.contains(app)) { 15307 addProcessToGcListLocked(app); 15308 scheduleAppGcsLocked(); 15309 } 15310 } 15311 15312 final void checkExcessivePowerUsageLocked(boolean doKills) { 15313 updateCpuStatsNow(); 15314 15315 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15316 boolean doWakeKills = doKills; 15317 boolean doCpuKills = doKills; 15318 if (mLastPowerCheckRealtime == 0) { 15319 doWakeKills = false; 15320 } 15321 if (mLastPowerCheckUptime == 0) { 15322 doCpuKills = false; 15323 } 15324 if (stats.isScreenOn()) { 15325 doWakeKills = false; 15326 } 15327 final long curRealtime = SystemClock.elapsedRealtime(); 15328 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15329 final long curUptime = SystemClock.uptimeMillis(); 15330 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15331 mLastPowerCheckRealtime = curRealtime; 15332 mLastPowerCheckUptime = curUptime; 15333 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15334 doWakeKills = false; 15335 } 15336 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15337 doCpuKills = false; 15338 } 15339 int i = mLruProcesses.size(); 15340 while (i > 0) { 15341 i--; 15342 ProcessRecord app = mLruProcesses.get(i); 15343 if (!app.keeping) { 15344 long wtime; 15345 synchronized (stats) { 15346 wtime = stats.getProcessWakeTime(app.info.uid, 15347 app.pid, curRealtime); 15348 } 15349 long wtimeUsed = wtime - app.lastWakeTime; 15350 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15351 if (DEBUG_POWER) { 15352 StringBuilder sb = new StringBuilder(128); 15353 sb.append("Wake for "); 15354 app.toShortString(sb); 15355 sb.append(": over "); 15356 TimeUtils.formatDuration(realtimeSince, sb); 15357 sb.append(" used "); 15358 TimeUtils.formatDuration(wtimeUsed, sb); 15359 sb.append(" ("); 15360 sb.append((wtimeUsed*100)/realtimeSince); 15361 sb.append("%)"); 15362 Slog.i(TAG, sb.toString()); 15363 sb.setLength(0); 15364 sb.append("CPU for "); 15365 app.toShortString(sb); 15366 sb.append(": over "); 15367 TimeUtils.formatDuration(uptimeSince, sb); 15368 sb.append(" used "); 15369 TimeUtils.formatDuration(cputimeUsed, sb); 15370 sb.append(" ("); 15371 sb.append((cputimeUsed*100)/uptimeSince); 15372 sb.append("%)"); 15373 Slog.i(TAG, sb.toString()); 15374 } 15375 // If a process has held a wake lock for more 15376 // than 50% of the time during this period, 15377 // that sounds bad. Kill! 15378 if (doWakeKills && realtimeSince > 0 15379 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15380 synchronized (stats) { 15381 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15382 realtimeSince, wtimeUsed); 15383 } 15384 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15385 + " during " + realtimeSince); 15386 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15387 } else if (doCpuKills && uptimeSince > 0 15388 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15389 synchronized (stats) { 15390 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15391 uptimeSince, cputimeUsed); 15392 } 15393 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15394 + " during " + uptimeSince); 15395 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15396 } else { 15397 app.lastWakeTime = wtime; 15398 app.lastCpuTime = app.curCpuTime; 15399 } 15400 } 15401 } 15402 } 15403 15404 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15405 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15406 boolean success = true; 15407 15408 if (app.curRawAdj != app.setRawAdj) { 15409 if (wasKeeping && !app.keeping) { 15410 // This app is no longer something we want to keep. Note 15411 // its current wake lock time to later know to kill it if 15412 // it is not behaving well. 15413 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15414 synchronized (stats) { 15415 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15416 app.pid, SystemClock.elapsedRealtime()); 15417 } 15418 app.lastCpuTime = app.curCpuTime; 15419 } 15420 15421 app.setRawAdj = app.curRawAdj; 15422 } 15423 15424 if (app.curAdj != app.setAdj) { 15425 ProcessList.setOomAdj(app.pid, app.curAdj); 15426 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15427 TAG, "Set " + app.pid + " " + app.processName + 15428 " adj " + app.curAdj + ": " + app.adjType); 15429 app.setAdj = app.curAdj; 15430 } 15431 15432 if (app.setSchedGroup != app.curSchedGroup) { 15433 app.setSchedGroup = app.curSchedGroup; 15434 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15435 "Setting process group of " + app.processName 15436 + " to " + app.curSchedGroup); 15437 if (app.waitingToKill != null && 15438 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15439 killUnneededProcessLocked(app, app.waitingToKill); 15440 success = false; 15441 } else { 15442 if (true) { 15443 long oldId = Binder.clearCallingIdentity(); 15444 try { 15445 Process.setProcessGroup(app.pid, app.curSchedGroup); 15446 } catch (Exception e) { 15447 Slog.w(TAG, "Failed setting process group of " + app.pid 15448 + " to " + app.curSchedGroup); 15449 e.printStackTrace(); 15450 } finally { 15451 Binder.restoreCallingIdentity(oldId); 15452 } 15453 } else { 15454 if (app.thread != null) { 15455 try { 15456 app.thread.setSchedulingGroup(app.curSchedGroup); 15457 } catch (RemoteException e) { 15458 } 15459 } 15460 } 15461 Process.setSwappiness(app.pid, 15462 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15463 } 15464 } 15465 if (app.repProcState != app.curProcState) { 15466 app.repProcState = app.curProcState; 15467 if (!reportingProcessState && app.thread != null) { 15468 try { 15469 if (false) { 15470 //RuntimeException h = new RuntimeException("here"); 15471 Slog.i(TAG, "Sending new process state " + app.repProcState 15472 + " to " + app /*, h*/); 15473 } 15474 app.thread.setProcessState(app.repProcState); 15475 } catch (RemoteException e) { 15476 } 15477 } 15478 } 15479 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15480 app.setProcState)) { 15481 app.lastStateTime = now; 15482 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15483 mSleeping, now); 15484 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15485 + ProcessList.makeProcStateString(app.setProcState) + " to " 15486 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15487 + (app.nextPssTime-now) + ": " + app); 15488 } else { 15489 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15490 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15491 requestPssLocked(app, app.setProcState); 15492 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15493 mSleeping, now); 15494 } else if (false && DEBUG_PSS) { 15495 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15496 } 15497 } 15498 if (app.setProcState != app.curProcState) { 15499 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15500 "Proc state change of " + app.processName 15501 + " to " + app.curProcState); 15502 app.setProcState = app.curProcState; 15503 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15504 app.notCachedSinceIdle = false; 15505 } 15506 if (!doingAll) { 15507 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15508 } else { 15509 app.procStateChanged = true; 15510 } 15511 } 15512 return success; 15513 } 15514 15515 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15516 if (proc.thread != null && proc.baseProcessTracker != null) { 15517 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15518 } 15519 } 15520 15521 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15522 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15523 if (app.thread == null) { 15524 return false; 15525 } 15526 15527 final boolean wasKeeping = app.keeping; 15528 15529 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15530 15531 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15532 reportingProcessState, now); 15533 } 15534 15535 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15536 boolean oomAdj) { 15537 if (isForeground != proc.foregroundServices) { 15538 proc.foregroundServices = isForeground; 15539 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15540 proc.info.uid); 15541 if (isForeground) { 15542 if (curProcs == null) { 15543 curProcs = new ArrayList<ProcessRecord>(); 15544 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15545 } 15546 if (!curProcs.contains(proc)) { 15547 curProcs.add(proc); 15548 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15549 proc.info.packageName, proc.info.uid); 15550 } 15551 } else { 15552 if (curProcs != null) { 15553 if (curProcs.remove(proc)) { 15554 mBatteryStatsService.noteEvent( 15555 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15556 proc.info.packageName, proc.info.uid); 15557 if (curProcs.size() <= 0) { 15558 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15559 } 15560 } 15561 } 15562 } 15563 if (oomAdj) { 15564 updateOomAdjLocked(); 15565 } 15566 } 15567 } 15568 15569 private final ActivityRecord resumedAppLocked() { 15570 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15571 String pkg; 15572 int uid; 15573 if (act != null) { 15574 pkg = act.packageName; 15575 uid = act.info.applicationInfo.uid; 15576 } else { 15577 pkg = null; 15578 uid = -1; 15579 } 15580 // Has the UID or resumed package name changed? 15581 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15582 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15583 if (mCurResumedPackage != null) { 15584 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15585 mCurResumedPackage, mCurResumedUid); 15586 } 15587 mCurResumedPackage = pkg; 15588 mCurResumedUid = uid; 15589 if (mCurResumedPackage != null) { 15590 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15591 mCurResumedPackage, mCurResumedUid); 15592 } 15593 } 15594 return act; 15595 } 15596 15597 final boolean updateOomAdjLocked(ProcessRecord app) { 15598 return updateOomAdjLocked(app, false); 15599 } 15600 15601 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15602 final ActivityRecord TOP_ACT = resumedAppLocked(); 15603 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15604 final boolean wasCached = app.cached; 15605 15606 mAdjSeq++; 15607 15608 // This is the desired cached adjusment we want to tell it to use. 15609 // If our app is currently cached, we know it, and that is it. Otherwise, 15610 // we don't know it yet, and it needs to now be cached we will then 15611 // need to do a complete oom adj. 15612 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15613 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15614 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15615 SystemClock.uptimeMillis()); 15616 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15617 // Changed to/from cached state, so apps after it in the LRU 15618 // list may also be changed. 15619 updateOomAdjLocked(); 15620 } 15621 return success; 15622 } 15623 15624 final void updateOomAdjLocked() { 15625 final ActivityRecord TOP_ACT = resumedAppLocked(); 15626 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15627 final long now = SystemClock.uptimeMillis(); 15628 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15629 final int N = mLruProcesses.size(); 15630 15631 if (false) { 15632 RuntimeException e = new RuntimeException(); 15633 e.fillInStackTrace(); 15634 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15635 } 15636 15637 mAdjSeq++; 15638 mNewNumServiceProcs = 0; 15639 mNewNumAServiceProcs = 0; 15640 15641 final int emptyProcessLimit; 15642 final int cachedProcessLimit; 15643 if (mProcessLimit <= 0) { 15644 emptyProcessLimit = cachedProcessLimit = 0; 15645 } else if (mProcessLimit == 1) { 15646 emptyProcessLimit = 1; 15647 cachedProcessLimit = 0; 15648 } else { 15649 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15650 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15651 } 15652 15653 // Let's determine how many processes we have running vs. 15654 // how many slots we have for background processes; we may want 15655 // to put multiple processes in a slot of there are enough of 15656 // them. 15657 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15658 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15659 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15660 if (numEmptyProcs > cachedProcessLimit) { 15661 // If there are more empty processes than our limit on cached 15662 // processes, then use the cached process limit for the factor. 15663 // This ensures that the really old empty processes get pushed 15664 // down to the bottom, so if we are running low on memory we will 15665 // have a better chance at keeping around more cached processes 15666 // instead of a gazillion empty processes. 15667 numEmptyProcs = cachedProcessLimit; 15668 } 15669 int emptyFactor = numEmptyProcs/numSlots; 15670 if (emptyFactor < 1) emptyFactor = 1; 15671 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15672 if (cachedFactor < 1) cachedFactor = 1; 15673 int stepCached = 0; 15674 int stepEmpty = 0; 15675 int numCached = 0; 15676 int numEmpty = 0; 15677 int numTrimming = 0; 15678 15679 mNumNonCachedProcs = 0; 15680 mNumCachedHiddenProcs = 0; 15681 15682 // First update the OOM adjustment for each of the 15683 // application processes based on their current state. 15684 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15685 int nextCachedAdj = curCachedAdj+1; 15686 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15687 int nextEmptyAdj = curEmptyAdj+2; 15688 for (int i=N-1; i>=0; i--) { 15689 ProcessRecord app = mLruProcesses.get(i); 15690 if (!app.killedByAm && app.thread != null) { 15691 app.procStateChanged = false; 15692 final boolean wasKeeping = app.keeping; 15693 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15694 15695 // If we haven't yet assigned the final cached adj 15696 // to the process, do that now. 15697 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15698 switch (app.curProcState) { 15699 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15700 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15701 // This process is a cached process holding activities... 15702 // assign it the next cached value for that type, and then 15703 // step that cached level. 15704 app.curRawAdj = curCachedAdj; 15705 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15706 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15707 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15708 + ")"); 15709 if (curCachedAdj != nextCachedAdj) { 15710 stepCached++; 15711 if (stepCached >= cachedFactor) { 15712 stepCached = 0; 15713 curCachedAdj = nextCachedAdj; 15714 nextCachedAdj += 2; 15715 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15716 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15717 } 15718 } 15719 } 15720 break; 15721 default: 15722 // For everything else, assign next empty cached process 15723 // level and bump that up. Note that this means that 15724 // long-running services that have dropped down to the 15725 // cached level will be treated as empty (since their process 15726 // state is still as a service), which is what we want. 15727 app.curRawAdj = curEmptyAdj; 15728 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15729 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15730 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15731 + ")"); 15732 if (curEmptyAdj != nextEmptyAdj) { 15733 stepEmpty++; 15734 if (stepEmpty >= emptyFactor) { 15735 stepEmpty = 0; 15736 curEmptyAdj = nextEmptyAdj; 15737 nextEmptyAdj += 2; 15738 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15739 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15740 } 15741 } 15742 } 15743 break; 15744 } 15745 } 15746 15747 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15748 15749 // Count the number of process types. 15750 switch (app.curProcState) { 15751 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15752 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15753 mNumCachedHiddenProcs++; 15754 numCached++; 15755 if (numCached > cachedProcessLimit) { 15756 killUnneededProcessLocked(app, "cached #" + numCached); 15757 } 15758 break; 15759 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15760 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15761 && app.lastActivityTime < oldTime) { 15762 killUnneededProcessLocked(app, "empty for " 15763 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15764 / 1000) + "s"); 15765 } else { 15766 numEmpty++; 15767 if (numEmpty > emptyProcessLimit) { 15768 killUnneededProcessLocked(app, "empty #" + numEmpty); 15769 } 15770 } 15771 break; 15772 default: 15773 mNumNonCachedProcs++; 15774 break; 15775 } 15776 15777 if (app.isolated && app.services.size() <= 0) { 15778 // If this is an isolated process, and there are no 15779 // services running in it, then the process is no longer 15780 // needed. We agressively kill these because we can by 15781 // definition not re-use the same process again, and it is 15782 // good to avoid having whatever code was running in them 15783 // left sitting around after no longer needed. 15784 killUnneededProcessLocked(app, "isolated not needed"); 15785 } 15786 15787 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15788 && !app.killedByAm) { 15789 numTrimming++; 15790 } 15791 } 15792 } 15793 15794 mNumServiceProcs = mNewNumServiceProcs; 15795 15796 // Now determine the memory trimming level of background processes. 15797 // Unfortunately we need to start at the back of the list to do this 15798 // properly. We only do this if the number of background apps we 15799 // are managing to keep around is less than half the maximum we desire; 15800 // if we are keeping a good number around, we'll let them use whatever 15801 // memory they want. 15802 final int numCachedAndEmpty = numCached + numEmpty; 15803 int memFactor; 15804 if (numCached <= ProcessList.TRIM_CACHED_APPS 15805 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15806 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15807 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15808 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15809 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15810 } else { 15811 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15812 } 15813 } else { 15814 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15815 } 15816 // We always allow the memory level to go up (better). We only allow it to go 15817 // down if we are in a state where that is allowed, *and* the total number of processes 15818 // has gone down since last time. 15819 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15820 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15821 + " last=" + mLastNumProcesses); 15822 if (memFactor > mLastMemoryLevel) { 15823 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15824 memFactor = mLastMemoryLevel; 15825 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15826 } 15827 } 15828 mLastMemoryLevel = memFactor; 15829 mLastNumProcesses = mLruProcesses.size(); 15830 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15831 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15832 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15833 if (mLowRamStartTime == 0) { 15834 mLowRamStartTime = now; 15835 } 15836 int step = 0; 15837 int fgTrimLevel; 15838 switch (memFactor) { 15839 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15840 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15841 break; 15842 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15843 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15844 break; 15845 default: 15846 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15847 break; 15848 } 15849 int factor = numTrimming/3; 15850 int minFactor = 2; 15851 if (mHomeProcess != null) minFactor++; 15852 if (mPreviousProcess != null) minFactor++; 15853 if (factor < minFactor) factor = minFactor; 15854 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15855 for (int i=N-1; i>=0; i--) { 15856 ProcessRecord app = mLruProcesses.get(i); 15857 if (allChanged || app.procStateChanged) { 15858 setProcessTrackerState(app, trackerMemFactor, now); 15859 app.procStateChanged = false; 15860 } 15861 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15862 && !app.killedByAm) { 15863 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15864 try { 15865 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15866 "Trimming memory of " + app.processName 15867 + " to " + curLevel); 15868 app.thread.scheduleTrimMemory(curLevel); 15869 } catch (RemoteException e) { 15870 } 15871 if (false) { 15872 // For now we won't do this; our memory trimming seems 15873 // to be good enough at this point that destroying 15874 // activities causes more harm than good. 15875 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15876 && app != mHomeProcess && app != mPreviousProcess) { 15877 // Need to do this on its own message because the stack may not 15878 // be in a consistent state at this point. 15879 // For these apps we will also finish their activities 15880 // to help them free memory. 15881 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15882 } 15883 } 15884 } 15885 app.trimMemoryLevel = curLevel; 15886 step++; 15887 if (step >= factor) { 15888 step = 0; 15889 switch (curLevel) { 15890 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15891 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15892 break; 15893 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15894 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15895 break; 15896 } 15897 } 15898 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15899 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15900 && app.thread != null) { 15901 try { 15902 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15903 "Trimming memory of heavy-weight " + app.processName 15904 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15905 app.thread.scheduleTrimMemory( 15906 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15907 } catch (RemoteException e) { 15908 } 15909 } 15910 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15911 } else { 15912 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15913 || app.systemNoUi) && app.pendingUiClean) { 15914 // If this application is now in the background and it 15915 // had done UI, then give it the special trim level to 15916 // have it free UI resources. 15917 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 15918 if (app.trimMemoryLevel < level && app.thread != null) { 15919 try { 15920 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15921 "Trimming memory of bg-ui " + app.processName 15922 + " to " + level); 15923 app.thread.scheduleTrimMemory(level); 15924 } catch (RemoteException e) { 15925 } 15926 } 15927 app.pendingUiClean = false; 15928 } 15929 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 15930 try { 15931 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15932 "Trimming memory of fg " + app.processName 15933 + " to " + fgTrimLevel); 15934 app.thread.scheduleTrimMemory(fgTrimLevel); 15935 } catch (RemoteException e) { 15936 } 15937 } 15938 app.trimMemoryLevel = fgTrimLevel; 15939 } 15940 } 15941 } else { 15942 if (mLowRamStartTime != 0) { 15943 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 15944 mLowRamStartTime = 0; 15945 } 15946 for (int i=N-1; i>=0; i--) { 15947 ProcessRecord app = mLruProcesses.get(i); 15948 if (allChanged || app.procStateChanged) { 15949 setProcessTrackerState(app, trackerMemFactor, now); 15950 app.procStateChanged = false; 15951 } 15952 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 15953 || app.systemNoUi) && app.pendingUiClean) { 15954 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 15955 && app.thread != null) { 15956 try { 15957 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15958 "Trimming memory of ui hidden " + app.processName 15959 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15960 app.thread.scheduleTrimMemory( 15961 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 15962 } catch (RemoteException e) { 15963 } 15964 } 15965 app.pendingUiClean = false; 15966 } 15967 app.trimMemoryLevel = 0; 15968 } 15969 } 15970 15971 if (mAlwaysFinishActivities) { 15972 // Need to do this on its own message because the stack may not 15973 // be in a consistent state at this point. 15974 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 15975 } 15976 15977 if (allChanged) { 15978 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 15979 } 15980 15981 if (mProcessStats.shouldWriteNowLocked(now)) { 15982 mHandler.post(new Runnable() { 15983 @Override public void run() { 15984 synchronized (ActivityManagerService.this) { 15985 mProcessStats.writeStateAsyncLocked(); 15986 } 15987 } 15988 }); 15989 } 15990 15991 if (DEBUG_OOM_ADJ) { 15992 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 15993 } 15994 } 15995 15996 final void trimApplications() { 15997 synchronized (this) { 15998 int i; 15999 16000 // First remove any unused application processes whose package 16001 // has been removed. 16002 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16003 final ProcessRecord app = mRemovedProcesses.get(i); 16004 if (app.activities.size() == 0 16005 && app.curReceiver == null && app.services.size() == 0) { 16006 Slog.i( 16007 TAG, "Exiting empty application process " 16008 + app.processName + " (" 16009 + (app.thread != null ? app.thread.asBinder() : null) 16010 + ")\n"); 16011 if (app.pid > 0 && app.pid != MY_PID) { 16012 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16013 app.processName, app.setAdj, "empty"); 16014 app.killedByAm = true; 16015 Process.killProcessQuiet(app.pid); 16016 } else { 16017 try { 16018 app.thread.scheduleExit(); 16019 } catch (Exception e) { 16020 // Ignore exceptions. 16021 } 16022 } 16023 cleanUpApplicationRecordLocked(app, false, true, -1); 16024 mRemovedProcesses.remove(i); 16025 16026 if (app.persistent) { 16027 if (app.persistent) { 16028 addAppLocked(app.info, false); 16029 } 16030 } 16031 } 16032 } 16033 16034 // Now update the oom adj for all processes. 16035 updateOomAdjLocked(); 16036 } 16037 } 16038 16039 /** This method sends the specified signal to each of the persistent apps */ 16040 public void signalPersistentProcesses(int sig) throws RemoteException { 16041 if (sig != Process.SIGNAL_USR1) { 16042 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16043 } 16044 16045 synchronized (this) { 16046 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16047 != PackageManager.PERMISSION_GRANTED) { 16048 throw new SecurityException("Requires permission " 16049 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16050 } 16051 16052 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16053 ProcessRecord r = mLruProcesses.get(i); 16054 if (r.thread != null && r.persistent) { 16055 Process.sendSignal(r.pid, sig); 16056 } 16057 } 16058 } 16059 } 16060 16061 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16062 if (proc == null || proc == mProfileProc) { 16063 proc = mProfileProc; 16064 path = mProfileFile; 16065 profileType = mProfileType; 16066 clearProfilerLocked(); 16067 } 16068 if (proc == null) { 16069 return; 16070 } 16071 try { 16072 proc.thread.profilerControl(false, path, null, profileType); 16073 } catch (RemoteException e) { 16074 throw new IllegalStateException("Process disappeared"); 16075 } 16076 } 16077 16078 private void clearProfilerLocked() { 16079 if (mProfileFd != null) { 16080 try { 16081 mProfileFd.close(); 16082 } catch (IOException e) { 16083 } 16084 } 16085 mProfileApp = null; 16086 mProfileProc = null; 16087 mProfileFile = null; 16088 mProfileType = 0; 16089 mAutoStopProfiler = false; 16090 } 16091 16092 public boolean profileControl(String process, int userId, boolean start, 16093 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16094 16095 try { 16096 synchronized (this) { 16097 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16098 // its own permission. 16099 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16100 != PackageManager.PERMISSION_GRANTED) { 16101 throw new SecurityException("Requires permission " 16102 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16103 } 16104 16105 if (start && fd == null) { 16106 throw new IllegalArgumentException("null fd"); 16107 } 16108 16109 ProcessRecord proc = null; 16110 if (process != null) { 16111 proc = findProcessLocked(process, userId, "profileControl"); 16112 } 16113 16114 if (start && (proc == null || proc.thread == null)) { 16115 throw new IllegalArgumentException("Unknown process: " + process); 16116 } 16117 16118 if (start) { 16119 stopProfilerLocked(null, null, 0); 16120 setProfileApp(proc.info, proc.processName, path, fd, false); 16121 mProfileProc = proc; 16122 mProfileType = profileType; 16123 try { 16124 fd = fd.dup(); 16125 } catch (IOException e) { 16126 fd = null; 16127 } 16128 proc.thread.profilerControl(start, path, fd, profileType); 16129 fd = null; 16130 mProfileFd = null; 16131 } else { 16132 stopProfilerLocked(proc, path, profileType); 16133 if (fd != null) { 16134 try { 16135 fd.close(); 16136 } catch (IOException e) { 16137 } 16138 } 16139 } 16140 16141 return true; 16142 } 16143 } catch (RemoteException e) { 16144 throw new IllegalStateException("Process disappeared"); 16145 } finally { 16146 if (fd != null) { 16147 try { 16148 fd.close(); 16149 } catch (IOException e) { 16150 } 16151 } 16152 } 16153 } 16154 16155 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16156 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16157 userId, true, true, callName, null); 16158 ProcessRecord proc = null; 16159 try { 16160 int pid = Integer.parseInt(process); 16161 synchronized (mPidsSelfLocked) { 16162 proc = mPidsSelfLocked.get(pid); 16163 } 16164 } catch (NumberFormatException e) { 16165 } 16166 16167 if (proc == null) { 16168 ArrayMap<String, SparseArray<ProcessRecord>> all 16169 = mProcessNames.getMap(); 16170 SparseArray<ProcessRecord> procs = all.get(process); 16171 if (procs != null && procs.size() > 0) { 16172 proc = procs.valueAt(0); 16173 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16174 for (int i=1; i<procs.size(); i++) { 16175 ProcessRecord thisProc = procs.valueAt(i); 16176 if (thisProc.userId == userId) { 16177 proc = thisProc; 16178 break; 16179 } 16180 } 16181 } 16182 } 16183 } 16184 16185 return proc; 16186 } 16187 16188 public boolean dumpHeap(String process, int userId, boolean managed, 16189 String path, ParcelFileDescriptor fd) throws RemoteException { 16190 16191 try { 16192 synchronized (this) { 16193 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16194 // its own permission (same as profileControl). 16195 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16196 != PackageManager.PERMISSION_GRANTED) { 16197 throw new SecurityException("Requires permission " 16198 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16199 } 16200 16201 if (fd == null) { 16202 throw new IllegalArgumentException("null fd"); 16203 } 16204 16205 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16206 if (proc == null || proc.thread == null) { 16207 throw new IllegalArgumentException("Unknown process: " + process); 16208 } 16209 16210 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16211 if (!isDebuggable) { 16212 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16213 throw new SecurityException("Process not debuggable: " + proc); 16214 } 16215 } 16216 16217 proc.thread.dumpHeap(managed, path, fd); 16218 fd = null; 16219 return true; 16220 } 16221 } catch (RemoteException e) { 16222 throw new IllegalStateException("Process disappeared"); 16223 } finally { 16224 if (fd != null) { 16225 try { 16226 fd.close(); 16227 } catch (IOException e) { 16228 } 16229 } 16230 } 16231 } 16232 16233 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16234 public void monitor() { 16235 synchronized (this) { } 16236 } 16237 16238 void onCoreSettingsChange(Bundle settings) { 16239 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16240 ProcessRecord processRecord = mLruProcesses.get(i); 16241 try { 16242 if (processRecord.thread != null) { 16243 processRecord.thread.setCoreSettings(settings); 16244 } 16245 } catch (RemoteException re) { 16246 /* ignore */ 16247 } 16248 } 16249 } 16250 16251 // Multi-user methods 16252 16253 /** 16254 * Start user, if its not already running, but don't bring it to foreground. 16255 */ 16256 @Override 16257 public boolean startUserInBackground(final int userId) { 16258 return startUser(userId, /* foreground */ false); 16259 } 16260 16261 /** 16262 * Refreshes the list of users related to the current user when either a 16263 * user switch happens or when a new related user is started in the 16264 * background. 16265 */ 16266 private void updateRelatedUserIdsLocked() { 16267 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16268 int[] relatedUserIds = new int[relatedUsers.size()]; // relatedUsers will not be null 16269 for (int i = 0; i < relatedUserIds.length; i++) { 16270 relatedUserIds[i] = relatedUsers.get(i).id; 16271 } 16272 mRelatedUserIds = relatedUserIds; 16273 } 16274 16275 private Set getRelatedUsersLocked(int userId) { 16276 Set userIds = new HashSet<Integer>(); 16277 final List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(userId); 16278 for (UserInfo user : relatedUsers) { 16279 userIds.add(Integer.valueOf(user.id)); 16280 } 16281 return userIds; 16282 } 16283 16284 @Override 16285 public boolean switchUser(final int userId) { 16286 return startUser(userId, /* foregound */ true); 16287 } 16288 16289 private boolean startUser(final int userId, boolean foreground) { 16290 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16291 != PackageManager.PERMISSION_GRANTED) { 16292 String msg = "Permission Denial: switchUser() from pid=" 16293 + Binder.getCallingPid() 16294 + ", uid=" + Binder.getCallingUid() 16295 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16296 Slog.w(TAG, msg); 16297 throw new SecurityException(msg); 16298 } 16299 16300 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16301 16302 final long ident = Binder.clearCallingIdentity(); 16303 try { 16304 synchronized (this) { 16305 final int oldUserId = mCurrentUserId; 16306 if (oldUserId == userId) { 16307 return true; 16308 } 16309 16310 mStackSupervisor.setLockTaskModeLocked(null); 16311 16312 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16313 if (userInfo == null) { 16314 Slog.w(TAG, "No user info for user #" + userId); 16315 return false; 16316 } 16317 16318 if (foreground) { 16319 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16320 R.anim.screen_user_enter); 16321 } 16322 16323 boolean needStart = false; 16324 16325 // If the user we are switching to is not currently started, then 16326 // we need to start it now. 16327 if (mStartedUsers.get(userId) == null) { 16328 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16329 updateStartedUserArrayLocked(); 16330 needStart = true; 16331 } 16332 16333 final Integer userIdInt = Integer.valueOf(userId); 16334 mUserLru.remove(userIdInt); 16335 mUserLru.add(userIdInt); 16336 16337 if (foreground) { 16338 mCurrentUserId = userId; 16339 updateRelatedUserIdsLocked(); 16340 mWindowManager.setCurrentUser(userId, mRelatedUserIds); 16341 // Once the internal notion of the active user has switched, we lock the device 16342 // with the option to show the user switcher on the keyguard. 16343 mWindowManager.lockNow(null); 16344 } else { 16345 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16346 updateRelatedUserIdsLocked(); 16347 mWindowManager.updateRelatedUserIds(mRelatedUserIds); 16348 mUserLru.remove(currentUserIdInt); 16349 mUserLru.add(currentUserIdInt); 16350 } 16351 16352 final UserStartedState uss = mStartedUsers.get(userId); 16353 16354 // Make sure user is in the started state. If it is currently 16355 // stopping, we need to knock that off. 16356 if (uss.mState == UserStartedState.STATE_STOPPING) { 16357 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16358 // so we can just fairly silently bring the user back from 16359 // the almost-dead. 16360 uss.mState = UserStartedState.STATE_RUNNING; 16361 updateStartedUserArrayLocked(); 16362 needStart = true; 16363 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16364 // This means ACTION_SHUTDOWN has been sent, so we will 16365 // need to treat this as a new boot of the user. 16366 uss.mState = UserStartedState.STATE_BOOTING; 16367 updateStartedUserArrayLocked(); 16368 needStart = true; 16369 } 16370 16371 if (foreground) { 16372 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16373 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16374 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16375 oldUserId, userId, uss)); 16376 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16377 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16378 } 16379 16380 if (needStart) { 16381 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16382 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16383 | Intent.FLAG_RECEIVER_FOREGROUND); 16384 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16385 broadcastIntentLocked(null, null, intent, 16386 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16387 false, false, MY_PID, Process.SYSTEM_UID, userId); 16388 } 16389 16390 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16391 if (userId != 0) { 16392 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16393 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16394 broadcastIntentLocked(null, null, intent, null, 16395 new IIntentReceiver.Stub() { 16396 public void performReceive(Intent intent, int resultCode, 16397 String data, Bundle extras, boolean ordered, 16398 boolean sticky, int sendingUser) { 16399 userInitialized(uss, userId); 16400 } 16401 }, 0, null, null, null, AppOpsManager.OP_NONE, 16402 true, false, MY_PID, Process.SYSTEM_UID, 16403 userId); 16404 uss.initializing = true; 16405 } else { 16406 getUserManagerLocked().makeInitialized(userInfo.id); 16407 } 16408 } 16409 16410 if (foreground) { 16411 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16412 if (homeInFront) { 16413 startHomeActivityLocked(userId); 16414 } else { 16415 mStackSupervisor.resumeTopActivitiesLocked(); 16416 } 16417 EventLogTags.writeAmSwitchUser(userId); 16418 getUserManagerLocked().userForeground(userId); 16419 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16420 } 16421 16422 if (needStart) { 16423 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16424 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16425 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16426 broadcastIntentLocked(null, null, intent, 16427 null, new IIntentReceiver.Stub() { 16428 @Override 16429 public void performReceive(Intent intent, int resultCode, String data, 16430 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16431 throws RemoteException { 16432 } 16433 }, 0, null, null, 16434 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16435 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16436 } 16437 } 16438 } finally { 16439 Binder.restoreCallingIdentity(ident); 16440 } 16441 16442 return true; 16443 } 16444 16445 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16446 long ident = Binder.clearCallingIdentity(); 16447 try { 16448 Intent intent; 16449 if (oldUserId >= 0) { 16450 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16451 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16452 | Intent.FLAG_RECEIVER_FOREGROUND); 16453 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16454 broadcastIntentLocked(null, null, intent, 16455 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16456 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16457 } 16458 if (newUserId >= 0) { 16459 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16460 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16461 | Intent.FLAG_RECEIVER_FOREGROUND); 16462 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16463 broadcastIntentLocked(null, null, intent, 16464 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16465 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16466 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16467 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16468 | Intent.FLAG_RECEIVER_FOREGROUND); 16469 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16470 broadcastIntentLocked(null, null, intent, 16471 null, null, 0, null, null, 16472 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16473 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16474 } 16475 } finally { 16476 Binder.restoreCallingIdentity(ident); 16477 } 16478 } 16479 16480 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16481 final int newUserId) { 16482 final int N = mUserSwitchObservers.beginBroadcast(); 16483 if (N > 0) { 16484 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16485 int mCount = 0; 16486 @Override 16487 public void sendResult(Bundle data) throws RemoteException { 16488 synchronized (ActivityManagerService.this) { 16489 if (mCurUserSwitchCallback == this) { 16490 mCount++; 16491 if (mCount == N) { 16492 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16493 } 16494 } 16495 } 16496 } 16497 }; 16498 synchronized (this) { 16499 uss.switching = true; 16500 mCurUserSwitchCallback = callback; 16501 } 16502 for (int i=0; i<N; i++) { 16503 try { 16504 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16505 newUserId, callback); 16506 } catch (RemoteException e) { 16507 } 16508 } 16509 } else { 16510 synchronized (this) { 16511 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16512 } 16513 } 16514 mUserSwitchObservers.finishBroadcast(); 16515 } 16516 16517 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16518 synchronized (this) { 16519 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16520 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16521 } 16522 } 16523 16524 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16525 mCurUserSwitchCallback = null; 16526 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16527 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16528 oldUserId, newUserId, uss)); 16529 } 16530 16531 void userInitialized(UserStartedState uss, int newUserId) { 16532 completeSwitchAndInitalize(uss, newUserId, true, false); 16533 } 16534 16535 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16536 completeSwitchAndInitalize(uss, newUserId, false, true); 16537 } 16538 16539 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16540 boolean clearInitializing, boolean clearSwitching) { 16541 boolean unfrozen = false; 16542 synchronized (this) { 16543 if (clearInitializing) { 16544 uss.initializing = false; 16545 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16546 } 16547 if (clearSwitching) { 16548 uss.switching = false; 16549 } 16550 if (!uss.switching && !uss.initializing) { 16551 mWindowManager.stopFreezingScreen(); 16552 unfrozen = true; 16553 } 16554 } 16555 if (unfrozen) { 16556 final int N = mUserSwitchObservers.beginBroadcast(); 16557 for (int i=0; i<N; i++) { 16558 try { 16559 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16560 } catch (RemoteException e) { 16561 } 16562 } 16563 mUserSwitchObservers.finishBroadcast(); 16564 } 16565 } 16566 16567 void scheduleStartRelatedUsersLocked() { 16568 if (!mHandler.hasMessages(START_RELATED_USERS_MSG)) { 16569 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_RELATED_USERS_MSG), 16570 DateUtils.SECOND_IN_MILLIS); 16571 } 16572 } 16573 16574 void startRelatedUsersLocked() { 16575 if (DEBUG_MU) Slog.i(TAG_MU, "startRelatedUsersLocked"); 16576 List<UserInfo> relatedUsers = getUserManagerLocked().getRelatedUsers(mCurrentUserId); 16577 List<UserInfo> toStart = new ArrayList<UserInfo>(relatedUsers.size()); 16578 for (UserInfo relatedUser : relatedUsers) { 16579 if ((relatedUser.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED) { 16580 toStart.add(relatedUser); 16581 } 16582 } 16583 final int n = toStart.size(); 16584 int i = 0; 16585 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16586 startUserInBackground(toStart.get(i).id); 16587 } 16588 if (i < n) { 16589 Slog.w(TAG_MU, "More related users than MAX_RUNNING_USERS"); 16590 } 16591 } 16592 16593 void finishUserSwitch(UserStartedState uss) { 16594 synchronized (this) { 16595 if (uss.mState == UserStartedState.STATE_BOOTING 16596 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16597 uss.mState = UserStartedState.STATE_RUNNING; 16598 final int userId = uss.mHandle.getIdentifier(); 16599 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16600 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16601 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16602 broadcastIntentLocked(null, null, intent, 16603 null, null, 0, null, null, 16604 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16605 true, false, MY_PID, Process.SYSTEM_UID, userId); 16606 } 16607 16608 startRelatedUsersLocked(); 16609 16610 int num = mUserLru.size(); 16611 int i = 0; 16612 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16613 Integer oldUserId = mUserLru.get(i); 16614 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16615 if (oldUss == null) { 16616 // Shouldn't happen, but be sane if it does. 16617 mUserLru.remove(i); 16618 num--; 16619 continue; 16620 } 16621 if (oldUss.mState == UserStartedState.STATE_STOPPING 16622 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16623 // This user is already stopping, doesn't count. 16624 num--; 16625 i++; 16626 continue; 16627 } 16628 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16629 // Owner and current can't be stopped, but count as running. 16630 i++; 16631 continue; 16632 } 16633 // This is a user to be stopped. 16634 stopUserLocked(oldUserId, null); 16635 num--; 16636 i++; 16637 } 16638 } 16639 } 16640 16641 @Override 16642 public int stopUser(final int userId, final IStopUserCallback callback) { 16643 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16644 != PackageManager.PERMISSION_GRANTED) { 16645 String msg = "Permission Denial: switchUser() from pid=" 16646 + Binder.getCallingPid() 16647 + ", uid=" + Binder.getCallingUid() 16648 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16649 Slog.w(TAG, msg); 16650 throw new SecurityException(msg); 16651 } 16652 if (userId <= 0) { 16653 throw new IllegalArgumentException("Can't stop primary user " + userId); 16654 } 16655 synchronized (this) { 16656 return stopUserLocked(userId, callback); 16657 } 16658 } 16659 16660 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16661 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16662 if (mCurrentUserId == userId) { 16663 return ActivityManager.USER_OP_IS_CURRENT; 16664 } 16665 16666 final UserStartedState uss = mStartedUsers.get(userId); 16667 if (uss == null) { 16668 // User is not started, nothing to do... but we do need to 16669 // callback if requested. 16670 if (callback != null) { 16671 mHandler.post(new Runnable() { 16672 @Override 16673 public void run() { 16674 try { 16675 callback.userStopped(userId); 16676 } catch (RemoteException e) { 16677 } 16678 } 16679 }); 16680 } 16681 return ActivityManager.USER_OP_SUCCESS; 16682 } 16683 16684 if (callback != null) { 16685 uss.mStopCallbacks.add(callback); 16686 } 16687 16688 if (uss.mState != UserStartedState.STATE_STOPPING 16689 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16690 uss.mState = UserStartedState.STATE_STOPPING; 16691 updateStartedUserArrayLocked(); 16692 16693 long ident = Binder.clearCallingIdentity(); 16694 try { 16695 // We are going to broadcast ACTION_USER_STOPPING and then 16696 // once that is done send a final ACTION_SHUTDOWN and then 16697 // stop the user. 16698 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16699 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16700 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16701 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16702 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16703 // This is the result receiver for the final shutdown broadcast. 16704 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16705 @Override 16706 public void performReceive(Intent intent, int resultCode, String data, 16707 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16708 finishUserStop(uss); 16709 } 16710 }; 16711 // This is the result receiver for the initial stopping broadcast. 16712 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16713 @Override 16714 public void performReceive(Intent intent, int resultCode, String data, 16715 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16716 // On to the next. 16717 synchronized (ActivityManagerService.this) { 16718 if (uss.mState != UserStartedState.STATE_STOPPING) { 16719 // Whoops, we are being started back up. Abort, abort! 16720 return; 16721 } 16722 uss.mState = UserStartedState.STATE_SHUTDOWN; 16723 } 16724 broadcastIntentLocked(null, null, shutdownIntent, 16725 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16726 true, false, MY_PID, Process.SYSTEM_UID, userId); 16727 } 16728 }; 16729 // Kick things off. 16730 broadcastIntentLocked(null, null, stoppingIntent, 16731 null, stoppingReceiver, 0, null, null, 16732 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16733 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16734 } finally { 16735 Binder.restoreCallingIdentity(ident); 16736 } 16737 } 16738 16739 return ActivityManager.USER_OP_SUCCESS; 16740 } 16741 16742 void finishUserStop(UserStartedState uss) { 16743 final int userId = uss.mHandle.getIdentifier(); 16744 boolean stopped; 16745 ArrayList<IStopUserCallback> callbacks; 16746 synchronized (this) { 16747 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16748 if (mStartedUsers.get(userId) != uss) { 16749 stopped = false; 16750 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16751 stopped = false; 16752 } else { 16753 stopped = true; 16754 // User can no longer run. 16755 mStartedUsers.remove(userId); 16756 mUserLru.remove(Integer.valueOf(userId)); 16757 updateStartedUserArrayLocked(); 16758 16759 // Clean up all state and processes associated with the user. 16760 // Kill all the processes for the user. 16761 forceStopUserLocked(userId, "finish user"); 16762 } 16763 } 16764 16765 for (int i=0; i<callbacks.size(); i++) { 16766 try { 16767 if (stopped) callbacks.get(i).userStopped(userId); 16768 else callbacks.get(i).userStopAborted(userId); 16769 } catch (RemoteException e) { 16770 } 16771 } 16772 16773 mStackSupervisor.removeUserLocked(userId); 16774 } 16775 16776 @Override 16777 public UserInfo getCurrentUser() { 16778 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16779 != PackageManager.PERMISSION_GRANTED) && ( 16780 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16781 != PackageManager.PERMISSION_GRANTED)) { 16782 String msg = "Permission Denial: getCurrentUser() from pid=" 16783 + Binder.getCallingPid() 16784 + ", uid=" + Binder.getCallingUid() 16785 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16786 Slog.w(TAG, msg); 16787 throw new SecurityException(msg); 16788 } 16789 synchronized (this) { 16790 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16791 } 16792 } 16793 16794 int getCurrentUserIdLocked() { 16795 return mCurrentUserId; 16796 } 16797 16798 @Override 16799 public boolean isUserRunning(int userId, boolean orStopped) { 16800 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16801 != PackageManager.PERMISSION_GRANTED) { 16802 String msg = "Permission Denial: isUserRunning() from pid=" 16803 + Binder.getCallingPid() 16804 + ", uid=" + Binder.getCallingUid() 16805 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16806 Slog.w(TAG, msg); 16807 throw new SecurityException(msg); 16808 } 16809 synchronized (this) { 16810 return isUserRunningLocked(userId, orStopped); 16811 } 16812 } 16813 16814 boolean isUserRunningLocked(int userId, boolean orStopped) { 16815 UserStartedState state = mStartedUsers.get(userId); 16816 if (state == null) { 16817 return false; 16818 } 16819 if (orStopped) { 16820 return true; 16821 } 16822 return state.mState != UserStartedState.STATE_STOPPING 16823 && state.mState != UserStartedState.STATE_SHUTDOWN; 16824 } 16825 16826 @Override 16827 public int[] getRunningUserIds() { 16828 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16829 != PackageManager.PERMISSION_GRANTED) { 16830 String msg = "Permission Denial: isUserRunning() from pid=" 16831 + Binder.getCallingPid() 16832 + ", uid=" + Binder.getCallingUid() 16833 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16834 Slog.w(TAG, msg); 16835 throw new SecurityException(msg); 16836 } 16837 synchronized (this) { 16838 return mStartedUserArray; 16839 } 16840 } 16841 16842 private void updateStartedUserArrayLocked() { 16843 int num = 0; 16844 for (int i=0; i<mStartedUsers.size(); i++) { 16845 UserStartedState uss = mStartedUsers.valueAt(i); 16846 // This list does not include stopping users. 16847 if (uss.mState != UserStartedState.STATE_STOPPING 16848 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16849 num++; 16850 } 16851 } 16852 mStartedUserArray = new int[num]; 16853 num = 0; 16854 for (int i=0; i<mStartedUsers.size(); i++) { 16855 UserStartedState uss = mStartedUsers.valueAt(i); 16856 if (uss.mState != UserStartedState.STATE_STOPPING 16857 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16858 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16859 num++; 16860 } 16861 } 16862 } 16863 16864 @Override 16865 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16866 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16867 != PackageManager.PERMISSION_GRANTED) { 16868 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16869 + Binder.getCallingPid() 16870 + ", uid=" + Binder.getCallingUid() 16871 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16872 Slog.w(TAG, msg); 16873 throw new SecurityException(msg); 16874 } 16875 16876 mUserSwitchObservers.register(observer); 16877 } 16878 16879 @Override 16880 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16881 mUserSwitchObservers.unregister(observer); 16882 } 16883 16884 private boolean userExists(int userId) { 16885 if (userId == 0) { 16886 return true; 16887 } 16888 UserManagerService ums = getUserManagerLocked(); 16889 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16890 } 16891 16892 int[] getUsersLocked() { 16893 UserManagerService ums = getUserManagerLocked(); 16894 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16895 } 16896 16897 UserManagerService getUserManagerLocked() { 16898 if (mUserManager == null) { 16899 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16900 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16901 } 16902 return mUserManager; 16903 } 16904 16905 private int applyUserId(int uid, int userId) { 16906 return UserHandle.getUid(userId, uid); 16907 } 16908 16909 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 16910 if (info == null) return null; 16911 ApplicationInfo newInfo = new ApplicationInfo(info); 16912 newInfo.uid = applyUserId(info.uid, userId); 16913 newInfo.dataDir = USER_DATA_DIR + userId + "/" 16914 + info.packageName; 16915 return newInfo; 16916 } 16917 16918 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 16919 if (aInfo == null 16920 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 16921 return aInfo; 16922 } 16923 16924 ActivityInfo info = new ActivityInfo(aInfo); 16925 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 16926 return info; 16927 } 16928} 16929