ActivityManagerService.java revision 846318a3250fa95f47a9decfbffb05a31dbd0006
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.readBooleanAttribute; 21import static com.android.internal.util.XmlUtils.readIntAttribute; 22import static com.android.internal.util.XmlUtils.readLongAttribute; 23import static com.android.internal.util.XmlUtils.writeBooleanAttribute; 24import static com.android.internal.util.XmlUtils.writeIntAttribute; 25import static com.android.internal.util.XmlUtils.writeLongAttribute; 26import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; 27import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; 28import static org.xmlpull.v1.XmlPullParser.START_TAG; 29import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID; 30 31import android.app.AppOpsManager; 32import android.app.IActivityContainer; 33import android.app.IActivityContainerCallback; 34import android.appwidget.AppWidgetManager; 35import android.graphics.Rect; 36import android.os.BatteryStats; 37import android.util.ArrayMap; 38 39import com.android.internal.R; 40import com.android.internal.annotations.GuardedBy; 41import com.android.internal.app.IAppOpsService; 42import com.android.internal.app.ProcessMap; 43import com.android.internal.app.ProcessStats; 44import com.android.internal.os.BackgroundThread; 45import com.android.internal.os.BatteryStatsImpl; 46import com.android.internal.os.ProcessCpuTracker; 47import com.android.internal.os.TransferPipe; 48import com.android.internal.os.Zygote; 49import com.android.internal.util.FastPrintWriter; 50import com.android.internal.util.FastXmlSerializer; 51import com.android.internal.util.MemInfoReader; 52import com.android.internal.util.Preconditions; 53import com.android.server.AppOpsService; 54import com.android.server.AttributeCache; 55import com.android.server.IntentResolver; 56import com.android.server.LocalServices; 57import com.android.server.ServiceThread; 58import com.android.server.SystemService; 59import com.android.server.Watchdog; 60import com.android.server.am.ActivityStack.ActivityState; 61import com.android.server.firewall.IntentFirewall; 62import com.android.server.pm.UserManagerService; 63import com.android.server.wm.AppTransition; 64import com.android.server.wm.WindowManagerService; 65import com.google.android.collect.Lists; 66import com.google.android.collect.Maps; 67 68import libcore.io.IoUtils; 69 70import org.xmlpull.v1.XmlPullParser; 71import org.xmlpull.v1.XmlPullParserException; 72import org.xmlpull.v1.XmlSerializer; 73 74import android.app.Activity; 75import android.app.ActivityManager; 76import android.app.ActivityManager.RunningTaskInfo; 77import android.app.ActivityManager.StackInfo; 78import android.app.ActivityManagerInternal; 79import android.app.ActivityManagerNative; 80import android.app.ActivityOptions; 81import android.app.ActivityThread; 82import android.app.AlertDialog; 83import android.app.AppGlobals; 84import android.app.ApplicationErrorReport; 85import android.app.Dialog; 86import android.app.IActivityController; 87import android.app.IApplicationThread; 88import android.app.IInstrumentationWatcher; 89import android.app.INotificationManager; 90import android.app.IProcessObserver; 91import android.app.IServiceConnection; 92import android.app.IStopUserCallback; 93import android.app.IThumbnailReceiver; 94import android.app.IUiAutomationConnection; 95import android.app.IUserSwitchObserver; 96import android.app.Instrumentation; 97import android.app.Notification; 98import android.app.NotificationManager; 99import android.app.PendingIntent; 100import android.app.backup.IBackupManager; 101import android.content.ActivityNotFoundException; 102import android.content.BroadcastReceiver; 103import android.content.ClipData; 104import android.content.ComponentCallbacks2; 105import android.content.ComponentName; 106import android.content.ContentProvider; 107import android.content.ContentResolver; 108import android.content.Context; 109import android.content.DialogInterface; 110import android.content.IContentProvider; 111import android.content.IIntentReceiver; 112import android.content.IIntentSender; 113import android.content.Intent; 114import android.content.IntentFilter; 115import android.content.IntentSender; 116import android.content.pm.ActivityInfo; 117import android.content.pm.ApplicationInfo; 118import android.content.pm.ConfigurationInfo; 119import android.content.pm.IPackageDataObserver; 120import android.content.pm.IPackageManager; 121import android.content.pm.InstrumentationInfo; 122import android.content.pm.PackageInfo; 123import android.content.pm.PackageManager; 124import android.content.pm.ParceledListSlice; 125import android.content.pm.UserInfo; 126import android.content.pm.PackageManager.NameNotFoundException; 127import android.content.pm.PathPermission; 128import android.content.pm.ProviderInfo; 129import android.content.pm.ResolveInfo; 130import android.content.pm.ServiceInfo; 131import android.content.res.CompatibilityInfo; 132import android.content.res.Configuration; 133import android.graphics.Bitmap; 134import android.net.Proxy; 135import android.net.ProxyProperties; 136import android.net.Uri; 137import android.os.Binder; 138import android.os.Build; 139import android.os.Bundle; 140import android.os.Debug; 141import android.os.DropBoxManager; 142import android.os.Environment; 143import android.os.FactoryTest; 144import android.os.FileObserver; 145import android.os.FileUtils; 146import android.os.Handler; 147import android.os.IBinder; 148import android.os.IPermissionController; 149import android.os.IRemoteCallback; 150import android.os.IUserManager; 151import android.os.Looper; 152import android.os.Message; 153import android.os.Parcel; 154import android.os.ParcelFileDescriptor; 155import android.os.Process; 156import android.os.RemoteCallbackList; 157import android.os.RemoteException; 158import android.os.SELinux; 159import android.os.ServiceManager; 160import android.os.StrictMode; 161import android.os.SystemClock; 162import android.os.SystemProperties; 163import android.os.UpdateLock; 164import android.os.UserHandle; 165import android.provider.Settings; 166import android.text.format.DateUtils; 167import android.text.format.Time; 168import android.util.AtomicFile; 169import android.util.EventLog; 170import android.util.Log; 171import android.util.Pair; 172import android.util.PrintWriterPrinter; 173import android.util.Slog; 174import android.util.SparseArray; 175import android.util.TimeUtils; 176import android.util.Xml; 177import android.view.Gravity; 178import android.view.LayoutInflater; 179import android.view.View; 180import android.view.WindowManager; 181 182import java.io.BufferedInputStream; 183import java.io.BufferedOutputStream; 184import java.io.DataInputStream; 185import java.io.DataOutputStream; 186import java.io.File; 187import java.io.FileDescriptor; 188import java.io.FileInputStream; 189import java.io.FileNotFoundException; 190import java.io.FileOutputStream; 191import java.io.IOException; 192import java.io.InputStreamReader; 193import java.io.PrintWriter; 194import java.io.StringWriter; 195import java.lang.ref.WeakReference; 196import java.util.ArrayList; 197import java.util.Arrays; 198import java.util.Collections; 199import java.util.Comparator; 200import java.util.HashMap; 201import java.util.HashSet; 202import java.util.Iterator; 203import java.util.List; 204import java.util.Locale; 205import java.util.Map; 206import java.util.Set; 207import java.util.concurrent.atomic.AtomicBoolean; 208import java.util.concurrent.atomic.AtomicLong; 209 210public final class ActivityManagerService extends ActivityManagerNative 211 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { 212 private static final String USER_DATA_DIR = "/data/user/"; 213 static final String TAG = "ActivityManager"; 214 static final String TAG_MU = "ActivityManagerServiceMU"; 215 static final boolean DEBUG = false; 216 static final boolean localLOGV = DEBUG; 217 static final boolean DEBUG_BACKUP = localLOGV || false; 218 static final boolean DEBUG_BROADCAST = localLOGV || false; 219 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false; 220 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false; 221 static final boolean DEBUG_CLEANUP = localLOGV || false; 222 static final boolean DEBUG_CONFIGURATION = localLOGV || false; 223 static final boolean DEBUG_FOCUS = false; 224 static final boolean DEBUG_IMMERSIVE = localLOGV || false; 225 static final boolean DEBUG_MU = localLOGV || false; 226 static final boolean DEBUG_OOM_ADJ = localLOGV || false; 227 static final boolean DEBUG_LRU = localLOGV || false; 228 static final boolean DEBUG_PAUSE = localLOGV || false; 229 static final boolean DEBUG_POWER = localLOGV || false; 230 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false; 231 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false; 232 static final boolean DEBUG_PROCESSES = localLOGV || false; 233 static final boolean DEBUG_PROVIDER = localLOGV || false; 234 static final boolean DEBUG_RESULTS = localLOGV || false; 235 static final boolean DEBUG_SERVICE = localLOGV || false; 236 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false; 237 static final boolean DEBUG_STACK = localLOGV || false; 238 static final boolean DEBUG_SWITCH = localLOGV || false; 239 static final boolean DEBUG_TASKS = localLOGV || false; 240 static final boolean DEBUG_THUMBNAILS = localLOGV || false; 241 static final boolean DEBUG_TRANSITION = localLOGV || false; 242 static final boolean DEBUG_URI_PERMISSION = localLOGV || false; 243 static final boolean DEBUG_USER_LEAVING = localLOGV || false; 244 static final boolean DEBUG_VISBILITY = localLOGV || false; 245 static final boolean DEBUG_PSS = localLOGV || false; 246 static final boolean DEBUG_LOCKSCREEN = localLOGV || false; 247 static final boolean VALIDATE_TOKENS = false; 248 static final boolean SHOW_ACTIVITY_START_TIME = true; 249 250 // Control over CPU and battery monitoring. 251 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes. 252 static final boolean MONITOR_CPU_USAGE = true; 253 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds. 254 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample. 255 static final boolean MONITOR_THREAD_CPU_USAGE = false; 256 257 // The flags that are set for all calls we make to the package manager. 258 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES; 259 260 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable"; 261 262 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); 263 264 // Maximum number of recent tasks that we can remember. 265 static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 10 : 20; 266 267 // Amount of time after a call to stopAppSwitches() during which we will 268 // prevent further untrusted switches from happening. 269 static final long APP_SWITCH_DELAY_TIME = 5*1000; 270 271 // How long we wait for a launched process to attach to the activity manager 272 // before we decide it's never going to come up for real. 273 static final int PROC_START_TIMEOUT = 10*1000; 274 275 // How long we wait for a launched process to attach to the activity manager 276 // before we decide it's never going to come up for real, when the process was 277 // started with a wrapper for instrumentation (such as Valgrind) because it 278 // could take much longer than usual. 279 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; 280 281 // How long to wait after going idle before forcing apps to GC. 282 static final int GC_TIMEOUT = 5*1000; 283 284 // The minimum amount of time between successive GC requests for a process. 285 static final int GC_MIN_INTERVAL = 60*1000; 286 287 // The minimum amount of time between successive PSS requests for a process. 288 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000; 289 290 // The minimum amount of time between successive PSS requests for a process 291 // when the request is due to the memory state being lowered. 292 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000; 293 294 // The rate at which we check for apps using excessive power -- 15 mins. 295 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000; 296 297 // The minimum sample duration we will allow before deciding we have 298 // enough data on wake locks to start killing things. 299 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 300 301 // The minimum sample duration we will allow before deciding we have 302 // enough data on CPU usage to start killing things. 303 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000; 304 305 // How long we allow a receiver to run before giving up on it. 306 static final int BROADCAST_FG_TIMEOUT = 10*1000; 307 static final int BROADCAST_BG_TIMEOUT = 60*1000; 308 309 // How long we wait until we timeout on key dispatching. 310 static final int KEY_DISPATCHING_TIMEOUT = 5*1000; 311 312 // How long we wait until we timeout on key dispatching during instrumentation. 313 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000; 314 315 // Amount of time we wait for observers to handle a user switch before 316 // giving up on them and unfreezing the screen. 317 static final int USER_SWITCH_TIMEOUT = 2*1000; 318 319 // Maximum number of users we allow to be running at a time. 320 static final int MAX_RUNNING_USERS = 3; 321 322 // How long to wait in getAssistContextExtras for the activity and foreground services 323 // to respond with the result. 324 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500; 325 326 // Maximum number of persisted Uri grants a package is allowed 327 static final int MAX_PERSISTED_URI_GRANTS = 128; 328 329 static final int MY_PID = Process.myPid(); 330 331 static final String[] EMPTY_STRING_ARRAY = new String[0]; 332 333 // How many bytes to write into the dropbox log before truncating 334 static final int DROPBOX_MAX_SIZE = 256 * 1024; 335 336 /** Run all ActivityStacks through this */ 337 ActivityStackSupervisor mStackSupervisor; 338 339 public IntentFirewall mIntentFirewall; 340 341 // Whether we should show our dialogs (ANR, crash, etc) or just perform their 342 // default actuion automatically. Important for devices without direct input 343 // devices. 344 private boolean mShowDialogs = true; 345 346 /** 347 * Description of a request to start a new activity, which has been held 348 * due to app switches being disabled. 349 */ 350 static class PendingActivityLaunch { 351 final ActivityRecord r; 352 final ActivityRecord sourceRecord; 353 final int startFlags; 354 final ActivityStack stack; 355 356 PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, 357 int _startFlags, ActivityStack _stack) { 358 r = _r; 359 sourceRecord = _sourceRecord; 360 startFlags = _startFlags; 361 stack = _stack; 362 } 363 } 364 365 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches 366 = new ArrayList<PendingActivityLaunch>(); 367 368 BroadcastQueue mFgBroadcastQueue; 369 BroadcastQueue mBgBroadcastQueue; 370 // Convenient for easy iteration over the queues. Foreground is first 371 // so that dispatch of foreground broadcasts gets precedence. 372 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2]; 373 374 BroadcastQueue broadcastQueueForIntent(Intent intent) { 375 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0; 376 if (DEBUG_BACKGROUND_BROADCAST) { 377 Slog.i(TAG, "Broadcast intent " + intent + " on " 378 + (isFg ? "foreground" : "background") 379 + " queue"); 380 } 381 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue; 382 } 383 384 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) { 385 for (BroadcastQueue queue : mBroadcastQueues) { 386 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver); 387 if (r != null) { 388 return r; 389 } 390 } 391 return null; 392 } 393 394 /** 395 * Activity we have told the window manager to have key focus. 396 */ 397 ActivityRecord mFocusedActivity = null; 398 399 /** 400 * List of intents that were used to start the most recent tasks. 401 */ 402 private final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>(); 403 404 public class PendingAssistExtras extends Binder implements Runnable { 405 public final ActivityRecord activity; 406 public boolean haveResult = false; 407 public Bundle result = null; 408 public PendingAssistExtras(ActivityRecord _activity) { 409 activity = _activity; 410 } 411 @Override 412 public void run() { 413 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity); 414 synchronized (this) { 415 haveResult = true; 416 notifyAll(); 417 } 418 } 419 } 420 421 final ArrayList<PendingAssistExtras> mPendingAssistExtras 422 = new ArrayList<PendingAssistExtras>(); 423 424 /** 425 * Process management. 426 */ 427 final ProcessList mProcessList = new ProcessList(); 428 429 /** 430 * All of the applications we currently have running organized by name. 431 * The keys are strings of the application package name (as 432 * returned by the package manager), and the keys are ApplicationRecord 433 * objects. 434 */ 435 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>(); 436 437 /** 438 * Tracking long-term execution of processes to look for abuse and other 439 * bad app behavior. 440 */ 441 final ProcessStatsService mProcessStats; 442 443 /** 444 * The currently running isolated processes. 445 */ 446 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>(); 447 448 /** 449 * Counter for assigning isolated process uids, to avoid frequently reusing the 450 * same ones. 451 */ 452 int mNextIsolatedProcessUid = 0; 453 454 /** 455 * The currently running heavy-weight process, if any. 456 */ 457 ProcessRecord mHeavyWeightProcess = null; 458 459 /** 460 * The last time that various processes have crashed. 461 */ 462 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>(); 463 464 /** 465 * Information about a process that is currently marked as bad. 466 */ 467 static final class BadProcessInfo { 468 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) { 469 this.time = time; 470 this.shortMsg = shortMsg; 471 this.longMsg = longMsg; 472 this.stack = stack; 473 } 474 475 final long time; 476 final String shortMsg; 477 final String longMsg; 478 final String stack; 479 } 480 481 /** 482 * Set of applications that we consider to be bad, and will reject 483 * incoming broadcasts from (which the user has no control over). 484 * Processes are added to this set when they have crashed twice within 485 * a minimum amount of time; they are removed from it when they are 486 * later restarted (hopefully due to some user action). The value is the 487 * time it was added to the list. 488 */ 489 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>(); 490 491 /** 492 * All of the processes we currently have running organized by pid. 493 * The keys are the pid running the application. 494 * 495 * <p>NOTE: This object is protected by its own lock, NOT the global 496 * activity manager lock! 497 */ 498 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>(); 499 500 /** 501 * All of the processes that have been forced to be foreground. The key 502 * is the pid of the caller who requested it (we hold a death 503 * link on it). 504 */ 505 abstract class ForegroundToken implements IBinder.DeathRecipient { 506 int pid; 507 IBinder token; 508 } 509 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>(); 510 511 /** 512 * List of records for processes that someone had tried to start before the 513 * system was ready. We don't start them at that point, but ensure they 514 * are started by the time booting is complete. 515 */ 516 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>(); 517 518 /** 519 * List of persistent applications that are in the process 520 * of being started. 521 */ 522 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>(); 523 524 /** 525 * Processes that are being forcibly torn down. 526 */ 527 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 528 529 /** 530 * List of running applications, sorted by recent usage. 531 * The first entry in the list is the least recently used. 532 */ 533 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 534 535 /** 536 * Where in mLruProcesses that the processes hosting activities start. 537 */ 538 int mLruProcessActivityStart = 0; 539 540 /** 541 * Where in mLruProcesses that the processes hosting services start. 542 * This is after (lower index) than mLruProcessesActivityStart. 543 */ 544 int mLruProcessServiceStart = 0; 545 546 /** 547 * List of processes that should gc as soon as things are idle. 548 */ 549 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>(); 550 551 /** 552 * Processes we want to collect PSS data from. 553 */ 554 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>(); 555 556 /** 557 * Last time we requested PSS data of all processes. 558 */ 559 long mLastFullPssTime = SystemClock.uptimeMillis(); 560 561 /** 562 * This is the process holding what we currently consider to be 563 * the "home" activity. 564 */ 565 ProcessRecord mHomeProcess; 566 567 /** 568 * This is the process holding the activity the user last visited that 569 * is in a different process from the one they are currently in. 570 */ 571 ProcessRecord mPreviousProcess; 572 573 /** 574 * The time at which the previous process was last visible. 575 */ 576 long mPreviousProcessVisibleTime; 577 578 /** 579 * Which uses have been started, so are allowed to run code. 580 */ 581 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>(); 582 583 /** 584 * LRU list of history of current users. Most recently current is at the end. 585 */ 586 final ArrayList<Integer> mUserLru = new ArrayList<Integer>(); 587 588 /** 589 * Constant array of the users that are currently started. 590 */ 591 int[] mStartedUserArray = new int[] { 0 }; 592 593 /** 594 * Registered observers of the user switching mechanics. 595 */ 596 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers 597 = new RemoteCallbackList<IUserSwitchObserver>(); 598 599 /** 600 * Currently active user switch. 601 */ 602 Object mCurUserSwitchCallback; 603 604 /** 605 * Packages that the user has asked to have run in screen size 606 * compatibility mode instead of filling the screen. 607 */ 608 final CompatModePackages mCompatModePackages; 609 610 /** 611 * Set of IntentSenderRecord objects that are currently active. 612 */ 613 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords 614 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>(); 615 616 /** 617 * Fingerprints (hashCode()) of stack traces that we've 618 * already logged DropBox entries for. Guarded by itself. If 619 * something (rogue user app) forces this over 620 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared. 621 */ 622 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>(); 623 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000; 624 625 /** 626 * Strict Mode background batched logging state. 627 * 628 * The string buffer is guarded by itself, and its lock is also 629 * used to determine if another batched write is already 630 * in-flight. 631 */ 632 private final StringBuilder mStrictModeBuffer = new StringBuilder(); 633 634 /** 635 * Keeps track of all IIntentReceivers that have been registered for 636 * broadcasts. Hash keys are the receiver IBinder, hash value is 637 * a ReceiverList. 638 */ 639 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = 640 new HashMap<IBinder, ReceiverList>(); 641 642 /** 643 * Resolver for broadcast intents to registered receivers. 644 * Holds BroadcastFilter (subclass of IntentFilter). 645 */ 646 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver 647 = new IntentResolver<BroadcastFilter, BroadcastFilter>() { 648 @Override 649 protected boolean allowFilterResult( 650 BroadcastFilter filter, List<BroadcastFilter> dest) { 651 IBinder target = filter.receiverList.receiver.asBinder(); 652 for (int i=dest.size()-1; i>=0; i--) { 653 if (dest.get(i).receiverList.receiver.asBinder() == target) { 654 return false; 655 } 656 } 657 return true; 658 } 659 660 @Override 661 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) { 662 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL 663 || userId == filter.owningUserId) { 664 return super.newResult(filter, match, userId); 665 } 666 return null; 667 } 668 669 @Override 670 protected BroadcastFilter[] newArray(int size) { 671 return new BroadcastFilter[size]; 672 } 673 674 @Override 675 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) { 676 return packageName.equals(filter.packageName); 677 } 678 }; 679 680 /** 681 * State of all active sticky broadcasts per user. Keys are the action of the 682 * sticky Intent, values are an ArrayList of all broadcasted intents with 683 * that action (which should usually be one). The SparseArray is keyed 684 * by the user ID the sticky is for, and can include UserHandle.USER_ALL 685 * for stickies that are sent to all users. 686 */ 687 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts = 688 new SparseArray<ArrayMap<String, ArrayList<Intent>>>(); 689 690 final ActiveServices mServices; 691 692 /** 693 * Backup/restore process management 694 */ 695 String mBackupAppName = null; 696 BackupRecord mBackupTarget = null; 697 698 /** 699 * List of PendingThumbnailsRecord objects of clients who are still 700 * waiting to receive all of the thumbnails for a task. 701 */ 702 final ArrayList<PendingThumbnailsRecord> mPendingThumbnails = 703 new ArrayList<PendingThumbnailsRecord>(); 704 705 final ProviderMap mProviderMap; 706 707 /** 708 * List of content providers who have clients waiting for them. The 709 * application is currently being launched and the provider will be 710 * removed from this list once it is published. 711 */ 712 final ArrayList<ContentProviderRecord> mLaunchingProviders 713 = new ArrayList<ContentProviderRecord>(); 714 715 /** 716 * File storing persisted {@link #mGrantedUriPermissions}. 717 */ 718 private final AtomicFile mGrantFile; 719 720 /** XML constants used in {@link #mGrantFile} */ 721 private static final String TAG_URI_GRANTS = "uri-grants"; 722 private static final String TAG_URI_GRANT = "uri-grant"; 723 private static final String ATTR_USER_HANDLE = "userHandle"; 724 private static final String ATTR_SOURCE_PKG = "sourcePkg"; 725 private static final String ATTR_TARGET_PKG = "targetPkg"; 726 private static final String ATTR_URI = "uri"; 727 private static final String ATTR_MODE_FLAGS = "modeFlags"; 728 private static final String ATTR_CREATED_TIME = "createdTime"; 729 private static final String ATTR_PREFIX = "prefix"; 730 731 /** 732 * Global set of specific {@link Uri} permissions that have been granted. 733 * This optimized lookup structure maps from {@link UriPermission#targetUid} 734 * to {@link UriPermission#uri} to {@link UriPermission}. 735 */ 736 @GuardedBy("this") 737 private final SparseArray<ArrayMap<GrantUri, UriPermission>> 738 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>(); 739 740 public static class GrantUri { 741 public final Uri uri; 742 public final boolean prefix; 743 744 public GrantUri(Uri uri, boolean prefix) { 745 this.uri = uri; 746 this.prefix = prefix; 747 } 748 749 @Override 750 public int hashCode() { 751 return toString().hashCode(); 752 } 753 754 @Override 755 public boolean equals(Object o) { 756 if (o instanceof GrantUri) { 757 GrantUri other = (GrantUri) o; 758 return uri.equals(other.uri) && prefix == other.prefix; 759 } 760 return false; 761 } 762 763 @Override 764 public String toString() { 765 if (prefix) { 766 return uri.toString() + " [prefix]"; 767 } else { 768 return uri.toString(); 769 } 770 } 771 } 772 773 CoreSettingsObserver mCoreSettingsObserver; 774 775 /** 776 * Thread-local storage used to carry caller permissions over through 777 * indirect content-provider access. 778 */ 779 private class Identity { 780 public int pid; 781 public int uid; 782 783 Identity(int _pid, int _uid) { 784 pid = _pid; 785 uid = _uid; 786 } 787 } 788 789 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>(); 790 791 /** 792 * All information we have collected about the runtime performance of 793 * any user id that can impact battery performance. 794 */ 795 final BatteryStatsService mBatteryStatsService; 796 797 /** 798 * Information about component usage 799 */ 800 final UsageStatsService mUsageStatsService; 801 802 /** 803 * Information about and control over application operations 804 */ 805 final AppOpsService mAppOpsService; 806 807 /** 808 * Current configuration information. HistoryRecord objects are given 809 * a reference to this object to indicate which configuration they are 810 * currently running in, so this object must be kept immutable. 811 */ 812 Configuration mConfiguration = new Configuration(); 813 814 /** 815 * Current sequencing integer of the configuration, for skipping old 816 * configurations. 817 */ 818 int mConfigurationSeq = 0; 819 820 /** 821 * Hardware-reported OpenGLES version. 822 */ 823 final int GL_ES_VERSION; 824 825 /** 826 * List of initialization arguments to pass to all processes when binding applications to them. 827 * For example, references to the commonly used services. 828 */ 829 HashMap<String, IBinder> mAppBindArgs; 830 831 /** 832 * Temporary to avoid allocations. Protected by main lock. 833 */ 834 final StringBuilder mStringBuilder = new StringBuilder(256); 835 836 /** 837 * Used to control how we initialize the service. 838 */ 839 ComponentName mTopComponent; 840 String mTopAction = Intent.ACTION_MAIN; 841 String mTopData; 842 boolean mProcessesReady = false; 843 boolean mSystemReady = false; 844 boolean mBooting = false; 845 boolean mWaitingUpdate = false; 846 boolean mDidUpdate = false; 847 boolean mOnBattery = false; 848 boolean mLaunchWarningShown = false; 849 850 Context mContext; 851 852 int mFactoryTest; 853 854 boolean mCheckedForSetup; 855 856 /** 857 * The time at which we will allow normal application switches again, 858 * after a call to {@link #stopAppSwitches()}. 859 */ 860 long mAppSwitchesAllowedTime; 861 862 /** 863 * This is set to true after the first switch after mAppSwitchesAllowedTime 864 * is set; any switches after that will clear the time. 865 */ 866 boolean mDidAppSwitch; 867 868 /** 869 * Last time (in realtime) at which we checked for power usage. 870 */ 871 long mLastPowerCheckRealtime; 872 873 /** 874 * Last time (in uptime) at which we checked for power usage. 875 */ 876 long mLastPowerCheckUptime; 877 878 /** 879 * Set while we are wanting to sleep, to prevent any 880 * activities from being started/resumed. 881 */ 882 boolean mSleeping = false; 883 884 /** 885 * State of external calls telling us if the device is asleep. 886 */ 887 boolean mWentToSleep = false; 888 889 /** 890 * State of external call telling us if the lock screen is shown. 891 */ 892 boolean mLockScreenShown = false; 893 894 /** 895 * Set if we are shutting down the system, similar to sleeping. 896 */ 897 boolean mShuttingDown = false; 898 899 /** 900 * Current sequence id for oom_adj computation traversal. 901 */ 902 int mAdjSeq = 0; 903 904 /** 905 * Current sequence id for process LRU updating. 906 */ 907 int mLruSeq = 0; 908 909 /** 910 * Keep track of the non-cached/empty process we last found, to help 911 * determine how to distribute cached/empty processes next time. 912 */ 913 int mNumNonCachedProcs = 0; 914 915 /** 916 * Keep track of the number of cached hidden procs, to balance oom adj 917 * distribution between those and empty procs. 918 */ 919 int mNumCachedHiddenProcs = 0; 920 921 /** 922 * Keep track of the number of service processes we last found, to 923 * determine on the next iteration which should be B services. 924 */ 925 int mNumServiceProcs = 0; 926 int mNewNumAServiceProcs = 0; 927 int mNewNumServiceProcs = 0; 928 929 /** 930 * Allow the current computed overall memory level of the system to go down? 931 * This is set to false when we are killing processes for reasons other than 932 * memory management, so that the now smaller process list will not be taken as 933 * an indication that memory is tighter. 934 */ 935 boolean mAllowLowerMemLevel = false; 936 937 /** 938 * The last computed memory level, for holding when we are in a state that 939 * processes are going away for other reasons. 940 */ 941 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 942 943 /** 944 * The last total number of process we have, to determine if changes actually look 945 * like a shrinking number of process due to lower RAM. 946 */ 947 int mLastNumProcesses; 948 949 /** 950 * The uptime of the last time we performed idle maintenance. 951 */ 952 long mLastIdleTime = SystemClock.uptimeMillis(); 953 954 /** 955 * Total time spent with RAM that has been added in the past since the last idle time. 956 */ 957 long mLowRamTimeSinceLastIdle = 0; 958 959 /** 960 * If RAM is currently low, when that horrible situation started. 961 */ 962 long mLowRamStartTime = 0; 963 964 /** 965 * For reporting to battery stats the current top application. 966 */ 967 private String mCurResumedPackage = null; 968 private int mCurResumedUid = -1; 969 970 /** 971 * For reporting to battery stats the apps currently running foreground 972 * service. The ProcessMap is package/uid tuples; each of these contain 973 * an array of the currently foreground processes. 974 */ 975 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages 976 = new ProcessMap<ArrayList<ProcessRecord>>(); 977 978 /** 979 * This is set if we had to do a delayed dexopt of an app before launching 980 * it, to increasing the ANR timeouts in that case. 981 */ 982 boolean mDidDexOpt; 983 984 /** 985 * Set if the systemServer made a call to enterSafeMode. 986 */ 987 boolean mSafeMode; 988 989 String mDebugApp = null; 990 boolean mWaitForDebugger = false; 991 boolean mDebugTransient = false; 992 String mOrigDebugApp = null; 993 boolean mOrigWaitForDebugger = false; 994 boolean mAlwaysFinishActivities = false; 995 IActivityController mController = null; 996 String mProfileApp = null; 997 ProcessRecord mProfileProc = null; 998 String mProfileFile; 999 ParcelFileDescriptor mProfileFd; 1000 int mProfileType = 0; 1001 boolean mAutoStopProfiler = false; 1002 String mOpenGlTraceApp = null; 1003 1004 static class ProcessChangeItem { 1005 static final int CHANGE_ACTIVITIES = 1<<0; 1006 static final int CHANGE_IMPORTANCE= 1<<1; 1007 int changes; 1008 int uid; 1009 int pid; 1010 int importance; 1011 boolean foregroundActivities; 1012 } 1013 1014 final RemoteCallbackList<IProcessObserver> mProcessObservers 1015 = new RemoteCallbackList<IProcessObserver>(); 1016 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5]; 1017 1018 final ArrayList<ProcessChangeItem> mPendingProcessChanges 1019 = new ArrayList<ProcessChangeItem>(); 1020 final ArrayList<ProcessChangeItem> mAvailProcessChanges 1021 = new ArrayList<ProcessChangeItem>(); 1022 1023 /** 1024 * Runtime CPU use collection thread. This object's lock is used to 1025 * protect all related state. 1026 */ 1027 final Thread mProcessCpuThread; 1028 1029 /** 1030 * Used to collect process stats when showing not responding dialog. 1031 * Protected by mProcessCpuThread. 1032 */ 1033 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker( 1034 MONITOR_THREAD_CPU_USAGE); 1035 final AtomicLong mLastCpuTime = new AtomicLong(0); 1036 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true); 1037 1038 long mLastWriteTime = 0; 1039 1040 /** 1041 * Used to retain an update lock when the foreground activity is in 1042 * immersive mode. 1043 */ 1044 final UpdateLock mUpdateLock = new UpdateLock("immersive"); 1045 1046 /** 1047 * Set to true after the system has finished booting. 1048 */ 1049 boolean mBooted = false; 1050 1051 int mProcessLimit = ProcessList.MAX_CACHED_APPS; 1052 int mProcessLimitOverride = -1; 1053 1054 WindowManagerService mWindowManager; 1055 1056 final ActivityThread mSystemThread; 1057 1058 int mCurrentUserId = 0; 1059 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack 1060 private UserManagerService mUserManager; 1061 1062 private final class AppDeathRecipient implements IBinder.DeathRecipient { 1063 final ProcessRecord mApp; 1064 final int mPid; 1065 final IApplicationThread mAppThread; 1066 1067 AppDeathRecipient(ProcessRecord app, int pid, 1068 IApplicationThread thread) { 1069 if (localLOGV) Slog.v( 1070 TAG, "New death recipient " + this 1071 + " for thread " + thread.asBinder()); 1072 mApp = app; 1073 mPid = pid; 1074 mAppThread = thread; 1075 } 1076 1077 @Override 1078 public void binderDied() { 1079 if (localLOGV) Slog.v( 1080 TAG, "Death received in " + this 1081 + " for thread " + mAppThread.asBinder()); 1082 synchronized(ActivityManagerService.this) { 1083 appDiedLocked(mApp, mPid, mAppThread); 1084 } 1085 } 1086 } 1087 1088 static final int SHOW_ERROR_MSG = 1; 1089 static final int SHOW_NOT_RESPONDING_MSG = 2; 1090 static final int SHOW_FACTORY_ERROR_MSG = 3; 1091 static final int UPDATE_CONFIGURATION_MSG = 4; 1092 static final int GC_BACKGROUND_PROCESSES_MSG = 5; 1093 static final int WAIT_FOR_DEBUGGER_MSG = 6; 1094 static final int SERVICE_TIMEOUT_MSG = 12; 1095 static final int UPDATE_TIME_ZONE = 13; 1096 static final int SHOW_UID_ERROR_MSG = 14; 1097 static final int IM_FEELING_LUCKY_MSG = 15; 1098 static final int PROC_START_TIMEOUT_MSG = 20; 1099 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21; 1100 static final int KILL_APPLICATION_MSG = 22; 1101 static final int FINALIZE_PENDING_INTENT_MSG = 23; 1102 static final int POST_HEAVY_NOTIFICATION_MSG = 24; 1103 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25; 1104 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26; 1105 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27; 1106 static final int CLEAR_DNS_CACHE_MSG = 28; 1107 static final int UPDATE_HTTP_PROXY_MSG = 29; 1108 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30; 1109 static final int DISPATCH_PROCESSES_CHANGED = 31; 1110 static final int DISPATCH_PROCESS_DIED = 32; 1111 static final int REPORT_MEM_USAGE_MSG = 33; 1112 static final int REPORT_USER_SWITCH_MSG = 34; 1113 static final int CONTINUE_USER_SWITCH_MSG = 35; 1114 static final int USER_SWITCH_TIMEOUT_MSG = 36; 1115 static final int IMMERSIVE_MODE_LOCK_MSG = 37; 1116 static final int PERSIST_URI_GRANTS_MSG = 38; 1117 static final int REQUEST_ALL_PSS_MSG = 39; 1118 static final int START_PROFILES_MSG = 40; 1119 static final int UPDATE_TIME = 41; 1120 1121 static final int FIRST_ACTIVITY_STACK_MSG = 100; 1122 static final int FIRST_BROADCAST_QUEUE_MSG = 200; 1123 static final int FIRST_COMPAT_MODE_MSG = 300; 1124 static final int FIRST_SUPERVISOR_STACK_MSG = 100; 1125 1126 AlertDialog mUidAlert; 1127 CompatModeDialog mCompatModeDialog; 1128 long mLastMemUsageReportTime = 0; 1129 1130 /** 1131 * Flag whether the current user is a "monkey", i.e. whether 1132 * the UI is driven by a UI automation tool. 1133 */ 1134 private boolean mUserIsMonkey; 1135 1136 final ServiceThread mHandlerThread; 1137 final MainHandler mHandler; 1138 1139 final class MainHandler extends Handler { 1140 public MainHandler(Looper looper) { 1141 super(looper, null, true); 1142 } 1143 1144 @Override 1145 public void handleMessage(Message msg) { 1146 switch (msg.what) { 1147 case SHOW_ERROR_MSG: { 1148 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1149 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 1150 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 1151 synchronized (ActivityManagerService.this) { 1152 ProcessRecord proc = (ProcessRecord)data.get("app"); 1153 AppErrorResult res = (AppErrorResult) data.get("result"); 1154 if (proc != null && proc.crashDialog != null) { 1155 Slog.e(TAG, "App already has crash dialog: " + proc); 1156 if (res != null) { 1157 res.set(0); 1158 } 1159 return; 1160 } 1161 if (!showBackground && UserHandle.getAppId(proc.uid) 1162 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId 1163 && proc.pid != MY_PID) { 1164 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background"); 1165 if (res != null) { 1166 res.set(0); 1167 } 1168 return; 1169 } 1170 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1171 Dialog d = new AppErrorDialog(mContext, 1172 ActivityManagerService.this, res, proc); 1173 d.show(); 1174 proc.crashDialog = d; 1175 } else { 1176 // The device is asleep, so just pretend that the user 1177 // saw a crash dialog and hit "force quit". 1178 if (res != null) { 1179 res.set(0); 1180 } 1181 } 1182 } 1183 1184 ensureBootCompleted(); 1185 } break; 1186 case SHOW_NOT_RESPONDING_MSG: { 1187 synchronized (ActivityManagerService.this) { 1188 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1189 ProcessRecord proc = (ProcessRecord)data.get("app"); 1190 if (proc != null && proc.anrDialog != null) { 1191 Slog.e(TAG, "App already has anr dialog: " + proc); 1192 return; 1193 } 1194 1195 Intent intent = new Intent("android.intent.action.ANR"); 1196 if (!mProcessesReady) { 1197 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 1198 | Intent.FLAG_RECEIVER_FOREGROUND); 1199 } 1200 broadcastIntentLocked(null, null, intent, 1201 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 1202 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); 1203 1204 if (mShowDialogs) { 1205 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this, 1206 mContext, proc, (ActivityRecord)data.get("activity"), 1207 msg.arg1 != 0); 1208 d.show(); 1209 proc.anrDialog = d; 1210 } else { 1211 // Just kill the app if there is no dialog to be shown. 1212 killAppAtUsersRequest(proc, null); 1213 } 1214 } 1215 1216 ensureBootCompleted(); 1217 } break; 1218 case SHOW_STRICT_MODE_VIOLATION_MSG: { 1219 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; 1220 synchronized (ActivityManagerService.this) { 1221 ProcessRecord proc = (ProcessRecord) data.get("app"); 1222 if (proc == null) { 1223 Slog.e(TAG, "App not found when showing strict mode dialog."); 1224 break; 1225 } 1226 if (proc.crashDialog != null) { 1227 Slog.e(TAG, "App already has strict mode dialog: " + proc); 1228 return; 1229 } 1230 AppErrorResult res = (AppErrorResult) data.get("result"); 1231 if (mShowDialogs && !mSleeping && !mShuttingDown) { 1232 Dialog d = new StrictModeViolationDialog(mContext, 1233 ActivityManagerService.this, res, proc); 1234 d.show(); 1235 proc.crashDialog = d; 1236 } else { 1237 // The device is asleep, so just pretend that the user 1238 // saw a crash dialog and hit "force quit". 1239 res.set(0); 1240 } 1241 } 1242 ensureBootCompleted(); 1243 } break; 1244 case SHOW_FACTORY_ERROR_MSG: { 1245 Dialog d = new FactoryErrorDialog( 1246 mContext, msg.getData().getCharSequence("msg")); 1247 d.show(); 1248 ensureBootCompleted(); 1249 } break; 1250 case UPDATE_CONFIGURATION_MSG: { 1251 final ContentResolver resolver = mContext.getContentResolver(); 1252 Settings.System.putConfiguration(resolver, (Configuration)msg.obj); 1253 } break; 1254 case GC_BACKGROUND_PROCESSES_MSG: { 1255 synchronized (ActivityManagerService.this) { 1256 performAppGcsIfAppropriateLocked(); 1257 } 1258 } break; 1259 case WAIT_FOR_DEBUGGER_MSG: { 1260 synchronized (ActivityManagerService.this) { 1261 ProcessRecord app = (ProcessRecord)msg.obj; 1262 if (msg.arg1 != 0) { 1263 if (!app.waitedForDebugger) { 1264 Dialog d = new AppWaitingForDebuggerDialog( 1265 ActivityManagerService.this, 1266 mContext, app); 1267 app.waitDialog = d; 1268 app.waitedForDebugger = true; 1269 d.show(); 1270 } 1271 } else { 1272 if (app.waitDialog != null) { 1273 app.waitDialog.dismiss(); 1274 app.waitDialog = null; 1275 } 1276 } 1277 } 1278 } break; 1279 case SERVICE_TIMEOUT_MSG: { 1280 if (mDidDexOpt) { 1281 mDidDexOpt = false; 1282 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); 1283 nmsg.obj = msg.obj; 1284 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT); 1285 return; 1286 } 1287 mServices.serviceTimeout((ProcessRecord)msg.obj); 1288 } break; 1289 case UPDATE_TIME_ZONE: { 1290 synchronized (ActivityManagerService.this) { 1291 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1292 ProcessRecord r = mLruProcesses.get(i); 1293 if (r.thread != null) { 1294 try { 1295 r.thread.updateTimeZone(); 1296 } catch (RemoteException ex) { 1297 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName); 1298 } 1299 } 1300 } 1301 } 1302 } break; 1303 case CLEAR_DNS_CACHE_MSG: { 1304 synchronized (ActivityManagerService.this) { 1305 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1306 ProcessRecord r = mLruProcesses.get(i); 1307 if (r.thread != null) { 1308 try { 1309 r.thread.clearDnsCache(); 1310 } catch (RemoteException ex) { 1311 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 1312 } 1313 } 1314 } 1315 } 1316 } break; 1317 case UPDATE_HTTP_PROXY_MSG: { 1318 ProxyProperties proxy = (ProxyProperties)msg.obj; 1319 String host = ""; 1320 String port = ""; 1321 String exclList = ""; 1322 String pacFileUrl = null; 1323 if (proxy != null) { 1324 host = proxy.getHost(); 1325 port = Integer.toString(proxy.getPort()); 1326 exclList = proxy.getExclusionList(); 1327 pacFileUrl = proxy.getPacFileUrl(); 1328 } 1329 synchronized (ActivityManagerService.this) { 1330 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1331 ProcessRecord r = mLruProcesses.get(i); 1332 if (r.thread != null) { 1333 try { 1334 r.thread.setHttpProxy(host, port, exclList, pacFileUrl); 1335 } catch (RemoteException ex) { 1336 Slog.w(TAG, "Failed to update http proxy for: " + 1337 r.info.processName); 1338 } 1339 } 1340 } 1341 } 1342 } break; 1343 case SHOW_UID_ERROR_MSG: { 1344 String title = "System UIDs Inconsistent"; 1345 String text = "UIDs on the system are inconsistent, you need to wipe your" 1346 + " data partition or your device will be unstable."; 1347 Log.e(TAG, title + ": " + text); 1348 if (mShowDialogs) { 1349 // XXX This is a temporary dialog, no need to localize. 1350 AlertDialog d = new BaseErrorDialog(mContext); 1351 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); 1352 d.setCancelable(false); 1353 d.setTitle(title); 1354 d.setMessage(text); 1355 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky", 1356 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG)); 1357 mUidAlert = d; 1358 d.show(); 1359 } 1360 } break; 1361 case IM_FEELING_LUCKY_MSG: { 1362 if (mUidAlert != null) { 1363 mUidAlert.dismiss(); 1364 mUidAlert = null; 1365 } 1366 } break; 1367 case PROC_START_TIMEOUT_MSG: { 1368 if (mDidDexOpt) { 1369 mDidDexOpt = false; 1370 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 1371 nmsg.obj = msg.obj; 1372 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT); 1373 return; 1374 } 1375 ProcessRecord app = (ProcessRecord)msg.obj; 1376 synchronized (ActivityManagerService.this) { 1377 processStartTimedOutLocked(app); 1378 } 1379 } break; 1380 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { 1381 synchronized (ActivityManagerService.this) { 1382 doPendingActivityLaunchesLocked(true); 1383 } 1384 } break; 1385 case KILL_APPLICATION_MSG: { 1386 synchronized (ActivityManagerService.this) { 1387 int appid = msg.arg1; 1388 boolean restart = (msg.arg2 == 1); 1389 Bundle bundle = (Bundle)msg.obj; 1390 String pkg = bundle.getString("pkg"); 1391 String reason = bundle.getString("reason"); 1392 forceStopPackageLocked(pkg, appid, restart, false, true, false, 1393 false, UserHandle.USER_ALL, reason); 1394 } 1395 } break; 1396 case FINALIZE_PENDING_INTENT_MSG: { 1397 ((PendingIntentRecord)msg.obj).completeFinalize(); 1398 } break; 1399 case POST_HEAVY_NOTIFICATION_MSG: { 1400 INotificationManager inm = NotificationManager.getService(); 1401 if (inm == null) { 1402 return; 1403 } 1404 1405 ActivityRecord root = (ActivityRecord)msg.obj; 1406 ProcessRecord process = root.app; 1407 if (process == null) { 1408 return; 1409 } 1410 1411 try { 1412 Context context = mContext.createPackageContext(process.info.packageName, 0); 1413 String text = mContext.getString(R.string.heavy_weight_notification, 1414 context.getApplicationInfo().loadLabel(context.getPackageManager())); 1415 Notification notification = new Notification(); 1416 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon; 1417 notification.when = 0; 1418 notification.flags = Notification.FLAG_ONGOING_EVENT; 1419 notification.tickerText = text; 1420 notification.defaults = 0; // please be quiet 1421 notification.sound = null; 1422 notification.vibrate = null; 1423 notification.setLatestEventInfo(context, text, 1424 mContext.getText(R.string.heavy_weight_notification_detail), 1425 PendingIntent.getActivityAsUser(mContext, 0, root.intent, 1426 PendingIntent.FLAG_CANCEL_CURRENT, null, 1427 new UserHandle(root.userId))); 1428 1429 try { 1430 int[] outId = new int[1]; 1431 inm.enqueueNotificationWithTag("android", "android", null, 1432 R.string.heavy_weight_notification, 1433 notification, outId, root.userId); 1434 } catch (RuntimeException e) { 1435 Slog.w(ActivityManagerService.TAG, 1436 "Error showing notification for heavy-weight app", e); 1437 } catch (RemoteException e) { 1438 } 1439 } catch (NameNotFoundException e) { 1440 Slog.w(TAG, "Unable to create context for heavy notification", e); 1441 } 1442 } break; 1443 case CANCEL_HEAVY_NOTIFICATION_MSG: { 1444 INotificationManager inm = NotificationManager.getService(); 1445 if (inm == null) { 1446 return; 1447 } 1448 try { 1449 inm.cancelNotificationWithTag("android", null, 1450 R.string.heavy_weight_notification, msg.arg1); 1451 } catch (RuntimeException e) { 1452 Slog.w(ActivityManagerService.TAG, 1453 "Error canceling notification for service", e); 1454 } catch (RemoteException e) { 1455 } 1456 } break; 1457 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: { 1458 synchronized (ActivityManagerService.this) { 1459 checkExcessivePowerUsageLocked(true); 1460 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1461 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 1462 sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 1463 } 1464 } break; 1465 case SHOW_COMPAT_MODE_DIALOG_MSG: { 1466 synchronized (ActivityManagerService.this) { 1467 ActivityRecord ar = (ActivityRecord)msg.obj; 1468 if (mCompatModeDialog != null) { 1469 if (mCompatModeDialog.mAppInfo.packageName.equals( 1470 ar.info.applicationInfo.packageName)) { 1471 return; 1472 } 1473 mCompatModeDialog.dismiss(); 1474 mCompatModeDialog = null; 1475 } 1476 if (ar != null && false) { 1477 if (mCompatModePackages.getPackageAskCompatModeLocked( 1478 ar.packageName)) { 1479 int mode = mCompatModePackages.computeCompatModeLocked( 1480 ar.info.applicationInfo); 1481 if (mode == ActivityManager.COMPAT_MODE_DISABLED 1482 || mode == ActivityManager.COMPAT_MODE_ENABLED) { 1483 mCompatModeDialog = new CompatModeDialog( 1484 ActivityManagerService.this, mContext, 1485 ar.info.applicationInfo); 1486 mCompatModeDialog.show(); 1487 } 1488 } 1489 } 1490 } 1491 break; 1492 } 1493 case DISPATCH_PROCESSES_CHANGED: { 1494 dispatchProcessesChanged(); 1495 break; 1496 } 1497 case DISPATCH_PROCESS_DIED: { 1498 final int pid = msg.arg1; 1499 final int uid = msg.arg2; 1500 dispatchProcessDied(pid, uid); 1501 break; 1502 } 1503 case REPORT_MEM_USAGE_MSG: { 1504 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj; 1505 Thread thread = new Thread() { 1506 @Override public void run() { 1507 final SparseArray<ProcessMemInfo> infoMap 1508 = new SparseArray<ProcessMemInfo>(memInfos.size()); 1509 for (int i=0, N=memInfos.size(); i<N; i++) { 1510 ProcessMemInfo mi = memInfos.get(i); 1511 infoMap.put(mi.pid, mi); 1512 } 1513 updateCpuStatsNow(); 1514 synchronized (mProcessCpuThread) { 1515 final int N = mProcessCpuTracker.countStats(); 1516 for (int i=0; i<N; i++) { 1517 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 1518 if (st.vsize > 0) { 1519 long pss = Debug.getPss(st.pid, null); 1520 if (pss > 0) { 1521 if (infoMap.indexOfKey(st.pid) < 0) { 1522 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid, 1523 ProcessList.NATIVE_ADJ, -1, "native", null); 1524 mi.pss = pss; 1525 memInfos.add(mi); 1526 } 1527 } 1528 } 1529 } 1530 } 1531 1532 long totalPss = 0; 1533 for (int i=0, N=memInfos.size(); i<N; i++) { 1534 ProcessMemInfo mi = memInfos.get(i); 1535 if (mi.pss == 0) { 1536 mi.pss = Debug.getPss(mi.pid, null); 1537 } 1538 totalPss += mi.pss; 1539 } 1540 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() { 1541 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) { 1542 if (lhs.oomAdj != rhs.oomAdj) { 1543 return lhs.oomAdj < rhs.oomAdj ? -1 : 1; 1544 } 1545 if (lhs.pss != rhs.pss) { 1546 return lhs.pss < rhs.pss ? 1 : -1; 1547 } 1548 return 0; 1549 } 1550 }); 1551 1552 StringBuilder tag = new StringBuilder(128); 1553 StringBuilder stack = new StringBuilder(128); 1554 tag.append("Low on memory -- "); 1555 appendMemBucket(tag, totalPss, "total", false); 1556 appendMemBucket(stack, totalPss, "total", true); 1557 1558 StringBuilder logBuilder = new StringBuilder(1024); 1559 logBuilder.append("Low on memory:\n"); 1560 1561 boolean firstLine = true; 1562 int lastOomAdj = Integer.MIN_VALUE; 1563 for (int i=0, N=memInfos.size(); i<N; i++) { 1564 ProcessMemInfo mi = memInfos.get(i); 1565 1566 if (mi.oomAdj != ProcessList.NATIVE_ADJ 1567 && (mi.oomAdj < ProcessList.SERVICE_ADJ 1568 || mi.oomAdj == ProcessList.HOME_APP_ADJ 1569 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) { 1570 if (lastOomAdj != mi.oomAdj) { 1571 lastOomAdj = mi.oomAdj; 1572 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1573 tag.append(" / "); 1574 } 1575 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) { 1576 if (firstLine) { 1577 stack.append(":"); 1578 firstLine = false; 1579 } 1580 stack.append("\n\t at "); 1581 } else { 1582 stack.append("$"); 1583 } 1584 } else { 1585 tag.append(" "); 1586 stack.append("$"); 1587 } 1588 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) { 1589 appendMemBucket(tag, mi.pss, mi.name, false); 1590 } 1591 appendMemBucket(stack, mi.pss, mi.name, true); 1592 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ 1593 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) { 1594 stack.append("("); 1595 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) { 1596 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) { 1597 stack.append(DUMP_MEM_OOM_LABEL[k]); 1598 stack.append(":"); 1599 stack.append(DUMP_MEM_OOM_ADJ[k]); 1600 } 1601 } 1602 stack.append(")"); 1603 } 1604 } 1605 1606 logBuilder.append(" "); 1607 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj)); 1608 logBuilder.append(' '); 1609 logBuilder.append(ProcessList.makeProcStateString(mi.procState)); 1610 logBuilder.append(' '); 1611 ProcessList.appendRamKb(logBuilder, mi.pss); 1612 logBuilder.append(" kB: "); 1613 logBuilder.append(mi.name); 1614 logBuilder.append(" ("); 1615 logBuilder.append(mi.pid); 1616 logBuilder.append(") "); 1617 logBuilder.append(mi.adjType); 1618 logBuilder.append('\n'); 1619 if (mi.adjReason != null) { 1620 logBuilder.append(" "); 1621 logBuilder.append(mi.adjReason); 1622 logBuilder.append('\n'); 1623 } 1624 } 1625 1626 logBuilder.append(" "); 1627 ProcessList.appendRamKb(logBuilder, totalPss); 1628 logBuilder.append(" kB: TOTAL\n"); 1629 1630 long[] infos = new long[Debug.MEMINFO_COUNT]; 1631 Debug.getMemInfo(infos); 1632 logBuilder.append(" MemInfo: "); 1633 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, "); 1634 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, "); 1635 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, "); 1636 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, "); 1637 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n"); 1638 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) { 1639 logBuilder.append(" ZRAM: "); 1640 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]); 1641 logBuilder.append(" kB RAM, "); 1642 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]); 1643 logBuilder.append(" kB swap total, "); 1644 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]); 1645 logBuilder.append(" kB swap free\n"); 1646 } 1647 Slog.i(TAG, logBuilder.toString()); 1648 1649 StringBuilder dropBuilder = new StringBuilder(1024); 1650 /* 1651 StringWriter oomSw = new StringWriter(); 1652 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256); 1653 StringWriter catSw = new StringWriter(); 1654 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1655 String[] emptyArgs = new String[] { }; 1656 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw); 1657 oomPw.flush(); 1658 String oomString = oomSw.toString(); 1659 */ 1660 dropBuilder.append(stack); 1661 dropBuilder.append('\n'); 1662 dropBuilder.append('\n'); 1663 dropBuilder.append(logBuilder); 1664 dropBuilder.append('\n'); 1665 /* 1666 dropBuilder.append(oomString); 1667 dropBuilder.append('\n'); 1668 */ 1669 StringWriter catSw = new StringWriter(); 1670 synchronized (ActivityManagerService.this) { 1671 PrintWriter catPw = new FastPrintWriter(catSw, false, 256); 1672 String[] emptyArgs = new String[] { }; 1673 catPw.println(); 1674 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null); 1675 catPw.println(); 1676 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0, 1677 false, false, null); 1678 catPw.println(); 1679 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null); 1680 catPw.flush(); 1681 } 1682 dropBuilder.append(catSw.toString()); 1683 addErrorToDropBox("lowmem", null, "system_server", null, 1684 null, tag.toString(), dropBuilder.toString(), null, null); 1685 //Slog.i(TAG, "Sent to dropbox:"); 1686 //Slog.i(TAG, dropBuilder.toString()); 1687 synchronized (ActivityManagerService.this) { 1688 long now = SystemClock.uptimeMillis(); 1689 if (mLastMemUsageReportTime < now) { 1690 mLastMemUsageReportTime = now; 1691 } 1692 } 1693 } 1694 }; 1695 thread.start(); 1696 break; 1697 } 1698 case REPORT_USER_SWITCH_MSG: { 1699 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1700 break; 1701 } 1702 case CONTINUE_USER_SWITCH_MSG: { 1703 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1704 break; 1705 } 1706 case USER_SWITCH_TIMEOUT_MSG: { 1707 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2); 1708 break; 1709 } 1710 case IMMERSIVE_MODE_LOCK_MSG: { 1711 final boolean nextState = (msg.arg1 != 0); 1712 if (mUpdateLock.isHeld() != nextState) { 1713 if (DEBUG_IMMERSIVE) { 1714 final ActivityRecord r = (ActivityRecord) msg.obj; 1715 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r); 1716 } 1717 if (nextState) { 1718 mUpdateLock.acquire(); 1719 } else { 1720 mUpdateLock.release(); 1721 } 1722 } 1723 break; 1724 } 1725 case PERSIST_URI_GRANTS_MSG: { 1726 writeGrantedUriPermissions(); 1727 break; 1728 } 1729 case REQUEST_ALL_PSS_MSG: { 1730 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false); 1731 break; 1732 } 1733 case START_PROFILES_MSG: { 1734 synchronized (ActivityManagerService.this) { 1735 startProfilesLocked(); 1736 } 1737 break; 1738 } 1739 case UPDATE_TIME: { 1740 synchronized (ActivityManagerService.this) { 1741 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 1742 ProcessRecord r = mLruProcesses.get(i); 1743 if (r.thread != null) { 1744 try { 1745 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true); 1746 } catch (RemoteException ex) { 1747 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName); 1748 } 1749 } 1750 } 1751 } 1752 break; 1753 } 1754 } 1755 } 1756 }; 1757 1758 static final int COLLECT_PSS_BG_MSG = 1; 1759 1760 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) { 1761 @Override 1762 public void handleMessage(Message msg) { 1763 switch (msg.what) { 1764 case COLLECT_PSS_BG_MSG: { 1765 int i=0, num=0; 1766 long start = SystemClock.uptimeMillis(); 1767 long[] tmp = new long[1]; 1768 do { 1769 ProcessRecord proc; 1770 int procState; 1771 int pid; 1772 synchronized (ActivityManagerService.this) { 1773 if (i >= mPendingPssProcesses.size()) { 1774 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i 1775 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms"); 1776 mPendingPssProcesses.clear(); 1777 return; 1778 } 1779 proc = mPendingPssProcesses.get(i); 1780 procState = proc.pssProcState; 1781 if (proc.thread != null && procState == proc.setProcState) { 1782 pid = proc.pid; 1783 } else { 1784 proc = null; 1785 pid = 0; 1786 } 1787 i++; 1788 } 1789 if (proc != null) { 1790 long pss = Debug.getPss(pid, tmp); 1791 synchronized (ActivityManagerService.this) { 1792 if (proc.thread != null && proc.setProcState == procState 1793 && proc.pid == pid) { 1794 num++; 1795 proc.lastPssTime = SystemClock.uptimeMillis(); 1796 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList); 1797 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString() 1798 + ": " + pss + " lastPss=" + proc.lastPss 1799 + " state=" + ProcessList.makeProcStateString(procState)); 1800 if (proc.initialIdlePss == 0) { 1801 proc.initialIdlePss = pss; 1802 } 1803 proc.lastPss = pss; 1804 if (procState >= ActivityManager.PROCESS_STATE_HOME) { 1805 proc.lastCachedPss = pss; 1806 } 1807 } 1808 } 1809 } 1810 } while (true); 1811 } 1812 } 1813 } 1814 }; 1815 1816 public void setSystemProcess() { 1817 try { 1818 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true); 1819 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats); 1820 ServiceManager.addService("meminfo", new MemBinder(this)); 1821 ServiceManager.addService("gfxinfo", new GraphicsBinder(this)); 1822 ServiceManager.addService("dbinfo", new DbBinder(this)); 1823 if (MONITOR_CPU_USAGE) { 1824 ServiceManager.addService("cpuinfo", new CpuBinder(this)); 1825 } 1826 ServiceManager.addService("permission", new PermissionController(this)); 1827 1828 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo( 1829 "android", STOCK_PM_FLAGS); 1830 mSystemThread.installSystemApplicationInfo(info); 1831 1832 synchronized (this) { 1833 ProcessRecord app = newProcessRecordLocked(info, info.processName, false); 1834 app.persistent = true; 1835 app.pid = MY_PID; 1836 app.maxAdj = ProcessList.SYSTEM_ADJ; 1837 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats); 1838 mProcessNames.put(app.processName, app.uid, app); 1839 synchronized (mPidsSelfLocked) { 1840 mPidsSelfLocked.put(app.pid, app); 1841 } 1842 updateLruProcessLocked(app, false, null); 1843 updateOomAdjLocked(); 1844 } 1845 } catch (PackageManager.NameNotFoundException e) { 1846 throw new RuntimeException( 1847 "Unable to find android system package", e); 1848 } 1849 } 1850 1851 public void setWindowManager(WindowManagerService wm) { 1852 mWindowManager = wm; 1853 mStackSupervisor.setWindowManager(wm); 1854 } 1855 1856 public void startObservingNativeCrashes() { 1857 final NativeCrashListener ncl = new NativeCrashListener(this); 1858 ncl.start(); 1859 } 1860 1861 public IAppOpsService getAppOpsService() { 1862 return mAppOpsService; 1863 } 1864 1865 static class MemBinder extends Binder { 1866 ActivityManagerService mActivityManagerService; 1867 MemBinder(ActivityManagerService activityManagerService) { 1868 mActivityManagerService = activityManagerService; 1869 } 1870 1871 @Override 1872 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1873 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1874 != PackageManager.PERMISSION_GRANTED) { 1875 pw.println("Permission Denial: can't dump meminfo from from pid=" 1876 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1877 + " without permission " + android.Manifest.permission.DUMP); 1878 return; 1879 } 1880 1881 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); 1882 } 1883 } 1884 1885 static class GraphicsBinder extends Binder { 1886 ActivityManagerService mActivityManagerService; 1887 GraphicsBinder(ActivityManagerService activityManagerService) { 1888 mActivityManagerService = activityManagerService; 1889 } 1890 1891 @Override 1892 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1893 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1894 != PackageManager.PERMISSION_GRANTED) { 1895 pw.println("Permission Denial: can't dump gfxinfo from from pid=" 1896 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1897 + " without permission " + android.Manifest.permission.DUMP); 1898 return; 1899 } 1900 1901 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args); 1902 } 1903 } 1904 1905 static class DbBinder extends Binder { 1906 ActivityManagerService mActivityManagerService; 1907 DbBinder(ActivityManagerService activityManagerService) { 1908 mActivityManagerService = activityManagerService; 1909 } 1910 1911 @Override 1912 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1913 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1914 != PackageManager.PERMISSION_GRANTED) { 1915 pw.println("Permission Denial: can't dump dbinfo from from pid=" 1916 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1917 + " without permission " + android.Manifest.permission.DUMP); 1918 return; 1919 } 1920 1921 mActivityManagerService.dumpDbInfo(fd, pw, args); 1922 } 1923 } 1924 1925 static class CpuBinder extends Binder { 1926 ActivityManagerService mActivityManagerService; 1927 CpuBinder(ActivityManagerService activityManagerService) { 1928 mActivityManagerService = activityManagerService; 1929 } 1930 1931 @Override 1932 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1933 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP) 1934 != PackageManager.PERMISSION_GRANTED) { 1935 pw.println("Permission Denial: can't dump cpuinfo from from pid=" 1936 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 1937 + " without permission " + android.Manifest.permission.DUMP); 1938 return; 1939 } 1940 1941 synchronized (mActivityManagerService.mProcessCpuThread) { 1942 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad()); 1943 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState( 1944 SystemClock.uptimeMillis())); 1945 } 1946 } 1947 } 1948 1949 public static final class Lifecycle extends SystemService { 1950 private final ActivityManagerService mService; 1951 1952 public Lifecycle(Context context) { 1953 super(context); 1954 mService = new ActivityManagerService(context); 1955 } 1956 1957 @Override 1958 public void onStart() { 1959 mService.start(); 1960 } 1961 1962 public ActivityManagerService getService() { 1963 return mService; 1964 } 1965 } 1966 1967 // Note: This method is invoked on the main thread but may need to attach various 1968 // handlers to other threads. So take care to be explicit about the looper. 1969 public ActivityManagerService(Context systemContext) { 1970 mContext = systemContext; 1971 mFactoryTest = FactoryTest.getMode(); 1972 mSystemThread = ActivityThread.currentActivityThread(); 1973 1974 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass()); 1975 1976 mHandlerThread = new ServiceThread(TAG, 1977 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/); 1978 mHandlerThread.start(); 1979 mHandler = new MainHandler(mHandlerThread.getLooper()); 1980 1981 mFgBroadcastQueue = new BroadcastQueue(this, mHandler, 1982 "foreground", BROADCAST_FG_TIMEOUT, false); 1983 mBgBroadcastQueue = new BroadcastQueue(this, mHandler, 1984 "background", BROADCAST_BG_TIMEOUT, true); 1985 mBroadcastQueues[0] = mFgBroadcastQueue; 1986 mBroadcastQueues[1] = mBgBroadcastQueue; 1987 1988 mServices = new ActiveServices(this); 1989 mProviderMap = new ProviderMap(this); 1990 1991 // TODO: Move creation of battery stats service outside of activity manager service. 1992 File dataDir = Environment.getDataDirectory(); 1993 File systemDir = new File(dataDir, "system"); 1994 systemDir.mkdirs(); 1995 mBatteryStatsService = new BatteryStatsService(new File( 1996 systemDir, "batterystats.bin").toString(), mHandler); 1997 mBatteryStatsService.getActiveStatistics().readLocked(); 1998 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 1999 mOnBattery = DEBUG_POWER ? true 2000 : mBatteryStatsService.getActiveStatistics().getIsOnBattery(); 2001 mBatteryStatsService.getActiveStatistics().setCallback(this); 2002 2003 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats")); 2004 2005 mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString()); 2006 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler); 2007 2008 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml")); 2009 2010 // User 0 is the first and only user that runs at boot. 2011 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true)); 2012 mUserLru.add(Integer.valueOf(0)); 2013 updateStartedUserArrayLocked(); 2014 2015 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version", 2016 ConfigurationInfo.GL_ES_VERSION_UNDEFINED); 2017 2018 mConfiguration.setToDefaults(); 2019 mConfiguration.setLocale(Locale.getDefault()); 2020 2021 mConfigurationSeq = mConfiguration.seq = 1; 2022 mProcessCpuTracker.init(); 2023 2024 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler); 2025 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler); 2026 mStackSupervisor = new ActivityStackSupervisor(this); 2027 2028 mProcessCpuThread = new Thread("CpuTracker") { 2029 @Override 2030 public void run() { 2031 while (true) { 2032 try { 2033 try { 2034 synchronized(this) { 2035 final long now = SystemClock.uptimeMillis(); 2036 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now; 2037 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now; 2038 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay 2039 // + ", write delay=" + nextWriteDelay); 2040 if (nextWriteDelay < nextCpuDelay) { 2041 nextCpuDelay = nextWriteDelay; 2042 } 2043 if (nextCpuDelay > 0) { 2044 mProcessCpuMutexFree.set(true); 2045 this.wait(nextCpuDelay); 2046 } 2047 } 2048 } catch (InterruptedException e) { 2049 } 2050 updateCpuStatsNow(); 2051 } catch (Exception e) { 2052 Slog.e(TAG, "Unexpected exception collecting process stats", e); 2053 } 2054 } 2055 } 2056 }; 2057 2058 Watchdog.getInstance().addMonitor(this); 2059 Watchdog.getInstance().addThread(mHandler); 2060 } 2061 2062 private void start() { 2063 mProcessCpuThread.start(); 2064 2065 mBatteryStatsService.publish(mContext); 2066 mUsageStatsService.publish(mContext); 2067 mAppOpsService.publish(mContext); 2068 2069 LocalServices.addService(ActivityManagerInternal.class, new LocalService()); 2070 } 2071 2072 @Override 2073 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) 2074 throws RemoteException { 2075 if (code == SYSPROPS_TRANSACTION) { 2076 // We need to tell all apps about the system property change. 2077 ArrayList<IBinder> procs = new ArrayList<IBinder>(); 2078 synchronized(this) { 2079 final int NP = mProcessNames.getMap().size(); 2080 for (int ip=0; ip<NP; ip++) { 2081 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2082 final int NA = apps.size(); 2083 for (int ia=0; ia<NA; ia++) { 2084 ProcessRecord app = apps.valueAt(ia); 2085 if (app.thread != null) { 2086 procs.add(app.thread.asBinder()); 2087 } 2088 } 2089 } 2090 } 2091 2092 int N = procs.size(); 2093 for (int i=0; i<N; i++) { 2094 Parcel data2 = Parcel.obtain(); 2095 try { 2096 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0); 2097 } catch (RemoteException e) { 2098 } 2099 data2.recycle(); 2100 } 2101 } 2102 try { 2103 return super.onTransact(code, data, reply, flags); 2104 } catch (RuntimeException e) { 2105 // The activity manager only throws security exceptions, so let's 2106 // log all others. 2107 if (!(e instanceof SecurityException)) { 2108 Slog.wtf(TAG, "Activity Manager Crash", e); 2109 } 2110 throw e; 2111 } 2112 } 2113 2114 void updateCpuStats() { 2115 final long now = SystemClock.uptimeMillis(); 2116 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) { 2117 return; 2118 } 2119 if (mProcessCpuMutexFree.compareAndSet(true, false)) { 2120 synchronized (mProcessCpuThread) { 2121 mProcessCpuThread.notify(); 2122 } 2123 } 2124 } 2125 2126 void updateCpuStatsNow() { 2127 synchronized (mProcessCpuThread) { 2128 mProcessCpuMutexFree.set(false); 2129 final long now = SystemClock.uptimeMillis(); 2130 boolean haveNewCpuStats = false; 2131 2132 if (MONITOR_CPU_USAGE && 2133 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) { 2134 mLastCpuTime.set(now); 2135 haveNewCpuStats = true; 2136 mProcessCpuTracker.update(); 2137 //Slog.i(TAG, mProcessCpu.printCurrentState()); 2138 //Slog.i(TAG, "Total CPU usage: " 2139 // + mProcessCpu.getTotalCpuPercent() + "%"); 2140 2141 // Slog the cpu usage if the property is set. 2142 if ("true".equals(SystemProperties.get("events.cpu"))) { 2143 int user = mProcessCpuTracker.getLastUserTime(); 2144 int system = mProcessCpuTracker.getLastSystemTime(); 2145 int iowait = mProcessCpuTracker.getLastIoWaitTime(); 2146 int irq = mProcessCpuTracker.getLastIrqTime(); 2147 int softIrq = mProcessCpuTracker.getLastSoftIrqTime(); 2148 int idle = mProcessCpuTracker.getLastIdleTime(); 2149 2150 int total = user + system + iowait + irq + softIrq + idle; 2151 if (total == 0) total = 1; 2152 2153 EventLog.writeEvent(EventLogTags.CPU, 2154 ((user+system+iowait+irq+softIrq) * 100) / total, 2155 (user * 100) / total, 2156 (system * 100) / total, 2157 (iowait * 100) / total, 2158 (irq * 100) / total, 2159 (softIrq * 100) / total); 2160 } 2161 } 2162 2163 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes(); 2164 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics(); 2165 synchronized(bstats) { 2166 synchronized(mPidsSelfLocked) { 2167 if (haveNewCpuStats) { 2168 if (mOnBattery) { 2169 int perc = bstats.startAddingCpuLocked(); 2170 int totalUTime = 0; 2171 int totalSTime = 0; 2172 final int N = mProcessCpuTracker.countStats(); 2173 for (int i=0; i<N; i++) { 2174 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 2175 if (!st.working) { 2176 continue; 2177 } 2178 ProcessRecord pr = mPidsSelfLocked.get(st.pid); 2179 int otherUTime = (st.rel_utime*perc)/100; 2180 int otherSTime = (st.rel_stime*perc)/100; 2181 totalUTime += otherUTime; 2182 totalSTime += otherSTime; 2183 if (pr != null) { 2184 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats; 2185 if (ps == null || !ps.isActive()) { 2186 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked( 2187 pr.info.uid, pr.processName); 2188 } 2189 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2190 st.rel_stime-otherSTime); 2191 ps.addSpeedStepTimes(cpuSpeedTimes); 2192 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10; 2193 } else { 2194 BatteryStatsImpl.Uid.Proc ps = st.batteryStats; 2195 if (ps == null || !ps.isActive()) { 2196 st.batteryStats = ps = bstats.getProcessStatsLocked( 2197 bstats.mapUid(st.uid), st.name); 2198 } 2199 ps.addCpuTimeLocked(st.rel_utime-otherUTime, 2200 st.rel_stime-otherSTime); 2201 ps.addSpeedStepTimes(cpuSpeedTimes); 2202 } 2203 } 2204 bstats.finishAddingCpuLocked(perc, totalUTime, 2205 totalSTime, cpuSpeedTimes); 2206 } 2207 } 2208 } 2209 2210 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) { 2211 mLastWriteTime = now; 2212 mBatteryStatsService.getActiveStatistics().writeAsyncLocked(); 2213 } 2214 } 2215 } 2216 } 2217 2218 @Override 2219 public void batteryNeedsCpuUpdate() { 2220 updateCpuStatsNow(); 2221 } 2222 2223 @Override 2224 public void batteryPowerChanged(boolean onBattery) { 2225 // When plugging in, update the CPU stats first before changing 2226 // the plug state. 2227 updateCpuStatsNow(); 2228 synchronized (this) { 2229 synchronized(mPidsSelfLocked) { 2230 mOnBattery = DEBUG_POWER ? true : onBattery; 2231 } 2232 } 2233 } 2234 2235 /** 2236 * Initialize the application bind args. These are passed to each 2237 * process when the bindApplication() IPC is sent to the process. They're 2238 * lazily setup to make sure the services are running when they're asked for. 2239 */ 2240 private HashMap<String, IBinder> getCommonServicesLocked() { 2241 if (mAppBindArgs == null) { 2242 mAppBindArgs = new HashMap<String, IBinder>(); 2243 2244 // Setup the application init args 2245 mAppBindArgs.put("package", ServiceManager.getService("package")); 2246 mAppBindArgs.put("window", ServiceManager.getService("window")); 2247 mAppBindArgs.put(Context.ALARM_SERVICE, 2248 ServiceManager.getService(Context.ALARM_SERVICE)); 2249 } 2250 return mAppBindArgs; 2251 } 2252 2253 final void setFocusedActivityLocked(ActivityRecord r) { 2254 if (mFocusedActivity != r) { 2255 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r); 2256 mFocusedActivity = r; 2257 mStackSupervisor.setFocusedStack(r); 2258 if (r != null) { 2259 mWindowManager.setFocusedApp(r.appToken, true); 2260 } 2261 applyUpdateLockStateLocked(r); 2262 } 2263 } 2264 2265 @Override 2266 public void setFocusedStack(int stackId) { 2267 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId); 2268 synchronized (ActivityManagerService.this) { 2269 ActivityStack stack = mStackSupervisor.getStack(stackId); 2270 if (stack != null) { 2271 ActivityRecord r = stack.topRunningActivityLocked(null); 2272 if (r != null) { 2273 setFocusedActivityLocked(r); 2274 } 2275 } 2276 } 2277 } 2278 2279 @Override 2280 public void notifyActivityDrawn(IBinder token) { 2281 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token); 2282 synchronized (this) { 2283 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token); 2284 if (r != null) { 2285 r.task.stack.notifyActivityDrawnLocked(r); 2286 } 2287 } 2288 } 2289 2290 final void applyUpdateLockStateLocked(ActivityRecord r) { 2291 // Modifications to the UpdateLock state are done on our handler, outside 2292 // the activity manager's locks. The new state is determined based on the 2293 // state *now* of the relevant activity record. The object is passed to 2294 // the handler solely for logging detail, not to be consulted/modified. 2295 final boolean nextState = r != null && r.immersive; 2296 mHandler.sendMessage( 2297 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r)); 2298 } 2299 2300 final void showAskCompatModeDialogLocked(ActivityRecord r) { 2301 Message msg = Message.obtain(); 2302 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG; 2303 msg.obj = r.task.askedCompatMode ? null : r; 2304 mHandler.sendMessage(msg); 2305 } 2306 2307 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2308 String what, Object obj, ProcessRecord srcApp) { 2309 app.lastActivityTime = now; 2310 2311 if (app.activities.size() > 0) { 2312 // Don't want to touch dependent processes that are hosting activities. 2313 return index; 2314 } 2315 2316 int lrui = mLruProcesses.lastIndexOf(app); 2317 if (lrui < 0) { 2318 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2319 + what + " " + obj + " from " + srcApp); 2320 return index; 2321 } 2322 2323 if (lrui >= index) { 2324 // Don't want to cause this to move dependent processes *back* in the 2325 // list as if they were less frequently used. 2326 return index; 2327 } 2328 2329 if (lrui >= mLruProcessActivityStart) { 2330 // Don't want to touch dependent processes that are hosting activities. 2331 return index; 2332 } 2333 2334 mLruProcesses.remove(lrui); 2335 if (index > 0) { 2336 index--; 2337 } 2338 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index 2339 + " in LRU list: " + app); 2340 mLruProcesses.add(index, app); 2341 return index; 2342 } 2343 2344 final void removeLruProcessLocked(ProcessRecord app) { 2345 int lrui = mLruProcesses.lastIndexOf(app); 2346 if (lrui >= 0) { 2347 if (lrui <= mLruProcessActivityStart) { 2348 mLruProcessActivityStart--; 2349 } 2350 if (lrui <= mLruProcessServiceStart) { 2351 mLruProcessServiceStart--; 2352 } 2353 mLruProcesses.remove(lrui); 2354 } 2355 } 2356 2357 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2358 ProcessRecord client) { 2359 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities 2360 || app.treatLikeActivity; 2361 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2362 if (!activityChange && hasActivity) { 2363 // The process has activities, so we are only allowing activity-based adjustments 2364 // to move it. It should be kept in the front of the list with other 2365 // processes that have activities, and we don't want those to change their 2366 // order except due to activity operations. 2367 return; 2368 } 2369 2370 mLruSeq++; 2371 final long now = SystemClock.uptimeMillis(); 2372 app.lastActivityTime = now; 2373 2374 // First a quick reject: if the app is already at the position we will 2375 // put it, then there is nothing to do. 2376 if (hasActivity) { 2377 final int N = mLruProcesses.size(); 2378 if (N > 0 && mLruProcesses.get(N-1) == app) { 2379 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app); 2380 return; 2381 } 2382 } else { 2383 if (mLruProcessServiceStart > 0 2384 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2385 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app); 2386 return; 2387 } 2388 } 2389 2390 int lrui = mLruProcesses.lastIndexOf(app); 2391 2392 if (app.persistent && lrui >= 0) { 2393 // We don't care about the position of persistent processes, as long as 2394 // they are in the list. 2395 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app); 2396 return; 2397 } 2398 2399 /* In progress: compute new position first, so we can avoid doing work 2400 if the process is not actually going to move. Not yet working. 2401 int addIndex; 2402 int nextIndex; 2403 boolean inActivity = false, inService = false; 2404 if (hasActivity) { 2405 // Process has activities, put it at the very tipsy-top. 2406 addIndex = mLruProcesses.size(); 2407 nextIndex = mLruProcessServiceStart; 2408 inActivity = true; 2409 } else if (hasService) { 2410 // Process has services, put it at the top of the service list. 2411 addIndex = mLruProcessActivityStart; 2412 nextIndex = mLruProcessServiceStart; 2413 inActivity = true; 2414 inService = true; 2415 } else { 2416 // Process not otherwise of interest, it goes to the top of the non-service area. 2417 addIndex = mLruProcessServiceStart; 2418 if (client != null) { 2419 int clientIndex = mLruProcesses.lastIndexOf(client); 2420 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2421 + app); 2422 if (clientIndex >= 0 && addIndex > clientIndex) { 2423 addIndex = clientIndex; 2424 } 2425 } 2426 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2427 } 2428 2429 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2430 + mLruProcessActivityStart + "): " + app); 2431 */ 2432 2433 if (lrui >= 0) { 2434 if (lrui < mLruProcessActivityStart) { 2435 mLruProcessActivityStart--; 2436 } 2437 if (lrui < mLruProcessServiceStart) { 2438 mLruProcessServiceStart--; 2439 } 2440 /* 2441 if (addIndex > lrui) { 2442 addIndex--; 2443 } 2444 if (nextIndex > lrui) { 2445 nextIndex--; 2446 } 2447 */ 2448 mLruProcesses.remove(lrui); 2449 } 2450 2451 /* 2452 mLruProcesses.add(addIndex, app); 2453 if (inActivity) { 2454 mLruProcessActivityStart++; 2455 } 2456 if (inService) { 2457 mLruProcessActivityStart++; 2458 } 2459 */ 2460 2461 int nextIndex; 2462 if (hasActivity) { 2463 final int N = mLruProcesses.size(); 2464 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) { 2465 // Process doesn't have activities, but has clients with 2466 // activities... move it up, but one below the top (the top 2467 // should always have a real activity). 2468 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app); 2469 mLruProcesses.add(N-1, app); 2470 // To keep it from spamming the LRU list (by making a bunch of clients), 2471 // we will push down any other entries owned by the app. 2472 final int uid = app.info.uid; 2473 for (int i=N-2; i>mLruProcessActivityStart; i--) { 2474 ProcessRecord subProc = mLruProcesses.get(i); 2475 if (subProc.info.uid == uid) { 2476 // We want to push this one down the list. If the process after 2477 // it is for the same uid, however, don't do so, because we don't 2478 // want them internally to be re-ordered. 2479 if (mLruProcesses.get(i-1).info.uid != uid) { 2480 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i 2481 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1)); 2482 ProcessRecord tmp = mLruProcesses.get(i); 2483 mLruProcesses.set(i, mLruProcesses.get(i-1)); 2484 mLruProcesses.set(i-1, tmp); 2485 i--; 2486 } 2487 } else { 2488 // A gap, we can stop here. 2489 break; 2490 } 2491 } 2492 } else { 2493 // Process has activities, put it at the very tipsy-top. 2494 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app); 2495 mLruProcesses.add(app); 2496 } 2497 nextIndex = mLruProcessServiceStart; 2498 } else if (hasService) { 2499 // Process has services, put it at the top of the service list. 2500 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app); 2501 mLruProcesses.add(mLruProcessActivityStart, app); 2502 nextIndex = mLruProcessServiceStart; 2503 mLruProcessActivityStart++; 2504 } else { 2505 // Process not otherwise of interest, it goes to the top of the non-service area. 2506 int index = mLruProcessServiceStart; 2507 if (client != null) { 2508 // If there is a client, don't allow the process to be moved up higher 2509 // in the list than that client. 2510 int clientIndex = mLruProcesses.lastIndexOf(client); 2511 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client 2512 + " when updating " + app); 2513 if (clientIndex <= lrui) { 2514 // Don't allow the client index restriction to push it down farther in the 2515 // list than it already is. 2516 clientIndex = lrui; 2517 } 2518 if (clientIndex >= 0 && index > clientIndex) { 2519 index = clientIndex; 2520 } 2521 } 2522 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app); 2523 mLruProcesses.add(index, app); 2524 nextIndex = index-1; 2525 mLruProcessActivityStart++; 2526 mLruProcessServiceStart++; 2527 } 2528 2529 // If the app is currently using a content provider or service, 2530 // bump those processes as well. 2531 for (int j=app.connections.size()-1; j>=0; j--) { 2532 ConnectionRecord cr = app.connections.valueAt(j); 2533 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2534 && cr.binding.service.app != null 2535 && cr.binding.service.app.lruSeq != mLruSeq 2536 && !cr.binding.service.app.persistent) { 2537 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex, 2538 "service connection", cr, app); 2539 } 2540 } 2541 for (int j=app.conProviders.size()-1; j>=0; j--) { 2542 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2543 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) { 2544 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, 2545 "provider reference", cpr, app); 2546 } 2547 } 2548 } 2549 2550 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) { 2551 if (uid == Process.SYSTEM_UID) { 2552 // The system gets to run in any process. If there are multiple 2553 // processes with the same uid, just pick the first (this 2554 // should never happen). 2555 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 2556 if (procs == null) return null; 2557 final int N = procs.size(); 2558 for (int i = 0; i < N; i++) { 2559 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i); 2560 } 2561 } 2562 ProcessRecord proc = mProcessNames.get(processName, uid); 2563 if (false && proc != null && !keepIfLarge 2564 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 2565 && proc.lastCachedPss >= 4000) { 2566 // Turn this condition on to cause killing to happen regularly, for testing. 2567 if (proc.baseProcessTracker != null) { 2568 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2569 } 2570 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2571 + "k from cached"); 2572 } else if (proc != null && !keepIfLarge 2573 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 2574 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 2575 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss); 2576 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) { 2577 if (proc.baseProcessTracker != null) { 2578 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss); 2579 } 2580 killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss) 2581 + "k from cached"); 2582 } 2583 } 2584 return proc; 2585 } 2586 2587 void ensurePackageDexOpt(String packageName) { 2588 IPackageManager pm = AppGlobals.getPackageManager(); 2589 try { 2590 if (pm.performDexOpt(packageName)) { 2591 mDidDexOpt = true; 2592 } 2593 } catch (RemoteException e) { 2594 } 2595 } 2596 2597 boolean isNextTransitionForward() { 2598 int transit = mWindowManager.getPendingAppTransition(); 2599 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN 2600 || transit == AppTransition.TRANSIT_TASK_OPEN 2601 || transit == AppTransition.TRANSIT_TASK_TO_FRONT; 2602 } 2603 2604 final ProcessRecord startProcessLocked(String processName, 2605 ApplicationInfo info, boolean knownToBeDead, int intentFlags, 2606 String hostingType, ComponentName hostingName, boolean allowWhileBooting, 2607 boolean isolated, boolean keepIfLarge) { 2608 ProcessRecord app; 2609 if (!isolated) { 2610 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 2611 } else { 2612 // If this is an isolated process, it can't re-use an existing process. 2613 app = null; 2614 } 2615 // We don't have to do anything more if: 2616 // (1) There is an existing application record; and 2617 // (2) The caller doesn't think it is dead, OR there is no thread 2618 // object attached to it so we know it couldn't have crashed; and 2619 // (3) There is a pid assigned to it, so it is either starting or 2620 // already running. 2621 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName 2622 + " app=" + app + " knownToBeDead=" + knownToBeDead 2623 + " thread=" + (app != null ? app.thread : null) 2624 + " pid=" + (app != null ? app.pid : -1)); 2625 if (app != null && app.pid > 0) { 2626 if (!knownToBeDead || app.thread == null) { 2627 // We already have the app running, or are waiting for it to 2628 // come up (we have a pid but not yet its thread), so keep it. 2629 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app); 2630 // If this is a new package in the process, add the package to the list 2631 app.addPackage(info.packageName, mProcessStats); 2632 return app; 2633 } 2634 2635 // An application record is attached to a previous process, 2636 // clean it up now. 2637 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app); 2638 handleAppDiedLocked(app, true, true); 2639 } 2640 2641 String hostingNameStr = hostingName != null 2642 ? hostingName.flattenToShortString() : null; 2643 2644 if (!isolated) { 2645 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) { 2646 // If we are in the background, then check to see if this process 2647 // is bad. If so, we will just silently fail. 2648 if (mBadProcesses.get(info.processName, info.uid) != null) { 2649 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 2650 + "/" + info.processName); 2651 return null; 2652 } 2653 } else { 2654 // When the user is explicitly starting a process, then clear its 2655 // crash count so that we won't make it bad until they see at 2656 // least one crash dialog again, and make the process good again 2657 // if it had been bad. 2658 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 2659 + "/" + info.processName); 2660 mProcessCrashTimes.remove(info.processName, info.uid); 2661 if (mBadProcesses.get(info.processName, info.uid) != null) { 2662 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 2663 UserHandle.getUserId(info.uid), info.uid, 2664 info.processName); 2665 mBadProcesses.remove(info.processName, info.uid); 2666 if (app != null) { 2667 app.bad = false; 2668 } 2669 } 2670 } 2671 } 2672 2673 if (app == null) { 2674 app = newProcessRecordLocked(info, processName, isolated); 2675 if (app == null) { 2676 Slog.w(TAG, "Failed making new process record for " 2677 + processName + "/" + info.uid + " isolated=" + isolated); 2678 return null; 2679 } 2680 mProcessNames.put(processName, app.uid, app); 2681 if (isolated) { 2682 mIsolatedProcesses.put(app.uid, app); 2683 } 2684 } else { 2685 // If this is a new package in the process, add the package to the list 2686 app.addPackage(info.packageName, mProcessStats); 2687 } 2688 2689 // If the system is not ready yet, then hold off on starting this 2690 // process until it is. 2691 if (!mProcessesReady 2692 && !isAllowedWhileBooting(info) 2693 && !allowWhileBooting) { 2694 if (!mProcessesOnHold.contains(app)) { 2695 mProcessesOnHold.add(app); 2696 } 2697 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app); 2698 return app; 2699 } 2700 2701 startProcessLocked(app, hostingType, hostingNameStr); 2702 return (app.pid != 0) ? app : null; 2703 } 2704 2705 boolean isAllowedWhileBooting(ApplicationInfo ai) { 2706 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0; 2707 } 2708 2709 private final void startProcessLocked(ProcessRecord app, 2710 String hostingType, String hostingNameStr) { 2711 if (app.pid > 0 && app.pid != MY_PID) { 2712 synchronized (mPidsSelfLocked) { 2713 mPidsSelfLocked.remove(app.pid); 2714 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2715 } 2716 app.setPid(0); 2717 } 2718 2719 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 2720 "startProcessLocked removing on hold: " + app); 2721 mProcessesOnHold.remove(app); 2722 2723 updateCpuStats(); 2724 2725 try { 2726 int uid = app.uid; 2727 2728 int[] gids = null; 2729 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 2730 if (!app.isolated) { 2731 int[] permGids = null; 2732 try { 2733 final PackageManager pm = mContext.getPackageManager(); 2734 permGids = pm.getPackageGids(app.info.packageName); 2735 2736 if (Environment.isExternalStorageEmulated()) { 2737 if (pm.checkPermission( 2738 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE, 2739 app.info.packageName) == PERMISSION_GRANTED) { 2740 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL; 2741 } else { 2742 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER; 2743 } 2744 } 2745 } catch (PackageManager.NameNotFoundException e) { 2746 Slog.w(TAG, "Unable to retrieve gids", e); 2747 } 2748 2749 /* 2750 * Add shared application GID so applications can share some 2751 * resources like shared libraries 2752 */ 2753 if (permGids == null) { 2754 gids = new int[1]; 2755 } else { 2756 gids = new int[permGids.length + 1]; 2757 System.arraycopy(permGids, 0, gids, 1, permGids.length); 2758 } 2759 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 2760 } 2761 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) { 2762 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2763 && mTopComponent != null 2764 && app.processName.equals(mTopComponent.getPackageName())) { 2765 uid = 0; 2766 } 2767 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL 2768 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) { 2769 uid = 0; 2770 } 2771 } 2772 int debugFlags = 0; 2773 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 2774 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER; 2775 // Also turn on CheckJNI for debuggable apps. It's quite 2776 // awkward to turn on otherwise. 2777 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2778 } 2779 // Run the app in safe mode if its manifest requests so or the 2780 // system is booted in safe mode. 2781 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 2782 mSafeMode == true) { 2783 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 2784 } 2785 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 2786 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 2787 } 2788 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 2789 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 2790 } 2791 if ("1".equals(SystemProperties.get("debug.assert"))) { 2792 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; 2793 } 2794 2795 String requiredAbi = app.info.requiredCpuAbi; 2796 if (requiredAbi == null) { 2797 requiredAbi = Build.SUPPORTED_ABIS[0]; 2798 } 2799 2800 // Start the process. It will either succeed and return a result containing 2801 // the PID of the new process, or else throw a RuntimeException. 2802 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", 2803 app.processName, uid, uid, gids, debugFlags, mountExternal, 2804 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null); 2805 2806 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 2807 synchronized (bs) { 2808 if (bs.isOnBattery()) { 2809 bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked(); 2810 } 2811 } 2812 2813 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2814 UserHandle.getUserId(uid), startResult.pid, uid, 2815 app.processName, hostingType, 2816 hostingNameStr != null ? hostingNameStr : ""); 2817 2818 if (app.persistent) { 2819 Watchdog.getInstance().processStarted(app.processName, startResult.pid); 2820 } 2821 2822 StringBuilder buf = mStringBuilder; 2823 buf.setLength(0); 2824 buf.append("Start proc "); 2825 buf.append(app.processName); 2826 buf.append(" for "); 2827 buf.append(hostingType); 2828 if (hostingNameStr != null) { 2829 buf.append(" "); 2830 buf.append(hostingNameStr); 2831 } 2832 buf.append(": pid="); 2833 buf.append(startResult.pid); 2834 buf.append(" uid="); 2835 buf.append(uid); 2836 buf.append(" gids={"); 2837 if (gids != null) { 2838 for (int gi=0; gi<gids.length; gi++) { 2839 if (gi != 0) buf.append(", "); 2840 buf.append(gids[gi]); 2841 2842 } 2843 } 2844 buf.append("}"); 2845 Slog.i(TAG, buf.toString()); 2846 app.setPid(startResult.pid); 2847 app.usingWrapper = startResult.usingWrapper; 2848 app.removed = false; 2849 synchronized (mPidsSelfLocked) { 2850 this.mPidsSelfLocked.put(startResult.pid, app); 2851 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2852 msg.obj = app; 2853 mHandler.sendMessageDelayed(msg, startResult.usingWrapper 2854 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2855 } 2856 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START, 2857 app.processName, app.info.uid); 2858 if (app.isolated) { 2859 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid); 2860 } 2861 } catch (RuntimeException e) { 2862 // XXX do better error recovery. 2863 app.setPid(0); 2864 Slog.e(TAG, "Failure starting process " + app.processName, e); 2865 } 2866 } 2867 2868 void updateUsageStats(ActivityRecord component, boolean resumed) { 2869 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed); 2870 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 2871 if (resumed) { 2872 mUsageStatsService.noteResumeComponent(component.realActivity); 2873 synchronized (stats) { 2874 stats.noteActivityResumedLocked(component.app.uid); 2875 } 2876 } else { 2877 mUsageStatsService.notePauseComponent(component.realActivity); 2878 synchronized (stats) { 2879 stats.noteActivityPausedLocked(component.app.uid); 2880 } 2881 } 2882 } 2883 2884 Intent getHomeIntent() { 2885 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null); 2886 intent.setComponent(mTopComponent); 2887 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 2888 intent.addCategory(Intent.CATEGORY_HOME); 2889 } 2890 return intent; 2891 } 2892 2893 boolean startHomeActivityLocked(int userId) { 2894 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL 2895 && mTopAction == null) { 2896 // We are running in factory test mode, but unable to find 2897 // the factory test app, so just sit around displaying the 2898 // error message and don't try to start anything. 2899 return false; 2900 } 2901 Intent intent = getHomeIntent(); 2902 ActivityInfo aInfo = 2903 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId); 2904 if (aInfo != null) { 2905 intent.setComponent(new ComponentName( 2906 aInfo.applicationInfo.packageName, aInfo.name)); 2907 // Don't do this if the home app is currently being 2908 // instrumented. 2909 aInfo = new ActivityInfo(aInfo); 2910 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId); 2911 ProcessRecord app = getProcessRecordLocked(aInfo.processName, 2912 aInfo.applicationInfo.uid, true); 2913 if (app == null || app.instrumentationClass == null) { 2914 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK); 2915 mStackSupervisor.startHomeActivity(intent, aInfo); 2916 } 2917 } 2918 2919 return true; 2920 } 2921 2922 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) { 2923 ActivityInfo ai = null; 2924 ComponentName comp = intent.getComponent(); 2925 try { 2926 if (comp != null) { 2927 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId); 2928 } else { 2929 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent( 2930 intent, 2931 intent.resolveTypeIfNeeded(mContext.getContentResolver()), 2932 flags, userId); 2933 2934 if (info != null) { 2935 ai = info.activityInfo; 2936 } 2937 } 2938 } catch (RemoteException e) { 2939 // ignore 2940 } 2941 2942 return ai; 2943 } 2944 2945 /** 2946 * Starts the "new version setup screen" if appropriate. 2947 */ 2948 void startSetupActivityLocked() { 2949 // Only do this once per boot. 2950 if (mCheckedForSetup) { 2951 return; 2952 } 2953 2954 // We will show this screen if the current one is a different 2955 // version than the last one shown, and we are not running in 2956 // low-level factory test mode. 2957 final ContentResolver resolver = mContext.getContentResolver(); 2958 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL && 2959 Settings.Global.getInt(resolver, 2960 Settings.Global.DEVICE_PROVISIONED, 0) != 0) { 2961 mCheckedForSetup = true; 2962 2963 // See if we should be showing the platform update setup UI. 2964 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP); 2965 List<ResolveInfo> ris = mContext.getPackageManager() 2966 .queryIntentActivities(intent, PackageManager.GET_META_DATA); 2967 2968 // We don't allow third party apps to replace this. 2969 ResolveInfo ri = null; 2970 for (int i=0; ris != null && i<ris.size(); i++) { 2971 if ((ris.get(i).activityInfo.applicationInfo.flags 2972 & ApplicationInfo.FLAG_SYSTEM) != 0) { 2973 ri = ris.get(i); 2974 break; 2975 } 2976 } 2977 2978 if (ri != null) { 2979 String vers = ri.activityInfo.metaData != null 2980 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION) 2981 : null; 2982 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) { 2983 vers = ri.activityInfo.applicationInfo.metaData.getString( 2984 Intent.METADATA_SETUP_VERSION); 2985 } 2986 String lastVers = Settings.Secure.getString( 2987 resolver, Settings.Secure.LAST_SETUP_SHOWN); 2988 if (vers != null && !vers.equals(lastVers)) { 2989 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2990 intent.setComponent(new ComponentName( 2991 ri.activityInfo.packageName, ri.activityInfo.name)); 2992 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo, 2993 null, null, 0, 0, 0, null, 0, null, false, null, null); 2994 } 2995 } 2996 } 2997 } 2998 2999 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) { 3000 return mCompatModePackages.compatibilityInfoForPackageLocked(ai); 3001 } 3002 3003 void enforceNotIsolatedCaller(String caller) { 3004 if (UserHandle.isIsolated(Binder.getCallingUid())) { 3005 throw new SecurityException("Isolated process not allowed to call " + caller); 3006 } 3007 } 3008 3009 @Override 3010 public int getFrontActivityScreenCompatMode() { 3011 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode"); 3012 synchronized (this) { 3013 return mCompatModePackages.getFrontActivityScreenCompatModeLocked(); 3014 } 3015 } 3016 3017 @Override 3018 public void setFrontActivityScreenCompatMode(int mode) { 3019 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3020 "setFrontActivityScreenCompatMode"); 3021 synchronized (this) { 3022 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode); 3023 } 3024 } 3025 3026 @Override 3027 public int getPackageScreenCompatMode(String packageName) { 3028 enforceNotIsolatedCaller("getPackageScreenCompatMode"); 3029 synchronized (this) { 3030 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName); 3031 } 3032 } 3033 3034 @Override 3035 public void setPackageScreenCompatMode(String packageName, int mode) { 3036 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3037 "setPackageScreenCompatMode"); 3038 synchronized (this) { 3039 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode); 3040 } 3041 } 3042 3043 @Override 3044 public boolean getPackageAskScreenCompat(String packageName) { 3045 enforceNotIsolatedCaller("getPackageAskScreenCompat"); 3046 synchronized (this) { 3047 return mCompatModePackages.getPackageAskCompatModeLocked(packageName); 3048 } 3049 } 3050 3051 @Override 3052 public void setPackageAskScreenCompat(String packageName, boolean ask) { 3053 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY, 3054 "setPackageAskScreenCompat"); 3055 synchronized (this) { 3056 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask); 3057 } 3058 } 3059 3060 private void dispatchProcessesChanged() { 3061 int N; 3062 synchronized (this) { 3063 N = mPendingProcessChanges.size(); 3064 if (mActiveProcessChanges.length < N) { 3065 mActiveProcessChanges = new ProcessChangeItem[N]; 3066 } 3067 mPendingProcessChanges.toArray(mActiveProcessChanges); 3068 mAvailProcessChanges.addAll(mPendingProcessChanges); 3069 mPendingProcessChanges.clear(); 3070 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes"); 3071 } 3072 3073 int i = mProcessObservers.beginBroadcast(); 3074 while (i > 0) { 3075 i--; 3076 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3077 if (observer != null) { 3078 try { 3079 for (int j=0; j<N; j++) { 3080 ProcessChangeItem item = mActiveProcessChanges[j]; 3081 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) { 3082 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid=" 3083 + item.pid + " uid=" + item.uid + ": " 3084 + item.foregroundActivities); 3085 observer.onForegroundActivitiesChanged(item.pid, item.uid, 3086 item.foregroundActivities); 3087 } 3088 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) { 3089 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid=" 3090 + item.pid + " uid=" + item.uid + ": " + item.importance); 3091 observer.onImportanceChanged(item.pid, item.uid, 3092 item.importance); 3093 } 3094 } 3095 } catch (RemoteException e) { 3096 } 3097 } 3098 } 3099 mProcessObservers.finishBroadcast(); 3100 } 3101 3102 private void dispatchProcessDied(int pid, int uid) { 3103 int i = mProcessObservers.beginBroadcast(); 3104 while (i > 0) { 3105 i--; 3106 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i); 3107 if (observer != null) { 3108 try { 3109 observer.onProcessDied(pid, uid); 3110 } catch (RemoteException e) { 3111 } 3112 } 3113 } 3114 mProcessObservers.finishBroadcast(); 3115 } 3116 3117 final void doPendingActivityLaunchesLocked(boolean doResume) { 3118 final int N = mPendingActivityLaunches.size(); 3119 if (N <= 0) { 3120 return; 3121 } 3122 for (int i=0; i<N; i++) { 3123 PendingActivityLaunch pal = mPendingActivityLaunches.get(i); 3124 mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, 3125 doResume && i == (N-1), null); 3126 } 3127 mPendingActivityLaunches.clear(); 3128 } 3129 3130 @Override 3131 public final int startActivity(IApplicationThread caller, String callingPackage, 3132 Intent intent, String resolvedType, IBinder resultTo, 3133 String resultWho, int requestCode, int startFlags, 3134 String profileFile, ParcelFileDescriptor profileFd, Bundle options) { 3135 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, 3136 resultWho, requestCode, 3137 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId()); 3138 } 3139 3140 @Override 3141 public final int startActivityAsUser(IApplicationThread caller, String callingPackage, 3142 Intent intent, String resolvedType, IBinder resultTo, 3143 String resultWho, int requestCode, int startFlags, 3144 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) { 3145 enforceNotIsolatedCaller("startActivity"); 3146 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3147 false, true, "startActivity", null); 3148 // TODO: Switch to user app stacks here. 3149 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3150 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3151 null, null, options, userId, null); 3152 } 3153 3154 @Override 3155 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage, 3156 Intent intent, String resolvedType, IBinder resultTo, 3157 String resultWho, int requestCode, int startFlags, String profileFile, 3158 ParcelFileDescriptor profileFd, Bundle options, int userId) { 3159 enforceNotIsolatedCaller("startActivityAndWait"); 3160 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3161 false, true, "startActivityAndWait", null); 3162 WaitResult res = new WaitResult(); 3163 // TODO: Switch to user app stacks here. 3164 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType, 3165 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd, 3166 res, null, options, UserHandle.getCallingUserId(), null); 3167 return res; 3168 } 3169 3170 @Override 3171 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage, 3172 Intent intent, String resolvedType, IBinder resultTo, 3173 String resultWho, int requestCode, int startFlags, Configuration config, 3174 Bundle options, int userId) { 3175 enforceNotIsolatedCaller("startActivityWithConfig"); 3176 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3177 false, true, "startActivityWithConfig", null); 3178 // TODO: Switch to user app stacks here. 3179 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, 3180 resolvedType, resultTo, resultWho, requestCode, startFlags, 3181 null, null, null, config, options, userId, null); 3182 return ret; 3183 } 3184 3185 @Override 3186 public int startActivityIntentSender(IApplicationThread caller, 3187 IntentSender intent, Intent fillInIntent, String resolvedType, 3188 IBinder resultTo, String resultWho, int requestCode, 3189 int flagsMask, int flagsValues, Bundle options) { 3190 enforceNotIsolatedCaller("startActivityIntentSender"); 3191 // Refuse possible leaked file descriptors 3192 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) { 3193 throw new IllegalArgumentException("File descriptors passed in Intent"); 3194 } 3195 3196 IIntentSender sender = intent.getTarget(); 3197 if (!(sender instanceof PendingIntentRecord)) { 3198 throw new IllegalArgumentException("Bad PendingIntent object"); 3199 } 3200 3201 PendingIntentRecord pir = (PendingIntentRecord)sender; 3202 3203 synchronized (this) { 3204 // If this is coming from the currently resumed activity, it is 3205 // effectively saying that app switches are allowed at this point. 3206 final ActivityStack stack = getFocusedStack(); 3207 if (stack.mResumedActivity != null && 3208 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) { 3209 mAppSwitchesAllowedTime = 0; 3210 } 3211 } 3212 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null, 3213 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null); 3214 return ret; 3215 } 3216 3217 @Override 3218 public boolean startNextMatchingActivity(IBinder callingActivity, 3219 Intent intent, Bundle options) { 3220 // Refuse possible leaked file descriptors 3221 if (intent != null && intent.hasFileDescriptors() == true) { 3222 throw new IllegalArgumentException("File descriptors passed in Intent"); 3223 } 3224 3225 synchronized (this) { 3226 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity); 3227 if (r == null) { 3228 ActivityOptions.abort(options); 3229 return false; 3230 } 3231 if (r.app == null || r.app.thread == null) { 3232 // The caller is not running... d'oh! 3233 ActivityOptions.abort(options); 3234 return false; 3235 } 3236 intent = new Intent(intent); 3237 // The caller is not allowed to change the data. 3238 intent.setDataAndType(r.intent.getData(), r.intent.getType()); 3239 // And we are resetting to find the next component... 3240 intent.setComponent(null); 3241 3242 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); 3243 3244 ActivityInfo aInfo = null; 3245 try { 3246 List<ResolveInfo> resolves = 3247 AppGlobals.getPackageManager().queryIntentActivities( 3248 intent, r.resolvedType, 3249 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS, 3250 UserHandle.getCallingUserId()); 3251 3252 // Look for the original activity in the list... 3253 final int N = resolves != null ? resolves.size() : 0; 3254 for (int i=0; i<N; i++) { 3255 ResolveInfo rInfo = resolves.get(i); 3256 if (rInfo.activityInfo.packageName.equals(r.packageName) 3257 && rInfo.activityInfo.name.equals(r.info.name)) { 3258 // We found the current one... the next matching is 3259 // after it. 3260 i++; 3261 if (i<N) { 3262 aInfo = resolves.get(i).activityInfo; 3263 } 3264 if (debug) { 3265 Slog.v(TAG, "Next matching activity: found current " + r.packageName 3266 + "/" + r.info.name); 3267 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName 3268 + "/" + aInfo.name); 3269 } 3270 break; 3271 } 3272 } 3273 } catch (RemoteException e) { 3274 } 3275 3276 if (aInfo == null) { 3277 // Nobody who is next! 3278 ActivityOptions.abort(options); 3279 if (debug) Slog.d(TAG, "Next matching activity: nothing found"); 3280 return false; 3281 } 3282 3283 intent.setComponent(new ComponentName( 3284 aInfo.applicationInfo.packageName, aInfo.name)); 3285 intent.setFlags(intent.getFlags()&~( 3286 Intent.FLAG_ACTIVITY_FORWARD_RESULT| 3287 Intent.FLAG_ACTIVITY_CLEAR_TOP| 3288 Intent.FLAG_ACTIVITY_MULTIPLE_TASK| 3289 Intent.FLAG_ACTIVITY_NEW_TASK)); 3290 3291 // Okay now we need to start the new activity, replacing the 3292 // currently running activity. This is a little tricky because 3293 // we want to start the new one as if the current one is finished, 3294 // but not finish the current one first so that there is no flicker. 3295 // And thus... 3296 final boolean wasFinishing = r.finishing; 3297 r.finishing = true; 3298 3299 // Propagate reply information over to the new activity. 3300 final ActivityRecord resultTo = r.resultTo; 3301 final String resultWho = r.resultWho; 3302 final int requestCode = r.requestCode; 3303 r.resultTo = null; 3304 if (resultTo != null) { 3305 resultTo.removeResultsLocked(r, resultWho, requestCode); 3306 } 3307 3308 final long origId = Binder.clearCallingIdentity(); 3309 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent, 3310 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null, 3311 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0, 3312 options, false, null, null); 3313 Binder.restoreCallingIdentity(origId); 3314 3315 r.finishing = wasFinishing; 3316 if (res != ActivityManager.START_SUCCESS) { 3317 return false; 3318 } 3319 return true; 3320 } 3321 } 3322 3323 final int startActivityInPackage(int uid, String callingPackage, 3324 Intent intent, String resolvedType, IBinder resultTo, 3325 String resultWho, int requestCode, int startFlags, Bundle options, int userId, 3326 IActivityContainer container) { 3327 3328 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3329 false, true, "startActivityInPackage", null); 3330 3331 // TODO: Switch to user app stacks here. 3332 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType, 3333 resultTo, resultWho, requestCode, startFlags, 3334 null, null, null, null, options, userId, container); 3335 return ret; 3336 } 3337 3338 @Override 3339 public final int startActivities(IApplicationThread caller, String callingPackage, 3340 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options, 3341 int userId) { 3342 enforceNotIsolatedCaller("startActivities"); 3343 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3344 false, true, "startActivity", null); 3345 // TODO: Switch to user app stacks here. 3346 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents, 3347 resolvedTypes, resultTo, options, userId); 3348 return ret; 3349 } 3350 3351 final int startActivitiesInPackage(int uid, String callingPackage, 3352 Intent[] intents, String[] resolvedTypes, IBinder resultTo, 3353 Bundle options, int userId) { 3354 3355 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 3356 false, true, "startActivityInPackage", null); 3357 // TODO: Switch to user app stacks here. 3358 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes, 3359 resultTo, options, userId); 3360 return ret; 3361 } 3362 3363 final void addRecentTaskLocked(TaskRecord task) { 3364 int N = mRecentTasks.size(); 3365 // Quick case: check if the top-most recent task is the same. 3366 if (N > 0 && mRecentTasks.get(0) == task) { 3367 return; 3368 } 3369 // Remove any existing entries that are the same kind of task. 3370 final Intent intent = task.intent; 3371 final boolean document = intent != null && intent.isDocument(); 3372 for (int i=0; i<N; i++) { 3373 TaskRecord tr = mRecentTasks.get(i); 3374 if (task != tr) { 3375 if (task.userId != tr.userId) { 3376 continue; 3377 } 3378 final Intent trIntent = tr.intent; 3379 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) && 3380 (intent == null || !intent.filterEquals(trIntent))) { 3381 continue; 3382 } 3383 if (document || trIntent != null && trIntent.isDocument()) { 3384 // Document tasks do not match other tasks. 3385 continue; 3386 } 3387 } 3388 3389 // Either task and tr are the same or, their affinities match or their intents match 3390 // and neither of them is a document. 3391 tr.disposeThumbnail(); 3392 mRecentTasks.remove(i); 3393 i--; 3394 N--; 3395 if (task.intent == null) { 3396 // If the new recent task we are adding is not fully 3397 // specified, then replace it with the existing recent task. 3398 task = tr; 3399 } 3400 } 3401 if (N >= MAX_RECENT_TASKS) { 3402 mRecentTasks.remove(N-1).disposeThumbnail(); 3403 } 3404 mRecentTasks.add(0, task); 3405 } 3406 3407 @Override 3408 public void reportActivityFullyDrawn(IBinder token) { 3409 synchronized (this) { 3410 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3411 if (r == null) { 3412 return; 3413 } 3414 r.reportFullyDrawnLocked(); 3415 } 3416 } 3417 3418 @Override 3419 public void setRequestedOrientation(IBinder token, int requestedOrientation) { 3420 synchronized (this) { 3421 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3422 if (r == null) { 3423 return; 3424 } 3425 final long origId = Binder.clearCallingIdentity(); 3426 mWindowManager.setAppOrientation(r.appToken, requestedOrientation); 3427 Configuration config = mWindowManager.updateOrientationFromAppTokens( 3428 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null); 3429 if (config != null) { 3430 r.frozenBeforeDestroy = true; 3431 if (!updateConfigurationLocked(config, r, false, false)) { 3432 mStackSupervisor.resumeTopActivitiesLocked(); 3433 } 3434 } 3435 Binder.restoreCallingIdentity(origId); 3436 } 3437 } 3438 3439 @Override 3440 public int getRequestedOrientation(IBinder token) { 3441 synchronized (this) { 3442 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3443 if (r == null) { 3444 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; 3445 } 3446 return mWindowManager.getAppOrientation(r.appToken); 3447 } 3448 } 3449 3450 /** 3451 * This is the internal entry point for handling Activity.finish(). 3452 * 3453 * @param token The Binder token referencing the Activity we want to finish. 3454 * @param resultCode Result code, if any, from this Activity. 3455 * @param resultData Result data (Intent), if any, from this Activity. 3456 * 3457 * @return Returns true if the activity successfully finished, or false if it is still running. 3458 */ 3459 @Override 3460 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) { 3461 // Refuse possible leaked file descriptors 3462 if (resultData != null && resultData.hasFileDescriptors() == true) { 3463 throw new IllegalArgumentException("File descriptors passed in Intent"); 3464 } 3465 3466 synchronized(this) { 3467 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3468 if (r == null) { 3469 return true; 3470 } 3471 if (mController != null) { 3472 // Find the first activity that is not finishing. 3473 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0); 3474 if (next != null) { 3475 // ask watcher if this is allowed 3476 boolean resumeOK = true; 3477 try { 3478 resumeOK = mController.activityResuming(next.packageName); 3479 } catch (RemoteException e) { 3480 mController = null; 3481 Watchdog.getInstance().setActivityController(null); 3482 } 3483 3484 if (!resumeOK) { 3485 return false; 3486 } 3487 } 3488 } 3489 final long origId = Binder.clearCallingIdentity(); 3490 boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode, 3491 resultData, "app-request", true); 3492 Binder.restoreCallingIdentity(origId); 3493 return res; 3494 } 3495 } 3496 3497 @Override 3498 public final void finishHeavyWeightApp() { 3499 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3500 != PackageManager.PERMISSION_GRANTED) { 3501 String msg = "Permission Denial: finishHeavyWeightApp() from pid=" 3502 + Binder.getCallingPid() 3503 + ", uid=" + Binder.getCallingUid() 3504 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3505 Slog.w(TAG, msg); 3506 throw new SecurityException(msg); 3507 } 3508 3509 synchronized(this) { 3510 if (mHeavyWeightProcess == null) { 3511 return; 3512 } 3513 3514 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>( 3515 mHeavyWeightProcess.activities); 3516 for (int i=0; i<activities.size(); i++) { 3517 ActivityRecord r = activities.get(i); 3518 if (!r.finishing) { 3519 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, 3520 null, "finish-heavy", true); 3521 } 3522 } 3523 3524 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 3525 mHeavyWeightProcess.userId, 0)); 3526 mHeavyWeightProcess = null; 3527 } 3528 } 3529 3530 @Override 3531 public void crashApplication(int uid, int initialPid, String packageName, 3532 String message) { 3533 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 3534 != PackageManager.PERMISSION_GRANTED) { 3535 String msg = "Permission Denial: crashApplication() from pid=" 3536 + Binder.getCallingPid() 3537 + ", uid=" + Binder.getCallingUid() 3538 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 3539 Slog.w(TAG, msg); 3540 throw new SecurityException(msg); 3541 } 3542 3543 synchronized(this) { 3544 ProcessRecord proc = null; 3545 3546 // Figure out which process to kill. We don't trust that initialPid 3547 // still has any relation to current pids, so must scan through the 3548 // list. 3549 synchronized (mPidsSelfLocked) { 3550 for (int i=0; i<mPidsSelfLocked.size(); i++) { 3551 ProcessRecord p = mPidsSelfLocked.valueAt(i); 3552 if (p.uid != uid) { 3553 continue; 3554 } 3555 if (p.pid == initialPid) { 3556 proc = p; 3557 break; 3558 } 3559 if (p.pkgList.containsKey(packageName)) { 3560 proc = p; 3561 } 3562 } 3563 } 3564 3565 if (proc == null) { 3566 Slog.w(TAG, "crashApplication: nothing for uid=" + uid 3567 + " initialPid=" + initialPid 3568 + " packageName=" + packageName); 3569 return; 3570 } 3571 3572 if (proc.thread != null) { 3573 if (proc.pid == Process.myPid()) { 3574 Log.w(TAG, "crashApplication: trying to crash self!"); 3575 return; 3576 } 3577 long ident = Binder.clearCallingIdentity(); 3578 try { 3579 proc.thread.scheduleCrash(message); 3580 } catch (RemoteException e) { 3581 } 3582 Binder.restoreCallingIdentity(ident); 3583 } 3584 } 3585 } 3586 3587 @Override 3588 public final void finishSubActivity(IBinder token, String resultWho, 3589 int requestCode) { 3590 synchronized(this) { 3591 final long origId = Binder.clearCallingIdentity(); 3592 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3593 if (r != null) { 3594 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode); 3595 } 3596 Binder.restoreCallingIdentity(origId); 3597 } 3598 } 3599 3600 @Override 3601 public boolean finishActivityAffinity(IBinder token) { 3602 synchronized(this) { 3603 final long origId = Binder.clearCallingIdentity(); 3604 ActivityRecord r = ActivityRecord.isInStackLocked(token); 3605 boolean res = false; 3606 if (r != null) { 3607 res = r.task.stack.finishActivityAffinityLocked(r); 3608 } 3609 Binder.restoreCallingIdentity(origId); 3610 return res; 3611 } 3612 } 3613 3614 @Override 3615 public boolean willActivityBeVisible(IBinder token) { 3616 synchronized(this) { 3617 ActivityStack stack = ActivityRecord.getStackLocked(token); 3618 if (stack != null) { 3619 return stack.willActivityBeVisibleLocked(token); 3620 } 3621 return false; 3622 } 3623 } 3624 3625 @Override 3626 public void overridePendingTransition(IBinder token, String packageName, 3627 int enterAnim, int exitAnim) { 3628 synchronized(this) { 3629 ActivityRecord self = ActivityRecord.isInStackLocked(token); 3630 if (self == null) { 3631 return; 3632 } 3633 3634 final long origId = Binder.clearCallingIdentity(); 3635 3636 if (self.state == ActivityState.RESUMED 3637 || self.state == ActivityState.PAUSING) { 3638 mWindowManager.overridePendingAppTransition(packageName, 3639 enterAnim, exitAnim, null); 3640 } 3641 3642 Binder.restoreCallingIdentity(origId); 3643 } 3644 } 3645 3646 /** 3647 * Main function for removing an existing process from the activity manager 3648 * as a result of that process going away. Clears out all connections 3649 * to the process. 3650 */ 3651 private final void handleAppDiedLocked(ProcessRecord app, 3652 boolean restarting, boolean allowRestart) { 3653 int pid = app.pid; 3654 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1); 3655 if (!restarting) { 3656 removeLruProcessLocked(app); 3657 if (pid > 0) { 3658 ProcessList.remove(pid); 3659 } 3660 } 3661 3662 if (mProfileProc == app) { 3663 clearProfilerLocked(); 3664 } 3665 3666 // Remove this application's activities from active lists. 3667 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app); 3668 3669 app.activities.clear(); 3670 3671 if (app.instrumentationClass != null) { 3672 Slog.w(TAG, "Crash of app " + app.processName 3673 + " running instrumentation " + app.instrumentationClass); 3674 Bundle info = new Bundle(); 3675 info.putString("shortMsg", "Process crashed."); 3676 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info); 3677 } 3678 3679 if (!restarting) { 3680 if (!mStackSupervisor.resumeTopActivitiesLocked()) { 3681 // If there was nothing to resume, and we are not already 3682 // restarting this process, but there is a visible activity that 3683 // is hosted by the process... then make sure all visible 3684 // activities are running, taking care of restarting this 3685 // process. 3686 if (hasVisibleActivities) { 3687 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 3688 } 3689 } 3690 } 3691 } 3692 3693 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) { 3694 IBinder threadBinder = thread.asBinder(); 3695 // Find the application record. 3696 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3697 ProcessRecord rec = mLruProcesses.get(i); 3698 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 3699 return i; 3700 } 3701 } 3702 return -1; 3703 } 3704 3705 final ProcessRecord getRecordForAppLocked( 3706 IApplicationThread thread) { 3707 if (thread == null) { 3708 return null; 3709 } 3710 3711 int appIndex = getLRURecordIndexForAppLocked(thread); 3712 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null; 3713 } 3714 3715 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) { 3716 // If there are no longer any background processes running, 3717 // and the app that died was not running instrumentation, 3718 // then tell everyone we are now low on memory. 3719 boolean haveBg = false; 3720 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3721 ProcessRecord rec = mLruProcesses.get(i); 3722 if (rec.thread != null 3723 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 3724 haveBg = true; 3725 break; 3726 } 3727 } 3728 3729 if (!haveBg) { 3730 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 3731 if (doReport) { 3732 long now = SystemClock.uptimeMillis(); 3733 if (now < (mLastMemUsageReportTime+5*60*1000)) { 3734 doReport = false; 3735 } else { 3736 mLastMemUsageReportTime = now; 3737 } 3738 } 3739 final ArrayList<ProcessMemInfo> memInfos 3740 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null; 3741 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size()); 3742 long now = SystemClock.uptimeMillis(); 3743 for (int i=mLruProcesses.size()-1; i>=0; i--) { 3744 ProcessRecord rec = mLruProcesses.get(i); 3745 if (rec == dyingProc || rec.thread == null) { 3746 continue; 3747 } 3748 if (doReport) { 3749 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj, 3750 rec.setProcState, rec.adjType, rec.makeAdjReason())); 3751 } 3752 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { 3753 // The low memory report is overriding any current 3754 // state for a GC request. Make sure to do 3755 // heavy/important/visible/foreground processes first. 3756 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 3757 rec.lastRequestedGc = 0; 3758 } else { 3759 rec.lastRequestedGc = rec.lastLowMemory; 3760 } 3761 rec.reportLowMemory = true; 3762 rec.lastLowMemory = now; 3763 mProcessesToGc.remove(rec); 3764 addProcessToGcListLocked(rec); 3765 } 3766 } 3767 if (doReport) { 3768 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos); 3769 mHandler.sendMessage(msg); 3770 } 3771 scheduleAppGcsLocked(); 3772 } 3773 } 3774 3775 final void appDiedLocked(ProcessRecord app, int pid, 3776 IApplicationThread thread) { 3777 3778 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 3779 synchronized (stats) { 3780 stats.noteProcessDiedLocked(app.info.uid, pid); 3781 } 3782 3783 // Clean up already done if the process has been re-started. 3784 if (app.pid == pid && app.thread != null && 3785 app.thread.asBinder() == thread.asBinder()) { 3786 boolean doLowMem = app.instrumentationClass == null; 3787 boolean doOomAdj = doLowMem; 3788 if (!app.killedByAm) { 3789 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3790 + ") has died."); 3791 mAllowLowerMemLevel = true; 3792 } else { 3793 // Note that we always want to do oom adj to update our state with the 3794 // new number of procs. 3795 mAllowLowerMemLevel = false; 3796 doLowMem = false; 3797 } 3798 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3799 if (DEBUG_CLEANUP) Slog.v( 3800 TAG, "Dying app: " + app + ", pid: " + pid 3801 + ", thread: " + thread.asBinder()); 3802 handleAppDiedLocked(app, false, true); 3803 3804 if (doOomAdj) { 3805 updateOomAdjLocked(); 3806 } 3807 if (doLowMem) { 3808 doLowMemReportIfNeededLocked(app); 3809 } 3810 } else if (app.pid != pid) { 3811 // A new process has already been started. 3812 Slog.i(TAG, "Process " + app.processName + " (pid " + pid 3813 + ") has died and restarted (pid " + app.pid + ")."); 3814 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); 3815 } else if (DEBUG_PROCESSES) { 3816 Slog.d(TAG, "Received spurious death notification for thread " 3817 + thread.asBinder()); 3818 } 3819 } 3820 3821 /** 3822 * If a stack trace dump file is configured, dump process stack traces. 3823 * @param clearTraces causes the dump file to be erased prior to the new 3824 * traces being written, if true; when false, the new traces will be 3825 * appended to any existing file content. 3826 * @param firstPids of dalvik VM processes to dump stack traces for first 3827 * @param lastPids of dalvik VM processes to dump stack traces for last 3828 * @param nativeProcs optional list of native process names to dump stack crawls 3829 * @return file containing stack traces, or null if no dump file is configured 3830 */ 3831 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, 3832 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3833 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3834 if (tracesPath == null || tracesPath.length() == 0) { 3835 return null; 3836 } 3837 3838 File tracesFile = new File(tracesPath); 3839 try { 3840 File tracesDir = tracesFile.getParentFile(); 3841 if (!tracesDir.exists()) { 3842 tracesFile.mkdirs(); 3843 if (!SELinux.restorecon(tracesDir)) { 3844 return null; 3845 } 3846 } 3847 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3848 3849 if (clearTraces && tracesFile.exists()) tracesFile.delete(); 3850 tracesFile.createNewFile(); 3851 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3852 } catch (IOException e) { 3853 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e); 3854 return null; 3855 } 3856 3857 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs); 3858 return tracesFile; 3859 } 3860 3861 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, 3862 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) { 3863 // Use a FileObserver to detect when traces finish writing. 3864 // The order of traces is considered important to maintain for legibility. 3865 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) { 3866 @Override 3867 public synchronized void onEvent(int event, String path) { notify(); } 3868 }; 3869 3870 try { 3871 observer.startWatching(); 3872 3873 // First collect all of the stacks of the most important pids. 3874 if (firstPids != null) { 3875 try { 3876 int num = firstPids.size(); 3877 for (int i = 0; i < num; i++) { 3878 synchronized (observer) { 3879 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT); 3880 observer.wait(200); // Wait for write-close, give up after 200msec 3881 } 3882 } 3883 } catch (InterruptedException e) { 3884 Log.wtf(TAG, e); 3885 } 3886 } 3887 3888 // Next collect the stacks of the native pids 3889 if (nativeProcs != null) { 3890 int[] pids = Process.getPidsForCommands(nativeProcs); 3891 if (pids != null) { 3892 for (int pid : pids) { 3893 Debug.dumpNativeBacktraceToFile(pid, tracesPath); 3894 } 3895 } 3896 } 3897 3898 // Lastly, measure CPU usage. 3899 if (processCpuTracker != null) { 3900 processCpuTracker.init(); 3901 System.gc(); 3902 processCpuTracker.update(); 3903 try { 3904 synchronized (processCpuTracker) { 3905 processCpuTracker.wait(500); // measure over 1/2 second. 3906 } 3907 } catch (InterruptedException e) { 3908 } 3909 processCpuTracker.update(); 3910 3911 // We'll take the stack crawls of just the top apps using CPU. 3912 final int N = processCpuTracker.countWorkingStats(); 3913 int numProcs = 0; 3914 for (int i=0; i<N && numProcs<5; i++) { 3915 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i); 3916 if (lastPids.indexOfKey(stats.pid) >= 0) { 3917 numProcs++; 3918 try { 3919 synchronized (observer) { 3920 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT); 3921 observer.wait(200); // Wait for write-close, give up after 200msec 3922 } 3923 } catch (InterruptedException e) { 3924 Log.wtf(TAG, e); 3925 } 3926 3927 } 3928 } 3929 } 3930 } finally { 3931 observer.stopWatching(); 3932 } 3933 } 3934 3935 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) { 3936 if (true || IS_USER_BUILD) { 3937 return; 3938 } 3939 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null); 3940 if (tracesPath == null || tracesPath.length() == 0) { 3941 return; 3942 } 3943 3944 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 3945 StrictMode.allowThreadDiskWrites(); 3946 try { 3947 final File tracesFile = new File(tracesPath); 3948 final File tracesDir = tracesFile.getParentFile(); 3949 final File tracesTmp = new File(tracesDir, "__tmp__"); 3950 try { 3951 if (!tracesDir.exists()) { 3952 tracesFile.mkdirs(); 3953 if (!SELinux.restorecon(tracesDir.getPath())) { 3954 return; 3955 } 3956 } 3957 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x 3958 3959 if (tracesFile.exists()) { 3960 tracesTmp.delete(); 3961 tracesFile.renameTo(tracesTmp); 3962 } 3963 StringBuilder sb = new StringBuilder(); 3964 Time tobj = new Time(); 3965 tobj.set(System.currentTimeMillis()); 3966 sb.append(tobj.format("%Y-%m-%d %H:%M:%S")); 3967 sb.append(": "); 3968 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb); 3969 sb.append(" since "); 3970 sb.append(msg); 3971 FileOutputStream fos = new FileOutputStream(tracesFile); 3972 fos.write(sb.toString().getBytes()); 3973 if (app == null) { 3974 fos.write("\n*** No application process!".getBytes()); 3975 } 3976 fos.close(); 3977 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw- 3978 } catch (IOException e) { 3979 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e); 3980 return; 3981 } 3982 3983 if (app != null) { 3984 ArrayList<Integer> firstPids = new ArrayList<Integer>(); 3985 firstPids.add(app.pid); 3986 dumpStackTraces(tracesPath, firstPids, null, null, null); 3987 } 3988 3989 File lastTracesFile = null; 3990 File curTracesFile = null; 3991 for (int i=9; i>=0; i--) { 3992 String name = String.format(Locale.US, "slow%02d.txt", i); 3993 curTracesFile = new File(tracesDir, name); 3994 if (curTracesFile.exists()) { 3995 if (lastTracesFile != null) { 3996 curTracesFile.renameTo(lastTracesFile); 3997 } else { 3998 curTracesFile.delete(); 3999 } 4000 } 4001 lastTracesFile = curTracesFile; 4002 } 4003 tracesFile.renameTo(curTracesFile); 4004 if (tracesTmp.exists()) { 4005 tracesTmp.renameTo(tracesFile); 4006 } 4007 } finally { 4008 StrictMode.setThreadPolicy(oldPolicy); 4009 } 4010 } 4011 4012 final void appNotResponding(ProcessRecord app, ActivityRecord activity, 4013 ActivityRecord parent, boolean aboveSystem, final String annotation) { 4014 ArrayList<Integer> firstPids = new ArrayList<Integer>(5); 4015 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20); 4016 4017 if (mController != null) { 4018 try { 4019 // 0 == continue, -1 = kill process immediately 4020 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation); 4021 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid); 4022 } catch (RemoteException e) { 4023 mController = null; 4024 Watchdog.getInstance().setActivityController(null); 4025 } 4026 } 4027 4028 long anrTime = SystemClock.uptimeMillis(); 4029 if (MONITOR_CPU_USAGE) { 4030 updateCpuStatsNow(); 4031 } 4032 4033 synchronized (this) { 4034 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down. 4035 if (mShuttingDown) { 4036 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation); 4037 return; 4038 } else if (app.notResponding) { 4039 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation); 4040 return; 4041 } else if (app.crashing) { 4042 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation); 4043 return; 4044 } 4045 4046 // In case we come through here for the same app before completing 4047 // this one, mark as anring now so we will bail out. 4048 app.notResponding = true; 4049 4050 // Log the ANR to the event log. 4051 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid, 4052 app.processName, app.info.flags, annotation); 4053 4054 // Dump thread traces as quickly as we can, starting with "interesting" processes. 4055 firstPids.add(app.pid); 4056 4057 int parentPid = app.pid; 4058 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid; 4059 if (parentPid != app.pid) firstPids.add(parentPid); 4060 4061 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID); 4062 4063 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 4064 ProcessRecord r = mLruProcesses.get(i); 4065 if (r != null && r.thread != null) { 4066 int pid = r.pid; 4067 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) { 4068 if (r.persistent) { 4069 firstPids.add(pid); 4070 } else { 4071 lastPids.put(pid, Boolean.TRUE); 4072 } 4073 } 4074 } 4075 } 4076 } 4077 4078 // Log the ANR to the main log. 4079 StringBuilder info = new StringBuilder(); 4080 info.setLength(0); 4081 info.append("ANR in ").append(app.processName); 4082 if (activity != null && activity.shortComponentName != null) { 4083 info.append(" (").append(activity.shortComponentName).append(")"); 4084 } 4085 info.append("\n"); 4086 info.append("PID: ").append(app.pid).append("\n"); 4087 if (annotation != null) { 4088 info.append("Reason: ").append(annotation).append("\n"); 4089 } 4090 if (parent != null && parent != activity) { 4091 info.append("Parent: ").append(parent.shortComponentName).append("\n"); 4092 } 4093 4094 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true); 4095 4096 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids, 4097 NATIVE_STACKS_OF_INTEREST); 4098 4099 String cpuInfo = null; 4100 if (MONITOR_CPU_USAGE) { 4101 updateCpuStatsNow(); 4102 synchronized (mProcessCpuThread) { 4103 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime); 4104 } 4105 info.append(processCpuTracker.printCurrentLoad()); 4106 info.append(cpuInfo); 4107 } 4108 4109 info.append(processCpuTracker.printCurrentState(anrTime)); 4110 4111 Slog.e(TAG, info.toString()); 4112 if (tracesFile == null) { 4113 // There is no trace file, so dump (only) the alleged culprit's threads to the log 4114 Process.sendSignal(app.pid, Process.SIGNAL_QUIT); 4115 } 4116 4117 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation, 4118 cpuInfo, tracesFile, null); 4119 4120 if (mController != null) { 4121 try { 4122 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately 4123 int res = mController.appNotResponding(app.processName, app.pid, info.toString()); 4124 if (res != 0) { 4125 if (res < 0 && app.pid != MY_PID) { 4126 Process.killProcess(app.pid); 4127 } else { 4128 synchronized (this) { 4129 mServices.scheduleServiceTimeoutLocked(app); 4130 } 4131 } 4132 return; 4133 } 4134 } catch (RemoteException e) { 4135 mController = null; 4136 Watchdog.getInstance().setActivityController(null); 4137 } 4138 } 4139 4140 // Unless configured otherwise, swallow ANRs in background processes & kill the process. 4141 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), 4142 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; 4143 4144 synchronized (this) { 4145 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) { 4146 killUnneededProcessLocked(app, "background ANR"); 4147 return; 4148 } 4149 4150 // Set the app's notResponding state, and look up the errorReportReceiver 4151 makeAppNotRespondingLocked(app, 4152 activity != null ? activity.shortComponentName : null, 4153 annotation != null ? "ANR " + annotation : "ANR", 4154 info.toString()); 4155 4156 // Bring up the infamous App Not Responding dialog 4157 Message msg = Message.obtain(); 4158 HashMap<String, Object> map = new HashMap<String, Object>(); 4159 msg.what = SHOW_NOT_RESPONDING_MSG; 4160 msg.obj = map; 4161 msg.arg1 = aboveSystem ? 1 : 0; 4162 map.put("app", app); 4163 if (activity != null) { 4164 map.put("activity", activity); 4165 } 4166 4167 mHandler.sendMessage(msg); 4168 } 4169 } 4170 4171 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) { 4172 if (!mLaunchWarningShown) { 4173 mLaunchWarningShown = true; 4174 mHandler.post(new Runnable() { 4175 @Override 4176 public void run() { 4177 synchronized (ActivityManagerService.this) { 4178 final Dialog d = new LaunchWarningWindow(mContext, cur, next); 4179 d.show(); 4180 mHandler.postDelayed(new Runnable() { 4181 @Override 4182 public void run() { 4183 synchronized (ActivityManagerService.this) { 4184 d.dismiss(); 4185 mLaunchWarningShown = false; 4186 } 4187 } 4188 }, 4000); 4189 } 4190 } 4191 }); 4192 } 4193 } 4194 4195 @Override 4196 public boolean clearApplicationUserData(final String packageName, 4197 final IPackageDataObserver observer, int userId) { 4198 enforceNotIsolatedCaller("clearApplicationUserData"); 4199 int uid = Binder.getCallingUid(); 4200 int pid = Binder.getCallingPid(); 4201 userId = handleIncomingUser(pid, uid, 4202 userId, false, true, "clearApplicationUserData", null); 4203 long callingId = Binder.clearCallingIdentity(); 4204 try { 4205 IPackageManager pm = AppGlobals.getPackageManager(); 4206 int pkgUid = -1; 4207 synchronized(this) { 4208 try { 4209 pkgUid = pm.getPackageUid(packageName, userId); 4210 } catch (RemoteException e) { 4211 } 4212 if (pkgUid == -1) { 4213 Slog.w(TAG, "Invalid packageName: " + packageName); 4214 if (observer != null) { 4215 try { 4216 observer.onRemoveCompleted(packageName, false); 4217 } catch (RemoteException e) { 4218 Slog.i(TAG, "Observer no longer exists."); 4219 } 4220 } 4221 return false; 4222 } 4223 if (uid == pkgUid || checkComponentPermission( 4224 android.Manifest.permission.CLEAR_APP_USER_DATA, 4225 pid, uid, -1, true) 4226 == PackageManager.PERMISSION_GRANTED) { 4227 forceStopPackageLocked(packageName, pkgUid, "clear data"); 4228 } else { 4229 throw new SecurityException("PID " + pid + " does not have permission " 4230 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data" 4231 + " of package " + packageName); 4232 } 4233 } 4234 4235 try { 4236 // Clear application user data 4237 pm.clearApplicationUserData(packageName, observer, userId); 4238 4239 // Remove all permissions granted from/to this package 4240 removeUriPermissionsForPackageLocked(packageName, userId, true); 4241 4242 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, 4243 Uri.fromParts("package", packageName, null)); 4244 intent.putExtra(Intent.EXTRA_UID, pkgUid); 4245 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, 4246 null, null, 0, null, null, null, false, false, userId); 4247 } catch (RemoteException e) { 4248 } 4249 } finally { 4250 Binder.restoreCallingIdentity(callingId); 4251 } 4252 return true; 4253 } 4254 4255 @Override 4256 public void killBackgroundProcesses(final String packageName, int userId) { 4257 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4258 != PackageManager.PERMISSION_GRANTED && 4259 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES) 4260 != PackageManager.PERMISSION_GRANTED) { 4261 String msg = "Permission Denial: killBackgroundProcesses() from pid=" 4262 + Binder.getCallingPid() 4263 + ", uid=" + Binder.getCallingUid() 4264 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4265 Slog.w(TAG, msg); 4266 throw new SecurityException(msg); 4267 } 4268 4269 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 4270 userId, true, true, "killBackgroundProcesses", null); 4271 long callingId = Binder.clearCallingIdentity(); 4272 try { 4273 IPackageManager pm = AppGlobals.getPackageManager(); 4274 synchronized(this) { 4275 int appId = -1; 4276 try { 4277 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0)); 4278 } catch (RemoteException e) { 4279 } 4280 if (appId == -1) { 4281 Slog.w(TAG, "Invalid packageName: " + packageName); 4282 return; 4283 } 4284 killPackageProcessesLocked(packageName, appId, userId, 4285 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background"); 4286 } 4287 } finally { 4288 Binder.restoreCallingIdentity(callingId); 4289 } 4290 } 4291 4292 @Override 4293 public void killAllBackgroundProcesses() { 4294 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES) 4295 != PackageManager.PERMISSION_GRANTED) { 4296 String msg = "Permission Denial: killAllBackgroundProcesses() from pid=" 4297 + Binder.getCallingPid() 4298 + ", uid=" + Binder.getCallingUid() 4299 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES; 4300 Slog.w(TAG, msg); 4301 throw new SecurityException(msg); 4302 } 4303 4304 long callingId = Binder.clearCallingIdentity(); 4305 try { 4306 synchronized(this) { 4307 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4308 final int NP = mProcessNames.getMap().size(); 4309 for (int ip=0; ip<NP; ip++) { 4310 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4311 final int NA = apps.size(); 4312 for (int ia=0; ia<NA; ia++) { 4313 ProcessRecord app = apps.valueAt(ia); 4314 if (app.persistent) { 4315 // we don't kill persistent processes 4316 continue; 4317 } 4318 if (app.removed) { 4319 procs.add(app); 4320 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 4321 app.removed = true; 4322 procs.add(app); 4323 } 4324 } 4325 } 4326 4327 int N = procs.size(); 4328 for (int i=0; i<N; i++) { 4329 removeProcessLocked(procs.get(i), false, true, "kill all background"); 4330 } 4331 mAllowLowerMemLevel = true; 4332 updateOomAdjLocked(); 4333 doLowMemReportIfNeededLocked(null); 4334 } 4335 } finally { 4336 Binder.restoreCallingIdentity(callingId); 4337 } 4338 } 4339 4340 @Override 4341 public void forceStopPackage(final String packageName, int userId) { 4342 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES) 4343 != PackageManager.PERMISSION_GRANTED) { 4344 String msg = "Permission Denial: forceStopPackage() from pid=" 4345 + Binder.getCallingPid() 4346 + ", uid=" + Binder.getCallingUid() 4347 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES; 4348 Slog.w(TAG, msg); 4349 throw new SecurityException(msg); 4350 } 4351 final int callingPid = Binder.getCallingPid(); 4352 userId = handleIncomingUser(callingPid, Binder.getCallingUid(), 4353 userId, true, true, "forceStopPackage", null); 4354 long callingId = Binder.clearCallingIdentity(); 4355 try { 4356 IPackageManager pm = AppGlobals.getPackageManager(); 4357 synchronized(this) { 4358 int[] users = userId == UserHandle.USER_ALL 4359 ? getUsersLocked() : new int[] { userId }; 4360 for (int user : users) { 4361 int pkgUid = -1; 4362 try { 4363 pkgUid = pm.getPackageUid(packageName, user); 4364 } catch (RemoteException e) { 4365 } 4366 if (pkgUid == -1) { 4367 Slog.w(TAG, "Invalid packageName: " + packageName); 4368 continue; 4369 } 4370 try { 4371 pm.setPackageStoppedState(packageName, true, user); 4372 } catch (RemoteException e) { 4373 } catch (IllegalArgumentException e) { 4374 Slog.w(TAG, "Failed trying to unstop package " 4375 + packageName + ": " + e); 4376 } 4377 if (isUserRunningLocked(user, false)) { 4378 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid); 4379 } 4380 } 4381 } 4382 } finally { 4383 Binder.restoreCallingIdentity(callingId); 4384 } 4385 } 4386 4387 /* 4388 * The pkg name and app id have to be specified. 4389 */ 4390 @Override 4391 public void killApplicationWithAppId(String pkg, int appid, String reason) { 4392 if (pkg == null) { 4393 return; 4394 } 4395 // Make sure the uid is valid. 4396 if (appid < 0) { 4397 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg); 4398 return; 4399 } 4400 int callerUid = Binder.getCallingUid(); 4401 // Only the system server can kill an application 4402 if (callerUid == Process.SYSTEM_UID) { 4403 // Post an aysnc message to kill the application 4404 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG); 4405 msg.arg1 = appid; 4406 msg.arg2 = 0; 4407 Bundle bundle = new Bundle(); 4408 bundle.putString("pkg", pkg); 4409 bundle.putString("reason", reason); 4410 msg.obj = bundle; 4411 mHandler.sendMessage(msg); 4412 } else { 4413 throw new SecurityException(callerUid + " cannot kill pkg: " + 4414 pkg); 4415 } 4416 } 4417 4418 @Override 4419 public void closeSystemDialogs(String reason) { 4420 enforceNotIsolatedCaller("closeSystemDialogs"); 4421 4422 final int pid = Binder.getCallingPid(); 4423 final int uid = Binder.getCallingUid(); 4424 final long origId = Binder.clearCallingIdentity(); 4425 try { 4426 synchronized (this) { 4427 // Only allow this from foreground processes, so that background 4428 // applications can't abuse it to prevent system UI from being shown. 4429 if (uid >= Process.FIRST_APPLICATION_UID) { 4430 ProcessRecord proc; 4431 synchronized (mPidsSelfLocked) { 4432 proc = mPidsSelfLocked.get(pid); 4433 } 4434 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 4435 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason 4436 + " from background process " + proc); 4437 return; 4438 } 4439 } 4440 closeSystemDialogsLocked(reason); 4441 } 4442 } finally { 4443 Binder.restoreCallingIdentity(origId); 4444 } 4445 } 4446 4447 void closeSystemDialogsLocked(String reason) { 4448 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); 4449 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4450 | Intent.FLAG_RECEIVER_FOREGROUND); 4451 if (reason != null) { 4452 intent.putExtra("reason", reason); 4453 } 4454 mWindowManager.closeSystemDialogs(reason); 4455 4456 mStackSupervisor.closeSystemDialogsLocked(); 4457 4458 broadcastIntentLocked(null, null, intent, null, 4459 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1, 4460 Process.SYSTEM_UID, UserHandle.USER_ALL); 4461 } 4462 4463 @Override 4464 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) { 4465 enforceNotIsolatedCaller("getProcessMemoryInfo"); 4466 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length]; 4467 for (int i=pids.length-1; i>=0; i--) { 4468 ProcessRecord proc; 4469 int oomAdj; 4470 synchronized (this) { 4471 synchronized (mPidsSelfLocked) { 4472 proc = mPidsSelfLocked.get(pids[i]); 4473 oomAdj = proc != null ? proc.setAdj : 0; 4474 } 4475 } 4476 infos[i] = new Debug.MemoryInfo(); 4477 Debug.getMemoryInfo(pids[i], infos[i]); 4478 if (proc != null) { 4479 synchronized (this) { 4480 if (proc.thread != null && proc.setAdj == oomAdj) { 4481 // Record this for posterity if the process has been stable. 4482 proc.baseProcessTracker.addPss(infos[i].getTotalPss(), 4483 infos[i].getTotalUss(), false, proc.pkgList); 4484 } 4485 } 4486 } 4487 } 4488 return infos; 4489 } 4490 4491 @Override 4492 public long[] getProcessPss(int[] pids) { 4493 enforceNotIsolatedCaller("getProcessPss"); 4494 long[] pss = new long[pids.length]; 4495 for (int i=pids.length-1; i>=0; i--) { 4496 ProcessRecord proc; 4497 int oomAdj; 4498 synchronized (this) { 4499 synchronized (mPidsSelfLocked) { 4500 proc = mPidsSelfLocked.get(pids[i]); 4501 oomAdj = proc != null ? proc.setAdj : 0; 4502 } 4503 } 4504 long[] tmpUss = new long[1]; 4505 pss[i] = Debug.getPss(pids[i], tmpUss); 4506 if (proc != null) { 4507 synchronized (this) { 4508 if (proc.thread != null && proc.setAdj == oomAdj) { 4509 // Record this for posterity if the process has been stable. 4510 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList); 4511 } 4512 } 4513 } 4514 } 4515 return pss; 4516 } 4517 4518 @Override 4519 public void killApplicationProcess(String processName, int uid) { 4520 if (processName == null) { 4521 return; 4522 } 4523 4524 int callerUid = Binder.getCallingUid(); 4525 // Only the system server can kill an application 4526 if (callerUid == Process.SYSTEM_UID) { 4527 synchronized (this) { 4528 ProcessRecord app = getProcessRecordLocked(processName, uid, true); 4529 if (app != null && app.thread != null) { 4530 try { 4531 app.thread.scheduleSuicide(); 4532 } catch (RemoteException e) { 4533 // If the other end already died, then our work here is done. 4534 } 4535 } else { 4536 Slog.w(TAG, "Process/uid not found attempting kill of " 4537 + processName + " / " + uid); 4538 } 4539 } 4540 } else { 4541 throw new SecurityException(callerUid + " cannot kill app process: " + 4542 processName); 4543 } 4544 } 4545 4546 private void forceStopPackageLocked(final String packageName, int uid, String reason) { 4547 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false, 4548 false, true, false, false, UserHandle.getUserId(uid), reason); 4549 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, 4550 Uri.fromParts("package", packageName, null)); 4551 if (!mProcessesReady) { 4552 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4553 | Intent.FLAG_RECEIVER_FOREGROUND); 4554 } 4555 intent.putExtra(Intent.EXTRA_UID, uid); 4556 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid)); 4557 broadcastIntentLocked(null, null, intent, 4558 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4559 false, false, 4560 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid)); 4561 } 4562 4563 private void forceStopUserLocked(int userId, String reason) { 4564 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason); 4565 Intent intent = new Intent(Intent.ACTION_USER_STOPPED); 4566 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 4567 | Intent.FLAG_RECEIVER_FOREGROUND); 4568 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 4569 broadcastIntentLocked(null, null, intent, 4570 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 4571 false, false, 4572 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 4573 } 4574 4575 private final boolean killPackageProcessesLocked(String packageName, int appId, 4576 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 4577 boolean doit, boolean evenPersistent, String reason) { 4578 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 4579 4580 // Remove all processes this package may have touched: all with the 4581 // same UID (except for the system or root user), and all whose name 4582 // matches the package name. 4583 final String procNamePrefix = packageName != null ? (packageName + ":") : null; 4584 final int NP = mProcessNames.getMap().size(); 4585 for (int ip=0; ip<NP; ip++) { 4586 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 4587 final int NA = apps.size(); 4588 for (int ia=0; ia<NA; ia++) { 4589 ProcessRecord app = apps.valueAt(ia); 4590 if (app.persistent && !evenPersistent) { 4591 // we don't kill persistent processes 4592 continue; 4593 } 4594 if (app.removed) { 4595 if (doit) { 4596 procs.add(app); 4597 } 4598 continue; 4599 } 4600 4601 // Skip process if it doesn't meet our oom adj requirement. 4602 if (app.setAdj < minOomAdj) { 4603 continue; 4604 } 4605 4606 // If no package is specified, we call all processes under the 4607 // give user id. 4608 if (packageName == null) { 4609 if (app.userId != userId) { 4610 continue; 4611 } 4612 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 4613 continue; 4614 } 4615 // Package has been specified, we want to hit all processes 4616 // that match it. We need to qualify this by the processes 4617 // that are running under the specified app and user ID. 4618 } else { 4619 if (UserHandle.getAppId(app.uid) != appId) { 4620 continue; 4621 } 4622 if (userId != UserHandle.USER_ALL && app.userId != userId) { 4623 continue; 4624 } 4625 if (!app.pkgList.containsKey(packageName)) { 4626 continue; 4627 } 4628 } 4629 4630 // Process has passed all conditions, kill it! 4631 if (!doit) { 4632 return true; 4633 } 4634 app.removed = true; 4635 procs.add(app); 4636 } 4637 } 4638 4639 int N = procs.size(); 4640 for (int i=0; i<N; i++) { 4641 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 4642 } 4643 updateOomAdjLocked(); 4644 return N > 0; 4645 } 4646 4647 private final boolean forceStopPackageLocked(String name, int appId, 4648 boolean callerWillRestart, boolean purgeCache, boolean doit, 4649 boolean evenPersistent, boolean uninstalling, int userId, String reason) { 4650 int i; 4651 int N; 4652 4653 if (userId == UserHandle.USER_ALL && name == null) { 4654 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!"); 4655 } 4656 4657 if (appId < 0 && name != null) { 4658 try { 4659 appId = UserHandle.getAppId( 4660 AppGlobals.getPackageManager().getPackageUid(name, 0)); 4661 } catch (RemoteException e) { 4662 } 4663 } 4664 4665 if (doit) { 4666 if (name != null) { 4667 Slog.i(TAG, "Force stopping " + name + " appid=" + appId 4668 + " user=" + userId + ": " + reason); 4669 } else { 4670 Slog.i(TAG, "Force stopping u" + userId + ": " + reason); 4671 } 4672 4673 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 4674 for (int ip=pmap.size()-1; ip>=0; ip--) { 4675 SparseArray<Long> ba = pmap.valueAt(ip); 4676 for (i=ba.size()-1; i>=0; i--) { 4677 boolean remove = false; 4678 final int entUid = ba.keyAt(i); 4679 if (name != null) { 4680 if (userId == UserHandle.USER_ALL) { 4681 if (UserHandle.getAppId(entUid) == appId) { 4682 remove = true; 4683 } 4684 } else { 4685 if (entUid == UserHandle.getUid(userId, appId)) { 4686 remove = true; 4687 } 4688 } 4689 } else if (UserHandle.getUserId(entUid) == userId) { 4690 remove = true; 4691 } 4692 if (remove) { 4693 ba.removeAt(i); 4694 } 4695 } 4696 if (ba.size() == 0) { 4697 pmap.removeAt(ip); 4698 } 4699 } 4700 } 4701 4702 boolean didSomething = killPackageProcessesLocked(name, appId, userId, 4703 -100, callerWillRestart, true, doit, evenPersistent, 4704 name == null ? ("stop user " + userId) : ("stop " + name)); 4705 4706 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) { 4707 if (!doit) { 4708 return true; 4709 } 4710 didSomething = true; 4711 } 4712 4713 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) { 4714 if (!doit) { 4715 return true; 4716 } 4717 didSomething = true; 4718 } 4719 4720 if (name == null) { 4721 // Remove all sticky broadcasts from this user. 4722 mStickyBroadcasts.remove(userId); 4723 } 4724 4725 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>(); 4726 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent, 4727 userId, providers)) { 4728 if (!doit) { 4729 return true; 4730 } 4731 didSomething = true; 4732 } 4733 N = providers.size(); 4734 for (i=0; i<N; i++) { 4735 removeDyingProviderLocked(null, providers.get(i), true); 4736 } 4737 4738 // Remove transient permissions granted from/to this package/user 4739 removeUriPermissionsForPackageLocked(name, userId, false); 4740 4741 if (name == null || uninstalling) { 4742 // Remove pending intents. For now we only do this when force 4743 // stopping users, because we have some problems when doing this 4744 // for packages -- app widgets are not currently cleaned up for 4745 // such packages, so they can be left with bad pending intents. 4746 if (mIntentSenderRecords.size() > 0) { 4747 Iterator<WeakReference<PendingIntentRecord>> it 4748 = mIntentSenderRecords.values().iterator(); 4749 while (it.hasNext()) { 4750 WeakReference<PendingIntentRecord> wpir = it.next(); 4751 if (wpir == null) { 4752 it.remove(); 4753 continue; 4754 } 4755 PendingIntentRecord pir = wpir.get(); 4756 if (pir == null) { 4757 it.remove(); 4758 continue; 4759 } 4760 if (name == null) { 4761 // Stopping user, remove all objects for the user. 4762 if (pir.key.userId != userId) { 4763 // Not the same user, skip it. 4764 continue; 4765 } 4766 } else { 4767 if (UserHandle.getAppId(pir.uid) != appId) { 4768 // Different app id, skip it. 4769 continue; 4770 } 4771 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) { 4772 // Different user, skip it. 4773 continue; 4774 } 4775 if (!pir.key.packageName.equals(name)) { 4776 // Different package, skip it. 4777 continue; 4778 } 4779 } 4780 if (!doit) { 4781 return true; 4782 } 4783 didSomething = true; 4784 it.remove(); 4785 pir.canceled = true; 4786 if (pir.key.activity != null) { 4787 pir.key.activity.pendingResults.remove(pir.ref); 4788 } 4789 } 4790 } 4791 } 4792 4793 if (doit) { 4794 if (purgeCache && name != null) { 4795 AttributeCache ac = AttributeCache.instance(); 4796 if (ac != null) { 4797 ac.removePackage(name); 4798 } 4799 } 4800 if (mBooted) { 4801 mStackSupervisor.resumeTopActivitiesLocked(); 4802 mStackSupervisor.scheduleIdleLocked(); 4803 } 4804 } 4805 4806 return didSomething; 4807 } 4808 4809 private final boolean removeProcessLocked(ProcessRecord app, 4810 boolean callerWillRestart, boolean allowRestart, String reason) { 4811 final String name = app.processName; 4812 final int uid = app.uid; 4813 if (DEBUG_PROCESSES) Slog.d( 4814 TAG, "Force removing proc " + app.toShortString() + " (" + name 4815 + "/" + uid + ")"); 4816 4817 mProcessNames.remove(name, uid); 4818 mIsolatedProcesses.remove(app.uid); 4819 if (mHeavyWeightProcess == app) { 4820 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4821 mHeavyWeightProcess.userId, 0)); 4822 mHeavyWeightProcess = null; 4823 } 4824 boolean needRestart = false; 4825 if (app.pid > 0 && app.pid != MY_PID) { 4826 int pid = app.pid; 4827 synchronized (mPidsSelfLocked) { 4828 mPidsSelfLocked.remove(pid); 4829 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4830 } 4831 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4832 app.processName, app.info.uid); 4833 if (app.isolated) { 4834 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4835 } 4836 killUnneededProcessLocked(app, reason); 4837 handleAppDiedLocked(app, true, allowRestart); 4838 removeLruProcessLocked(app); 4839 4840 if (app.persistent && !app.isolated) { 4841 if (!callerWillRestart) { 4842 addAppLocked(app.info, false); 4843 } else { 4844 needRestart = true; 4845 } 4846 } 4847 } else { 4848 mRemovedProcesses.add(app); 4849 } 4850 4851 return needRestart; 4852 } 4853 4854 private final void processStartTimedOutLocked(ProcessRecord app) { 4855 final int pid = app.pid; 4856 boolean gone = false; 4857 synchronized (mPidsSelfLocked) { 4858 ProcessRecord knownApp = mPidsSelfLocked.get(pid); 4859 if (knownApp != null && knownApp.thread == null) { 4860 mPidsSelfLocked.remove(pid); 4861 gone = true; 4862 } 4863 } 4864 4865 if (gone) { 4866 Slog.w(TAG, "Process " + app + " failed to attach"); 4867 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId, 4868 pid, app.uid, app.processName); 4869 mProcessNames.remove(app.processName, app.uid); 4870 mIsolatedProcesses.remove(app.uid); 4871 if (mHeavyWeightProcess == app) { 4872 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 4873 mHeavyWeightProcess.userId, 0)); 4874 mHeavyWeightProcess = null; 4875 } 4876 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 4877 app.processName, app.info.uid); 4878 if (app.isolated) { 4879 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 4880 } 4881 // Take care of any launching providers waiting for this process. 4882 checkAppInLaunchingProvidersLocked(app, true); 4883 // Take care of any services that are waiting for the process. 4884 mServices.processStartTimedOutLocked(app); 4885 killUnneededProcessLocked(app, "start timeout"); 4886 if (mBackupTarget != null && mBackupTarget.app.pid == pid) { 4887 Slog.w(TAG, "Unattached app died before backup, skipping"); 4888 try { 4889 IBackupManager bm = IBackupManager.Stub.asInterface( 4890 ServiceManager.getService(Context.BACKUP_SERVICE)); 4891 bm.agentDisconnected(app.info.packageName); 4892 } catch (RemoteException e) { 4893 // Can't happen; the backup manager is local 4894 } 4895 } 4896 if (isPendingBroadcastProcessLocked(pid)) { 4897 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 4898 skipPendingBroadcastLocked(pid); 4899 } 4900 } else { 4901 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app); 4902 } 4903 } 4904 4905 private final boolean attachApplicationLocked(IApplicationThread thread, 4906 int pid) { 4907 4908 // Find the application record that is being attached... either via 4909 // the pid if we are running in multiple processes, or just pull the 4910 // next app record if we are emulating process with anonymous threads. 4911 ProcessRecord app; 4912 if (pid != MY_PID && pid >= 0) { 4913 synchronized (mPidsSelfLocked) { 4914 app = mPidsSelfLocked.get(pid); 4915 } 4916 } else { 4917 app = null; 4918 } 4919 4920 if (app == null) { 4921 Slog.w(TAG, "No pending application record for pid " + pid 4922 + " (IApplicationThread " + thread + "); dropping process"); 4923 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid); 4924 if (pid > 0 && pid != MY_PID) { 4925 Process.killProcessQuiet(pid); 4926 } else { 4927 try { 4928 thread.scheduleExit(); 4929 } catch (Exception e) { 4930 // Ignore exceptions. 4931 } 4932 } 4933 return false; 4934 } 4935 4936 // If this application record is still attached to a previous 4937 // process, clean it up now. 4938 if (app.thread != null) { 4939 handleAppDiedLocked(app, true, true); 4940 } 4941 4942 // Tell the process all about itself. 4943 4944 if (localLOGV) Slog.v( 4945 TAG, "Binding process pid " + pid + " to record " + app); 4946 4947 final String processName = app.processName; 4948 try { 4949 AppDeathRecipient adr = new AppDeathRecipient( 4950 app, pid, thread); 4951 thread.asBinder().linkToDeath(adr, 0); 4952 app.deathRecipient = adr; 4953 } catch (RemoteException e) { 4954 app.resetPackageList(mProcessStats); 4955 startProcessLocked(app, "link fail", processName); 4956 return false; 4957 } 4958 4959 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName); 4960 4961 app.makeActive(thread, mProcessStats); 4962 app.curAdj = app.setAdj = -100; 4963 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT; 4964 app.forcingToForeground = null; 4965 updateProcessForegroundLocked(app, false, false); 4966 app.hasShownUi = false; 4967 app.debugging = false; 4968 app.cached = false; 4969 4970 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 4971 4972 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); 4973 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; 4974 4975 if (!normalMode) { 4976 Slog.i(TAG, "Launching preboot mode app: " + app); 4977 } 4978 4979 if (localLOGV) Slog.v( 4980 TAG, "New app record " + app 4981 + " thread=" + thread.asBinder() + " pid=" + pid); 4982 try { 4983 int testMode = IApplicationThread.DEBUG_OFF; 4984 if (mDebugApp != null && mDebugApp.equals(processName)) { 4985 testMode = mWaitForDebugger 4986 ? IApplicationThread.DEBUG_WAIT 4987 : IApplicationThread.DEBUG_ON; 4988 app.debugging = true; 4989 if (mDebugTransient) { 4990 mDebugApp = mOrigDebugApp; 4991 mWaitForDebugger = mOrigWaitForDebugger; 4992 } 4993 } 4994 String profileFile = app.instrumentationProfileFile; 4995 ParcelFileDescriptor profileFd = null; 4996 boolean profileAutoStop = false; 4997 if (mProfileApp != null && mProfileApp.equals(processName)) { 4998 mProfileProc = app; 4999 profileFile = mProfileFile; 5000 profileFd = mProfileFd; 5001 profileAutoStop = mAutoStopProfiler; 5002 } 5003 boolean enableOpenGlTrace = false; 5004 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) { 5005 enableOpenGlTrace = true; 5006 mOpenGlTraceApp = null; 5007 } 5008 5009 // If the app is being launched for restore or full backup, set it up specially 5010 boolean isRestrictedBackupMode = false; 5011 if (mBackupTarget != null && mBackupAppName.equals(processName)) { 5012 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE) 5013 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL) 5014 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL); 5015 } 5016 5017 ensurePackageDexOpt(app.instrumentationInfo != null 5018 ? app.instrumentationInfo.packageName 5019 : app.info.packageName); 5020 if (app.instrumentationClass != null) { 5021 ensurePackageDexOpt(app.instrumentationClass.getPackageName()); 5022 } 5023 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc " 5024 + processName + " with config " + mConfiguration); 5025 ApplicationInfo appInfo = app.instrumentationInfo != null 5026 ? app.instrumentationInfo : app.info; 5027 app.compat = compatibilityInfoForPackageLocked(appInfo); 5028 if (profileFd != null) { 5029 profileFd = profileFd.dup(); 5030 } 5031 thread.bindApplication(processName, appInfo, providers, 5032 app.instrumentationClass, profileFile, profileFd, profileAutoStop, 5033 app.instrumentationArguments, app.instrumentationWatcher, 5034 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, 5035 isRestrictedBackupMode || !normalMode, app.persistent, 5036 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(), 5037 mCoreSettingsObserver.getCoreSettingsLocked()); 5038 updateLruProcessLocked(app, false, null); 5039 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); 5040 } catch (Exception e) { 5041 // todo: Yikes! What should we do? For now we will try to 5042 // start another process, but that could easily get us in 5043 // an infinite loop of restarting processes... 5044 Slog.w(TAG, "Exception thrown during bind!", e); 5045 5046 app.resetPackageList(mProcessStats); 5047 app.unlinkDeathRecipient(); 5048 startProcessLocked(app, "bind fail", processName); 5049 return false; 5050 } 5051 5052 // Remove this record from the list of starting applications. 5053 mPersistentStartingProcesses.remove(app); 5054 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG, 5055 "Attach application locked removing on hold: " + app); 5056 mProcessesOnHold.remove(app); 5057 5058 boolean badApp = false; 5059 boolean didSomething = false; 5060 5061 // See if the top visible activity is waiting to run in this process... 5062 if (normalMode) { 5063 try { 5064 if (mStackSupervisor.attachApplicationLocked(app)) { 5065 didSomething = true; 5066 } 5067 } catch (Exception e) { 5068 badApp = true; 5069 } 5070 } 5071 5072 // Find any services that should be running in this process... 5073 if (!badApp) { 5074 try { 5075 didSomething |= mServices.attachApplicationLocked(app, processName); 5076 } catch (Exception e) { 5077 badApp = true; 5078 } 5079 } 5080 5081 // Check if a next-broadcast receiver is in this process... 5082 if (!badApp && isPendingBroadcastProcessLocked(pid)) { 5083 try { 5084 didSomething |= sendPendingBroadcastsLocked(app); 5085 } catch (Exception e) { 5086 // If the app died trying to launch the receiver we declare it 'bad' 5087 badApp = true; 5088 } 5089 } 5090 5091 // Check whether the next backup agent is in this process... 5092 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) { 5093 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app); 5094 ensurePackageDexOpt(mBackupTarget.appInfo.packageName); 5095 try { 5096 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo, 5097 compatibilityInfoForPackageLocked(mBackupTarget.appInfo), 5098 mBackupTarget.backupMode); 5099 } catch (Exception e) { 5100 Slog.w(TAG, "Exception scheduling backup agent creation: "); 5101 e.printStackTrace(); 5102 } 5103 } 5104 5105 if (badApp) { 5106 // todo: Also need to kill application to deal with all 5107 // kinds of exceptions. 5108 handleAppDiedLocked(app, false, true); 5109 return false; 5110 } 5111 5112 if (!didSomething) { 5113 updateOomAdjLocked(); 5114 } 5115 5116 return true; 5117 } 5118 5119 @Override 5120 public final void attachApplication(IApplicationThread thread) { 5121 synchronized (this) { 5122 int callingPid = Binder.getCallingPid(); 5123 final long origId = Binder.clearCallingIdentity(); 5124 attachApplicationLocked(thread, callingPid); 5125 Binder.restoreCallingIdentity(origId); 5126 } 5127 } 5128 5129 @Override 5130 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) { 5131 final long origId = Binder.clearCallingIdentity(); 5132 synchronized (this) { 5133 ActivityStack stack = ActivityRecord.getStackLocked(token); 5134 if (stack != null) { 5135 ActivityRecord r = 5136 mStackSupervisor.activityIdleInternalLocked(token, false, config); 5137 if (stopProfiling) { 5138 if ((mProfileProc == r.app) && (mProfileFd != null)) { 5139 try { 5140 mProfileFd.close(); 5141 } catch (IOException e) { 5142 } 5143 clearProfilerLocked(); 5144 } 5145 } 5146 } 5147 } 5148 Binder.restoreCallingIdentity(origId); 5149 } 5150 5151 void enableScreenAfterBoot() { 5152 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN, 5153 SystemClock.uptimeMillis()); 5154 mWindowManager.enableScreenAfterBoot(); 5155 5156 synchronized (this) { 5157 updateEventDispatchingLocked(); 5158 } 5159 } 5160 5161 @Override 5162 public void showBootMessage(final CharSequence msg, final boolean always) { 5163 enforceNotIsolatedCaller("showBootMessage"); 5164 mWindowManager.showBootMessage(msg, always); 5165 } 5166 5167 @Override 5168 public void dismissKeyguardOnNextActivity() { 5169 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity"); 5170 final long token = Binder.clearCallingIdentity(); 5171 try { 5172 synchronized (this) { 5173 if (DEBUG_LOCKSCREEN) logLockScreen(""); 5174 if (mLockScreenShown) { 5175 mLockScreenShown = false; 5176 comeOutOfSleepIfNeededLocked(); 5177 } 5178 mStackSupervisor.setDismissKeyguard(true); 5179 } 5180 } finally { 5181 Binder.restoreCallingIdentity(token); 5182 } 5183 } 5184 5185 final void finishBooting() { 5186 IntentFilter pkgFilter = new IntentFilter(); 5187 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5188 pkgFilter.addDataScheme("package"); 5189 mContext.registerReceiver(new BroadcastReceiver() { 5190 @Override 5191 public void onReceive(Context context, Intent intent) { 5192 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES); 5193 if (pkgs != null) { 5194 for (String pkg : pkgs) { 5195 synchronized (ActivityManagerService.this) { 5196 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0, 5197 "finished booting")) { 5198 setResultCode(Activity.RESULT_OK); 5199 return; 5200 } 5201 } 5202 } 5203 } 5204 } 5205 }, pkgFilter); 5206 5207 synchronized (this) { 5208 // Ensure that any processes we had put on hold are now started 5209 // up. 5210 final int NP = mProcessesOnHold.size(); 5211 if (NP > 0) { 5212 ArrayList<ProcessRecord> procs = 5213 new ArrayList<ProcessRecord>(mProcessesOnHold); 5214 for (int ip=0; ip<NP; ip++) { 5215 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: " 5216 + procs.get(ip)); 5217 startProcessLocked(procs.get(ip), "on-hold", null); 5218 } 5219 } 5220 5221 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 5222 // Start looking for apps that are abusing wake locks. 5223 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 5224 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 5225 // Tell anyone interested that we are done booting! 5226 SystemProperties.set("sys.boot_completed", "1"); 5227 SystemProperties.set("dev.bootcomplete", "1"); 5228 for (int i=0; i<mStartedUsers.size(); i++) { 5229 UserStartedState uss = mStartedUsers.valueAt(i); 5230 if (uss.mState == UserStartedState.STATE_BOOTING) { 5231 uss.mState = UserStartedState.STATE_RUNNING; 5232 final int userId = mStartedUsers.keyAt(i); 5233 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 5234 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 5235 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 5236 broadcastIntentLocked(null, null, intent, null, 5237 new IIntentReceiver.Stub() { 5238 @Override 5239 public void performReceive(Intent intent, int resultCode, 5240 String data, Bundle extras, boolean ordered, 5241 boolean sticky, int sendingUser) { 5242 synchronized (ActivityManagerService.this) { 5243 requestPssAllProcsLocked(SystemClock.uptimeMillis(), 5244 true, false); 5245 } 5246 } 5247 }, 5248 0, null, null, 5249 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, 5250 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID, 5251 userId); 5252 } 5253 } 5254 scheduleStartProfilesLocked(); 5255 } 5256 } 5257 } 5258 5259 final void ensureBootCompleted() { 5260 boolean booting; 5261 boolean enableScreen; 5262 synchronized (this) { 5263 booting = mBooting; 5264 mBooting = false; 5265 enableScreen = !mBooted; 5266 mBooted = true; 5267 } 5268 5269 if (booting) { 5270 finishBooting(); 5271 } 5272 5273 if (enableScreen) { 5274 enableScreenAfterBoot(); 5275 } 5276 } 5277 5278 @Override 5279 public final void activityResumed(IBinder token) { 5280 final long origId = Binder.clearCallingIdentity(); 5281 synchronized(this) { 5282 ActivityStack stack = ActivityRecord.getStackLocked(token); 5283 if (stack != null) { 5284 ActivityRecord.activityResumedLocked(token); 5285 } 5286 } 5287 Binder.restoreCallingIdentity(origId); 5288 } 5289 5290 @Override 5291 public final void activityPaused(IBinder token) { 5292 final long origId = Binder.clearCallingIdentity(); 5293 synchronized(this) { 5294 ActivityStack stack = ActivityRecord.getStackLocked(token); 5295 if (stack != null) { 5296 stack.activityPausedLocked(token, false); 5297 } 5298 } 5299 Binder.restoreCallingIdentity(origId); 5300 } 5301 5302 @Override 5303 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail, 5304 CharSequence description) { 5305 if (localLOGV) Slog.v( 5306 TAG, "Activity stopped: token=" + token); 5307 5308 // Refuse possible leaked file descriptors 5309 if (icicle != null && icicle.hasFileDescriptors()) { 5310 throw new IllegalArgumentException("File descriptors passed in Bundle"); 5311 } 5312 5313 ActivityRecord r = null; 5314 5315 final long origId = Binder.clearCallingIdentity(); 5316 5317 synchronized (this) { 5318 r = ActivityRecord.isInStackLocked(token); 5319 if (r != null) { 5320 r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description); 5321 } 5322 } 5323 5324 if (r != null) { 5325 sendPendingThumbnail(r, null, null, null, false); 5326 } 5327 5328 trimApplications(); 5329 5330 Binder.restoreCallingIdentity(origId); 5331 } 5332 5333 @Override 5334 public final void activityDestroyed(IBinder token) { 5335 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token); 5336 synchronized (this) { 5337 ActivityStack stack = ActivityRecord.getStackLocked(token); 5338 if (stack != null) { 5339 stack.activityDestroyedLocked(token); 5340 } 5341 } 5342 } 5343 5344 @Override 5345 public String getCallingPackage(IBinder token) { 5346 synchronized (this) { 5347 ActivityRecord r = getCallingRecordLocked(token); 5348 return r != null ? r.info.packageName : null; 5349 } 5350 } 5351 5352 @Override 5353 public ComponentName getCallingActivity(IBinder token) { 5354 synchronized (this) { 5355 ActivityRecord r = getCallingRecordLocked(token); 5356 return r != null ? r.intent.getComponent() : null; 5357 } 5358 } 5359 5360 private ActivityRecord getCallingRecordLocked(IBinder token) { 5361 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5362 if (r == null) { 5363 return null; 5364 } 5365 return r.resultTo; 5366 } 5367 5368 @Override 5369 public ComponentName getActivityClassForToken(IBinder token) { 5370 synchronized(this) { 5371 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5372 if (r == null) { 5373 return null; 5374 } 5375 return r.intent.getComponent(); 5376 } 5377 } 5378 5379 @Override 5380 public String getPackageForToken(IBinder token) { 5381 synchronized(this) { 5382 ActivityRecord r = ActivityRecord.isInStackLocked(token); 5383 if (r == null) { 5384 return null; 5385 } 5386 return r.packageName; 5387 } 5388 } 5389 5390 @Override 5391 public IIntentSender getIntentSender(int type, 5392 String packageName, IBinder token, String resultWho, 5393 int requestCode, Intent[] intents, String[] resolvedTypes, 5394 int flags, Bundle options, int userId) { 5395 enforceNotIsolatedCaller("getIntentSender"); 5396 // Refuse possible leaked file descriptors 5397 if (intents != null) { 5398 if (intents.length < 1) { 5399 throw new IllegalArgumentException("Intents array length must be >= 1"); 5400 } 5401 for (int i=0; i<intents.length; i++) { 5402 Intent intent = intents[i]; 5403 if (intent != null) { 5404 if (intent.hasFileDescriptors()) { 5405 throw new IllegalArgumentException("File descriptors passed in Intent"); 5406 } 5407 if (type == ActivityManager.INTENT_SENDER_BROADCAST && 5408 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 5409 throw new IllegalArgumentException( 5410 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 5411 } 5412 intents[i] = new Intent(intent); 5413 } 5414 } 5415 if (resolvedTypes != null && resolvedTypes.length != intents.length) { 5416 throw new IllegalArgumentException( 5417 "Intent array length does not match resolvedTypes length"); 5418 } 5419 } 5420 if (options != null) { 5421 if (options.hasFileDescriptors()) { 5422 throw new IllegalArgumentException("File descriptors passed in options"); 5423 } 5424 } 5425 5426 synchronized(this) { 5427 int callingUid = Binder.getCallingUid(); 5428 int origUserId = userId; 5429 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId, 5430 type == ActivityManager.INTENT_SENDER_BROADCAST, false, 5431 "getIntentSender", null); 5432 if (origUserId == UserHandle.USER_CURRENT) { 5433 // We don't want to evaluate this until the pending intent is 5434 // actually executed. However, we do want to always do the 5435 // security checking for it above. 5436 userId = UserHandle.USER_CURRENT; 5437 } 5438 try { 5439 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 5440 int uid = AppGlobals.getPackageManager() 5441 .getPackageUid(packageName, UserHandle.getUserId(callingUid)); 5442 if (!UserHandle.isSameApp(callingUid, uid)) { 5443 String msg = "Permission Denial: getIntentSender() from pid=" 5444 + Binder.getCallingPid() 5445 + ", uid=" + Binder.getCallingUid() 5446 + ", (need uid=" + uid + ")" 5447 + " is not allowed to send as package " + packageName; 5448 Slog.w(TAG, msg); 5449 throw new SecurityException(msg); 5450 } 5451 } 5452 5453 return getIntentSenderLocked(type, packageName, callingUid, userId, 5454 token, resultWho, requestCode, intents, resolvedTypes, flags, options); 5455 5456 } catch (RemoteException e) { 5457 throw new SecurityException(e); 5458 } 5459 } 5460 } 5461 5462 IIntentSender getIntentSenderLocked(int type, String packageName, 5463 int callingUid, int userId, IBinder token, String resultWho, 5464 int requestCode, Intent[] intents, String[] resolvedTypes, int flags, 5465 Bundle options) { 5466 if (DEBUG_MU) 5467 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid); 5468 ActivityRecord activity = null; 5469 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5470 activity = ActivityRecord.isInStackLocked(token); 5471 if (activity == null) { 5472 return null; 5473 } 5474 if (activity.finishing) { 5475 return null; 5476 } 5477 } 5478 5479 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0; 5480 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0; 5481 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0; 5482 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT 5483 |PendingIntent.FLAG_UPDATE_CURRENT); 5484 5485 PendingIntentRecord.Key key = new PendingIntentRecord.Key( 5486 type, packageName, activity, resultWho, 5487 requestCode, intents, resolvedTypes, flags, options, userId); 5488 WeakReference<PendingIntentRecord> ref; 5489 ref = mIntentSenderRecords.get(key); 5490 PendingIntentRecord rec = ref != null ? ref.get() : null; 5491 if (rec != null) { 5492 if (!cancelCurrent) { 5493 if (updateCurrent) { 5494 if (rec.key.requestIntent != null) { 5495 rec.key.requestIntent.replaceExtras(intents != null ? 5496 intents[intents.length - 1] : null); 5497 } 5498 if (intents != null) { 5499 intents[intents.length-1] = rec.key.requestIntent; 5500 rec.key.allIntents = intents; 5501 rec.key.allResolvedTypes = resolvedTypes; 5502 } else { 5503 rec.key.allIntents = null; 5504 rec.key.allResolvedTypes = null; 5505 } 5506 } 5507 return rec; 5508 } 5509 rec.canceled = true; 5510 mIntentSenderRecords.remove(key); 5511 } 5512 if (noCreate) { 5513 return rec; 5514 } 5515 rec = new PendingIntentRecord(this, key, callingUid); 5516 mIntentSenderRecords.put(key, rec.ref); 5517 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) { 5518 if (activity.pendingResults == null) { 5519 activity.pendingResults 5520 = new HashSet<WeakReference<PendingIntentRecord>>(); 5521 } 5522 activity.pendingResults.add(rec.ref); 5523 } 5524 return rec; 5525 } 5526 5527 @Override 5528 public void cancelIntentSender(IIntentSender sender) { 5529 if (!(sender instanceof PendingIntentRecord)) { 5530 return; 5531 } 5532 synchronized(this) { 5533 PendingIntentRecord rec = (PendingIntentRecord)sender; 5534 try { 5535 int uid = AppGlobals.getPackageManager() 5536 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId()); 5537 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) { 5538 String msg = "Permission Denial: cancelIntentSender() from pid=" 5539 + Binder.getCallingPid() 5540 + ", uid=" + Binder.getCallingUid() 5541 + " is not allowed to cancel packges " 5542 + rec.key.packageName; 5543 Slog.w(TAG, msg); 5544 throw new SecurityException(msg); 5545 } 5546 } catch (RemoteException e) { 5547 throw new SecurityException(e); 5548 } 5549 cancelIntentSenderLocked(rec, true); 5550 } 5551 } 5552 5553 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) { 5554 rec.canceled = true; 5555 mIntentSenderRecords.remove(rec.key); 5556 if (cleanActivity && rec.key.activity != null) { 5557 rec.key.activity.pendingResults.remove(rec.ref); 5558 } 5559 } 5560 5561 @Override 5562 public String getPackageForIntentSender(IIntentSender pendingResult) { 5563 if (!(pendingResult instanceof PendingIntentRecord)) { 5564 return null; 5565 } 5566 try { 5567 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5568 return res.key.packageName; 5569 } catch (ClassCastException e) { 5570 } 5571 return null; 5572 } 5573 5574 @Override 5575 public int getUidForIntentSender(IIntentSender sender) { 5576 if (sender instanceof PendingIntentRecord) { 5577 try { 5578 PendingIntentRecord res = (PendingIntentRecord)sender; 5579 return res.uid; 5580 } catch (ClassCastException e) { 5581 } 5582 } 5583 return -1; 5584 } 5585 5586 @Override 5587 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { 5588 if (!(pendingResult instanceof PendingIntentRecord)) { 5589 return false; 5590 } 5591 try { 5592 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5593 if (res.key.allIntents == null) { 5594 return false; 5595 } 5596 for (int i=0; i<res.key.allIntents.length; i++) { 5597 Intent intent = res.key.allIntents[i]; 5598 if (intent.getPackage() != null && intent.getComponent() != null) { 5599 return false; 5600 } 5601 } 5602 return true; 5603 } catch (ClassCastException e) { 5604 } 5605 return false; 5606 } 5607 5608 @Override 5609 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) { 5610 if (!(pendingResult instanceof PendingIntentRecord)) { 5611 return false; 5612 } 5613 try { 5614 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5615 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) { 5616 return true; 5617 } 5618 return false; 5619 } catch (ClassCastException e) { 5620 } 5621 return false; 5622 } 5623 5624 @Override 5625 public Intent getIntentForIntentSender(IIntentSender pendingResult) { 5626 if (!(pendingResult instanceof PendingIntentRecord)) { 5627 return null; 5628 } 5629 try { 5630 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5631 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null; 5632 } catch (ClassCastException e) { 5633 } 5634 return null; 5635 } 5636 5637 @Override 5638 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) { 5639 if (!(pendingResult instanceof PendingIntentRecord)) { 5640 return null; 5641 } 5642 try { 5643 PendingIntentRecord res = (PendingIntentRecord)pendingResult; 5644 Intent intent = res.key.requestIntent; 5645 if (intent != null) { 5646 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null 5647 || res.lastTagPrefix.equals(prefix))) { 5648 return res.lastTag; 5649 } 5650 res.lastTagPrefix = prefix; 5651 StringBuilder sb = new StringBuilder(128); 5652 if (prefix != null) { 5653 sb.append(prefix); 5654 } 5655 if (intent.getAction() != null) { 5656 sb.append(intent.getAction()); 5657 } else if (intent.getComponent() != null) { 5658 intent.getComponent().appendShortString(sb); 5659 } else { 5660 sb.append("?"); 5661 } 5662 return res.lastTag = sb.toString(); 5663 } 5664 } catch (ClassCastException e) { 5665 } 5666 return null; 5667 } 5668 5669 @Override 5670 public void setProcessLimit(int max) { 5671 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5672 "setProcessLimit()"); 5673 synchronized (this) { 5674 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max; 5675 mProcessLimitOverride = max; 5676 } 5677 trimApplications(); 5678 } 5679 5680 @Override 5681 public int getProcessLimit() { 5682 synchronized (this) { 5683 return mProcessLimitOverride; 5684 } 5685 } 5686 5687 void foregroundTokenDied(ForegroundToken token) { 5688 synchronized (ActivityManagerService.this) { 5689 synchronized (mPidsSelfLocked) { 5690 ForegroundToken cur 5691 = mForegroundProcesses.get(token.pid); 5692 if (cur != token) { 5693 return; 5694 } 5695 mForegroundProcesses.remove(token.pid); 5696 ProcessRecord pr = mPidsSelfLocked.get(token.pid); 5697 if (pr == null) { 5698 return; 5699 } 5700 pr.forcingToForeground = null; 5701 updateProcessForegroundLocked(pr, false, false); 5702 } 5703 updateOomAdjLocked(); 5704 } 5705 } 5706 5707 @Override 5708 public void setProcessForeground(IBinder token, int pid, boolean isForeground) { 5709 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT, 5710 "setProcessForeground()"); 5711 synchronized(this) { 5712 boolean changed = false; 5713 5714 synchronized (mPidsSelfLocked) { 5715 ProcessRecord pr = mPidsSelfLocked.get(pid); 5716 if (pr == null && isForeground) { 5717 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid); 5718 return; 5719 } 5720 ForegroundToken oldToken = mForegroundProcesses.get(pid); 5721 if (oldToken != null) { 5722 oldToken.token.unlinkToDeath(oldToken, 0); 5723 mForegroundProcesses.remove(pid); 5724 if (pr != null) { 5725 pr.forcingToForeground = null; 5726 } 5727 changed = true; 5728 } 5729 if (isForeground && token != null) { 5730 ForegroundToken newToken = new ForegroundToken() { 5731 @Override 5732 public void binderDied() { 5733 foregroundTokenDied(this); 5734 } 5735 }; 5736 newToken.pid = pid; 5737 newToken.token = token; 5738 try { 5739 token.linkToDeath(newToken, 0); 5740 mForegroundProcesses.put(pid, newToken); 5741 pr.forcingToForeground = token; 5742 changed = true; 5743 } catch (RemoteException e) { 5744 // If the process died while doing this, we will later 5745 // do the cleanup with the process death link. 5746 } 5747 } 5748 } 5749 5750 if (changed) { 5751 updateOomAdjLocked(); 5752 } 5753 } 5754 } 5755 5756 // ========================================================= 5757 // PERMISSIONS 5758 // ========================================================= 5759 5760 static class PermissionController extends IPermissionController.Stub { 5761 ActivityManagerService mActivityManagerService; 5762 PermissionController(ActivityManagerService activityManagerService) { 5763 mActivityManagerService = activityManagerService; 5764 } 5765 5766 @Override 5767 public boolean checkPermission(String permission, int pid, int uid) { 5768 return mActivityManagerService.checkPermission(permission, pid, 5769 uid) == PackageManager.PERMISSION_GRANTED; 5770 } 5771 } 5772 5773 class IntentFirewallInterface implements IntentFirewall.AMSInterface { 5774 @Override 5775 public int checkComponentPermission(String permission, int pid, int uid, 5776 int owningUid, boolean exported) { 5777 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid, 5778 owningUid, exported); 5779 } 5780 5781 @Override 5782 public Object getAMSLock() { 5783 return ActivityManagerService.this; 5784 } 5785 } 5786 5787 /** 5788 * This can be called with or without the global lock held. 5789 */ 5790 int checkComponentPermission(String permission, int pid, int uid, 5791 int owningUid, boolean exported) { 5792 // We might be performing an operation on behalf of an indirect binder 5793 // invocation, e.g. via {@link #openContentUri}. Check and adjust the 5794 // client identity accordingly before proceeding. 5795 Identity tlsIdentity = sCallerIdentity.get(); 5796 if (tlsIdentity != null) { 5797 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {" 5798 + tlsIdentity.pid + "," + tlsIdentity.uid + "}"); 5799 uid = tlsIdentity.uid; 5800 pid = tlsIdentity.pid; 5801 } 5802 5803 if (pid == MY_PID) { 5804 return PackageManager.PERMISSION_GRANTED; 5805 } 5806 5807 return ActivityManager.checkComponentPermission(permission, uid, 5808 owningUid, exported); 5809 } 5810 5811 /** 5812 * As the only public entry point for permissions checking, this method 5813 * can enforce the semantic that requesting a check on a null global 5814 * permission is automatically denied. (Internally a null permission 5815 * string is used when calling {@link #checkComponentPermission} in cases 5816 * when only uid-based security is needed.) 5817 * 5818 * This can be called with or without the global lock held. 5819 */ 5820 @Override 5821 public int checkPermission(String permission, int pid, int uid) { 5822 if (permission == null) { 5823 return PackageManager.PERMISSION_DENIED; 5824 } 5825 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true); 5826 } 5827 5828 /** 5829 * Binder IPC calls go through the public entry point. 5830 * This can be called with or without the global lock held. 5831 */ 5832 int checkCallingPermission(String permission) { 5833 return checkPermission(permission, 5834 Binder.getCallingPid(), 5835 UserHandle.getAppId(Binder.getCallingUid())); 5836 } 5837 5838 /** 5839 * This can be called with or without the global lock held. 5840 */ 5841 void enforceCallingPermission(String permission, String func) { 5842 if (checkCallingPermission(permission) 5843 == PackageManager.PERMISSION_GRANTED) { 5844 return; 5845 } 5846 5847 String msg = "Permission Denial: " + func + " from pid=" 5848 + Binder.getCallingPid() 5849 + ", uid=" + Binder.getCallingUid() 5850 + " requires " + permission; 5851 Slog.w(TAG, msg); 5852 throw new SecurityException(msg); 5853 } 5854 5855 /** 5856 * Determine if UID is holding permissions required to access {@link Uri} in 5857 * the given {@link ProviderInfo}. Final permission checking is always done 5858 * in {@link ContentProvider}. 5859 */ 5860 private final boolean checkHoldingPermissionsLocked( 5861 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, final int modeFlags) { 5862 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 5863 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid); 5864 5865 if (pi.applicationInfo.uid == uid) { 5866 return true; 5867 } else if (!pi.exported) { 5868 return false; 5869 } 5870 5871 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0; 5872 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0; 5873 try { 5874 // check if target holds top-level <provider> permissions 5875 if (!readMet && pi.readPermission != null 5876 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) { 5877 readMet = true; 5878 } 5879 if (!writeMet && pi.writePermission != null 5880 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) { 5881 writeMet = true; 5882 } 5883 5884 // track if unprotected read/write is allowed; any denied 5885 // <path-permission> below removes this ability 5886 boolean allowDefaultRead = pi.readPermission == null; 5887 boolean allowDefaultWrite = pi.writePermission == null; 5888 5889 // check if target holds any <path-permission> that match uri 5890 final PathPermission[] pps = pi.pathPermissions; 5891 if (pps != null) { 5892 final String path = uri.getPath(); 5893 int i = pps.length; 5894 while (i > 0 && (!readMet || !writeMet)) { 5895 i--; 5896 PathPermission pp = pps[i]; 5897 if (pp.match(path)) { 5898 if (!readMet) { 5899 final String pprperm = pp.getReadPermission(); 5900 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for " 5901 + pprperm + " for " + pp.getPath() 5902 + ": match=" + pp.match(path) 5903 + " check=" + pm.checkUidPermission(pprperm, uid)); 5904 if (pprperm != null) { 5905 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) { 5906 readMet = true; 5907 } else { 5908 allowDefaultRead = false; 5909 } 5910 } 5911 } 5912 if (!writeMet) { 5913 final String ppwperm = pp.getWritePermission(); 5914 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm " 5915 + ppwperm + " for " + pp.getPath() 5916 + ": match=" + pp.match(path) 5917 + " check=" + pm.checkUidPermission(ppwperm, uid)); 5918 if (ppwperm != null) { 5919 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) { 5920 writeMet = true; 5921 } else { 5922 allowDefaultWrite = false; 5923 } 5924 } 5925 } 5926 } 5927 } 5928 } 5929 5930 // grant unprotected <provider> read/write, if not blocked by 5931 // <path-permission> above 5932 if (allowDefaultRead) readMet = true; 5933 if (allowDefaultWrite) writeMet = true; 5934 5935 } catch (RemoteException e) { 5936 return false; 5937 } 5938 5939 return readMet && writeMet; 5940 } 5941 5942 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) { 5943 ProviderInfo pi = null; 5944 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle); 5945 if (cpr != null) { 5946 pi = cpr.info; 5947 } else { 5948 try { 5949 pi = AppGlobals.getPackageManager().resolveContentProvider( 5950 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle); 5951 } catch (RemoteException ex) { 5952 } 5953 } 5954 return pi; 5955 } 5956 5957 private UriPermission findUriPermissionLocked(int targetUid, GrantUri uri) { 5958 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5959 if (targetUris != null) { 5960 return targetUris.get(uri); 5961 } 5962 return null; 5963 } 5964 5965 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg, 5966 String targetPkg, int targetUid, GrantUri uri) { 5967 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid); 5968 if (targetUris == null) { 5969 targetUris = Maps.newArrayMap(); 5970 mGrantedUriPermissions.put(targetUid, targetUris); 5971 } 5972 5973 UriPermission perm = targetUris.get(uri); 5974 if (perm == null) { 5975 perm = new UriPermission(sourcePkg, targetPkg, targetUid, uri); 5976 targetUris.put(uri, perm); 5977 } 5978 5979 return perm; 5980 } 5981 5982 private final boolean checkUriPermissionLocked( 5983 Uri uri, int uid, final int modeFlags, int minStrength) { 5984 // Root gets to do everything. 5985 if (uid == 0) { 5986 return true; 5987 } 5988 5989 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 5990 if (perms == null) return false; 5991 5992 // First look for exact match 5993 final UriPermission exactPerm = perms.get(new GrantUri(uri, false)); 5994 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) { 5995 return true; 5996 } 5997 5998 // No exact match, look for prefixes 5999 final int N = perms.size(); 6000 for (int i = 0; i < N; i++) { 6001 final UriPermission perm = perms.valueAt(i); 6002 if (perm.uri.prefix && uri.isPathPrefixMatch(perm.uri.uri) 6003 && perm.getStrength(modeFlags) >= minStrength) { 6004 return true; 6005 } 6006 } 6007 6008 return false; 6009 } 6010 6011 @Override 6012 public int checkUriPermission(Uri uri, int pid, int uid, final int modeFlags) { 6013 enforceNotIsolatedCaller("checkUriPermission"); 6014 6015 // Another redirected-binder-call permissions check as in 6016 // {@link checkComponentPermission}. 6017 Identity tlsIdentity = sCallerIdentity.get(); 6018 if (tlsIdentity != null) { 6019 uid = tlsIdentity.uid; 6020 pid = tlsIdentity.pid; 6021 } 6022 6023 // Our own process gets to do everything. 6024 if (pid == MY_PID) { 6025 return PackageManager.PERMISSION_GRANTED; 6026 } 6027 synchronized(this) { 6028 return checkUriPermissionLocked(uri, uid, modeFlags, UriPermission.STRENGTH_OWNED) 6029 ? PackageManager.PERMISSION_GRANTED 6030 : PackageManager.PERMISSION_DENIED; 6031 } 6032 } 6033 6034 /** 6035 * Check if the targetPkg can be granted permission to access uri by 6036 * the callingUid using the given modeFlags. Throws a security exception 6037 * if callingUid is not allowed to do this. Returns the uid of the target 6038 * if the URI permission grant should be performed; returns -1 if it is not 6039 * needed (for example targetPkg already has permission to access the URI). 6040 * If you already know the uid of the target, you can supply it in 6041 * lastTargetUid else set that to -1. 6042 */ 6043 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, 6044 Uri uri, final int modeFlags, int lastTargetUid) { 6045 if (!Intent.isAccessUriMode(modeFlags)) { 6046 return -1; 6047 } 6048 6049 if (targetPkg != null) { 6050 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6051 "Checking grant " + targetPkg + " permission to " + uri); 6052 } 6053 6054 final IPackageManager pm = AppGlobals.getPackageManager(); 6055 6056 // If this is not a content: uri, we can't do anything with it. 6057 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) { 6058 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6059 "Can't grant URI permission for non-content URI: " + uri); 6060 return -1; 6061 } 6062 6063 final String authority = uri.getAuthority(); 6064 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6065 if (pi == null) { 6066 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString()); 6067 return -1; 6068 } 6069 6070 int targetUid = lastTargetUid; 6071 if (targetUid < 0 && targetPkg != null) { 6072 try { 6073 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid)); 6074 if (targetUid < 0) { 6075 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6076 "Can't grant URI permission no uid for: " + targetPkg); 6077 return -1; 6078 } 6079 } catch (RemoteException ex) { 6080 return -1; 6081 } 6082 } 6083 6084 if (targetUid >= 0) { 6085 // First... does the target actually need this permission? 6086 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) { 6087 // No need to grant the target this permission. 6088 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6089 "Target " + targetPkg + " already has full permission to " + uri); 6090 return -1; 6091 } 6092 } else { 6093 // First... there is no target package, so can anyone access it? 6094 boolean allowed = pi.exported; 6095 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) { 6096 if (pi.readPermission != null) { 6097 allowed = false; 6098 } 6099 } 6100 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) { 6101 if (pi.writePermission != null) { 6102 allowed = false; 6103 } 6104 } 6105 if (allowed) { 6106 return -1; 6107 } 6108 } 6109 6110 // Second... is the provider allowing granting of URI permissions? 6111 if (!pi.grantUriPermissions) { 6112 throw new SecurityException("Provider " + pi.packageName 6113 + "/" + pi.name 6114 + " does not allow granting of Uri permissions (uri " 6115 + uri + ")"); 6116 } 6117 if (pi.uriPermissionPatterns != null) { 6118 final int N = pi.uriPermissionPatterns.length; 6119 boolean allowed = false; 6120 for (int i=0; i<N; i++) { 6121 if (pi.uriPermissionPatterns[i] != null 6122 && pi.uriPermissionPatterns[i].match(uri.getPath())) { 6123 allowed = true; 6124 break; 6125 } 6126 } 6127 if (!allowed) { 6128 throw new SecurityException("Provider " + pi.packageName 6129 + "/" + pi.name 6130 + " does not allow granting of permission to path of Uri " 6131 + uri); 6132 } 6133 } 6134 6135 // Third... does the caller itself have permission to access 6136 // this uri? 6137 if (callingUid != Process.myUid()) { 6138 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6139 // Require they hold a strong enough Uri permission 6140 final boolean persistable = 6141 (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0; 6142 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE 6143 : UriPermission.STRENGTH_OWNED; 6144 if (!checkUriPermissionLocked(uri, callingUid, modeFlags, minStrength)) { 6145 throw new SecurityException("Uid " + callingUid 6146 + " does not have permission to uri " + uri); 6147 } 6148 } 6149 } 6150 6151 return targetUid; 6152 } 6153 6154 @Override 6155 public int checkGrantUriPermission(int callingUid, String targetPkg, 6156 Uri uri, final int modeFlags) { 6157 enforceNotIsolatedCaller("checkGrantUriPermission"); 6158 synchronized(this) { 6159 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6160 } 6161 } 6162 6163 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, Uri uri, 6164 final int modeFlags, UriPermissionOwner owner) { 6165 if (!Intent.isAccessUriMode(modeFlags)) { 6166 return; 6167 } 6168 6169 // So here we are: the caller has the assumed permission 6170 // to the uri, and the target doesn't. Let's now give this to 6171 // the target. 6172 6173 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6174 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri); 6175 6176 final String authority = uri.getAuthority(); 6177 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(targetUid)); 6178 if (pi == null) { 6179 Slog.w(TAG, "No content provider found for grant: " + uri.toSafeString()); 6180 return; 6181 } 6182 6183 final boolean prefix = (modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0; 6184 final UriPermission perm = findOrCreateUriPermissionLocked( 6185 pi.packageName, targetPkg, targetUid, new GrantUri(uri, prefix)); 6186 perm.grantModes(modeFlags, owner); 6187 } 6188 6189 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri, 6190 final int modeFlags, UriPermissionOwner owner) { 6191 if (targetPkg == null) { 6192 throw new NullPointerException("targetPkg"); 6193 } 6194 6195 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1); 6196 if (targetUid < 0) { 6197 return; 6198 } 6199 6200 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner); 6201 } 6202 6203 static class NeededUriGrants extends ArrayList<Uri> { 6204 final String targetPkg; 6205 final int targetUid; 6206 final int flags; 6207 6208 NeededUriGrants(String targetPkg, int targetUid, int flags) { 6209 this.targetPkg = targetPkg; 6210 this.targetUid = targetUid; 6211 this.flags = flags; 6212 } 6213 } 6214 6215 /** 6216 * Like checkGrantUriPermissionLocked, but takes an Intent. 6217 */ 6218 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid, 6219 String targetPkg, Intent intent, int mode, NeededUriGrants needed) { 6220 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6221 "Checking URI perm to data=" + (intent != null ? intent.getData() : null) 6222 + " clip=" + (intent != null ? intent.getClipData() : null) 6223 + " from " + intent + "; flags=0x" 6224 + Integer.toHexString(intent != null ? intent.getFlags() : 0)); 6225 6226 if (targetPkg == null) { 6227 throw new NullPointerException("targetPkg"); 6228 } 6229 6230 if (intent == null) { 6231 return null; 6232 } 6233 Uri data = intent.getData(); 6234 ClipData clip = intent.getClipData(); 6235 if (data == null && clip == null) { 6236 return null; 6237 } 6238 6239 if (data != null) { 6240 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, data, 6241 mode, needed != null ? needed.targetUid : -1); 6242 if (targetUid > 0) { 6243 if (needed == null) { 6244 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6245 } 6246 needed.add(data); 6247 } 6248 } 6249 if (clip != null) { 6250 for (int i=0; i<clip.getItemCount(); i++) { 6251 Uri uri = clip.getItemAt(i).getUri(); 6252 if (uri != null) { 6253 int targetUid = -1; 6254 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, 6255 mode, needed != null ? needed.targetUid : -1); 6256 if (targetUid > 0) { 6257 if (needed == null) { 6258 needed = new NeededUriGrants(targetPkg, targetUid, mode); 6259 } 6260 needed.add(uri); 6261 } 6262 } else { 6263 Intent clipIntent = clip.getItemAt(i).getIntent(); 6264 if (clipIntent != null) { 6265 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked( 6266 callingUid, targetPkg, clipIntent, mode, needed); 6267 if (newNeeded != null) { 6268 needed = newNeeded; 6269 } 6270 } 6271 } 6272 } 6273 } 6274 6275 return needed; 6276 } 6277 6278 /** 6279 * Like grantUriPermissionUncheckedLocked, but takes an Intent. 6280 */ 6281 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, 6282 UriPermissionOwner owner) { 6283 if (needed != null) { 6284 for (int i=0; i<needed.size(); i++) { 6285 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg, 6286 needed.get(i), needed.flags, owner); 6287 } 6288 } 6289 } 6290 6291 void grantUriPermissionFromIntentLocked(int callingUid, 6292 String targetPkg, Intent intent, UriPermissionOwner owner) { 6293 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, 6294 intent, intent != null ? intent.getFlags() : 0, null); 6295 if (needed == null) { 6296 return; 6297 } 6298 6299 grantUriPermissionUncheckedFromIntentLocked(needed, owner); 6300 } 6301 6302 @Override 6303 public void grantUriPermission(IApplicationThread caller, String targetPkg, 6304 Uri uri, final int modeFlags) { 6305 enforceNotIsolatedCaller("grantUriPermission"); 6306 synchronized(this) { 6307 final ProcessRecord r = getRecordForAppLocked(caller); 6308 if (r == null) { 6309 throw new SecurityException("Unable to find app for caller " 6310 + caller 6311 + " when granting permission to uri " + uri); 6312 } 6313 if (targetPkg == null) { 6314 throw new IllegalArgumentException("null target"); 6315 } 6316 if (uri == null) { 6317 throw new IllegalArgumentException("null uri"); 6318 } 6319 6320 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION 6321 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION 6322 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION 6323 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION); 6324 6325 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags, null); 6326 } 6327 } 6328 6329 void removeUriPermissionIfNeededLocked(UriPermission perm) { 6330 if (perm.modeFlags == 0) { 6331 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6332 perm.targetUid); 6333 if (perms != null) { 6334 if (DEBUG_URI_PERMISSION) Slog.v(TAG, 6335 "Removing " + perm.targetUid + " permission to " + perm.uri); 6336 6337 perms.remove(perm.uri); 6338 if (perms.isEmpty()) { 6339 mGrantedUriPermissions.remove(perm.targetUid); 6340 } 6341 } 6342 } 6343 } 6344 6345 private void revokeUriPermissionLocked(int callingUid, Uri uri, final int modeFlags) { 6346 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + uri); 6347 6348 final IPackageManager pm = AppGlobals.getPackageManager(); 6349 final String authority = uri.getAuthority(); 6350 final ProviderInfo pi = getProviderInfoLocked(authority, UserHandle.getUserId(callingUid)); 6351 if (pi == null) { 6352 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString()); 6353 return; 6354 } 6355 6356 // Does the caller have this permission on the URI? 6357 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) { 6358 // Right now, if you are not the original owner of the permission, 6359 // you are not allowed to revoke it. 6360 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) { 6361 throw new SecurityException("Uid " + callingUid 6362 + " does not have permission to uri " + uri); 6363 //} 6364 } 6365 6366 boolean persistChanged = false; 6367 6368 // Go through all of the permissions and remove any that match. 6369 int N = mGrantedUriPermissions.size(); 6370 for (int i = 0; i < N; i++) { 6371 final int targetUid = mGrantedUriPermissions.keyAt(i); 6372 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6373 6374 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6375 final UriPermission perm = it.next(); 6376 if (perm.uri.uri.isPathPrefixMatch(uri)) { 6377 if (DEBUG_URI_PERMISSION) 6378 Slog.v(TAG, 6379 "Revoking " + perm.targetUid + " permission to " + perm.uri); 6380 persistChanged |= perm.revokeModes( 6381 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6382 if (perm.modeFlags == 0) { 6383 it.remove(); 6384 } 6385 } 6386 } 6387 6388 if (perms.isEmpty()) { 6389 mGrantedUriPermissions.remove(targetUid); 6390 N--; 6391 i--; 6392 } 6393 } 6394 6395 if (persistChanged) { 6396 schedulePersistUriGrants(); 6397 } 6398 } 6399 6400 @Override 6401 public void revokeUriPermission(IApplicationThread caller, Uri uri, 6402 final int modeFlags) { 6403 enforceNotIsolatedCaller("revokeUriPermission"); 6404 synchronized(this) { 6405 final ProcessRecord r = getRecordForAppLocked(caller); 6406 if (r == null) { 6407 throw new SecurityException("Unable to find app for caller " 6408 + caller 6409 + " when revoking permission to uri " + uri); 6410 } 6411 if (uri == null) { 6412 Slog.w(TAG, "revokeUriPermission: null uri"); 6413 return; 6414 } 6415 6416 if (!Intent.isAccessUriMode(modeFlags)) { 6417 return; 6418 } 6419 6420 final IPackageManager pm = AppGlobals.getPackageManager(); 6421 final String authority = uri.getAuthority(); 6422 final ProviderInfo pi = getProviderInfoLocked(authority, r.userId); 6423 if (pi == null) { 6424 Slog.w(TAG, "No content provider found for permission revoke: " 6425 + uri.toSafeString()); 6426 return; 6427 } 6428 6429 revokeUriPermissionLocked(r.uid, uri, modeFlags); 6430 } 6431 } 6432 6433 /** 6434 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the 6435 * given package. 6436 * 6437 * @param packageName Package name to match, or {@code null} to apply to all 6438 * packages. 6439 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply 6440 * to all users. 6441 * @param persistable If persistable grants should be removed. 6442 */ 6443 private void removeUriPermissionsForPackageLocked( 6444 String packageName, int userHandle, boolean persistable) { 6445 if (userHandle == UserHandle.USER_ALL && packageName == null) { 6446 throw new IllegalArgumentException("Must narrow by either package or user"); 6447 } 6448 6449 boolean persistChanged = false; 6450 6451 int N = mGrantedUriPermissions.size(); 6452 for (int i = 0; i < N; i++) { 6453 final int targetUid = mGrantedUriPermissions.keyAt(i); 6454 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6455 6456 // Only inspect grants matching user 6457 if (userHandle == UserHandle.USER_ALL 6458 || userHandle == UserHandle.getUserId(targetUid)) { 6459 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) { 6460 final UriPermission perm = it.next(); 6461 6462 // Only inspect grants matching package 6463 if (packageName == null || perm.sourcePkg.equals(packageName) 6464 || perm.targetPkg.equals(packageName)) { 6465 persistChanged |= perm.revokeModes( 6466 persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); 6467 6468 // Only remove when no modes remain; any persisted grants 6469 // will keep this alive. 6470 if (perm.modeFlags == 0) { 6471 it.remove(); 6472 } 6473 } 6474 } 6475 6476 if (perms.isEmpty()) { 6477 mGrantedUriPermissions.remove(targetUid); 6478 N--; 6479 i--; 6480 } 6481 } 6482 } 6483 6484 if (persistChanged) { 6485 schedulePersistUriGrants(); 6486 } 6487 } 6488 6489 @Override 6490 public IBinder newUriPermissionOwner(String name) { 6491 enforceNotIsolatedCaller("newUriPermissionOwner"); 6492 synchronized(this) { 6493 UriPermissionOwner owner = new UriPermissionOwner(this, name); 6494 return owner.getExternalTokenLocked(); 6495 } 6496 } 6497 6498 @Override 6499 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, 6500 Uri uri, final int modeFlags) { 6501 synchronized(this) { 6502 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6503 if (owner == null) { 6504 throw new IllegalArgumentException("Unknown owner: " + token); 6505 } 6506 if (fromUid != Binder.getCallingUid()) { 6507 if (Binder.getCallingUid() != Process.myUid()) { 6508 // Only system code can grant URI permissions on behalf 6509 // of other users. 6510 throw new SecurityException("nice try"); 6511 } 6512 } 6513 if (targetPkg == null) { 6514 throw new IllegalArgumentException("null target"); 6515 } 6516 if (uri == null) { 6517 throw new IllegalArgumentException("null uri"); 6518 } 6519 6520 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner); 6521 } 6522 } 6523 6524 @Override 6525 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) { 6526 synchronized(this) { 6527 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token); 6528 if (owner == null) { 6529 throw new IllegalArgumentException("Unknown owner: " + token); 6530 } 6531 6532 if (uri == null) { 6533 owner.removeUriPermissionsLocked(mode); 6534 } else { 6535 owner.removeUriPermissionLocked(uri, mode); 6536 } 6537 } 6538 } 6539 6540 private void schedulePersistUriGrants() { 6541 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) { 6542 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG), 6543 10 * DateUtils.SECOND_IN_MILLIS); 6544 } 6545 } 6546 6547 private void writeGrantedUriPermissions() { 6548 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()"); 6549 6550 // Snapshot permissions so we can persist without lock 6551 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList(); 6552 synchronized (this) { 6553 final int size = mGrantedUriPermissions.size(); 6554 for (int i = 0; i < size; i++) { 6555 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 6556 for (UriPermission perm : perms.values()) { 6557 if (perm.persistedModeFlags != 0) { 6558 persist.add(perm.snapshot()); 6559 } 6560 } 6561 } 6562 } 6563 6564 FileOutputStream fos = null; 6565 try { 6566 fos = mGrantFile.startWrite(); 6567 6568 XmlSerializer out = new FastXmlSerializer(); 6569 out.setOutput(fos, "utf-8"); 6570 out.startDocument(null, true); 6571 out.startTag(null, TAG_URI_GRANTS); 6572 for (UriPermission.Snapshot perm : persist) { 6573 out.startTag(null, TAG_URI_GRANT); 6574 writeIntAttribute(out, ATTR_USER_HANDLE, perm.userHandle); 6575 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg); 6576 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg); 6577 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri)); 6578 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix); 6579 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags); 6580 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime); 6581 out.endTag(null, TAG_URI_GRANT); 6582 } 6583 out.endTag(null, TAG_URI_GRANTS); 6584 out.endDocument(); 6585 6586 mGrantFile.finishWrite(fos); 6587 } catch (IOException e) { 6588 if (fos != null) { 6589 mGrantFile.failWrite(fos); 6590 } 6591 } 6592 } 6593 6594 private void readGrantedUriPermissionsLocked() { 6595 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()"); 6596 6597 final long now = System.currentTimeMillis(); 6598 6599 FileInputStream fis = null; 6600 try { 6601 fis = mGrantFile.openRead(); 6602 final XmlPullParser in = Xml.newPullParser(); 6603 in.setInput(fis, null); 6604 6605 int type; 6606 while ((type = in.next()) != END_DOCUMENT) { 6607 final String tag = in.getName(); 6608 if (type == START_TAG) { 6609 if (TAG_URI_GRANT.equals(tag)) { 6610 final int userHandle = readIntAttribute(in, ATTR_USER_HANDLE); 6611 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG); 6612 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG); 6613 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI)); 6614 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX); 6615 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS); 6616 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now); 6617 6618 // Sanity check that provider still belongs to source package 6619 final ProviderInfo pi = getProviderInfoLocked( 6620 uri.getAuthority(), userHandle); 6621 if (pi != null && sourcePkg.equals(pi.packageName)) { 6622 int targetUid = -1; 6623 try { 6624 targetUid = AppGlobals.getPackageManager() 6625 .getPackageUid(targetPkg, userHandle); 6626 } catch (RemoteException e) { 6627 } 6628 if (targetUid != -1) { 6629 final UriPermission perm = findOrCreateUriPermissionLocked( 6630 sourcePkg, targetPkg, targetUid, new GrantUri(uri, prefix)); 6631 perm.initPersistedModes(modeFlags, createdTime); 6632 } 6633 } else { 6634 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg 6635 + " but instead found " + pi); 6636 } 6637 } 6638 } 6639 } 6640 } catch (FileNotFoundException e) { 6641 // Missing grants is okay 6642 } catch (IOException e) { 6643 Log.wtf(TAG, "Failed reading Uri grants", e); 6644 } catch (XmlPullParserException e) { 6645 Log.wtf(TAG, "Failed reading Uri grants", e); 6646 } finally { 6647 IoUtils.closeQuietly(fis); 6648 } 6649 } 6650 6651 @Override 6652 public void takePersistableUriPermission(Uri uri, final int modeFlags) { 6653 enforceNotIsolatedCaller("takePersistableUriPermission"); 6654 6655 Preconditions.checkFlagsArgument(modeFlags, 6656 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6657 6658 synchronized (this) { 6659 final int callingUid = Binder.getCallingUid(); 6660 boolean persistChanged = false; 6661 6662 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6663 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6664 6665 final boolean exactValid = (exactPerm != null) 6666 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags); 6667 final boolean prefixValid = (prefixPerm != null) 6668 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags); 6669 6670 if (!(exactValid || prefixValid)) { 6671 throw new SecurityException("No persistable permission grants found for UID " 6672 + callingUid + " and Uri " + uri.toSafeString()); 6673 } 6674 6675 if (exactValid) { 6676 persistChanged |= exactPerm.takePersistableModes(modeFlags); 6677 } 6678 if (prefixValid) { 6679 persistChanged |= prefixPerm.takePersistableModes(modeFlags); 6680 } 6681 6682 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid); 6683 6684 if (persistChanged) { 6685 schedulePersistUriGrants(); 6686 } 6687 } 6688 } 6689 6690 @Override 6691 public void releasePersistableUriPermission(Uri uri, final int modeFlags) { 6692 enforceNotIsolatedCaller("releasePersistableUriPermission"); 6693 6694 Preconditions.checkFlagsArgument(modeFlags, 6695 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 6696 6697 synchronized (this) { 6698 final int callingUid = Binder.getCallingUid(); 6699 boolean persistChanged = false; 6700 6701 UriPermission exactPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, false)); 6702 UriPermission prefixPerm = findUriPermissionLocked(callingUid, new GrantUri(uri, true)); 6703 if (exactPerm == null && prefixPerm == null) { 6704 throw new SecurityException("No permission grants found for UID " + callingUid 6705 + " and Uri " + uri.toSafeString()); 6706 } 6707 6708 if (exactPerm != null) { 6709 persistChanged |= exactPerm.releasePersistableModes(modeFlags); 6710 removeUriPermissionIfNeededLocked(exactPerm); 6711 } 6712 if (prefixPerm != null) { 6713 persistChanged |= prefixPerm.releasePersistableModes(modeFlags); 6714 removeUriPermissionIfNeededLocked(prefixPerm); 6715 } 6716 6717 if (persistChanged) { 6718 schedulePersistUriGrants(); 6719 } 6720 } 6721 } 6722 6723 /** 6724 * Prune any older {@link UriPermission} for the given UID until outstanding 6725 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}. 6726 * 6727 * @return if any mutations occured that require persisting. 6728 */ 6729 private boolean maybePrunePersistedUriGrantsLocked(int uid) { 6730 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid); 6731 if (perms == null) return false; 6732 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false; 6733 6734 final ArrayList<UriPermission> persisted = Lists.newArrayList(); 6735 for (UriPermission perm : perms.values()) { 6736 if (perm.persistedModeFlags != 0) { 6737 persisted.add(perm); 6738 } 6739 } 6740 6741 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS; 6742 if (trimCount <= 0) return false; 6743 6744 Collections.sort(persisted, new UriPermission.PersistedTimeComparator()); 6745 for (int i = 0; i < trimCount; i++) { 6746 final UriPermission perm = persisted.get(i); 6747 6748 if (DEBUG_URI_PERMISSION) { 6749 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime); 6750 } 6751 6752 perm.releasePersistableModes(~0); 6753 removeUriPermissionIfNeededLocked(perm); 6754 } 6755 6756 return true; 6757 } 6758 6759 @Override 6760 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions( 6761 String packageName, boolean incoming) { 6762 enforceNotIsolatedCaller("getPersistedUriPermissions"); 6763 Preconditions.checkNotNull(packageName, "packageName"); 6764 6765 final int callingUid = Binder.getCallingUid(); 6766 final IPackageManager pm = AppGlobals.getPackageManager(); 6767 try { 6768 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid)); 6769 if (packageUid != callingUid) { 6770 throw new SecurityException( 6771 "Package " + packageName + " does not belong to calling UID " + callingUid); 6772 } 6773 } catch (RemoteException e) { 6774 throw new SecurityException("Failed to verify package name ownership"); 6775 } 6776 6777 final ArrayList<android.content.UriPermission> result = Lists.newArrayList(); 6778 synchronized (this) { 6779 if (incoming) { 6780 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get( 6781 callingUid); 6782 if (perms == null) { 6783 Slog.w(TAG, "No permission grants found for " + packageName); 6784 } else { 6785 for (UriPermission perm : perms.values()) { 6786 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) { 6787 result.add(perm.buildPersistedPublicApiObject()); 6788 } 6789 } 6790 } 6791 } else { 6792 final int size = mGrantedUriPermissions.size(); 6793 for (int i = 0; i < size; i++) { 6794 final ArrayMap<GrantUri, UriPermission> perms = 6795 mGrantedUriPermissions.valueAt(i); 6796 for (UriPermission perm : perms.values()) { 6797 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) { 6798 result.add(perm.buildPersistedPublicApiObject()); 6799 } 6800 } 6801 } 6802 } 6803 } 6804 return new ParceledListSlice<android.content.UriPermission>(result); 6805 } 6806 6807 @Override 6808 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) { 6809 synchronized (this) { 6810 ProcessRecord app = 6811 who != null ? getRecordForAppLocked(who) : null; 6812 if (app == null) return; 6813 6814 Message msg = Message.obtain(); 6815 msg.what = WAIT_FOR_DEBUGGER_MSG; 6816 msg.obj = app; 6817 msg.arg1 = waiting ? 1 : 0; 6818 mHandler.sendMessage(msg); 6819 } 6820 } 6821 6822 @Override 6823 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 6824 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ); 6825 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ); 6826 outInfo.availMem = Process.getFreeMemory(); 6827 outInfo.totalMem = Process.getTotalMemory(); 6828 outInfo.threshold = homeAppMem; 6829 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 6830 outInfo.hiddenAppThreshold = cachedAppMem; 6831 outInfo.secondaryServerThreshold = mProcessList.getMemLevel( 6832 ProcessList.SERVICE_ADJ); 6833 outInfo.visibleAppThreshold = mProcessList.getMemLevel( 6834 ProcessList.VISIBLE_APP_ADJ); 6835 outInfo.foregroundAppThreshold = mProcessList.getMemLevel( 6836 ProcessList.FOREGROUND_APP_ADJ); 6837 } 6838 6839 // ========================================================= 6840 // TASK MANAGEMENT 6841 // ========================================================= 6842 6843 @Override 6844 public List<RunningTaskInfo> getTasks(int maxNum, int flags, 6845 IThumbnailReceiver receiver) { 6846 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>(); 6847 6848 PendingThumbnailsRecord pending = new PendingThumbnailsRecord(receiver); 6849 ActivityRecord topRecord = null; 6850 6851 synchronized(this) { 6852 if (localLOGV) Slog.v( 6853 TAG, "getTasks: max=" + maxNum + ", flags=" + flags 6854 + ", receiver=" + receiver); 6855 6856 if (checkCallingPermission(android.Manifest.permission.GET_TASKS) 6857 != PackageManager.PERMISSION_GRANTED) { 6858 if (receiver != null) { 6859 // If the caller wants to wait for pending thumbnails, 6860 // it ain't gonna get them. 6861 try { 6862 receiver.finished(); 6863 } catch (RemoteException ex) { 6864 } 6865 } 6866 String msg = "Permission Denial: getTasks() from pid=" 6867 + Binder.getCallingPid() 6868 + ", uid=" + Binder.getCallingUid() 6869 + " requires " + android.Manifest.permission.GET_TASKS; 6870 Slog.w(TAG, msg); 6871 throw new SecurityException(msg); 6872 } 6873 6874 // TODO: Improve with MRU list from all ActivityStacks. 6875 topRecord = mStackSupervisor.getTasksLocked(maxNum, receiver, pending, list); 6876 6877 if (!pending.pendingRecords.isEmpty()) { 6878 mPendingThumbnails.add(pending); 6879 } 6880 } 6881 6882 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending); 6883 6884 if (topRecord != null) { 6885 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail"); 6886 try { 6887 IApplicationThread topThumbnail = topRecord.app.thread; 6888 topThumbnail.requestThumbnail(topRecord.appToken); 6889 } catch (Exception e) { 6890 Slog.w(TAG, "Exception thrown when requesting thumbnail", e); 6891 sendPendingThumbnail(null, topRecord.appToken, null, null, true); 6892 } 6893 } 6894 6895 if (pending.pendingRecords.isEmpty() && receiver != null) { 6896 // In this case all thumbnails were available and the client 6897 // is being asked to be told when the remaining ones come in... 6898 // which is unusually, since the top-most currently running 6899 // activity should never have a canned thumbnail! Oh well. 6900 try { 6901 receiver.finished(); 6902 } catch (RemoteException ex) { 6903 } 6904 } 6905 6906 return list; 6907 } 6908 6909 TaskRecord getMostRecentTask() { 6910 return mRecentTasks.get(0); 6911 } 6912 6913 @Override 6914 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, 6915 int flags, int userId) { 6916 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 6917 false, true, "getRecentTasks", null); 6918 6919 synchronized (this) { 6920 enforceCallingPermission(android.Manifest.permission.GET_TASKS, 6921 "getRecentTasks()"); 6922 final boolean detailed = checkCallingPermission( 6923 android.Manifest.permission.GET_DETAILED_TASKS) 6924 == PackageManager.PERMISSION_GRANTED; 6925 6926 IPackageManager pm = AppGlobals.getPackageManager(); 6927 6928 final int N = mRecentTasks.size(); 6929 ArrayList<ActivityManager.RecentTaskInfo> res 6930 = new ArrayList<ActivityManager.RecentTaskInfo>( 6931 maxNum < N ? maxNum : N); 6932 6933 final Set<Integer> includedUsers; 6934 if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) { 6935 includedUsers = getProfileIdsLocked(userId); 6936 } else { 6937 includedUsers = new HashSet<Integer>(); 6938 } 6939 includedUsers.add(Integer.valueOf(userId)); 6940 for (int i=0; i<N && maxNum > 0; i++) { 6941 TaskRecord tr = mRecentTasks.get(i); 6942 // Only add calling user or related users recent tasks 6943 if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue; 6944 6945 // Return the entry if desired by the caller. We always return 6946 // the first entry, because callers always expect this to be the 6947 // foreground app. We may filter others if the caller has 6948 // not supplied RECENT_WITH_EXCLUDED and there is some reason 6949 // we should exclude the entry. 6950 6951 if (i == 0 6952 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0) 6953 || (tr.intent == null) 6954 || ((tr.intent.getFlags() 6955 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) { 6956 ActivityManager.RecentTaskInfo rti 6957 = new ActivityManager.RecentTaskInfo(); 6958 rti.id = tr.numActivities > 0 ? tr.taskId : -1; 6959 rti.persistentId = tr.taskId; 6960 rti.baseIntent = new Intent( 6961 tr.intent != null ? tr.intent : tr.affinityIntent); 6962 if (!detailed) { 6963 rti.baseIntent.replaceExtras((Bundle)null); 6964 } 6965 rti.origActivity = tr.origActivity; 6966 rti.description = tr.lastDescription; 6967 rti.stackId = tr.stack.mStackId; 6968 rti.userId = tr.userId; 6969 6970 // Traverse upwards looking for any break between main task activities and 6971 // utility activities. 6972 final ArrayList<ActivityRecord> activities = tr.mActivities; 6973 int activityNdx; 6974 final int numActivities = activities.size(); 6975 for (activityNdx = Math.min(numActivities, 1); activityNdx < numActivities; 6976 ++activityNdx) { 6977 final ActivityRecord r = activities.get(activityNdx); 6978 if (r.intent != null && 6979 (r.intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) 6980 != 0) { 6981 break; 6982 } 6983 } 6984 // Traverse downwards starting below break looking for set label and icon. 6985 for (--activityNdx; activityNdx >= 0; --activityNdx) { 6986 final ActivityRecord r = activities.get(activityNdx); 6987 if (r.activityLabel != null || r.activityIcon != null) { 6988 rti.activityLabel = r.activityLabel; 6989 rti.activityIcon = r.activityIcon; 6990 break; 6991 } 6992 } 6993 6994 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) { 6995 // Check whether this activity is currently available. 6996 try { 6997 if (rti.origActivity != null) { 6998 if (pm.getActivityInfo(rti.origActivity, 0, userId) 6999 == null) { 7000 continue; 7001 } 7002 } else if (rti.baseIntent != null) { 7003 if (pm.queryIntentActivities(rti.baseIntent, 7004 null, 0, userId) == null) { 7005 continue; 7006 } 7007 } 7008 } catch (RemoteException e) { 7009 // Will never happen. 7010 } 7011 } 7012 7013 res.add(rti); 7014 maxNum--; 7015 } 7016 } 7017 return res; 7018 } 7019 } 7020 7021 private TaskRecord recentTaskForIdLocked(int id) { 7022 final int N = mRecentTasks.size(); 7023 for (int i=0; i<N; i++) { 7024 TaskRecord tr = mRecentTasks.get(i); 7025 if (tr.taskId == id) { 7026 return tr; 7027 } 7028 } 7029 return null; 7030 } 7031 7032 @Override 7033 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) { 7034 synchronized (this) { 7035 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7036 "getTaskThumbnails()"); 7037 TaskRecord tr = recentTaskForIdLocked(id); 7038 if (tr != null) { 7039 return tr.getTaskThumbnailsLocked(); 7040 } 7041 } 7042 return null; 7043 } 7044 7045 @Override 7046 public Bitmap getTaskTopThumbnail(int id) { 7047 synchronized (this) { 7048 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER, 7049 "getTaskTopThumbnail()"); 7050 TaskRecord tr = recentTaskForIdLocked(id); 7051 if (tr != null) { 7052 return tr.getTaskTopThumbnailLocked(); 7053 } 7054 } 7055 return null; 7056 } 7057 7058 @Override 7059 public void setActivityLabelAndIcon(IBinder token, CharSequence activityLabel, 7060 Bitmap activityIcon) { 7061 synchronized (this) { 7062 ActivityRecord r = ActivityRecord.isInStackLocked(token); 7063 if (r != null) { 7064 r.activityLabel = activityLabel.toString(); 7065 r.activityIcon = activityIcon; 7066 } 7067 } 7068 } 7069 7070 @Override 7071 public boolean removeSubTask(int taskId, int subTaskIndex) { 7072 synchronized (this) { 7073 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7074 "removeSubTask()"); 7075 long ident = Binder.clearCallingIdentity(); 7076 try { 7077 TaskRecord tr = recentTaskForIdLocked(taskId); 7078 if (tr != null) { 7079 return tr.removeTaskActivitiesLocked(subTaskIndex, true) != null; 7080 } 7081 return false; 7082 } finally { 7083 Binder.restoreCallingIdentity(ident); 7084 } 7085 } 7086 } 7087 7088 private void killUnneededProcessLocked(ProcessRecord pr, String reason) { 7089 if (!pr.killedByAm) { 7090 Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason); 7091 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid, 7092 pr.processName, pr.setAdj, reason); 7093 pr.killedByAm = true; 7094 Process.killProcessQuiet(pr.pid); 7095 } 7096 } 7097 7098 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) { 7099 tr.disposeThumbnail(); 7100 mRecentTasks.remove(tr); 7101 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0; 7102 Intent baseIntent = new Intent( 7103 tr.intent != null ? tr.intent : tr.affinityIntent); 7104 ComponentName component = baseIntent.getComponent(); 7105 if (component == null) { 7106 Slog.w(TAG, "Now component for base intent of task: " + tr); 7107 return; 7108 } 7109 7110 // Find any running services associated with this app. 7111 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent); 7112 7113 if (killProcesses) { 7114 // Find any running processes associated with this app. 7115 final String pkg = component.getPackageName(); 7116 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(); 7117 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap(); 7118 for (int i=0; i<pmap.size(); i++) { 7119 SparseArray<ProcessRecord> uids = pmap.valueAt(i); 7120 for (int j=0; j<uids.size(); j++) { 7121 ProcessRecord proc = uids.valueAt(j); 7122 if (proc.userId != tr.userId) { 7123 continue; 7124 } 7125 if (!proc.pkgList.containsKey(pkg)) { 7126 continue; 7127 } 7128 procs.add(proc); 7129 } 7130 } 7131 7132 // Kill the running processes. 7133 for (int i=0; i<procs.size(); i++) { 7134 ProcessRecord pr = procs.get(i); 7135 if (pr == mHomeProcess) { 7136 // Don't kill the home process along with tasks from the same package. 7137 continue; 7138 } 7139 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 7140 killUnneededProcessLocked(pr, "remove task"); 7141 } else { 7142 pr.waitingToKill = "remove task"; 7143 } 7144 } 7145 } 7146 } 7147 7148 @Override 7149 public boolean removeTask(int taskId, int flags) { 7150 synchronized (this) { 7151 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, 7152 "removeTask()"); 7153 long ident = Binder.clearCallingIdentity(); 7154 try { 7155 TaskRecord tr = recentTaskForIdLocked(taskId); 7156 if (tr != null) { 7157 ActivityRecord r = tr.removeTaskActivitiesLocked(-1, false); 7158 if (r != null) { 7159 cleanUpRemovedTaskLocked(tr, flags); 7160 return true; 7161 } 7162 if (tr.mActivities.size() == 0) { 7163 // Caller is just removing a recent task that is 7164 // not actively running. That is easy! 7165 cleanUpRemovedTaskLocked(tr, flags); 7166 return true; 7167 } 7168 Slog.w(TAG, "removeTask: task " + taskId 7169 + " does not have activities to remove, " 7170 + " but numActivities=" + tr.numActivities 7171 + ": " + tr); 7172 } 7173 } finally { 7174 Binder.restoreCallingIdentity(ident); 7175 } 7176 } 7177 return false; 7178 } 7179 7180 /** 7181 * TODO: Add mController hook 7182 */ 7183 @Override 7184 public void moveTaskToFront(int taskId, int flags, Bundle options) { 7185 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7186 "moveTaskToFront()"); 7187 7188 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId); 7189 synchronized(this) { 7190 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7191 Binder.getCallingUid(), "Task to front")) { 7192 ActivityOptions.abort(options); 7193 return; 7194 } 7195 final long origId = Binder.clearCallingIdentity(); 7196 try { 7197 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId); 7198 if (task == null) { 7199 return; 7200 } 7201 if (mStackSupervisor.isLockTaskModeViolation(task)) { 7202 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode"); 7203 return; 7204 } 7205 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options); 7206 } finally { 7207 Binder.restoreCallingIdentity(origId); 7208 } 7209 ActivityOptions.abort(options); 7210 } 7211 } 7212 7213 @Override 7214 public void moveTaskToBack(int taskId) { 7215 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7216 "moveTaskToBack()"); 7217 7218 synchronized(this) { 7219 TaskRecord tr = recentTaskForIdLocked(taskId); 7220 if (tr != null) { 7221 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr); 7222 ActivityStack stack = tr.stack; 7223 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) { 7224 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7225 Binder.getCallingUid(), "Task to back")) { 7226 return; 7227 } 7228 } 7229 final long origId = Binder.clearCallingIdentity(); 7230 try { 7231 stack.moveTaskToBackLocked(taskId, null); 7232 } finally { 7233 Binder.restoreCallingIdentity(origId); 7234 } 7235 } 7236 } 7237 } 7238 7239 /** 7240 * Moves an activity, and all of the other activities within the same task, to the bottom 7241 * of the history stack. The activity's order within the task is unchanged. 7242 * 7243 * @param token A reference to the activity we wish to move 7244 * @param nonRoot If false then this only works if the activity is the root 7245 * of a task; if true it will work for any activity in a task. 7246 * @return Returns true if the move completed, false if not. 7247 */ 7248 @Override 7249 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) { 7250 enforceNotIsolatedCaller("moveActivityTaskToBack"); 7251 synchronized(this) { 7252 final long origId = Binder.clearCallingIdentity(); 7253 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot); 7254 if (taskId >= 0) { 7255 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null); 7256 } 7257 Binder.restoreCallingIdentity(origId); 7258 } 7259 return false; 7260 } 7261 7262 @Override 7263 public void moveTaskBackwards(int task) { 7264 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7265 "moveTaskBackwards()"); 7266 7267 synchronized(this) { 7268 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(), 7269 Binder.getCallingUid(), "Task backwards")) { 7270 return; 7271 } 7272 final long origId = Binder.clearCallingIdentity(); 7273 moveTaskBackwardsLocked(task); 7274 Binder.restoreCallingIdentity(origId); 7275 } 7276 } 7277 7278 private final void moveTaskBackwardsLocked(int task) { 7279 Slog.e(TAG, "moveTaskBackwards not yet implemented!"); 7280 } 7281 7282 @Override 7283 public IBinder getHomeActivityToken() throws RemoteException { 7284 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7285 "getHomeActivityToken()"); 7286 synchronized (this) { 7287 return mStackSupervisor.getHomeActivityToken(); 7288 } 7289 } 7290 7291 @Override 7292 public IActivityContainer createActivityContainer(IBinder parentActivityToken, 7293 IActivityContainerCallback callback) throws RemoteException { 7294 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7295 "createActivityContainer()"); 7296 synchronized (this) { 7297 if (parentActivityToken == null) { 7298 throw new IllegalArgumentException("parent token must not be null"); 7299 } 7300 ActivityRecord r = ActivityRecord.forToken(parentActivityToken); 7301 if (r == null) { 7302 return null; 7303 } 7304 if (callback == null) { 7305 throw new IllegalArgumentException("callback must not be null"); 7306 } 7307 return mStackSupervisor.createActivityContainer(r, callback); 7308 } 7309 } 7310 7311 @Override 7312 public void deleteActivityContainer(IActivityContainer container) throws RemoteException { 7313 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7314 "deleteActivityContainer()"); 7315 synchronized (this) { 7316 mStackSupervisor.deleteActivityContainer(container); 7317 } 7318 } 7319 7320 @Override 7321 public IActivityContainer getEnclosingActivityContainer(IBinder activityToken) 7322 throws RemoteException { 7323 synchronized (this) { 7324 ActivityStack stack = ActivityRecord.getStackLocked(activityToken); 7325 if (stack != null) { 7326 return stack.mActivityContainer; 7327 } 7328 return null; 7329 } 7330 } 7331 7332 @Override 7333 public void moveTaskToStack(int taskId, int stackId, boolean toTop) { 7334 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7335 "moveTaskToStack()"); 7336 if (stackId == HOME_STACK_ID) { 7337 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack", 7338 new RuntimeException("here").fillInStackTrace()); 7339 } 7340 synchronized (this) { 7341 long ident = Binder.clearCallingIdentity(); 7342 try { 7343 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId=" 7344 + stackId + " toTop=" + toTop); 7345 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop); 7346 } finally { 7347 Binder.restoreCallingIdentity(ident); 7348 } 7349 } 7350 } 7351 7352 @Override 7353 public void resizeStack(int stackBoxId, Rect bounds) { 7354 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7355 "resizeStackBox()"); 7356 long ident = Binder.clearCallingIdentity(); 7357 try { 7358 mWindowManager.resizeStack(stackBoxId, bounds); 7359 } finally { 7360 Binder.restoreCallingIdentity(ident); 7361 } 7362 } 7363 7364 @Override 7365 public List<StackInfo> getAllStackInfos() { 7366 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7367 "getAllStackInfos()"); 7368 long ident = Binder.clearCallingIdentity(); 7369 try { 7370 synchronized (this) { 7371 return mStackSupervisor.getAllStackInfosLocked(); 7372 } 7373 } finally { 7374 Binder.restoreCallingIdentity(ident); 7375 } 7376 } 7377 7378 @Override 7379 public StackInfo getStackInfo(int stackId) { 7380 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7381 "getStackInfo()"); 7382 long ident = Binder.clearCallingIdentity(); 7383 try { 7384 synchronized (this) { 7385 return mStackSupervisor.getStackInfoLocked(stackId); 7386 } 7387 } finally { 7388 Binder.restoreCallingIdentity(ident); 7389 } 7390 } 7391 7392 @Override 7393 public boolean isInHomeStack(int taskId) { 7394 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS, 7395 "getStackInfo()"); 7396 long ident = Binder.clearCallingIdentity(); 7397 try { 7398 synchronized (this) { 7399 TaskRecord tr = recentTaskForIdLocked(taskId); 7400 if (tr != null) { 7401 return tr.stack.isHomeStack(); 7402 } 7403 } 7404 } finally { 7405 Binder.restoreCallingIdentity(ident); 7406 } 7407 return false; 7408 } 7409 7410 @Override 7411 public int getTaskForActivity(IBinder token, boolean onlyRoot) { 7412 synchronized(this) { 7413 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot); 7414 } 7415 } 7416 7417 private boolean isLockTaskAuthorized(ComponentName name) { 7418// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7419// "startLockTaskMode()"); 7420// DevicePolicyManager dpm = (DevicePolicyManager) 7421// mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 7422// return dpm != null && dpm.isLockTaskPermitted(name); 7423 return true; 7424 } 7425 7426 private void startLockTaskMode(TaskRecord task) { 7427 if (!isLockTaskAuthorized(task.intent.getComponent())) { 7428 return; 7429 } 7430 long ident = Binder.clearCallingIdentity(); 7431 try { 7432 synchronized (this) { 7433 // Since we lost lock on task, make sure it is still there. 7434 task = mStackSupervisor.anyTaskForIdLocked(task.taskId); 7435 if (task != null) { 7436 mStackSupervisor.setLockTaskModeLocked(task); 7437 } 7438 } 7439 } finally { 7440 Binder.restoreCallingIdentity(ident); 7441 } 7442 } 7443 7444 @Override 7445 public void startLockTaskMode(int taskId) { 7446 long ident = Binder.clearCallingIdentity(); 7447 try { 7448 final TaskRecord task; 7449 synchronized (this) { 7450 task = mStackSupervisor.anyTaskForIdLocked(taskId); 7451 } 7452 if (task != null) { 7453 startLockTaskMode(task); 7454 } 7455 } finally { 7456 Binder.restoreCallingIdentity(ident); 7457 } 7458 } 7459 7460 @Override 7461 public void startLockTaskMode(IBinder token) { 7462 long ident = Binder.clearCallingIdentity(); 7463 try { 7464 final TaskRecord task; 7465 synchronized (this) { 7466 final ActivityRecord r = ActivityRecord.forToken(token); 7467 if (r == null) { 7468 return; 7469 } 7470 task = r.task; 7471 } 7472 if (task != null) { 7473 startLockTaskMode(task); 7474 } 7475 } finally { 7476 Binder.restoreCallingIdentity(ident); 7477 } 7478 } 7479 7480 @Override 7481 public void stopLockTaskMode() { 7482// enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, 7483// "stopLockTaskMode()"); 7484 synchronized (this) { 7485 mStackSupervisor.setLockTaskModeLocked(null); 7486 } 7487 } 7488 7489 @Override 7490 public boolean isInLockTaskMode() { 7491 synchronized (this) { 7492 return mStackSupervisor.isInLockTaskMode(); 7493 } 7494 } 7495 7496 // ========================================================= 7497 // THUMBNAILS 7498 // ========================================================= 7499 7500 public void reportThumbnail(IBinder token, 7501 Bitmap thumbnail, CharSequence description) { 7502 //System.out.println("Report thumbnail for " + token + ": " + thumbnail); 7503 final long origId = Binder.clearCallingIdentity(); 7504 sendPendingThumbnail(null, token, thumbnail, description, true); 7505 Binder.restoreCallingIdentity(origId); 7506 } 7507 7508 final void sendPendingThumbnail(ActivityRecord r, IBinder token, 7509 Bitmap thumbnail, CharSequence description, boolean always) { 7510 TaskRecord task; 7511 ArrayList<PendingThumbnailsRecord> receivers = null; 7512 7513 //System.out.println("Send pending thumbnail: " + r); 7514 7515 synchronized(this) { 7516 if (r == null) { 7517 r = ActivityRecord.isInStackLocked(token); 7518 if (r == null) { 7519 return; 7520 } 7521 } 7522 if (thumbnail == null && r.thumbHolder != null) { 7523 thumbnail = r.thumbHolder.lastThumbnail; 7524 description = r.thumbHolder.lastDescription; 7525 } 7526 if (thumbnail == null && !always) { 7527 // If there is no thumbnail, and this entry is not actually 7528 // going away, then abort for now and pick up the next 7529 // thumbnail we get. 7530 return; 7531 } 7532 task = r.task; 7533 7534 int N = mPendingThumbnails.size(); 7535 int i=0; 7536 while (i<N) { 7537 PendingThumbnailsRecord pr = mPendingThumbnails.get(i); 7538 //System.out.println("Looking in " + pr.pendingRecords); 7539 if (pr.pendingRecords.remove(r)) { 7540 if (receivers == null) { 7541 receivers = new ArrayList<PendingThumbnailsRecord>(); 7542 } 7543 receivers.add(pr); 7544 if (pr.pendingRecords.size() == 0) { 7545 pr.finished = true; 7546 mPendingThumbnails.remove(i); 7547 N--; 7548 continue; 7549 } 7550 } 7551 i++; 7552 } 7553 } 7554 7555 if (receivers != null) { 7556 final int N = receivers.size(); 7557 for (int i=0; i<N; i++) { 7558 try { 7559 PendingThumbnailsRecord pr = receivers.get(i); 7560 pr.receiver.newThumbnail( 7561 task != null ? task.taskId : -1, thumbnail, description); 7562 if (pr.finished) { 7563 pr.receiver.finished(); 7564 } 7565 } catch (Exception e) { 7566 Slog.w(TAG, "Exception thrown when sending thumbnail", e); 7567 } 7568 } 7569 } 7570 } 7571 7572 // ========================================================= 7573 // CONTENT PROVIDERS 7574 // ========================================================= 7575 7576 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) { 7577 List<ProviderInfo> providers = null; 7578 try { 7579 providers = AppGlobals.getPackageManager(). 7580 queryContentProviders(app.processName, app.uid, 7581 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); 7582 } catch (RemoteException ex) { 7583 } 7584 if (DEBUG_MU) 7585 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid); 7586 int userId = app.userId; 7587 if (providers != null) { 7588 int N = providers.size(); 7589 app.pubProviders.ensureCapacity(N + app.pubProviders.size()); 7590 for (int i=0; i<N; i++) { 7591 ProviderInfo cpi = 7592 (ProviderInfo)providers.get(i); 7593 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7594 cpi.name, cpi.flags); 7595 if (singleton && UserHandle.getUserId(app.uid) != 0) { 7596 // This is a singleton provider, but a user besides the 7597 // default user is asking to initialize a process it runs 7598 // in... well, no, it doesn't actually run in this process, 7599 // it runs in the process of the default user. Get rid of it. 7600 providers.remove(i); 7601 N--; 7602 i--; 7603 continue; 7604 } 7605 7606 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7607 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId); 7608 if (cpr == null) { 7609 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton); 7610 mProviderMap.putProviderByClass(comp, cpr); 7611 } 7612 if (DEBUG_MU) 7613 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid); 7614 app.pubProviders.put(cpi.name, cpr); 7615 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) { 7616 // Don't add this if it is a platform component that is marked 7617 // to run in multiple processes, because this is actually 7618 // part of the framework so doesn't make sense to track as a 7619 // separate apk in the process. 7620 app.addPackage(cpi.applicationInfo.packageName, mProcessStats); 7621 } 7622 ensurePackageDexOpt(cpi.applicationInfo.packageName); 7623 } 7624 } 7625 return providers; 7626 } 7627 7628 /** 7629 * Check if {@link ProcessRecord} has a possible chance at accessing the 7630 * given {@link ProviderInfo}. Final permission checking is always done 7631 * in {@link ContentProvider}. 7632 */ 7633 private final String checkContentProviderPermissionLocked( 7634 ProviderInfo cpi, ProcessRecord r) { 7635 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid(); 7636 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid(); 7637 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid, 7638 cpi.applicationInfo.uid, cpi.exported) 7639 == PackageManager.PERMISSION_GRANTED) { 7640 return null; 7641 } 7642 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid, 7643 cpi.applicationInfo.uid, cpi.exported) 7644 == PackageManager.PERMISSION_GRANTED) { 7645 return null; 7646 } 7647 7648 PathPermission[] pps = cpi.pathPermissions; 7649 if (pps != null) { 7650 int i = pps.length; 7651 while (i > 0) { 7652 i--; 7653 PathPermission pp = pps[i]; 7654 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid, 7655 cpi.applicationInfo.uid, cpi.exported) 7656 == PackageManager.PERMISSION_GRANTED) { 7657 return null; 7658 } 7659 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid, 7660 cpi.applicationInfo.uid, cpi.exported) 7661 == PackageManager.PERMISSION_GRANTED) { 7662 return null; 7663 } 7664 } 7665 } 7666 7667 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid); 7668 if (perms != null) { 7669 for (GrantUri uri : perms.keySet()) { 7670 if (uri.uri.getAuthority().equals(cpi.authority)) { 7671 return null; 7672 } 7673 } 7674 } 7675 7676 String msg; 7677 if (!cpi.exported) { 7678 msg = "Permission Denial: opening provider " + cpi.name 7679 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7680 + ", uid=" + callingUid + ") that is not exported from uid " 7681 + cpi.applicationInfo.uid; 7682 } else { 7683 msg = "Permission Denial: opening provider " + cpi.name 7684 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid 7685 + ", uid=" + callingUid + ") requires " 7686 + cpi.readPermission + " or " + cpi.writePermission; 7687 } 7688 Slog.w(TAG, msg); 7689 return msg; 7690 } 7691 7692 ContentProviderConnection incProviderCountLocked(ProcessRecord r, 7693 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7694 if (r != null) { 7695 for (int i=0; i<r.conProviders.size(); i++) { 7696 ContentProviderConnection conn = r.conProviders.get(i); 7697 if (conn.provider == cpr) { 7698 if (DEBUG_PROVIDER) Slog.v(TAG, 7699 "Adding provider requested by " 7700 + r.processName + " from process " 7701 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7702 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7703 if (stable) { 7704 conn.stableCount++; 7705 conn.numStableIncs++; 7706 } else { 7707 conn.unstableCount++; 7708 conn.numUnstableIncs++; 7709 } 7710 return conn; 7711 } 7712 } 7713 ContentProviderConnection conn = new ContentProviderConnection(cpr, r); 7714 if (stable) { 7715 conn.stableCount = 1; 7716 conn.numStableIncs = 1; 7717 } else { 7718 conn.unstableCount = 1; 7719 conn.numUnstableIncs = 1; 7720 } 7721 cpr.connections.add(conn); 7722 r.conProviders.add(conn); 7723 return conn; 7724 } 7725 cpr.addExternalProcessHandleLocked(externalProcessToken); 7726 return null; 7727 } 7728 7729 boolean decProviderCountLocked(ContentProviderConnection conn, 7730 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) { 7731 if (conn != null) { 7732 cpr = conn.provider; 7733 if (DEBUG_PROVIDER) Slog.v(TAG, 7734 "Removing provider requested by " 7735 + conn.client.processName + " from process " 7736 + cpr.info.processName + ": " + cpr.name.flattenToShortString() 7737 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount); 7738 if (stable) { 7739 conn.stableCount--; 7740 } else { 7741 conn.unstableCount--; 7742 } 7743 if (conn.stableCount == 0 && conn.unstableCount == 0) { 7744 cpr.connections.remove(conn); 7745 conn.client.conProviders.remove(conn); 7746 return true; 7747 } 7748 return false; 7749 } 7750 cpr.removeExternalProcessHandleLocked(externalProcessToken); 7751 return false; 7752 } 7753 7754 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller, 7755 String name, IBinder token, boolean stable, int userId) { 7756 ContentProviderRecord cpr; 7757 ContentProviderConnection conn = null; 7758 ProviderInfo cpi = null; 7759 7760 synchronized(this) { 7761 ProcessRecord r = null; 7762 if (caller != null) { 7763 r = getRecordForAppLocked(caller); 7764 if (r == null) { 7765 throw new SecurityException( 7766 "Unable to find app for caller " + caller 7767 + " (pid=" + Binder.getCallingPid() 7768 + ") when getting content provider " + name); 7769 } 7770 } 7771 7772 // First check if this content provider has been published... 7773 cpr = mProviderMap.getProviderByName(name, userId); 7774 boolean providerRunning = cpr != null; 7775 if (providerRunning) { 7776 cpi = cpr.info; 7777 String msg; 7778 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7779 throw new SecurityException(msg); 7780 } 7781 7782 if (r != null && cpr.canRunHere(r)) { 7783 // This provider has been published or is in the process 7784 // of being published... but it is also allowed to run 7785 // in the caller's process, so don't make a connection 7786 // and just let the caller instantiate its own instance. 7787 ContentProviderHolder holder = cpr.newHolder(null); 7788 // don't give caller the provider object, it needs 7789 // to make its own. 7790 holder.provider = null; 7791 return holder; 7792 } 7793 7794 final long origId = Binder.clearCallingIdentity(); 7795 7796 // In this case the provider instance already exists, so we can 7797 // return it right away. 7798 conn = incProviderCountLocked(r, cpr, token, stable); 7799 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) { 7800 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 7801 // If this is a perceptible app accessing the provider, 7802 // make sure to count it as being accessed and thus 7803 // back up on the LRU list. This is good because 7804 // content providers are often expensive to start. 7805 updateLruProcessLocked(cpr.proc, false, null); 7806 } 7807 } 7808 7809 if (cpr.proc != null) { 7810 if (false) { 7811 if (cpr.name.flattenToShortString().equals( 7812 "com.android.providers.calendar/.CalendarProvider2")) { 7813 Slog.v(TAG, "****************** KILLING " 7814 + cpr.name.flattenToShortString()); 7815 Process.killProcess(cpr.proc.pid); 7816 } 7817 } 7818 boolean success = updateOomAdjLocked(cpr.proc); 7819 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success); 7820 // NOTE: there is still a race here where a signal could be 7821 // pending on the process even though we managed to update its 7822 // adj level. Not sure what to do about this, but at least 7823 // the race is now smaller. 7824 if (!success) { 7825 // Uh oh... it looks like the provider's process 7826 // has been killed on us. We need to wait for a new 7827 // process to be started, and make sure its death 7828 // doesn't kill our process. 7829 Slog.i(TAG, 7830 "Existing provider " + cpr.name.flattenToShortString() 7831 + " is crashing; detaching " + r); 7832 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable); 7833 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread); 7834 if (!lastRef) { 7835 // This wasn't the last ref our process had on 7836 // the provider... we have now been killed, bail. 7837 return null; 7838 } 7839 providerRunning = false; 7840 conn = null; 7841 } 7842 } 7843 7844 Binder.restoreCallingIdentity(origId); 7845 } 7846 7847 boolean singleton; 7848 if (!providerRunning) { 7849 try { 7850 cpi = AppGlobals.getPackageManager(). 7851 resolveContentProvider(name, 7852 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId); 7853 } catch (RemoteException ex) { 7854 } 7855 if (cpi == null) { 7856 return null; 7857 } 7858 singleton = isSingleton(cpi.processName, cpi.applicationInfo, 7859 cpi.name, cpi.flags); 7860 if (singleton) { 7861 userId = 0; 7862 } 7863 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId); 7864 7865 String msg; 7866 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) { 7867 throw new SecurityException(msg); 7868 } 7869 7870 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate 7871 && !cpi.processName.equals("system")) { 7872 // If this content provider does not run in the system 7873 // process, and the system is not yet ready to run other 7874 // processes, then fail fast instead of hanging. 7875 throw new IllegalArgumentException( 7876 "Attempt to launch content provider before system ready"); 7877 } 7878 7879 // Make sure that the user who owns this provider is started. If not, 7880 // we don't want to allow it to run. 7881 if (mStartedUsers.get(userId) == null) { 7882 Slog.w(TAG, "Unable to launch app " 7883 + cpi.applicationInfo.packageName + "/" 7884 + cpi.applicationInfo.uid + " for provider " 7885 + name + ": user " + userId + " is stopped"); 7886 return null; 7887 } 7888 7889 ComponentName comp = new ComponentName(cpi.packageName, cpi.name); 7890 cpr = mProviderMap.getProviderByClass(comp, userId); 7891 final boolean firstClass = cpr == null; 7892 if (firstClass) { 7893 try { 7894 ApplicationInfo ai = 7895 AppGlobals.getPackageManager(). 7896 getApplicationInfo( 7897 cpi.applicationInfo.packageName, 7898 STOCK_PM_FLAGS, userId); 7899 if (ai == null) { 7900 Slog.w(TAG, "No package info for content provider " 7901 + cpi.name); 7902 return null; 7903 } 7904 ai = getAppInfoForUser(ai, userId); 7905 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton); 7906 } catch (RemoteException ex) { 7907 // pm is in same process, this will never happen. 7908 } 7909 } 7910 7911 if (r != null && cpr.canRunHere(r)) { 7912 // If this is a multiprocess provider, then just return its 7913 // info and allow the caller to instantiate it. Only do 7914 // this if the provider is the same user as the caller's 7915 // process, or can run as root (so can be in any process). 7916 return cpr.newHolder(null); 7917 } 7918 7919 if (DEBUG_PROVIDER) { 7920 RuntimeException e = new RuntimeException("here"); 7921 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null) 7922 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e); 7923 } 7924 7925 // This is single process, and our app is now connecting to it. 7926 // See if we are already in the process of launching this 7927 // provider. 7928 final int N = mLaunchingProviders.size(); 7929 int i; 7930 for (i=0; i<N; i++) { 7931 if (mLaunchingProviders.get(i) == cpr) { 7932 break; 7933 } 7934 } 7935 7936 // If the provider is not already being launched, then get it 7937 // started. 7938 if (i >= N) { 7939 final long origId = Binder.clearCallingIdentity(); 7940 7941 try { 7942 // Content provider is now in use, its package can't be stopped. 7943 try { 7944 AppGlobals.getPackageManager().setPackageStoppedState( 7945 cpr.appInfo.packageName, false, userId); 7946 } catch (RemoteException e) { 7947 } catch (IllegalArgumentException e) { 7948 Slog.w(TAG, "Failed trying to unstop package " 7949 + cpr.appInfo.packageName + ": " + e); 7950 } 7951 7952 // Use existing process if already started 7953 ProcessRecord proc = getProcessRecordLocked( 7954 cpi.processName, cpr.appInfo.uid, false); 7955 if (proc != null && proc.thread != null) { 7956 if (DEBUG_PROVIDER) { 7957 Slog.d(TAG, "Installing in existing process " + proc); 7958 } 7959 proc.pubProviders.put(cpi.name, cpr); 7960 try { 7961 proc.thread.scheduleInstallProvider(cpi); 7962 } catch (RemoteException e) { 7963 } 7964 } else { 7965 proc = startProcessLocked(cpi.processName, 7966 cpr.appInfo, false, 0, "content provider", 7967 new ComponentName(cpi.applicationInfo.packageName, 7968 cpi.name), false, false, false); 7969 if (proc == null) { 7970 Slog.w(TAG, "Unable to launch app " 7971 + cpi.applicationInfo.packageName + "/" 7972 + cpi.applicationInfo.uid + " for provider " 7973 + name + ": process is bad"); 7974 return null; 7975 } 7976 } 7977 cpr.launchingApp = proc; 7978 mLaunchingProviders.add(cpr); 7979 } finally { 7980 Binder.restoreCallingIdentity(origId); 7981 } 7982 } 7983 7984 // Make sure the provider is published (the same provider class 7985 // may be published under multiple names). 7986 if (firstClass) { 7987 mProviderMap.putProviderByClass(comp, cpr); 7988 } 7989 7990 mProviderMap.putProviderByName(name, cpr); 7991 conn = incProviderCountLocked(r, cpr, token, stable); 7992 if (conn != null) { 7993 conn.waiting = true; 7994 } 7995 } 7996 } 7997 7998 // Wait for the provider to be published... 7999 synchronized (cpr) { 8000 while (cpr.provider == null) { 8001 if (cpr.launchingApp == null) { 8002 Slog.w(TAG, "Unable to launch app " 8003 + cpi.applicationInfo.packageName + "/" 8004 + cpi.applicationInfo.uid + " for provider " 8005 + name + ": launching app became null"); 8006 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS, 8007 UserHandle.getUserId(cpi.applicationInfo.uid), 8008 cpi.applicationInfo.packageName, 8009 cpi.applicationInfo.uid, name); 8010 return null; 8011 } 8012 try { 8013 if (DEBUG_MU) { 8014 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp=" 8015 + cpr.launchingApp); 8016 } 8017 if (conn != null) { 8018 conn.waiting = true; 8019 } 8020 cpr.wait(); 8021 } catch (InterruptedException ex) { 8022 } finally { 8023 if (conn != null) { 8024 conn.waiting = false; 8025 } 8026 } 8027 } 8028 } 8029 return cpr != null ? cpr.newHolder(conn) : null; 8030 } 8031 8032 public final ContentProviderHolder getContentProvider( 8033 IApplicationThread caller, String name, int userId, boolean stable) { 8034 enforceNotIsolatedCaller("getContentProvider"); 8035 if (caller == null) { 8036 String msg = "null IApplicationThread when getting content provider " 8037 + name; 8038 Slog.w(TAG, msg); 8039 throw new SecurityException(msg); 8040 } 8041 8042 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8043 false, true, "getContentProvider", null); 8044 return getContentProviderImpl(caller, name, null, stable, userId); 8045 } 8046 8047 public ContentProviderHolder getContentProviderExternal( 8048 String name, int userId, IBinder token) { 8049 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8050 "Do not have permission in call getContentProviderExternal()"); 8051 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, 8052 false, true, "getContentProvider", null); 8053 return getContentProviderExternalUnchecked(name, token, userId); 8054 } 8055 8056 private ContentProviderHolder getContentProviderExternalUnchecked(String name, 8057 IBinder token, int userId) { 8058 return getContentProviderImpl(null, name, token, true, userId); 8059 } 8060 8061 /** 8062 * Drop a content provider from a ProcessRecord's bookkeeping 8063 */ 8064 public void removeContentProvider(IBinder connection, boolean stable) { 8065 enforceNotIsolatedCaller("removeContentProvider"); 8066 long ident = Binder.clearCallingIdentity(); 8067 try { 8068 synchronized (this) { 8069 ContentProviderConnection conn; 8070 try { 8071 conn = (ContentProviderConnection)connection; 8072 } catch (ClassCastException e) { 8073 String msg ="removeContentProvider: " + connection 8074 + " not a ContentProviderConnection"; 8075 Slog.w(TAG, msg); 8076 throw new IllegalArgumentException(msg); 8077 } 8078 if (conn == null) { 8079 throw new NullPointerException("connection is null"); 8080 } 8081 if (decProviderCountLocked(conn, null, null, stable)) { 8082 updateOomAdjLocked(); 8083 } 8084 } 8085 } finally { 8086 Binder.restoreCallingIdentity(ident); 8087 } 8088 } 8089 8090 public void removeContentProviderExternal(String name, IBinder token) { 8091 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY, 8092 "Do not have permission in call removeContentProviderExternal()"); 8093 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId()); 8094 } 8095 8096 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) { 8097 synchronized (this) { 8098 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId); 8099 if(cpr == null) { 8100 //remove from mProvidersByClass 8101 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list"); 8102 return; 8103 } 8104 8105 //update content provider record entry info 8106 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name); 8107 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId); 8108 if (localCpr.hasExternalProcessHandles()) { 8109 if (localCpr.removeExternalProcessHandleLocked(token)) { 8110 updateOomAdjLocked(); 8111 } else { 8112 Slog.e(TAG, "Attmpt to remove content provider " + localCpr 8113 + " with no external reference for token: " 8114 + token + "."); 8115 } 8116 } else { 8117 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr 8118 + " with no external references."); 8119 } 8120 } 8121 } 8122 8123 public final void publishContentProviders(IApplicationThread caller, 8124 List<ContentProviderHolder> providers) { 8125 if (providers == null) { 8126 return; 8127 } 8128 8129 enforceNotIsolatedCaller("publishContentProviders"); 8130 synchronized (this) { 8131 final ProcessRecord r = getRecordForAppLocked(caller); 8132 if (DEBUG_MU) 8133 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid); 8134 if (r == null) { 8135 throw new SecurityException( 8136 "Unable to find app for caller " + caller 8137 + " (pid=" + Binder.getCallingPid() 8138 + ") when publishing content providers"); 8139 } 8140 8141 final long origId = Binder.clearCallingIdentity(); 8142 8143 final int N = providers.size(); 8144 for (int i=0; i<N; i++) { 8145 ContentProviderHolder src = providers.get(i); 8146 if (src == null || src.info == null || src.provider == null) { 8147 continue; 8148 } 8149 ContentProviderRecord dst = r.pubProviders.get(src.info.name); 8150 if (DEBUG_MU) 8151 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid); 8152 if (dst != null) { 8153 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name); 8154 mProviderMap.putProviderByClass(comp, dst); 8155 String names[] = dst.info.authority.split(";"); 8156 for (int j = 0; j < names.length; j++) { 8157 mProviderMap.putProviderByName(names[j], dst); 8158 } 8159 8160 int NL = mLaunchingProviders.size(); 8161 int j; 8162 for (j=0; j<NL; j++) { 8163 if (mLaunchingProviders.get(j) == dst) { 8164 mLaunchingProviders.remove(j); 8165 j--; 8166 NL--; 8167 } 8168 } 8169 synchronized (dst) { 8170 dst.provider = src.provider; 8171 dst.proc = r; 8172 dst.notifyAll(); 8173 } 8174 updateOomAdjLocked(r); 8175 } 8176 } 8177 8178 Binder.restoreCallingIdentity(origId); 8179 } 8180 } 8181 8182 public boolean refContentProvider(IBinder connection, int stable, int unstable) { 8183 ContentProviderConnection conn; 8184 try { 8185 conn = (ContentProviderConnection)connection; 8186 } catch (ClassCastException e) { 8187 String msg ="refContentProvider: " + connection 8188 + " not a ContentProviderConnection"; 8189 Slog.w(TAG, msg); 8190 throw new IllegalArgumentException(msg); 8191 } 8192 if (conn == null) { 8193 throw new NullPointerException("connection is null"); 8194 } 8195 8196 synchronized (this) { 8197 if (stable > 0) { 8198 conn.numStableIncs += stable; 8199 } 8200 stable = conn.stableCount + stable; 8201 if (stable < 0) { 8202 throw new IllegalStateException("stableCount < 0: " + stable); 8203 } 8204 8205 if (unstable > 0) { 8206 conn.numUnstableIncs += unstable; 8207 } 8208 unstable = conn.unstableCount + unstable; 8209 if (unstable < 0) { 8210 throw new IllegalStateException("unstableCount < 0: " + unstable); 8211 } 8212 8213 if ((stable+unstable) <= 0) { 8214 throw new IllegalStateException("ref counts can't go to zero here: stable=" 8215 + stable + " unstable=" + unstable); 8216 } 8217 conn.stableCount = stable; 8218 conn.unstableCount = unstable; 8219 return !conn.dead; 8220 } 8221 } 8222 8223 public void unstableProviderDied(IBinder connection) { 8224 ContentProviderConnection conn; 8225 try { 8226 conn = (ContentProviderConnection)connection; 8227 } catch (ClassCastException e) { 8228 String msg ="refContentProvider: " + connection 8229 + " not a ContentProviderConnection"; 8230 Slog.w(TAG, msg); 8231 throw new IllegalArgumentException(msg); 8232 } 8233 if (conn == null) { 8234 throw new NullPointerException("connection is null"); 8235 } 8236 8237 // Safely retrieve the content provider associated with the connection. 8238 IContentProvider provider; 8239 synchronized (this) { 8240 provider = conn.provider.provider; 8241 } 8242 8243 if (provider == null) { 8244 // Um, yeah, we're way ahead of you. 8245 return; 8246 } 8247 8248 // Make sure the caller is being honest with us. 8249 if (provider.asBinder().pingBinder()) { 8250 // Er, no, still looks good to us. 8251 synchronized (this) { 8252 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid() 8253 + " says " + conn + " died, but we don't agree"); 8254 return; 8255 } 8256 } 8257 8258 // Well look at that! It's dead! 8259 synchronized (this) { 8260 if (conn.provider.provider != provider) { 8261 // But something changed... good enough. 8262 return; 8263 } 8264 8265 ProcessRecord proc = conn.provider.proc; 8266 if (proc == null || proc.thread == null) { 8267 // Seems like the process is already cleaned up. 8268 return; 8269 } 8270 8271 // As far as we're concerned, this is just like receiving a 8272 // death notification... just a bit prematurely. 8273 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid 8274 + ") early provider death"); 8275 final long ident = Binder.clearCallingIdentity(); 8276 try { 8277 appDiedLocked(proc, proc.pid, proc.thread); 8278 } finally { 8279 Binder.restoreCallingIdentity(ident); 8280 } 8281 } 8282 } 8283 8284 @Override 8285 public void appNotRespondingViaProvider(IBinder connection) { 8286 enforceCallingPermission( 8287 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()"); 8288 8289 final ContentProviderConnection conn = (ContentProviderConnection) connection; 8290 if (conn == null) { 8291 Slog.w(TAG, "ContentProviderConnection is null"); 8292 return; 8293 } 8294 8295 final ProcessRecord host = conn.provider.proc; 8296 if (host == null) { 8297 Slog.w(TAG, "Failed to find hosting ProcessRecord"); 8298 return; 8299 } 8300 8301 final long token = Binder.clearCallingIdentity(); 8302 try { 8303 appNotResponding(host, null, null, false, "ContentProvider not responding"); 8304 } finally { 8305 Binder.restoreCallingIdentity(token); 8306 } 8307 } 8308 8309 public final void installSystemProviders() { 8310 List<ProviderInfo> providers; 8311 synchronized (this) { 8312 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID); 8313 providers = generateApplicationProvidersLocked(app); 8314 if (providers != null) { 8315 for (int i=providers.size()-1; i>=0; i--) { 8316 ProviderInfo pi = (ProviderInfo)providers.get(i); 8317 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) { 8318 Slog.w(TAG, "Not installing system proc provider " + pi.name 8319 + ": not system .apk"); 8320 providers.remove(i); 8321 } 8322 } 8323 } 8324 } 8325 if (providers != null) { 8326 mSystemThread.installSystemProviders(providers); 8327 } 8328 8329 mCoreSettingsObserver = new CoreSettingsObserver(this); 8330 8331 mUsageStatsService.monitorPackages(); 8332 } 8333 8334 /** 8335 * Allows app to retrieve the MIME type of a URI without having permission 8336 * to access its content provider. 8337 * 8338 * CTS tests for this functionality can be run with "runtest cts-appsecurity". 8339 * 8340 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/ 8341 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java 8342 */ 8343 public String getProviderMimeType(Uri uri, int userId) { 8344 enforceNotIsolatedCaller("getProviderMimeType"); 8345 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 8346 userId, false, true, "getProviderMimeType", null); 8347 final String name = uri.getAuthority(); 8348 final long ident = Binder.clearCallingIdentity(); 8349 ContentProviderHolder holder = null; 8350 8351 try { 8352 holder = getContentProviderExternalUnchecked(name, null, userId); 8353 if (holder != null) { 8354 return holder.provider.getType(uri); 8355 } 8356 } catch (RemoteException e) { 8357 Log.w(TAG, "Content provider dead retrieving " + uri, e); 8358 return null; 8359 } finally { 8360 if (holder != null) { 8361 removeContentProviderExternalUnchecked(name, null, userId); 8362 } 8363 Binder.restoreCallingIdentity(ident); 8364 } 8365 8366 return null; 8367 } 8368 8369 // ========================================================= 8370 // GLOBAL MANAGEMENT 8371 // ========================================================= 8372 8373 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 8374 boolean isolated) { 8375 String proc = customProcess != null ? customProcess : info.processName; 8376 BatteryStatsImpl.Uid.Proc ps = null; 8377 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 8378 int uid = info.uid; 8379 if (isolated) { 8380 int userId = UserHandle.getUserId(uid); 8381 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1; 8382 while (true) { 8383 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID 8384 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) { 8385 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID; 8386 } 8387 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid); 8388 mNextIsolatedProcessUid++; 8389 if (mIsolatedProcesses.indexOfKey(uid) < 0) { 8390 // No process for this uid, use it. 8391 break; 8392 } 8393 stepsLeft--; 8394 if (stepsLeft <= 0) { 8395 return null; 8396 } 8397 } 8398 } 8399 return new ProcessRecord(stats, info, proc, uid); 8400 } 8401 8402 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) { 8403 ProcessRecord app; 8404 if (!isolated) { 8405 app = getProcessRecordLocked(info.processName, info.uid, true); 8406 } else { 8407 app = null; 8408 } 8409 8410 if (app == null) { 8411 app = newProcessRecordLocked(info, null, isolated); 8412 mProcessNames.put(info.processName, app.uid, app); 8413 if (isolated) { 8414 mIsolatedProcesses.put(app.uid, app); 8415 } 8416 updateLruProcessLocked(app, false, null); 8417 updateOomAdjLocked(); 8418 } 8419 8420 // This package really, really can not be stopped. 8421 try { 8422 AppGlobals.getPackageManager().setPackageStoppedState( 8423 info.packageName, false, UserHandle.getUserId(app.uid)); 8424 } catch (RemoteException e) { 8425 } catch (IllegalArgumentException e) { 8426 Slog.w(TAG, "Failed trying to unstop package " 8427 + info.packageName + ": " + e); 8428 } 8429 8430 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) 8431 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) { 8432 app.persistent = true; 8433 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 8434 } 8435 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) { 8436 mPersistentStartingProcesses.add(app); 8437 startProcessLocked(app, "added application", app.processName); 8438 } 8439 8440 return app; 8441 } 8442 8443 public void unhandledBack() { 8444 enforceCallingPermission(android.Manifest.permission.FORCE_BACK, 8445 "unhandledBack()"); 8446 8447 synchronized(this) { 8448 final long origId = Binder.clearCallingIdentity(); 8449 try { 8450 getFocusedStack().unhandledBackLocked(); 8451 } finally { 8452 Binder.restoreCallingIdentity(origId); 8453 } 8454 } 8455 } 8456 8457 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException { 8458 enforceNotIsolatedCaller("openContentUri"); 8459 final int userId = UserHandle.getCallingUserId(); 8460 String name = uri.getAuthority(); 8461 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId); 8462 ParcelFileDescriptor pfd = null; 8463 if (cph != null) { 8464 // We record the binder invoker's uid in thread-local storage before 8465 // going to the content provider to open the file. Later, in the code 8466 // that handles all permissions checks, we look for this uid and use 8467 // that rather than the Activity Manager's own uid. The effect is that 8468 // we do the check against the caller's permissions even though it looks 8469 // to the content provider like the Activity Manager itself is making 8470 // the request. 8471 sCallerIdentity.set(new Identity( 8472 Binder.getCallingPid(), Binder.getCallingUid())); 8473 try { 8474 pfd = cph.provider.openFile(null, uri, "r", null); 8475 } catch (FileNotFoundException e) { 8476 // do nothing; pfd will be returned null 8477 } finally { 8478 // Ensure that whatever happens, we clean up the identity state 8479 sCallerIdentity.remove(); 8480 } 8481 8482 // We've got the fd now, so we're done with the provider. 8483 removeContentProviderExternalUnchecked(name, null, userId); 8484 } else { 8485 Slog.d(TAG, "Failed to get provider for authority '" + name + "'"); 8486 } 8487 return pfd; 8488 } 8489 8490 // Actually is sleeping or shutting down or whatever else in the future 8491 // is an inactive state. 8492 public boolean isSleepingOrShuttingDown() { 8493 return mSleeping || mShuttingDown; 8494 } 8495 8496 void goingToSleep() { 8497 synchronized(this) { 8498 mWentToSleep = true; 8499 updateEventDispatchingLocked(); 8500 8501 if (!mSleeping) { 8502 mSleeping = true; 8503 mStackSupervisor.goingToSleepLocked(); 8504 8505 // Initialize the wake times of all processes. 8506 checkExcessivePowerUsageLocked(false); 8507 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8508 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG); 8509 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY); 8510 } 8511 } 8512 } 8513 8514 @Override 8515 public boolean shutdown(int timeout) { 8516 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN) 8517 != PackageManager.PERMISSION_GRANTED) { 8518 throw new SecurityException("Requires permission " 8519 + android.Manifest.permission.SHUTDOWN); 8520 } 8521 8522 boolean timedout = false; 8523 8524 synchronized(this) { 8525 mShuttingDown = true; 8526 updateEventDispatchingLocked(); 8527 timedout = mStackSupervisor.shutdownLocked(timeout); 8528 } 8529 8530 mAppOpsService.shutdown(); 8531 mUsageStatsService.shutdown(); 8532 mBatteryStatsService.shutdown(); 8533 synchronized (this) { 8534 mProcessStats.shutdownLocked(); 8535 } 8536 8537 return timedout; 8538 } 8539 8540 public final void activitySlept(IBinder token) { 8541 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token); 8542 8543 final long origId = Binder.clearCallingIdentity(); 8544 8545 synchronized (this) { 8546 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8547 if (r != null) { 8548 mStackSupervisor.activitySleptLocked(r); 8549 } 8550 } 8551 8552 Binder.restoreCallingIdentity(origId); 8553 } 8554 8555 void logLockScreen(String msg) { 8556 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg + 8557 " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" + 8558 mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" + 8559 mStackSupervisor.mDismissKeyguardOnNextActivity); 8560 } 8561 8562 private void comeOutOfSleepIfNeededLocked() { 8563 if (!mWentToSleep && !mLockScreenShown) { 8564 if (mSleeping) { 8565 mSleeping = false; 8566 mStackSupervisor.comeOutOfSleepIfNeededLocked(); 8567 } 8568 } 8569 } 8570 8571 void wakingUp() { 8572 synchronized(this) { 8573 mWentToSleep = false; 8574 updateEventDispatchingLocked(); 8575 comeOutOfSleepIfNeededLocked(); 8576 } 8577 } 8578 8579 private void updateEventDispatchingLocked() { 8580 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown); 8581 } 8582 8583 public void setLockScreenShown(boolean shown) { 8584 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER) 8585 != PackageManager.PERMISSION_GRANTED) { 8586 throw new SecurityException("Requires permission " 8587 + android.Manifest.permission.DEVICE_POWER); 8588 } 8589 8590 synchronized(this) { 8591 long ident = Binder.clearCallingIdentity(); 8592 try { 8593 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown); 8594 mLockScreenShown = shown; 8595 comeOutOfSleepIfNeededLocked(); 8596 } finally { 8597 Binder.restoreCallingIdentity(ident); 8598 } 8599 } 8600 } 8601 8602 public void stopAppSwitches() { 8603 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8604 != PackageManager.PERMISSION_GRANTED) { 8605 throw new SecurityException("Requires permission " 8606 + android.Manifest.permission.STOP_APP_SWITCHES); 8607 } 8608 8609 synchronized(this) { 8610 mAppSwitchesAllowedTime = SystemClock.uptimeMillis() 8611 + APP_SWITCH_DELAY_TIME; 8612 mDidAppSwitch = false; 8613 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8614 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG); 8615 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME); 8616 } 8617 } 8618 8619 public void resumeAppSwitches() { 8620 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) 8621 != PackageManager.PERMISSION_GRANTED) { 8622 throw new SecurityException("Requires permission " 8623 + android.Manifest.permission.STOP_APP_SWITCHES); 8624 } 8625 8626 synchronized(this) { 8627 // Note that we don't execute any pending app switches... we will 8628 // let those wait until either the timeout, or the next start 8629 // activity request. 8630 mAppSwitchesAllowedTime = 0; 8631 } 8632 } 8633 8634 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid, 8635 String name) { 8636 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) { 8637 return true; 8638 } 8639 8640 final int perm = checkComponentPermission( 8641 android.Manifest.permission.STOP_APP_SWITCHES, callingPid, 8642 callingUid, -1, true); 8643 if (perm == PackageManager.PERMISSION_GRANTED) { 8644 return true; 8645 } 8646 8647 Slog.w(TAG, name + " request from " + callingUid + " stopped"); 8648 return false; 8649 } 8650 8651 public void setDebugApp(String packageName, boolean waitForDebugger, 8652 boolean persistent) { 8653 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP, 8654 "setDebugApp()"); 8655 8656 long ident = Binder.clearCallingIdentity(); 8657 try { 8658 // Note that this is not really thread safe if there are multiple 8659 // callers into it at the same time, but that's not a situation we 8660 // care about. 8661 if (persistent) { 8662 final ContentResolver resolver = mContext.getContentResolver(); 8663 Settings.Global.putString( 8664 resolver, Settings.Global.DEBUG_APP, 8665 packageName); 8666 Settings.Global.putInt( 8667 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 8668 waitForDebugger ? 1 : 0); 8669 } 8670 8671 synchronized (this) { 8672 if (!persistent) { 8673 mOrigDebugApp = mDebugApp; 8674 mOrigWaitForDebugger = mWaitForDebugger; 8675 } 8676 mDebugApp = packageName; 8677 mWaitForDebugger = waitForDebugger; 8678 mDebugTransient = !persistent; 8679 if (packageName != null) { 8680 forceStopPackageLocked(packageName, -1, false, false, true, true, 8681 false, UserHandle.USER_ALL, "set debug app"); 8682 } 8683 } 8684 } finally { 8685 Binder.restoreCallingIdentity(ident); 8686 } 8687 } 8688 8689 void setOpenGlTraceApp(ApplicationInfo app, String processName) { 8690 synchronized (this) { 8691 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8692 if (!isDebuggable) { 8693 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8694 throw new SecurityException("Process not debuggable: " + app.packageName); 8695 } 8696 } 8697 8698 mOpenGlTraceApp = processName; 8699 } 8700 } 8701 8702 void setProfileApp(ApplicationInfo app, String processName, String profileFile, 8703 ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 8704 synchronized (this) { 8705 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 8706 if (!isDebuggable) { 8707 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 8708 throw new SecurityException("Process not debuggable: " + app.packageName); 8709 } 8710 } 8711 mProfileApp = processName; 8712 mProfileFile = profileFile; 8713 if (mProfileFd != null) { 8714 try { 8715 mProfileFd.close(); 8716 } catch (IOException e) { 8717 } 8718 mProfileFd = null; 8719 } 8720 mProfileFd = profileFd; 8721 mProfileType = 0; 8722 mAutoStopProfiler = autoStopProfiler; 8723 } 8724 } 8725 8726 @Override 8727 public void setAlwaysFinish(boolean enabled) { 8728 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH, 8729 "setAlwaysFinish()"); 8730 8731 Settings.Global.putInt( 8732 mContext.getContentResolver(), 8733 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0); 8734 8735 synchronized (this) { 8736 mAlwaysFinishActivities = enabled; 8737 } 8738 } 8739 8740 @Override 8741 public void setActivityController(IActivityController controller) { 8742 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8743 "setActivityController()"); 8744 synchronized (this) { 8745 mController = controller; 8746 Watchdog.getInstance().setActivityController(controller); 8747 } 8748 } 8749 8750 @Override 8751 public void setUserIsMonkey(boolean userIsMonkey) { 8752 synchronized (this) { 8753 synchronized (mPidsSelfLocked) { 8754 final int callingPid = Binder.getCallingPid(); 8755 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid); 8756 if (precessRecord == null) { 8757 throw new SecurityException("Unknown process: " + callingPid); 8758 } 8759 if (precessRecord.instrumentationUiAutomationConnection == null) { 8760 throw new SecurityException("Only an instrumentation process " 8761 + "with a UiAutomation can call setUserIsMonkey"); 8762 } 8763 } 8764 mUserIsMonkey = userIsMonkey; 8765 } 8766 } 8767 8768 @Override 8769 public boolean isUserAMonkey() { 8770 synchronized (this) { 8771 // If there is a controller also implies the user is a monkey. 8772 return (mUserIsMonkey || mController != null); 8773 } 8774 } 8775 8776 public void requestBugReport() { 8777 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport"); 8778 SystemProperties.set("ctl.start", "bugreport"); 8779 } 8780 8781 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) { 8782 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT; 8783 } 8784 8785 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) { 8786 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) { 8787 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; 8788 } 8789 return KEY_DISPATCHING_TIMEOUT; 8790 } 8791 8792 @Override 8793 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) { 8794 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8795 != PackageManager.PERMISSION_GRANTED) { 8796 throw new SecurityException("Requires permission " 8797 + android.Manifest.permission.FILTER_EVENTS); 8798 } 8799 ProcessRecord proc; 8800 long timeout; 8801 synchronized (this) { 8802 synchronized (mPidsSelfLocked) { 8803 proc = mPidsSelfLocked.get(pid); 8804 } 8805 timeout = getInputDispatchingTimeoutLocked(proc); 8806 } 8807 8808 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) { 8809 return -1; 8810 } 8811 8812 return timeout; 8813 } 8814 8815 /** 8816 * Handle input dispatching timeouts. 8817 * Returns whether input dispatching should be aborted or not. 8818 */ 8819 public boolean inputDispatchingTimedOut(final ProcessRecord proc, 8820 final ActivityRecord activity, final ActivityRecord parent, 8821 final boolean aboveSystem, String reason) { 8822 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS) 8823 != PackageManager.PERMISSION_GRANTED) { 8824 throw new SecurityException("Requires permission " 8825 + android.Manifest.permission.FILTER_EVENTS); 8826 } 8827 8828 final String annotation; 8829 if (reason == null) { 8830 annotation = "Input dispatching timed out"; 8831 } else { 8832 annotation = "Input dispatching timed out (" + reason + ")"; 8833 } 8834 8835 if (proc != null) { 8836 synchronized (this) { 8837 if (proc.debugging) { 8838 return false; 8839 } 8840 8841 if (mDidDexOpt) { 8842 // Give more time since we were dexopting. 8843 mDidDexOpt = false; 8844 return false; 8845 } 8846 8847 if (proc.instrumentationClass != null) { 8848 Bundle info = new Bundle(); 8849 info.putString("shortMsg", "keyDispatchingTimedOut"); 8850 info.putString("longMsg", annotation); 8851 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info); 8852 return true; 8853 } 8854 } 8855 mHandler.post(new Runnable() { 8856 @Override 8857 public void run() { 8858 appNotResponding(proc, activity, parent, aboveSystem, annotation); 8859 } 8860 }); 8861 } 8862 8863 return true; 8864 } 8865 8866 public Bundle getAssistContextExtras(int requestType) { 8867 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO, 8868 "getAssistContextExtras()"); 8869 PendingAssistExtras pae; 8870 Bundle extras = new Bundle(); 8871 synchronized (this) { 8872 ActivityRecord activity = getFocusedStack().mResumedActivity; 8873 if (activity == null) { 8874 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity"); 8875 return null; 8876 } 8877 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName); 8878 if (activity.app == null || activity.app.thread == null) { 8879 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity); 8880 return extras; 8881 } 8882 if (activity.app.pid == Binder.getCallingPid()) { 8883 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity); 8884 return extras; 8885 } 8886 pae = new PendingAssistExtras(activity); 8887 try { 8888 activity.app.thread.requestAssistContextExtras(activity.appToken, pae, 8889 requestType); 8890 mPendingAssistExtras.add(pae); 8891 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT); 8892 } catch (RemoteException e) { 8893 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity); 8894 return extras; 8895 } 8896 } 8897 synchronized (pae) { 8898 while (!pae.haveResult) { 8899 try { 8900 pae.wait(); 8901 } catch (InterruptedException e) { 8902 } 8903 } 8904 if (pae.result != null) { 8905 extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result); 8906 } 8907 } 8908 synchronized (this) { 8909 mPendingAssistExtras.remove(pae); 8910 mHandler.removeCallbacks(pae); 8911 } 8912 return extras; 8913 } 8914 8915 public void reportAssistContextExtras(IBinder token, Bundle extras) { 8916 PendingAssistExtras pae = (PendingAssistExtras)token; 8917 synchronized (pae) { 8918 pae.result = extras; 8919 pae.haveResult = true; 8920 pae.notifyAll(); 8921 } 8922 } 8923 8924 public void registerProcessObserver(IProcessObserver observer) { 8925 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER, 8926 "registerProcessObserver()"); 8927 synchronized (this) { 8928 mProcessObservers.register(observer); 8929 } 8930 } 8931 8932 @Override 8933 public void unregisterProcessObserver(IProcessObserver observer) { 8934 synchronized (this) { 8935 mProcessObservers.unregister(observer); 8936 } 8937 } 8938 8939 @Override 8940 public boolean convertFromTranslucent(IBinder token) { 8941 final long origId = Binder.clearCallingIdentity(); 8942 try { 8943 synchronized (this) { 8944 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8945 if (r == null) { 8946 return false; 8947 } 8948 if (r.changeWindowTranslucency(true)) { 8949 mWindowManager.setAppFullscreen(token, true); 8950 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8951 return true; 8952 } 8953 return false; 8954 } 8955 } finally { 8956 Binder.restoreCallingIdentity(origId); 8957 } 8958 } 8959 8960 @Override 8961 public boolean convertToTranslucent(IBinder token) { 8962 final long origId = Binder.clearCallingIdentity(); 8963 try { 8964 synchronized (this) { 8965 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8966 if (r == null) { 8967 return false; 8968 } 8969 if (r.changeWindowTranslucency(false)) { 8970 r.task.stack.convertToTranslucent(r); 8971 mWindowManager.setAppFullscreen(token, false); 8972 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0); 8973 return true; 8974 } 8975 return false; 8976 } 8977 } finally { 8978 Binder.restoreCallingIdentity(origId); 8979 } 8980 } 8981 8982 @Override 8983 public void setImmersive(IBinder token, boolean immersive) { 8984 synchronized(this) { 8985 final ActivityRecord r = ActivityRecord.isInStackLocked(token); 8986 if (r == null) { 8987 throw new IllegalArgumentException(); 8988 } 8989 r.immersive = immersive; 8990 8991 // update associated state if we're frontmost 8992 if (r == mFocusedActivity) { 8993 if (DEBUG_IMMERSIVE) { 8994 Slog.d(TAG, "Frontmost changed immersion: "+ r); 8995 } 8996 applyUpdateLockStateLocked(r); 8997 } 8998 } 8999 } 9000 9001 @Override 9002 public boolean isImmersive(IBinder token) { 9003 synchronized (this) { 9004 ActivityRecord r = ActivityRecord.isInStackLocked(token); 9005 if (r == null) { 9006 throw new IllegalArgumentException(); 9007 } 9008 return r.immersive; 9009 } 9010 } 9011 9012 public boolean isTopActivityImmersive() { 9013 enforceNotIsolatedCaller("startActivity"); 9014 synchronized (this) { 9015 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null); 9016 return (r != null) ? r.immersive : false; 9017 } 9018 } 9019 9020 public final void enterSafeMode() { 9021 synchronized(this) { 9022 // It only makes sense to do this before the system is ready 9023 // and started launching other packages. 9024 if (!mSystemReady) { 9025 try { 9026 AppGlobals.getPackageManager().enterSafeMode(); 9027 } catch (RemoteException e) { 9028 } 9029 } 9030 9031 mSafeMode = true; 9032 } 9033 } 9034 9035 public final void showSafeModeOverlay() { 9036 View v = LayoutInflater.from(mContext).inflate( 9037 com.android.internal.R.layout.safe_mode, null); 9038 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(); 9039 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 9040 lp.width = WindowManager.LayoutParams.WRAP_CONTENT; 9041 lp.height = WindowManager.LayoutParams.WRAP_CONTENT; 9042 lp.gravity = Gravity.BOTTOM | Gravity.START; 9043 lp.format = v.getBackground().getOpacity(); 9044 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 9045 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; 9046 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; 9047 ((WindowManager)mContext.getSystemService( 9048 Context.WINDOW_SERVICE)).addView(v, lp); 9049 } 9050 9051 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) { 9052 if (!(sender instanceof PendingIntentRecord)) { 9053 return; 9054 } 9055 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 9056 synchronized (stats) { 9057 if (mBatteryStatsService.isOnBattery()) { 9058 mBatteryStatsService.enforceCallingPermission(); 9059 PendingIntentRecord rec = (PendingIntentRecord)sender; 9060 int MY_UID = Binder.getCallingUid(); 9061 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid; 9062 BatteryStatsImpl.Uid.Pkg pkg = 9063 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid, 9064 sourcePkg != null ? sourcePkg : rec.key.packageName); 9065 pkg.incWakeupsLocked(); 9066 } 9067 } 9068 } 9069 9070 public boolean killPids(int[] pids, String pReason, boolean secure) { 9071 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9072 throw new SecurityException("killPids only available to the system"); 9073 } 9074 String reason = (pReason == null) ? "Unknown" : pReason; 9075 // XXX Note: don't acquire main activity lock here, because the window 9076 // manager calls in with its locks held. 9077 9078 boolean killed = false; 9079 synchronized (mPidsSelfLocked) { 9080 int[] types = new int[pids.length]; 9081 int worstType = 0; 9082 for (int i=0; i<pids.length; i++) { 9083 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9084 if (proc != null) { 9085 int type = proc.setAdj; 9086 types[i] = type; 9087 if (type > worstType) { 9088 worstType = type; 9089 } 9090 } 9091 } 9092 9093 // If the worst oom_adj is somewhere in the cached proc LRU range, 9094 // then constrain it so we will kill all cached procs. 9095 if (worstType < ProcessList.CACHED_APP_MAX_ADJ 9096 && worstType > ProcessList.CACHED_APP_MIN_ADJ) { 9097 worstType = ProcessList.CACHED_APP_MIN_ADJ; 9098 } 9099 9100 // If this is not a secure call, don't let it kill processes that 9101 // are important. 9102 if (!secure && worstType < ProcessList.SERVICE_ADJ) { 9103 worstType = ProcessList.SERVICE_ADJ; 9104 } 9105 9106 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType); 9107 for (int i=0; i<pids.length; i++) { 9108 ProcessRecord proc = mPidsSelfLocked.get(pids[i]); 9109 if (proc == null) { 9110 continue; 9111 } 9112 int adj = proc.setAdj; 9113 if (adj >= worstType && !proc.killedByAm) { 9114 killUnneededProcessLocked(proc, reason); 9115 killed = true; 9116 } 9117 } 9118 } 9119 return killed; 9120 } 9121 9122 @Override 9123 public void killUid(int uid, String reason) { 9124 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9125 throw new SecurityException("killUid only available to the system"); 9126 } 9127 synchronized (this) { 9128 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid), 9129 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false, 9130 reason != null ? reason : "kill uid"); 9131 } 9132 } 9133 9134 @Override 9135 public boolean killProcessesBelowForeground(String reason) { 9136 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9137 throw new SecurityException("killProcessesBelowForeground() only available to system"); 9138 } 9139 9140 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason); 9141 } 9142 9143 private boolean killProcessesBelowAdj(int belowAdj, String reason) { 9144 if (Binder.getCallingUid() != Process.SYSTEM_UID) { 9145 throw new SecurityException("killProcessesBelowAdj() only available to system"); 9146 } 9147 9148 boolean killed = false; 9149 synchronized (mPidsSelfLocked) { 9150 final int size = mPidsSelfLocked.size(); 9151 for (int i = 0; i < size; i++) { 9152 final int pid = mPidsSelfLocked.keyAt(i); 9153 final ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9154 if (proc == null) continue; 9155 9156 final int adj = proc.setAdj; 9157 if (adj > belowAdj && !proc.killedByAm) { 9158 killUnneededProcessLocked(proc, reason); 9159 killed = true; 9160 } 9161 } 9162 } 9163 return killed; 9164 } 9165 9166 @Override 9167 public void hang(final IBinder who, boolean allowRestart) { 9168 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9169 != PackageManager.PERMISSION_GRANTED) { 9170 throw new SecurityException("Requires permission " 9171 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9172 } 9173 9174 final IBinder.DeathRecipient death = new DeathRecipient() { 9175 @Override 9176 public void binderDied() { 9177 synchronized (this) { 9178 notifyAll(); 9179 } 9180 } 9181 }; 9182 9183 try { 9184 who.linkToDeath(death, 0); 9185 } catch (RemoteException e) { 9186 Slog.w(TAG, "hang: given caller IBinder is already dead."); 9187 return; 9188 } 9189 9190 synchronized (this) { 9191 Watchdog.getInstance().setAllowRestart(allowRestart); 9192 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid()); 9193 synchronized (death) { 9194 while (who.isBinderAlive()) { 9195 try { 9196 death.wait(); 9197 } catch (InterruptedException e) { 9198 } 9199 } 9200 } 9201 Watchdog.getInstance().setAllowRestart(true); 9202 } 9203 } 9204 9205 @Override 9206 public void restart() { 9207 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9208 != PackageManager.PERMISSION_GRANTED) { 9209 throw new SecurityException("Requires permission " 9210 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9211 } 9212 9213 Log.i(TAG, "Sending shutdown broadcast..."); 9214 9215 BroadcastReceiver br = new BroadcastReceiver() { 9216 @Override public void onReceive(Context context, Intent intent) { 9217 // Now the broadcast is done, finish up the low-level shutdown. 9218 Log.i(TAG, "Shutting down activity manager..."); 9219 shutdown(10000); 9220 Log.i(TAG, "Shutdown complete, restarting!"); 9221 Process.killProcess(Process.myPid()); 9222 System.exit(10); 9223 } 9224 }; 9225 9226 // First send the high-level shut down broadcast. 9227 Intent intent = new Intent(Intent.ACTION_SHUTDOWN); 9228 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 9229 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 9230 /* For now we are not doing a clean shutdown, because things seem to get unhappy. 9231 mContext.sendOrderedBroadcastAsUser(intent, 9232 UserHandle.ALL, null, br, mHandler, 0, null, null); 9233 */ 9234 br.onReceive(mContext, intent); 9235 } 9236 9237 private long getLowRamTimeSinceIdle(long now) { 9238 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0); 9239 } 9240 9241 @Override 9242 public void performIdleMaintenance() { 9243 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 9244 != PackageManager.PERMISSION_GRANTED) { 9245 throw new SecurityException("Requires permission " 9246 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 9247 } 9248 9249 synchronized (this) { 9250 final long now = SystemClock.uptimeMillis(); 9251 final long timeSinceLastIdle = now - mLastIdleTime; 9252 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now); 9253 mLastIdleTime = now; 9254 mLowRamTimeSinceLastIdle = 0; 9255 if (mLowRamStartTime != 0) { 9256 mLowRamStartTime = now; 9257 } 9258 9259 StringBuilder sb = new StringBuilder(128); 9260 sb.append("Idle maintenance over "); 9261 TimeUtils.formatDuration(timeSinceLastIdle, sb); 9262 sb.append(" low RAM for "); 9263 TimeUtils.formatDuration(lowRamSinceLastIdle, sb); 9264 Slog.i(TAG, sb.toString()); 9265 9266 // If at least 1/3 of our time since the last idle period has been spent 9267 // with RAM low, then we want to kill processes. 9268 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3); 9269 9270 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 9271 ProcessRecord proc = mLruProcesses.get(i); 9272 if (proc.notCachedSinceIdle) { 9273 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP 9274 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) { 9275 if (doKilling && proc.initialIdlePss != 0 9276 && proc.lastPss > ((proc.initialIdlePss*3)/2)) { 9277 killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss 9278 + " from " + proc.initialIdlePss + ")"); 9279 } 9280 } 9281 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) { 9282 proc.notCachedSinceIdle = true; 9283 proc.initialIdlePss = 0; 9284 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true, 9285 mSleeping, now); 9286 } 9287 } 9288 9289 mHandler.removeMessages(REQUEST_ALL_PSS_MSG); 9290 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000); 9291 } 9292 } 9293 9294 private void retrieveSettings() { 9295 final ContentResolver resolver = mContext.getContentResolver(); 9296 String debugApp = Settings.Global.getString( 9297 resolver, Settings.Global.DEBUG_APP); 9298 boolean waitForDebugger = Settings.Global.getInt( 9299 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0; 9300 boolean alwaysFinishActivities = Settings.Global.getInt( 9301 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0; 9302 boolean forceRtl = Settings.Global.getInt( 9303 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0; 9304 // Transfer any global setting for forcing RTL layout, into a System Property 9305 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0"); 9306 9307 Configuration configuration = new Configuration(); 9308 Settings.System.getConfiguration(resolver, configuration); 9309 if (forceRtl) { 9310 // This will take care of setting the correct layout direction flags 9311 configuration.setLayoutDirection(configuration.locale); 9312 } 9313 9314 synchronized (this) { 9315 mDebugApp = mOrigDebugApp = debugApp; 9316 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger; 9317 mAlwaysFinishActivities = alwaysFinishActivities; 9318 // This happens before any activities are started, so we can 9319 // change mConfiguration in-place. 9320 updateConfigurationLocked(configuration, null, false, true); 9321 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration); 9322 } 9323 } 9324 9325 public boolean testIsSystemReady() { 9326 // no need to synchronize(this) just to read & return the value 9327 return mSystemReady; 9328 } 9329 9330 private static File getCalledPreBootReceiversFile() { 9331 File dataDir = Environment.getDataDirectory(); 9332 File systemDir = new File(dataDir, "system"); 9333 File fname = new File(systemDir, "called_pre_boots.dat"); 9334 return fname; 9335 } 9336 9337 static final int LAST_DONE_VERSION = 10000; 9338 9339 private static ArrayList<ComponentName> readLastDonePreBootReceivers() { 9340 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>(); 9341 File file = getCalledPreBootReceiversFile(); 9342 FileInputStream fis = null; 9343 try { 9344 fis = new FileInputStream(file); 9345 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048)); 9346 int fvers = dis.readInt(); 9347 if (fvers == LAST_DONE_VERSION) { 9348 String vers = dis.readUTF(); 9349 String codename = dis.readUTF(); 9350 String build = dis.readUTF(); 9351 if (android.os.Build.VERSION.RELEASE.equals(vers) 9352 && android.os.Build.VERSION.CODENAME.equals(codename) 9353 && android.os.Build.VERSION.INCREMENTAL.equals(build)) { 9354 int num = dis.readInt(); 9355 while (num > 0) { 9356 num--; 9357 String pkg = dis.readUTF(); 9358 String cls = dis.readUTF(); 9359 lastDoneReceivers.add(new ComponentName(pkg, cls)); 9360 } 9361 } 9362 } 9363 } catch (FileNotFoundException e) { 9364 } catch (IOException e) { 9365 Slog.w(TAG, "Failure reading last done pre-boot receivers", e); 9366 } finally { 9367 if (fis != null) { 9368 try { 9369 fis.close(); 9370 } catch (IOException e) { 9371 } 9372 } 9373 } 9374 return lastDoneReceivers; 9375 } 9376 9377 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) { 9378 File file = getCalledPreBootReceiversFile(); 9379 FileOutputStream fos = null; 9380 DataOutputStream dos = null; 9381 try { 9382 Slog.i(TAG, "Writing new set of last done pre-boot receivers..."); 9383 fos = new FileOutputStream(file); 9384 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048)); 9385 dos.writeInt(LAST_DONE_VERSION); 9386 dos.writeUTF(android.os.Build.VERSION.RELEASE); 9387 dos.writeUTF(android.os.Build.VERSION.CODENAME); 9388 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL); 9389 dos.writeInt(list.size()); 9390 for (int i=0; i<list.size(); i++) { 9391 dos.writeUTF(list.get(i).getPackageName()); 9392 dos.writeUTF(list.get(i).getClassName()); 9393 } 9394 } catch (IOException e) { 9395 Slog.w(TAG, "Failure writing last done pre-boot receivers", e); 9396 file.delete(); 9397 } finally { 9398 FileUtils.sync(fos); 9399 if (dos != null) { 9400 try { 9401 dos.close(); 9402 } catch (IOException e) { 9403 // TODO Auto-generated catch block 9404 e.printStackTrace(); 9405 } 9406 } 9407 } 9408 } 9409 9410 public void systemReady(final Runnable goingCallback) { 9411 synchronized(this) { 9412 if (mSystemReady) { 9413 if (goingCallback != null) goingCallback.run(); 9414 return; 9415 } 9416 9417 // Check to see if there are any update receivers to run. 9418 if (!mDidUpdate) { 9419 if (mWaitingUpdate) { 9420 return; 9421 } 9422 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); 9423 List<ResolveInfo> ris = null; 9424 try { 9425 ris = AppGlobals.getPackageManager().queryIntentReceivers( 9426 intent, null, 0, 0); 9427 } catch (RemoteException e) { 9428 } 9429 if (ris != null) { 9430 for (int i=ris.size()-1; i>=0; i--) { 9431 if ((ris.get(i).activityInfo.applicationInfo.flags 9432 &ApplicationInfo.FLAG_SYSTEM) == 0) { 9433 ris.remove(i); 9434 } 9435 } 9436 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE); 9437 9438 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers(); 9439 9440 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>(); 9441 for (int i=0; i<ris.size(); i++) { 9442 ActivityInfo ai = ris.get(i).activityInfo; 9443 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9444 if (lastDoneReceivers.contains(comp)) { 9445 // We already did the pre boot receiver for this app with the current 9446 // platform version, so don't do it again... 9447 ris.remove(i); 9448 i--; 9449 // ...however, do keep it as one that has been done, so we don't 9450 // forget about it when rewriting the file of last done receivers. 9451 doneReceivers.add(comp); 9452 } 9453 } 9454 9455 final int[] users = getUsersLocked(); 9456 for (int i=0; i<ris.size(); i++) { 9457 ActivityInfo ai = ris.get(i).activityInfo; 9458 ComponentName comp = new ComponentName(ai.packageName, ai.name); 9459 doneReceivers.add(comp); 9460 intent.setComponent(comp); 9461 for (int j=0; j<users.length; j++) { 9462 IIntentReceiver finisher = null; 9463 if (i == ris.size()-1 && j == users.length-1) { 9464 finisher = new IIntentReceiver.Stub() { 9465 public void performReceive(Intent intent, int resultCode, 9466 String data, Bundle extras, boolean ordered, 9467 boolean sticky, int sendingUser) { 9468 // The raw IIntentReceiver interface is called 9469 // with the AM lock held, so redispatch to 9470 // execute our code without the lock. 9471 mHandler.post(new Runnable() { 9472 public void run() { 9473 synchronized (ActivityManagerService.this) { 9474 mDidUpdate = true; 9475 } 9476 writeLastDonePreBootReceivers(doneReceivers); 9477 showBootMessage(mContext.getText( 9478 R.string.android_upgrading_complete), 9479 false); 9480 systemReady(goingCallback); 9481 } 9482 }); 9483 } 9484 }; 9485 } 9486 Slog.i(TAG, "Sending system update to " + intent.getComponent() 9487 + " for user " + users[j]); 9488 broadcastIntentLocked(null, null, intent, null, finisher, 9489 0, null, null, null, AppOpsManager.OP_NONE, 9490 true, false, MY_PID, Process.SYSTEM_UID, 9491 users[j]); 9492 if (finisher != null) { 9493 mWaitingUpdate = true; 9494 } 9495 } 9496 } 9497 } 9498 if (mWaitingUpdate) { 9499 return; 9500 } 9501 mDidUpdate = true; 9502 } 9503 9504 mAppOpsService.systemReady(); 9505 mSystemReady = true; 9506 } 9507 9508 ArrayList<ProcessRecord> procsToKill = null; 9509 synchronized(mPidsSelfLocked) { 9510 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) { 9511 ProcessRecord proc = mPidsSelfLocked.valueAt(i); 9512 if (!isAllowedWhileBooting(proc.info)){ 9513 if (procsToKill == null) { 9514 procsToKill = new ArrayList<ProcessRecord>(); 9515 } 9516 procsToKill.add(proc); 9517 } 9518 } 9519 } 9520 9521 synchronized(this) { 9522 if (procsToKill != null) { 9523 for (int i=procsToKill.size()-1; i>=0; i--) { 9524 ProcessRecord proc = procsToKill.get(i); 9525 Slog.i(TAG, "Removing system update proc: " + proc); 9526 removeProcessLocked(proc, true, false, "system update done"); 9527 } 9528 } 9529 9530 // Now that we have cleaned up any update processes, we 9531 // are ready to start launching real processes and know that 9532 // we won't trample on them any more. 9533 mProcessesReady = true; 9534 } 9535 9536 Slog.i(TAG, "System now ready"); 9537 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY, 9538 SystemClock.uptimeMillis()); 9539 9540 synchronized(this) { 9541 // Make sure we have no pre-ready processes sitting around. 9542 9543 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9544 ResolveInfo ri = mContext.getPackageManager() 9545 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST), 9546 STOCK_PM_FLAGS); 9547 CharSequence errorMsg = null; 9548 if (ri != null) { 9549 ActivityInfo ai = ri.activityInfo; 9550 ApplicationInfo app = ai.applicationInfo; 9551 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) { 9552 mTopAction = Intent.ACTION_FACTORY_TEST; 9553 mTopData = null; 9554 mTopComponent = new ComponentName(app.packageName, 9555 ai.name); 9556 } else { 9557 errorMsg = mContext.getResources().getText( 9558 com.android.internal.R.string.factorytest_not_system); 9559 } 9560 } else { 9561 errorMsg = mContext.getResources().getText( 9562 com.android.internal.R.string.factorytest_no_action); 9563 } 9564 if (errorMsg != null) { 9565 mTopAction = null; 9566 mTopData = null; 9567 mTopComponent = null; 9568 Message msg = Message.obtain(); 9569 msg.what = SHOW_FACTORY_ERROR_MSG; 9570 msg.getData().putCharSequence("msg", errorMsg); 9571 mHandler.sendMessage(msg); 9572 } 9573 } 9574 } 9575 9576 retrieveSettings(); 9577 9578 synchronized (this) { 9579 readGrantedUriPermissionsLocked(); 9580 } 9581 9582 if (goingCallback != null) goingCallback.run(); 9583 9584 synchronized (this) { 9585 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) { 9586 try { 9587 List apps = AppGlobals.getPackageManager(). 9588 getPersistentApplications(STOCK_PM_FLAGS); 9589 if (apps != null) { 9590 int N = apps.size(); 9591 int i; 9592 for (i=0; i<N; i++) { 9593 ApplicationInfo info 9594 = (ApplicationInfo)apps.get(i); 9595 if (info != null && 9596 !info.packageName.equals("android")) { 9597 addAppLocked(info, false); 9598 } 9599 } 9600 } 9601 } catch (RemoteException ex) { 9602 // pm is in same process, this will never happen. 9603 } 9604 } 9605 9606 // Start up initial activity. 9607 mBooting = true; 9608 9609 try { 9610 if (AppGlobals.getPackageManager().hasSystemUidErrors()) { 9611 Message msg = Message.obtain(); 9612 msg.what = SHOW_UID_ERROR_MSG; 9613 mHandler.sendMessage(msg); 9614 } 9615 } catch (RemoteException e) { 9616 } 9617 9618 long ident = Binder.clearCallingIdentity(); 9619 try { 9620 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 9621 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 9622 | Intent.FLAG_RECEIVER_FOREGROUND); 9623 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9624 broadcastIntentLocked(null, null, intent, 9625 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 9626 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId); 9627 intent = new Intent(Intent.ACTION_USER_STARTING); 9628 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 9629 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId); 9630 broadcastIntentLocked(null, null, intent, 9631 null, new IIntentReceiver.Stub() { 9632 @Override 9633 public void performReceive(Intent intent, int resultCode, String data, 9634 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 9635 throws RemoteException { 9636 } 9637 }, 0, null, null, 9638 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 9639 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 9640 } finally { 9641 Binder.restoreCallingIdentity(ident); 9642 } 9643 mStackSupervisor.resumeTopActivitiesLocked(); 9644 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId); 9645 } 9646 } 9647 9648 private boolean makeAppCrashingLocked(ProcessRecord app, 9649 String shortMsg, String longMsg, String stackTrace) { 9650 app.crashing = true; 9651 app.crashingReport = generateProcessError(app, 9652 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace); 9653 startAppProblemLocked(app); 9654 app.stopFreezingAllLocked(); 9655 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace); 9656 } 9657 9658 private void makeAppNotRespondingLocked(ProcessRecord app, 9659 String activity, String shortMsg, String longMsg) { 9660 app.notResponding = true; 9661 app.notRespondingReport = generateProcessError(app, 9662 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING, 9663 activity, shortMsg, longMsg, null); 9664 startAppProblemLocked(app); 9665 app.stopFreezingAllLocked(); 9666 } 9667 9668 /** 9669 * Generate a process error record, suitable for attachment to a ProcessRecord. 9670 * 9671 * @param app The ProcessRecord in which the error occurred. 9672 * @param condition Crashing, Application Not Responding, etc. Values are defined in 9673 * ActivityManager.AppErrorStateInfo 9674 * @param activity The activity associated with the crash, if known. 9675 * @param shortMsg Short message describing the crash. 9676 * @param longMsg Long message describing the crash. 9677 * @param stackTrace Full crash stack trace, may be null. 9678 * 9679 * @return Returns a fully-formed AppErrorStateInfo record. 9680 */ 9681 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app, 9682 int condition, String activity, String shortMsg, String longMsg, String stackTrace) { 9683 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo(); 9684 9685 report.condition = condition; 9686 report.processName = app.processName; 9687 report.pid = app.pid; 9688 report.uid = app.info.uid; 9689 report.tag = activity; 9690 report.shortMsg = shortMsg; 9691 report.longMsg = longMsg; 9692 report.stackTrace = stackTrace; 9693 9694 return report; 9695 } 9696 9697 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) { 9698 synchronized (this) { 9699 app.crashing = false; 9700 app.crashingReport = null; 9701 app.notResponding = false; 9702 app.notRespondingReport = null; 9703 if (app.anrDialog == fromDialog) { 9704 app.anrDialog = null; 9705 } 9706 if (app.waitDialog == fromDialog) { 9707 app.waitDialog = null; 9708 } 9709 if (app.pid > 0 && app.pid != MY_PID) { 9710 handleAppCrashLocked(app, null, null, null); 9711 killUnneededProcessLocked(app, "user request after error"); 9712 } 9713 } 9714 } 9715 9716 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg, 9717 String stackTrace) { 9718 long now = SystemClock.uptimeMillis(); 9719 9720 Long crashTime; 9721 if (!app.isolated) { 9722 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); 9723 } else { 9724 crashTime = null; 9725 } 9726 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) { 9727 // This process loses! 9728 Slog.w(TAG, "Process " + app.info.processName 9729 + " has crashed too many times: killing!"); 9730 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, 9731 app.userId, app.info.processName, app.uid); 9732 mStackSupervisor.handleAppCrashLocked(app); 9733 if (!app.persistent) { 9734 // We don't want to start this process again until the user 9735 // explicitly does so... but for persistent process, we really 9736 // need to keep it running. If a persistent process is actually 9737 // repeatedly crashing, then badness for everyone. 9738 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid, 9739 app.info.processName); 9740 if (!app.isolated) { 9741 // XXX We don't have a way to mark isolated processes 9742 // as bad, since they don't have a peristent identity. 9743 mBadProcesses.put(app.info.processName, app.uid, 9744 new BadProcessInfo(now, shortMsg, longMsg, stackTrace)); 9745 mProcessCrashTimes.remove(app.info.processName, app.uid); 9746 } 9747 app.bad = true; 9748 app.removed = true; 9749 // Don't let services in this process be restarted and potentially 9750 // annoy the user repeatedly. Unless it is persistent, since those 9751 // processes run critical code. 9752 removeProcessLocked(app, false, false, "crash"); 9753 mStackSupervisor.resumeTopActivitiesLocked(); 9754 return false; 9755 } 9756 mStackSupervisor.resumeTopActivitiesLocked(); 9757 } else { 9758 mStackSupervisor.finishTopRunningActivityLocked(app); 9759 } 9760 9761 // Bump up the crash count of any services currently running in the proc. 9762 for (int i=app.services.size()-1; i>=0; i--) { 9763 // Any services running in the application need to be placed 9764 // back in the pending list. 9765 ServiceRecord sr = app.services.valueAt(i); 9766 sr.crashCount++; 9767 } 9768 9769 // If the crashing process is what we consider to be the "home process" and it has been 9770 // replaced by a third-party app, clear the package preferred activities from packages 9771 // with a home activity running in the process to prevent a repeatedly crashing app 9772 // from blocking the user to manually clear the list. 9773 final ArrayList<ActivityRecord> activities = app.activities; 9774 if (app == mHomeProcess && activities.size() > 0 9775 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 9776 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { 9777 final ActivityRecord r = activities.get(activityNdx); 9778 if (r.isHomeActivity()) { 9779 Log.i(TAG, "Clearing package preferred activities from " + r.packageName); 9780 try { 9781 ActivityThread.getPackageManager() 9782 .clearPackagePreferredActivities(r.packageName); 9783 } catch (RemoteException c) { 9784 // pm is in same process, this will never happen. 9785 } 9786 } 9787 } 9788 } 9789 9790 if (!app.isolated) { 9791 // XXX Can't keep track of crash times for isolated processes, 9792 // because they don't have a perisistent identity. 9793 mProcessCrashTimes.put(app.info.processName, app.uid, now); 9794 } 9795 9796 return true; 9797 } 9798 9799 void startAppProblemLocked(ProcessRecord app) { 9800 if (app.userId == mCurrentUserId) { 9801 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver( 9802 mContext, app.info.packageName, app.info.flags); 9803 } else { 9804 // If this app is not running under the current user, then we 9805 // can't give it a report button because that would require 9806 // launching the report UI under a different user. 9807 app.errorReportReceiver = null; 9808 } 9809 skipCurrentReceiverLocked(app); 9810 } 9811 9812 void skipCurrentReceiverLocked(ProcessRecord app) { 9813 for (BroadcastQueue queue : mBroadcastQueues) { 9814 queue.skipCurrentReceiverLocked(app); 9815 } 9816 } 9817 9818 /** 9819 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes. 9820 * The application process will exit immediately after this call returns. 9821 * @param app object of the crashing app, null for the system server 9822 * @param crashInfo describing the exception 9823 */ 9824 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) { 9825 ProcessRecord r = findAppProcess(app, "Crash"); 9826 final String processName = app == null ? "system_server" 9827 : (r == null ? "unknown" : r.processName); 9828 9829 handleApplicationCrashInner("crash", r, processName, crashInfo); 9830 } 9831 9832 /* Native crash reporting uses this inner version because it needs to be somewhat 9833 * decoupled from the AM-managed cleanup lifecycle 9834 */ 9835 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, 9836 ApplicationErrorReport.CrashInfo crashInfo) { 9837 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(), 9838 UserHandle.getUserId(Binder.getCallingUid()), processName, 9839 r == null ? -1 : r.info.flags, 9840 crashInfo.exceptionClassName, 9841 crashInfo.exceptionMessage, 9842 crashInfo.throwFileName, 9843 crashInfo.throwLineNumber); 9844 9845 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo); 9846 9847 crashApplication(r, crashInfo); 9848 } 9849 9850 public void handleApplicationStrictModeViolation( 9851 IBinder app, 9852 int violationMask, 9853 StrictMode.ViolationInfo info) { 9854 ProcessRecord r = findAppProcess(app, "StrictMode"); 9855 if (r == null) { 9856 return; 9857 } 9858 9859 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) { 9860 Integer stackFingerprint = info.hashCode(); 9861 boolean logIt = true; 9862 synchronized (mAlreadyLoggedViolatedStacks) { 9863 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) { 9864 logIt = false; 9865 // TODO: sub-sample into EventLog for these, with 9866 // the info.durationMillis? Then we'd get 9867 // the relative pain numbers, without logging all 9868 // the stack traces repeatedly. We'd want to do 9869 // likewise in the client code, which also does 9870 // dup suppression, before the Binder call. 9871 } else { 9872 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) { 9873 mAlreadyLoggedViolatedStacks.clear(); 9874 } 9875 mAlreadyLoggedViolatedStacks.add(stackFingerprint); 9876 } 9877 } 9878 if (logIt) { 9879 logStrictModeViolationToDropBox(r, info); 9880 } 9881 } 9882 9883 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) { 9884 AppErrorResult result = new AppErrorResult(); 9885 synchronized (this) { 9886 final long origId = Binder.clearCallingIdentity(); 9887 9888 Message msg = Message.obtain(); 9889 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG; 9890 HashMap<String, Object> data = new HashMap<String, Object>(); 9891 data.put("result", result); 9892 data.put("app", r); 9893 data.put("violationMask", violationMask); 9894 data.put("info", info); 9895 msg.obj = data; 9896 mHandler.sendMessage(msg); 9897 9898 Binder.restoreCallingIdentity(origId); 9899 } 9900 int res = result.get(); 9901 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res); 9902 } 9903 } 9904 9905 // Depending on the policy in effect, there could be a bunch of 9906 // these in quick succession so we try to batch these together to 9907 // minimize disk writes, number of dropbox entries, and maximize 9908 // compression, by having more fewer, larger records. 9909 private void logStrictModeViolationToDropBox( 9910 ProcessRecord process, 9911 StrictMode.ViolationInfo info) { 9912 if (info == null) { 9913 return; 9914 } 9915 final boolean isSystemApp = process == null || 9916 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM | 9917 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0; 9918 final String processName = process == null ? "unknown" : process.processName; 9919 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode"; 9920 final DropBoxManager dbox = (DropBoxManager) 9921 mContext.getSystemService(Context.DROPBOX_SERVICE); 9922 9923 // Exit early if the dropbox isn't configured to accept this report type. 9924 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 9925 9926 boolean bufferWasEmpty; 9927 boolean needsFlush; 9928 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024); 9929 synchronized (sb) { 9930 bufferWasEmpty = sb.length() == 0; 9931 appendDropBoxProcessHeaders(process, processName, sb); 9932 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 9933 sb.append("System-App: ").append(isSystemApp).append("\n"); 9934 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n"); 9935 if (info.violationNumThisLoop != 0) { 9936 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n"); 9937 } 9938 if (info.numAnimationsRunning != 0) { 9939 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n"); 9940 } 9941 if (info.broadcastIntentAction != null) { 9942 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n"); 9943 } 9944 if (info.durationMillis != -1) { 9945 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n"); 9946 } 9947 if (info.numInstances != -1) { 9948 sb.append("Instance-Count: ").append(info.numInstances).append("\n"); 9949 } 9950 if (info.tags != null) { 9951 for (String tag : info.tags) { 9952 sb.append("Span-Tag: ").append(tag).append("\n"); 9953 } 9954 } 9955 sb.append("\n"); 9956 if (info.crashInfo != null && info.crashInfo.stackTrace != null) { 9957 sb.append(info.crashInfo.stackTrace); 9958 } 9959 sb.append("\n"); 9960 9961 // Only buffer up to ~64k. Various logging bits truncate 9962 // things at 128k. 9963 needsFlush = (sb.length() > 64 * 1024); 9964 } 9965 9966 // Flush immediately if the buffer's grown too large, or this 9967 // is a non-system app. Non-system apps are isolated with a 9968 // different tag & policy and not batched. 9969 // 9970 // Batching is useful during internal testing with 9971 // StrictMode settings turned up high. Without batching, 9972 // thousands of separate files could be created on boot. 9973 if (!isSystemApp || needsFlush) { 9974 new Thread("Error dump: " + dropboxTag) { 9975 @Override 9976 public void run() { 9977 String report; 9978 synchronized (sb) { 9979 report = sb.toString(); 9980 sb.delete(0, sb.length()); 9981 sb.trimToSize(); 9982 } 9983 if (report.length() != 0) { 9984 dbox.addText(dropboxTag, report); 9985 } 9986 } 9987 }.start(); 9988 return; 9989 } 9990 9991 // System app batching: 9992 if (!bufferWasEmpty) { 9993 // An existing dropbox-writing thread is outstanding, so 9994 // we don't need to start it up. The existing thread will 9995 // catch the buffer appends we just did. 9996 return; 9997 } 9998 9999 // Worker thread to both batch writes and to avoid blocking the caller on I/O. 10000 // (After this point, we shouldn't access AMS internal data structures.) 10001 new Thread("Error dump: " + dropboxTag) { 10002 @Override 10003 public void run() { 10004 // 5 second sleep to let stacks arrive and be batched together 10005 try { 10006 Thread.sleep(5000); // 5 seconds 10007 } catch (InterruptedException e) {} 10008 10009 String errorReport; 10010 synchronized (mStrictModeBuffer) { 10011 errorReport = mStrictModeBuffer.toString(); 10012 if (errorReport.length() == 0) { 10013 return; 10014 } 10015 mStrictModeBuffer.delete(0, mStrictModeBuffer.length()); 10016 mStrictModeBuffer.trimToSize(); 10017 } 10018 dbox.addText(dropboxTag, errorReport); 10019 } 10020 }.start(); 10021 } 10022 10023 /** 10024 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors. 10025 * @param app object of the crashing app, null for the system server 10026 * @param tag reported by the caller 10027 * @param crashInfo describing the context of the error 10028 * @return true if the process should exit immediately (WTF is fatal) 10029 */ 10030 public boolean handleApplicationWtf(IBinder app, String tag, 10031 ApplicationErrorReport.CrashInfo crashInfo) { 10032 ProcessRecord r = findAppProcess(app, "WTF"); 10033 final String processName = app == null ? "system_server" 10034 : (r == null ? "unknown" : r.processName); 10035 10036 EventLog.writeEvent(EventLogTags.AM_WTF, 10037 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(), 10038 processName, 10039 r == null ? -1 : r.info.flags, 10040 tag, crashInfo.exceptionMessage); 10041 10042 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo); 10043 10044 if (r != null && r.pid != Process.myPid() && 10045 Settings.Global.getInt(mContext.getContentResolver(), 10046 Settings.Global.WTF_IS_FATAL, 0) != 0) { 10047 crashApplication(r, crashInfo); 10048 return true; 10049 } else { 10050 return false; 10051 } 10052 } 10053 10054 /** 10055 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit}) 10056 * @return the corresponding {@link ProcessRecord} object, or null if none could be found 10057 */ 10058 private ProcessRecord findAppProcess(IBinder app, String reason) { 10059 if (app == null) { 10060 return null; 10061 } 10062 10063 synchronized (this) { 10064 final int NP = mProcessNames.getMap().size(); 10065 for (int ip=0; ip<NP; ip++) { 10066 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 10067 final int NA = apps.size(); 10068 for (int ia=0; ia<NA; ia++) { 10069 ProcessRecord p = apps.valueAt(ia); 10070 if (p.thread != null && p.thread.asBinder() == app) { 10071 return p; 10072 } 10073 } 10074 } 10075 10076 Slog.w(TAG, "Can't find mystery application for " + reason 10077 + " from pid=" + Binder.getCallingPid() 10078 + " uid=" + Binder.getCallingUid() + ": " + app); 10079 return null; 10080 } 10081 } 10082 10083 /** 10084 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging 10085 * to append various headers to the dropbox log text. 10086 */ 10087 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName, 10088 StringBuilder sb) { 10089 // Watchdog thread ends up invoking this function (with 10090 // a null ProcessRecord) to add the stack file to dropbox. 10091 // Do not acquire a lock on this (am) in such cases, as it 10092 // could cause a potential deadlock, if and when watchdog 10093 // is invoked due to unavailability of lock on am and it 10094 // would prevent watchdog from killing system_server. 10095 if (process == null) { 10096 sb.append("Process: ").append(processName).append("\n"); 10097 return; 10098 } 10099 // Note: ProcessRecord 'process' is guarded by the service 10100 // instance. (notably process.pkgList, which could otherwise change 10101 // concurrently during execution of this method) 10102 synchronized (this) { 10103 sb.append("Process: ").append(processName).append("\n"); 10104 int flags = process.info.flags; 10105 IPackageManager pm = AppGlobals.getPackageManager(); 10106 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n"); 10107 for (int ip=0; ip<process.pkgList.size(); ip++) { 10108 String pkg = process.pkgList.keyAt(ip); 10109 sb.append("Package: ").append(pkg); 10110 try { 10111 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId()); 10112 if (pi != null) { 10113 sb.append(" v").append(pi.versionCode); 10114 if (pi.versionName != null) { 10115 sb.append(" (").append(pi.versionName).append(")"); 10116 } 10117 } 10118 } catch (RemoteException e) { 10119 Slog.e(TAG, "Error getting package info: " + pkg, e); 10120 } 10121 sb.append("\n"); 10122 } 10123 } 10124 } 10125 10126 private static String processClass(ProcessRecord process) { 10127 if (process == null || process.pid == MY_PID) { 10128 return "system_server"; 10129 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { 10130 return "system_app"; 10131 } else { 10132 return "data_app"; 10133 } 10134 } 10135 10136 /** 10137 * Write a description of an error (crash, WTF, ANR) to the drop box. 10138 * @param eventType to include in the drop box tag ("crash", "wtf", etc.) 10139 * @param process which caused the error, null means the system server 10140 * @param activity which triggered the error, null if unknown 10141 * @param parent activity related to the error, null if unknown 10142 * @param subject line related to the error, null if absent 10143 * @param report in long form describing the error, null if absent 10144 * @param logFile to include in the report, null if none 10145 * @param crashInfo giving an application stack trace, null if absent 10146 */ 10147 public void addErrorToDropBox(String eventType, 10148 ProcessRecord process, String processName, ActivityRecord activity, 10149 ActivityRecord parent, String subject, 10150 final String report, final File logFile, 10151 final ApplicationErrorReport.CrashInfo crashInfo) { 10152 // NOTE -- this must never acquire the ActivityManagerService lock, 10153 // otherwise the watchdog may be prevented from resetting the system. 10154 10155 final String dropboxTag = processClass(process) + "_" + eventType; 10156 final DropBoxManager dbox = (DropBoxManager) 10157 mContext.getSystemService(Context.DROPBOX_SERVICE); 10158 10159 // Exit early if the dropbox isn't configured to accept this report type. 10160 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return; 10161 10162 final StringBuilder sb = new StringBuilder(1024); 10163 appendDropBoxProcessHeaders(process, processName, sb); 10164 if (activity != null) { 10165 sb.append("Activity: ").append(activity.shortComponentName).append("\n"); 10166 } 10167 if (parent != null && parent.app != null && parent.app.pid != process.pid) { 10168 sb.append("Parent-Process: ").append(parent.app.processName).append("\n"); 10169 } 10170 if (parent != null && parent != activity) { 10171 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n"); 10172 } 10173 if (subject != null) { 10174 sb.append("Subject: ").append(subject).append("\n"); 10175 } 10176 sb.append("Build: ").append(Build.FINGERPRINT).append("\n"); 10177 if (Debug.isDebuggerConnected()) { 10178 sb.append("Debugger: Connected\n"); 10179 } 10180 sb.append("\n"); 10181 10182 // Do the rest in a worker thread to avoid blocking the caller on I/O 10183 // (After this point, we shouldn't access AMS internal data structures.) 10184 Thread worker = new Thread("Error dump: " + dropboxTag) { 10185 @Override 10186 public void run() { 10187 if (report != null) { 10188 sb.append(report); 10189 } 10190 if (logFile != null) { 10191 try { 10192 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE, 10193 "\n\n[[TRUNCATED]]")); 10194 } catch (IOException e) { 10195 Slog.e(TAG, "Error reading " + logFile, e); 10196 } 10197 } 10198 if (crashInfo != null && crashInfo.stackTrace != null) { 10199 sb.append(crashInfo.stackTrace); 10200 } 10201 10202 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag; 10203 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0); 10204 if (lines > 0) { 10205 sb.append("\n"); 10206 10207 // Merge several logcat streams, and take the last N lines 10208 InputStreamReader input = null; 10209 try { 10210 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", 10211 "-v", "time", "-b", "events", "-b", "system", "-b", "main", 10212 "-t", String.valueOf(lines)).redirectErrorStream(true).start(); 10213 10214 try { logcat.getOutputStream().close(); } catch (IOException e) {} 10215 try { logcat.getErrorStream().close(); } catch (IOException e) {} 10216 input = new InputStreamReader(logcat.getInputStream()); 10217 10218 int num; 10219 char[] buf = new char[8192]; 10220 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num); 10221 } catch (IOException e) { 10222 Slog.e(TAG, "Error running logcat", e); 10223 } finally { 10224 if (input != null) try { input.close(); } catch (IOException e) {} 10225 } 10226 } 10227 10228 dbox.addText(dropboxTag, sb.toString()); 10229 } 10230 }; 10231 10232 if (process == null) { 10233 // If process is null, we are being called from some internal code 10234 // and may be about to die -- run this synchronously. 10235 worker.run(); 10236 } else { 10237 worker.start(); 10238 } 10239 } 10240 10241 /** 10242 * Bring up the "unexpected error" dialog box for a crashing app. 10243 * Deal with edge cases (intercepts from instrumented applications, 10244 * ActivityController, error intent receivers, that sort of thing). 10245 * @param r the application crashing 10246 * @param crashInfo describing the failure 10247 */ 10248 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) { 10249 long timeMillis = System.currentTimeMillis(); 10250 String shortMsg = crashInfo.exceptionClassName; 10251 String longMsg = crashInfo.exceptionMessage; 10252 String stackTrace = crashInfo.stackTrace; 10253 if (shortMsg != null && longMsg != null) { 10254 longMsg = shortMsg + ": " + longMsg; 10255 } else if (shortMsg != null) { 10256 longMsg = shortMsg; 10257 } 10258 10259 AppErrorResult result = new AppErrorResult(); 10260 synchronized (this) { 10261 if (mController != null) { 10262 try { 10263 String name = r != null ? r.processName : null; 10264 int pid = r != null ? r.pid : Binder.getCallingPid(); 10265 if (!mController.appCrashed(name, pid, 10266 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) { 10267 Slog.w(TAG, "Force-killing crashed app " + name 10268 + " at watcher's request"); 10269 Process.killProcess(pid); 10270 return; 10271 } 10272 } catch (RemoteException e) { 10273 mController = null; 10274 Watchdog.getInstance().setActivityController(null); 10275 } 10276 } 10277 10278 final long origId = Binder.clearCallingIdentity(); 10279 10280 // If this process is running instrumentation, finish it. 10281 if (r != null && r.instrumentationClass != null) { 10282 Slog.w(TAG, "Error in app " + r.processName 10283 + " running instrumentation " + r.instrumentationClass + ":"); 10284 if (shortMsg != null) Slog.w(TAG, " " + shortMsg); 10285 if (longMsg != null) Slog.w(TAG, " " + longMsg); 10286 Bundle info = new Bundle(); 10287 info.putString("shortMsg", shortMsg); 10288 info.putString("longMsg", longMsg); 10289 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info); 10290 Binder.restoreCallingIdentity(origId); 10291 return; 10292 } 10293 10294 // If we can't identify the process or it's already exceeded its crash quota, 10295 // quit right away without showing a crash dialog. 10296 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) { 10297 Binder.restoreCallingIdentity(origId); 10298 return; 10299 } 10300 10301 Message msg = Message.obtain(); 10302 msg.what = SHOW_ERROR_MSG; 10303 HashMap data = new HashMap(); 10304 data.put("result", result); 10305 data.put("app", r); 10306 msg.obj = data; 10307 mHandler.sendMessage(msg); 10308 10309 Binder.restoreCallingIdentity(origId); 10310 } 10311 10312 int res = result.get(); 10313 10314 Intent appErrorIntent = null; 10315 synchronized (this) { 10316 if (r != null && !r.isolated) { 10317 // XXX Can't keep track of crash time for isolated processes, 10318 // since they don't have a persistent identity. 10319 mProcessCrashTimes.put(r.info.processName, r.uid, 10320 SystemClock.uptimeMillis()); 10321 } 10322 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) { 10323 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo); 10324 } 10325 } 10326 10327 if (appErrorIntent != null) { 10328 try { 10329 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId)); 10330 } catch (ActivityNotFoundException e) { 10331 Slog.w(TAG, "bug report receiver dissappeared", e); 10332 } 10333 } 10334 } 10335 10336 Intent createAppErrorIntentLocked(ProcessRecord r, 10337 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10338 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo); 10339 if (report == null) { 10340 return null; 10341 } 10342 Intent result = new Intent(Intent.ACTION_APP_ERROR); 10343 result.setComponent(r.errorReportReceiver); 10344 result.putExtra(Intent.EXTRA_BUG_REPORT, report); 10345 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 10346 return result; 10347 } 10348 10349 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r, 10350 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) { 10351 if (r.errorReportReceiver == null) { 10352 return null; 10353 } 10354 10355 if (!r.crashing && !r.notResponding && !r.forceCrashReport) { 10356 return null; 10357 } 10358 10359 ApplicationErrorReport report = new ApplicationErrorReport(); 10360 report.packageName = r.info.packageName; 10361 report.installerPackageName = r.errorReportReceiver.getPackageName(); 10362 report.processName = r.processName; 10363 report.time = timeMillis; 10364 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; 10365 10366 if (r.crashing || r.forceCrashReport) { 10367 report.type = ApplicationErrorReport.TYPE_CRASH; 10368 report.crashInfo = crashInfo; 10369 } else if (r.notResponding) { 10370 report.type = ApplicationErrorReport.TYPE_ANR; 10371 report.anrInfo = new ApplicationErrorReport.AnrInfo(); 10372 10373 report.anrInfo.activity = r.notRespondingReport.tag; 10374 report.anrInfo.cause = r.notRespondingReport.shortMsg; 10375 report.anrInfo.info = r.notRespondingReport.longMsg; 10376 } 10377 10378 return report; 10379 } 10380 10381 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() { 10382 enforceNotIsolatedCaller("getProcessesInErrorState"); 10383 // assume our apps are happy - lazy create the list 10384 List<ActivityManager.ProcessErrorStateInfo> errList = null; 10385 10386 final boolean allUsers = ActivityManager.checkUidPermission( 10387 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10388 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10389 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10390 10391 synchronized (this) { 10392 10393 // iterate across all processes 10394 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10395 ProcessRecord app = mLruProcesses.get(i); 10396 if (!allUsers && app.userId != userId) { 10397 continue; 10398 } 10399 if ((app.thread != null) && (app.crashing || app.notResponding)) { 10400 // This one's in trouble, so we'll generate a report for it 10401 // crashes are higher priority (in case there's a crash *and* an anr) 10402 ActivityManager.ProcessErrorStateInfo report = null; 10403 if (app.crashing) { 10404 report = app.crashingReport; 10405 } else if (app.notResponding) { 10406 report = app.notRespondingReport; 10407 } 10408 10409 if (report != null) { 10410 if (errList == null) { 10411 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1); 10412 } 10413 errList.add(report); 10414 } else { 10415 Slog.w(TAG, "Missing app error report, app = " + app.processName + 10416 " crashing = " + app.crashing + 10417 " notResponding = " + app.notResponding); 10418 } 10419 } 10420 } 10421 } 10422 10423 return errList; 10424 } 10425 10426 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) { 10427 if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 10428 if (currApp != null) { 10429 currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1; 10430 } 10431 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10432 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 10433 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10434 } else if (adj >= ProcessList.HOME_APP_ADJ) { 10435 if (currApp != null) { 10436 currApp.lru = 0; 10437 } 10438 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 10439 } else if (adj >= ProcessList.SERVICE_ADJ) { 10440 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 10441 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 10442 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 10443 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 10444 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 10445 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 10446 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 10447 } else { 10448 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 10449 } 10450 } 10451 10452 private void fillInProcMemInfo(ProcessRecord app, 10453 ActivityManager.RunningAppProcessInfo outInfo) { 10454 outInfo.pid = app.pid; 10455 outInfo.uid = app.info.uid; 10456 if (mHeavyWeightProcess == app) { 10457 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 10458 } 10459 if (app.persistent) { 10460 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 10461 } 10462 if (app.activities.size() > 0) { 10463 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 10464 } 10465 outInfo.lastTrimLevel = app.trimMemoryLevel; 10466 int adj = app.curAdj; 10467 outInfo.importance = oomAdjToImportance(adj, outInfo); 10468 outInfo.importanceReasonCode = app.adjTypeCode; 10469 } 10470 10471 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() { 10472 enforceNotIsolatedCaller("getRunningAppProcesses"); 10473 // Lazy instantiation of list 10474 List<ActivityManager.RunningAppProcessInfo> runList = null; 10475 final boolean allUsers = ActivityManager.checkUidPermission( 10476 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 10477 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED; 10478 int userId = UserHandle.getUserId(Binder.getCallingUid()); 10479 synchronized (this) { 10480 // Iterate across all processes 10481 for (int i=mLruProcesses.size()-1; i>=0; i--) { 10482 ProcessRecord app = mLruProcesses.get(i); 10483 if (!allUsers && app.userId != userId) { 10484 continue; 10485 } 10486 if ((app.thread != null) && (!app.crashing && !app.notResponding)) { 10487 // Generate process state info for running application 10488 ActivityManager.RunningAppProcessInfo currApp = 10489 new ActivityManager.RunningAppProcessInfo(app.processName, 10490 app.pid, app.getPackageList()); 10491 fillInProcMemInfo(app, currApp); 10492 if (app.adjSource instanceof ProcessRecord) { 10493 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 10494 currApp.importanceReasonImportance = oomAdjToImportance( 10495 app.adjSourceOom, null); 10496 } else if (app.adjSource instanceof ActivityRecord) { 10497 ActivityRecord r = (ActivityRecord)app.adjSource; 10498 if (r.app != null) currApp.importanceReasonPid = r.app.pid; 10499 } 10500 if (app.adjTarget instanceof ComponentName) { 10501 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 10502 } 10503 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 10504 // + " lru=" + currApp.lru); 10505 if (runList == null) { 10506 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>(); 10507 } 10508 runList.add(currApp); 10509 } 10510 } 10511 } 10512 return runList; 10513 } 10514 10515 public List<ApplicationInfo> getRunningExternalApplications() { 10516 enforceNotIsolatedCaller("getRunningExternalApplications"); 10517 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses(); 10518 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>(); 10519 if (runningApps != null && runningApps.size() > 0) { 10520 Set<String> extList = new HashSet<String>(); 10521 for (ActivityManager.RunningAppProcessInfo app : runningApps) { 10522 if (app.pkgList != null) { 10523 for (String pkg : app.pkgList) { 10524 extList.add(pkg); 10525 } 10526 } 10527 } 10528 IPackageManager pm = AppGlobals.getPackageManager(); 10529 for (String pkg : extList) { 10530 try { 10531 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId()); 10532 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { 10533 retList.add(info); 10534 } 10535 } catch (RemoteException e) { 10536 } 10537 } 10538 } 10539 return retList; 10540 } 10541 10542 @Override 10543 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) { 10544 enforceNotIsolatedCaller("getMyMemoryState"); 10545 synchronized (this) { 10546 ProcessRecord proc; 10547 synchronized (mPidsSelfLocked) { 10548 proc = mPidsSelfLocked.get(Binder.getCallingPid()); 10549 } 10550 fillInProcMemInfo(proc, outInfo); 10551 } 10552 } 10553 10554 @Override 10555 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 10556 if (checkCallingPermission(android.Manifest.permission.DUMP) 10557 != PackageManager.PERMISSION_GRANTED) { 10558 pw.println("Permission Denial: can't dump ActivityManager from from pid=" 10559 + Binder.getCallingPid() 10560 + ", uid=" + Binder.getCallingUid() 10561 + " without permission " 10562 + android.Manifest.permission.DUMP); 10563 return; 10564 } 10565 10566 boolean dumpAll = false; 10567 boolean dumpClient = false; 10568 String dumpPackage = null; 10569 10570 int opti = 0; 10571 while (opti < args.length) { 10572 String opt = args[opti]; 10573 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 10574 break; 10575 } 10576 opti++; 10577 if ("-a".equals(opt)) { 10578 dumpAll = true; 10579 } else if ("-c".equals(opt)) { 10580 dumpClient = true; 10581 } else if ("-h".equals(opt)) { 10582 pw.println("Activity manager dump options:"); 10583 pw.println(" [-a] [-c] [-h] [cmd] ..."); 10584 pw.println(" cmd may be one of:"); 10585 pw.println(" a[ctivities]: activity stack state"); 10586 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state"); 10587 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state"); 10588 pw.println(" p[rocesses] [PACKAGE_NAME]: process state"); 10589 pw.println(" o[om]: out of memory management"); 10590 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state"); 10591 pw.println(" provider [COMP_SPEC]: provider client-side state"); 10592 pw.println(" s[ervices] [COMP_SPEC ...]: service state"); 10593 pw.println(" service [COMP_SPEC]: service client-side state"); 10594 pw.println(" package [PACKAGE_NAME]: all state related to given package"); 10595 pw.println(" all: dump all activities"); 10596 pw.println(" top: dump the top activity"); 10597 pw.println(" cmd may also be a COMP_SPEC to dump activities."); 10598 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),"); 10599 pw.println(" a partial substring in a component name, a"); 10600 pw.println(" hex object identifier."); 10601 pw.println(" -a: include all available server state."); 10602 pw.println(" -c: include client state."); 10603 return; 10604 } else { 10605 pw.println("Unknown argument: " + opt + "; use -h for help"); 10606 } 10607 } 10608 10609 long origId = Binder.clearCallingIdentity(); 10610 boolean more = false; 10611 // Is the caller requesting to dump a particular piece of data? 10612 if (opti < args.length) { 10613 String cmd = args[opti]; 10614 opti++; 10615 if ("activities".equals(cmd) || "a".equals(cmd)) { 10616 synchronized (this) { 10617 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null); 10618 } 10619 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) { 10620 String[] newArgs; 10621 String name; 10622 if (opti >= args.length) { 10623 name = null; 10624 newArgs = EMPTY_STRING_ARRAY; 10625 } else { 10626 name = args[opti]; 10627 opti++; 10628 newArgs = new String[args.length - opti]; 10629 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10630 args.length - opti); 10631 } 10632 synchronized (this) { 10633 dumpBroadcastsLocked(fd, pw, args, opti, true, name); 10634 } 10635 } else if ("intents".equals(cmd) || "i".equals(cmd)) { 10636 String[] newArgs; 10637 String name; 10638 if (opti >= args.length) { 10639 name = null; 10640 newArgs = EMPTY_STRING_ARRAY; 10641 } else { 10642 name = args[opti]; 10643 opti++; 10644 newArgs = new String[args.length - opti]; 10645 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10646 args.length - opti); 10647 } 10648 synchronized (this) { 10649 dumpPendingIntentsLocked(fd, pw, args, opti, true, name); 10650 } 10651 } else if ("processes".equals(cmd) || "p".equals(cmd)) { 10652 String[] newArgs; 10653 String name; 10654 if (opti >= args.length) { 10655 name = null; 10656 newArgs = EMPTY_STRING_ARRAY; 10657 } else { 10658 name = args[opti]; 10659 opti++; 10660 newArgs = new String[args.length - opti]; 10661 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10662 args.length - opti); 10663 } 10664 synchronized (this) { 10665 dumpProcessesLocked(fd, pw, args, opti, true, name); 10666 } 10667 } else if ("oom".equals(cmd) || "o".equals(cmd)) { 10668 synchronized (this) { 10669 dumpOomLocked(fd, pw, args, opti, true); 10670 } 10671 } else if ("provider".equals(cmd)) { 10672 String[] newArgs; 10673 String name; 10674 if (opti >= args.length) { 10675 name = null; 10676 newArgs = EMPTY_STRING_ARRAY; 10677 } else { 10678 name = args[opti]; 10679 opti++; 10680 newArgs = new String[args.length - opti]; 10681 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti); 10682 } 10683 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) { 10684 pw.println("No providers match: " + name); 10685 pw.println("Use -h for help."); 10686 } 10687 } else if ("providers".equals(cmd) || "prov".equals(cmd)) { 10688 synchronized (this) { 10689 dumpProvidersLocked(fd, pw, args, opti, true, null); 10690 } 10691 } else if ("service".equals(cmd)) { 10692 String[] newArgs; 10693 String name; 10694 if (opti >= args.length) { 10695 name = null; 10696 newArgs = EMPTY_STRING_ARRAY; 10697 } else { 10698 name = args[opti]; 10699 opti++; 10700 newArgs = new String[args.length - opti]; 10701 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10702 args.length - opti); 10703 } 10704 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) { 10705 pw.println("No services match: " + name); 10706 pw.println("Use -h for help."); 10707 } 10708 } else if ("package".equals(cmd)) { 10709 String[] newArgs; 10710 if (opti >= args.length) { 10711 pw.println("package: no package name specified"); 10712 pw.println("Use -h for help."); 10713 } else { 10714 dumpPackage = args[opti]; 10715 opti++; 10716 newArgs = new String[args.length - opti]; 10717 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, 10718 args.length - opti); 10719 args = newArgs; 10720 opti = 0; 10721 more = true; 10722 } 10723 } else if ("services".equals(cmd) || "s".equals(cmd)) { 10724 synchronized (this) { 10725 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null); 10726 } 10727 } else { 10728 // Dumping a single activity? 10729 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) { 10730 pw.println("Bad activity command, or no activities match: " + cmd); 10731 pw.println("Use -h for help."); 10732 } 10733 } 10734 if (!more) { 10735 Binder.restoreCallingIdentity(origId); 10736 return; 10737 } 10738 } 10739 10740 // No piece of data specified, dump everything. 10741 synchronized (this) { 10742 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10743 pw.println(); 10744 if (dumpAll) { 10745 pw.println("-------------------------------------------------------------------------------"); 10746 } 10747 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10748 pw.println(); 10749 if (dumpAll) { 10750 pw.println("-------------------------------------------------------------------------------"); 10751 } 10752 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10753 pw.println(); 10754 if (dumpAll) { 10755 pw.println("-------------------------------------------------------------------------------"); 10756 } 10757 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10758 pw.println(); 10759 if (dumpAll) { 10760 pw.println("-------------------------------------------------------------------------------"); 10761 } 10762 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage); 10763 pw.println(); 10764 if (dumpAll) { 10765 pw.println("-------------------------------------------------------------------------------"); 10766 } 10767 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage); 10768 } 10769 Binder.restoreCallingIdentity(origId); 10770 } 10771 10772 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10773 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) { 10774 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)"); 10775 10776 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, 10777 dumpPackage); 10778 boolean needSep = printedAnything; 10779 10780 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity, 10781 dumpPackage, needSep, " mFocusedActivity: "); 10782 if (printed) { 10783 printedAnything = true; 10784 needSep = false; 10785 } 10786 10787 if (dumpPackage == null) { 10788 if (needSep) { 10789 pw.println(); 10790 } 10791 needSep = true; 10792 printedAnything = true; 10793 mStackSupervisor.dump(pw, " "); 10794 } 10795 10796 if (mRecentTasks.size() > 0) { 10797 boolean printedHeader = false; 10798 10799 final int N = mRecentTasks.size(); 10800 for (int i=0; i<N; i++) { 10801 TaskRecord tr = mRecentTasks.get(i); 10802 if (dumpPackage != null) { 10803 if (tr.realActivity == null || 10804 !dumpPackage.equals(tr.realActivity)) { 10805 continue; 10806 } 10807 } 10808 if (!printedHeader) { 10809 if (needSep) { 10810 pw.println(); 10811 } 10812 pw.println(" Recent tasks:"); 10813 printedHeader = true; 10814 printedAnything = true; 10815 } 10816 pw.print(" * Recent #"); pw.print(i); pw.print(": "); 10817 pw.println(tr); 10818 if (dumpAll) { 10819 mRecentTasks.get(i).dump(pw, " "); 10820 } 10821 } 10822 } 10823 10824 if (!printedAnything) { 10825 pw.println(" (nothing)"); 10826 } 10827 } 10828 10829 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, 10830 int opti, boolean dumpAll, String dumpPackage) { 10831 boolean needSep = false; 10832 boolean printedAnything = false; 10833 int numPers = 0; 10834 10835 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)"); 10836 10837 if (dumpAll) { 10838 final int NP = mProcessNames.getMap().size(); 10839 for (int ip=0; ip<NP; ip++) { 10840 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip); 10841 final int NA = procs.size(); 10842 for (int ia=0; ia<NA; ia++) { 10843 ProcessRecord r = procs.valueAt(ia); 10844 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10845 continue; 10846 } 10847 if (!needSep) { 10848 pw.println(" All known processes:"); 10849 needSep = true; 10850 printedAnything = true; 10851 } 10852 pw.print(r.persistent ? " *PERS*" : " *APP*"); 10853 pw.print(" UID "); pw.print(procs.keyAt(ia)); 10854 pw.print(" "); pw.println(r); 10855 r.dump(pw, " "); 10856 if (r.persistent) { 10857 numPers++; 10858 } 10859 } 10860 } 10861 } 10862 10863 if (mIsolatedProcesses.size() > 0) { 10864 boolean printed = false; 10865 for (int i=0; i<mIsolatedProcesses.size(); i++) { 10866 ProcessRecord r = mIsolatedProcesses.valueAt(i); 10867 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10868 continue; 10869 } 10870 if (!printed) { 10871 if (needSep) { 10872 pw.println(); 10873 } 10874 pw.println(" Isolated process list (sorted by uid):"); 10875 printedAnything = true; 10876 printed = true; 10877 needSep = true; 10878 } 10879 pw.println(String.format("%sIsolated #%2d: %s", 10880 " ", i, r.toString())); 10881 } 10882 } 10883 10884 if (mLruProcesses.size() > 0) { 10885 if (needSep) { 10886 pw.println(); 10887 } 10888 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 10889 pw.print(" total, non-act at "); 10890 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 10891 pw.print(", non-svc at "); 10892 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 10893 pw.println("):"); 10894 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage); 10895 needSep = true; 10896 printedAnything = true; 10897 } 10898 10899 if (dumpAll || dumpPackage != null) { 10900 synchronized (mPidsSelfLocked) { 10901 boolean printed = false; 10902 for (int i=0; i<mPidsSelfLocked.size(); i++) { 10903 ProcessRecord r = mPidsSelfLocked.valueAt(i); 10904 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 10905 continue; 10906 } 10907 if (!printed) { 10908 if (needSep) pw.println(); 10909 needSep = true; 10910 pw.println(" PID mappings:"); 10911 printed = true; 10912 printedAnything = true; 10913 } 10914 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i)); 10915 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i)); 10916 } 10917 } 10918 } 10919 10920 if (mForegroundProcesses.size() > 0) { 10921 synchronized (mPidsSelfLocked) { 10922 boolean printed = false; 10923 for (int i=0; i<mForegroundProcesses.size(); i++) { 10924 ProcessRecord r = mPidsSelfLocked.get( 10925 mForegroundProcesses.valueAt(i).pid); 10926 if (dumpPackage != null && (r == null 10927 || !r.pkgList.containsKey(dumpPackage))) { 10928 continue; 10929 } 10930 if (!printed) { 10931 if (needSep) pw.println(); 10932 needSep = true; 10933 pw.println(" Foreground Processes:"); 10934 printed = true; 10935 printedAnything = true; 10936 } 10937 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i)); 10938 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i)); 10939 } 10940 } 10941 } 10942 10943 if (mPersistentStartingProcesses.size() > 0) { 10944 if (needSep) pw.println(); 10945 needSep = true; 10946 printedAnything = true; 10947 pw.println(" Persisent processes that are starting:"); 10948 dumpProcessList(pw, this, mPersistentStartingProcesses, " ", 10949 "Starting Norm", "Restarting PERS", dumpPackage); 10950 } 10951 10952 if (mRemovedProcesses.size() > 0) { 10953 if (needSep) pw.println(); 10954 needSep = true; 10955 printedAnything = true; 10956 pw.println(" Processes that are being removed:"); 10957 dumpProcessList(pw, this, mRemovedProcesses, " ", 10958 "Removed Norm", "Removed PERS", dumpPackage); 10959 } 10960 10961 if (mProcessesOnHold.size() > 0) { 10962 if (needSep) pw.println(); 10963 needSep = true; 10964 printedAnything = true; 10965 pw.println(" Processes that are on old until the system is ready:"); 10966 dumpProcessList(pw, this, mProcessesOnHold, " ", 10967 "OnHold Norm", "OnHold PERS", dumpPackage); 10968 } 10969 10970 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage); 10971 10972 if (mProcessCrashTimes.getMap().size() > 0) { 10973 boolean printed = false; 10974 long now = SystemClock.uptimeMillis(); 10975 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap(); 10976 final int NP = pmap.size(); 10977 for (int ip=0; ip<NP; ip++) { 10978 String pname = pmap.keyAt(ip); 10979 SparseArray<Long> uids = pmap.valueAt(ip); 10980 final int N = uids.size(); 10981 for (int i=0; i<N; i++) { 10982 int puid = uids.keyAt(i); 10983 ProcessRecord r = mProcessNames.get(pname, puid); 10984 if (dumpPackage != null && (r == null 10985 || !r.pkgList.containsKey(dumpPackage))) { 10986 continue; 10987 } 10988 if (!printed) { 10989 if (needSep) pw.println(); 10990 needSep = true; 10991 pw.println(" Time since processes crashed:"); 10992 printed = true; 10993 printedAnything = true; 10994 } 10995 pw.print(" Process "); pw.print(pname); 10996 pw.print(" uid "); pw.print(puid); 10997 pw.print(": last crashed "); 10998 TimeUtils.formatDuration(now-uids.valueAt(i), pw); 10999 pw.println(" ago"); 11000 } 11001 } 11002 } 11003 11004 if (mBadProcesses.getMap().size() > 0) { 11005 boolean printed = false; 11006 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap(); 11007 final int NP = pmap.size(); 11008 for (int ip=0; ip<NP; ip++) { 11009 String pname = pmap.keyAt(ip); 11010 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip); 11011 final int N = uids.size(); 11012 for (int i=0; i<N; i++) { 11013 int puid = uids.keyAt(i); 11014 ProcessRecord r = mProcessNames.get(pname, puid); 11015 if (dumpPackage != null && (r == null 11016 || !r.pkgList.containsKey(dumpPackage))) { 11017 continue; 11018 } 11019 if (!printed) { 11020 if (needSep) pw.println(); 11021 needSep = true; 11022 pw.println(" Bad processes:"); 11023 printedAnything = true; 11024 } 11025 BadProcessInfo info = uids.valueAt(i); 11026 pw.print(" Bad process "); pw.print(pname); 11027 pw.print(" uid "); pw.print(puid); 11028 pw.print(": crashed at time "); pw.println(info.time); 11029 if (info.shortMsg != null) { 11030 pw.print(" Short msg: "); pw.println(info.shortMsg); 11031 } 11032 if (info.longMsg != null) { 11033 pw.print(" Long msg: "); pw.println(info.longMsg); 11034 } 11035 if (info.stack != null) { 11036 pw.println(" Stack:"); 11037 int lastPos = 0; 11038 for (int pos=0; pos<info.stack.length(); pos++) { 11039 if (info.stack.charAt(pos) == '\n') { 11040 pw.print(" "); 11041 pw.write(info.stack, lastPos, pos-lastPos); 11042 pw.println(); 11043 lastPos = pos+1; 11044 } 11045 } 11046 if (lastPos < info.stack.length()) { 11047 pw.print(" "); 11048 pw.write(info.stack, lastPos, info.stack.length()-lastPos); 11049 pw.println(); 11050 } 11051 } 11052 } 11053 } 11054 } 11055 11056 if (dumpPackage == null) { 11057 pw.println(); 11058 needSep = false; 11059 pw.println(" mStartedUsers:"); 11060 for (int i=0; i<mStartedUsers.size(); i++) { 11061 UserStartedState uss = mStartedUsers.valueAt(i); 11062 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier()); 11063 pw.print(": "); uss.dump("", pw); 11064 } 11065 pw.print(" mStartedUserArray: ["); 11066 for (int i=0; i<mStartedUserArray.length; i++) { 11067 if (i > 0) pw.print(", "); 11068 pw.print(mStartedUserArray[i]); 11069 } 11070 pw.println("]"); 11071 pw.print(" mUserLru: ["); 11072 for (int i=0; i<mUserLru.size(); i++) { 11073 if (i > 0) pw.print(", "); 11074 pw.print(mUserLru.get(i)); 11075 } 11076 pw.println("]"); 11077 if (dumpAll) { 11078 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray)); 11079 } 11080 } 11081 if (mHomeProcess != null && (dumpPackage == null 11082 || mHomeProcess.pkgList.containsKey(dumpPackage))) { 11083 if (needSep) { 11084 pw.println(); 11085 needSep = false; 11086 } 11087 pw.println(" mHomeProcess: " + mHomeProcess); 11088 } 11089 if (mPreviousProcess != null && (dumpPackage == null 11090 || mPreviousProcess.pkgList.containsKey(dumpPackage))) { 11091 if (needSep) { 11092 pw.println(); 11093 needSep = false; 11094 } 11095 pw.println(" mPreviousProcess: " + mPreviousProcess); 11096 } 11097 if (dumpAll) { 11098 StringBuilder sb = new StringBuilder(128); 11099 sb.append(" mPreviousProcessVisibleTime: "); 11100 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb); 11101 pw.println(sb); 11102 } 11103 if (mHeavyWeightProcess != null && (dumpPackage == null 11104 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) { 11105 if (needSep) { 11106 pw.println(); 11107 needSep = false; 11108 } 11109 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11110 } 11111 if (dumpPackage == null) { 11112 pw.println(" mConfiguration: " + mConfiguration); 11113 } 11114 if (dumpAll) { 11115 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange); 11116 if (mCompatModePackages.getPackages().size() > 0) { 11117 boolean printed = false; 11118 for (Map.Entry<String, Integer> entry 11119 : mCompatModePackages.getPackages().entrySet()) { 11120 String pkg = entry.getKey(); 11121 int mode = entry.getValue(); 11122 if (dumpPackage != null && !dumpPackage.equals(pkg)) { 11123 continue; 11124 } 11125 if (!printed) { 11126 pw.println(" mScreenCompatPackages:"); 11127 printed = true; 11128 } 11129 pw.print(" "); pw.print(pkg); pw.print(": "); 11130 pw.print(mode); pw.println(); 11131 } 11132 } 11133 } 11134 if (dumpPackage == null) { 11135 if (mSleeping || mWentToSleep || mLockScreenShown) { 11136 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep 11137 + " mLockScreenShown " + mLockScreenShown); 11138 } 11139 if (mShuttingDown) { 11140 pw.println(" mShuttingDown=" + mShuttingDown); 11141 } 11142 } 11143 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient 11144 || mOrigWaitForDebugger) { 11145 if (dumpPackage == null || dumpPackage.equals(mDebugApp) 11146 || dumpPackage.equals(mOrigDebugApp)) { 11147 if (needSep) { 11148 pw.println(); 11149 needSep = false; 11150 } 11151 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp 11152 + " mDebugTransient=" + mDebugTransient 11153 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger); 11154 } 11155 } 11156 if (mOpenGlTraceApp != null) { 11157 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) { 11158 if (needSep) { 11159 pw.println(); 11160 needSep = false; 11161 } 11162 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp); 11163 } 11164 } 11165 if (mProfileApp != null || mProfileProc != null || mProfileFile != null 11166 || mProfileFd != null) { 11167 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) { 11168 if (needSep) { 11169 pw.println(); 11170 needSep = false; 11171 } 11172 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc); 11173 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd); 11174 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler=" 11175 + mAutoStopProfiler); 11176 } 11177 } 11178 if (dumpPackage == null) { 11179 if (mAlwaysFinishActivities || mController != null) { 11180 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities 11181 + " mController=" + mController); 11182 } 11183 if (dumpAll) { 11184 pw.println(" Total persistent processes: " + numPers); 11185 pw.println(" mProcessesReady=" + mProcessesReady 11186 + " mSystemReady=" + mSystemReady); 11187 pw.println(" mBooting=" + mBooting 11188 + " mBooted=" + mBooted 11189 + " mFactoryTest=" + mFactoryTest); 11190 pw.print(" mLastPowerCheckRealtime="); 11191 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw); 11192 pw.println(""); 11193 pw.print(" mLastPowerCheckUptime="); 11194 TimeUtils.formatDuration(mLastPowerCheckUptime, pw); 11195 pw.println(""); 11196 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep); 11197 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity); 11198 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq); 11199 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 11200 + " (" + mLruProcesses.size() + " total)" 11201 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 11202 + " mNumServiceProcs=" + mNumServiceProcs 11203 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 11204 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel 11205 + " mLastMemoryLevel" + mLastMemoryLevel 11206 + " mLastNumProcesses" + mLastNumProcesses); 11207 long now = SystemClock.uptimeMillis(); 11208 pw.print(" mLastIdleTime="); 11209 TimeUtils.formatDuration(now, mLastIdleTime, pw); 11210 pw.print(" mLowRamSinceLastIdle="); 11211 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw); 11212 pw.println(); 11213 } 11214 } 11215 11216 if (!printedAnything) { 11217 pw.println(" (nothing)"); 11218 } 11219 } 11220 11221 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, 11222 int opti, boolean needSep, boolean dumpAll, String dumpPackage) { 11223 if (mProcessesToGc.size() > 0) { 11224 boolean printed = false; 11225 long now = SystemClock.uptimeMillis(); 11226 for (int i=0; i<mProcessesToGc.size(); i++) { 11227 ProcessRecord proc = mProcessesToGc.get(i); 11228 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) { 11229 continue; 11230 } 11231 if (!printed) { 11232 if (needSep) pw.println(); 11233 needSep = true; 11234 pw.println(" Processes that are waiting to GC:"); 11235 printed = true; 11236 } 11237 pw.print(" Process "); pw.println(proc); 11238 pw.print(" lowMem="); pw.print(proc.reportLowMemory); 11239 pw.print(", last gced="); 11240 pw.print(now-proc.lastRequestedGc); 11241 pw.print(" ms ago, last lowMem="); 11242 pw.print(now-proc.lastLowMemory); 11243 pw.println(" ms ago"); 11244 11245 } 11246 } 11247 return needSep; 11248 } 11249 11250 void printOomLevel(PrintWriter pw, String name, int adj) { 11251 pw.print(" "); 11252 if (adj >= 0) { 11253 pw.print(' '); 11254 if (adj < 10) pw.print(' '); 11255 } else { 11256 if (adj > -10) pw.print(' '); 11257 } 11258 pw.print(adj); 11259 pw.print(": "); 11260 pw.print(name); 11261 pw.print(" ("); 11262 pw.print(mProcessList.getMemLevel(adj)/1024); 11263 pw.println(" kB)"); 11264 } 11265 11266 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11267 int opti, boolean dumpAll) { 11268 boolean needSep = false; 11269 11270 if (mLruProcesses.size() > 0) { 11271 if (needSep) pw.println(); 11272 needSep = true; 11273 pw.println(" OOM levels:"); 11274 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ); 11275 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ); 11276 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ); 11277 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ); 11278 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ); 11279 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ); 11280 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ); 11281 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ); 11282 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ); 11283 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ); 11284 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ); 11285 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ); 11286 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ); 11287 11288 if (needSep) pw.println(); 11289 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size()); 11290 pw.print(" total, non-act at "); 11291 pw.print(mLruProcesses.size()-mLruProcessActivityStart); 11292 pw.print(", non-svc at "); 11293 pw.print(mLruProcesses.size()-mLruProcessServiceStart); 11294 pw.println("):"); 11295 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null); 11296 needSep = true; 11297 } 11298 11299 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null); 11300 11301 pw.println(); 11302 pw.println(" mHomeProcess: " + mHomeProcess); 11303 pw.println(" mPreviousProcess: " + mPreviousProcess); 11304 if (mHeavyWeightProcess != null) { 11305 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess); 11306 } 11307 11308 return true; 11309 } 11310 11311 /** 11312 * There are three ways to call this: 11313 * - no provider specified: dump all the providers 11314 * - a flattened component name that matched an existing provider was specified as the 11315 * first arg: dump that one provider 11316 * - the first arg isn't the flattened component name of an existing provider: 11317 * dump all providers whose component contains the first arg as a substring 11318 */ 11319 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11320 int opti, boolean dumpAll) { 11321 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll); 11322 } 11323 11324 static class ItemMatcher { 11325 ArrayList<ComponentName> components; 11326 ArrayList<String> strings; 11327 ArrayList<Integer> objects; 11328 boolean all; 11329 11330 ItemMatcher() { 11331 all = true; 11332 } 11333 11334 void build(String name) { 11335 ComponentName componentName = ComponentName.unflattenFromString(name); 11336 if (componentName != null) { 11337 if (components == null) { 11338 components = new ArrayList<ComponentName>(); 11339 } 11340 components.add(componentName); 11341 all = false; 11342 } else { 11343 int objectId = 0; 11344 // Not a '/' separated full component name; maybe an object ID? 11345 try { 11346 objectId = Integer.parseInt(name, 16); 11347 if (objects == null) { 11348 objects = new ArrayList<Integer>(); 11349 } 11350 objects.add(objectId); 11351 all = false; 11352 } catch (RuntimeException e) { 11353 // Not an integer; just do string match. 11354 if (strings == null) { 11355 strings = new ArrayList<String>(); 11356 } 11357 strings.add(name); 11358 all = false; 11359 } 11360 } 11361 } 11362 11363 int build(String[] args, int opti) { 11364 for (; opti<args.length; opti++) { 11365 String name = args[opti]; 11366 if ("--".equals(name)) { 11367 return opti+1; 11368 } 11369 build(name); 11370 } 11371 return opti; 11372 } 11373 11374 boolean match(Object object, ComponentName comp) { 11375 if (all) { 11376 return true; 11377 } 11378 if (components != null) { 11379 for (int i=0; i<components.size(); i++) { 11380 if (components.get(i).equals(comp)) { 11381 return true; 11382 } 11383 } 11384 } 11385 if (objects != null) { 11386 for (int i=0; i<objects.size(); i++) { 11387 if (System.identityHashCode(object) == objects.get(i)) { 11388 return true; 11389 } 11390 } 11391 } 11392 if (strings != null) { 11393 String flat = comp.flattenToString(); 11394 for (int i=0; i<strings.size(); i++) { 11395 if (flat.contains(strings.get(i))) { 11396 return true; 11397 } 11398 } 11399 } 11400 return false; 11401 } 11402 } 11403 11404 /** 11405 * There are three things that cmd can be: 11406 * - a flattened component name that matches an existing activity 11407 * - the cmd arg isn't the flattened component name of an existing activity: 11408 * dump all activity whose component contains the cmd as a substring 11409 * - A hex number of the ActivityRecord object instance. 11410 */ 11411 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, 11412 int opti, boolean dumpAll) { 11413 ArrayList<ActivityRecord> activities; 11414 11415 synchronized (this) { 11416 activities = mStackSupervisor.getDumpActivitiesLocked(name); 11417 } 11418 11419 if (activities.size() <= 0) { 11420 return false; 11421 } 11422 11423 String[] newArgs = new String[args.length - opti]; 11424 System.arraycopy(args, opti, newArgs, 0, args.length - opti); 11425 11426 TaskRecord lastTask = null; 11427 boolean needSep = false; 11428 for (int i=activities.size()-1; i>=0; i--) { 11429 ActivityRecord r = activities.get(i); 11430 if (needSep) { 11431 pw.println(); 11432 } 11433 needSep = true; 11434 synchronized (this) { 11435 if (lastTask != r.task) { 11436 lastTask = r.task; 11437 pw.print("TASK "); pw.print(lastTask.affinity); 11438 pw.print(" id="); pw.println(lastTask.taskId); 11439 if (dumpAll) { 11440 lastTask.dump(pw, " "); 11441 } 11442 } 11443 } 11444 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll); 11445 } 11446 return true; 11447 } 11448 11449 /** 11450 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if 11451 * there is a thread associated with the activity. 11452 */ 11453 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, 11454 final ActivityRecord r, String[] args, boolean dumpAll) { 11455 String innerPrefix = prefix + " "; 11456 synchronized (this) { 11457 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName); 11458 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r))); 11459 pw.print(" pid="); 11460 if (r.app != null) pw.println(r.app.pid); 11461 else pw.println("(not running)"); 11462 if (dumpAll) { 11463 r.dump(pw, innerPrefix); 11464 } 11465 } 11466 if (r.app != null && r.app.thread != null) { 11467 // flush anything that is already in the PrintWriter since the thread is going 11468 // to write to the file descriptor directly 11469 pw.flush(); 11470 try { 11471 TransferPipe tp = new TransferPipe(); 11472 try { 11473 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), 11474 r.appToken, innerPrefix, args); 11475 tp.go(fd); 11476 } finally { 11477 tp.kill(); 11478 } 11479 } catch (IOException e) { 11480 pw.println(innerPrefix + "Failure while dumping the activity: " + e); 11481 } catch (RemoteException e) { 11482 pw.println(innerPrefix + "Got a RemoteException while dumping the activity"); 11483 } 11484 } 11485 } 11486 11487 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11488 int opti, boolean dumpAll, String dumpPackage) { 11489 boolean needSep = false; 11490 boolean onlyHistory = false; 11491 boolean printedAnything = false; 11492 11493 if ("history".equals(dumpPackage)) { 11494 if (opti < args.length && "-s".equals(args[opti])) { 11495 dumpAll = false; 11496 } 11497 onlyHistory = true; 11498 dumpPackage = null; 11499 } 11500 11501 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)"); 11502 if (!onlyHistory && dumpAll) { 11503 if (mRegisteredReceivers.size() > 0) { 11504 boolean printed = false; 11505 Iterator it = mRegisteredReceivers.values().iterator(); 11506 while (it.hasNext()) { 11507 ReceiverList r = (ReceiverList)it.next(); 11508 if (dumpPackage != null && (r.app == null || 11509 !dumpPackage.equals(r.app.info.packageName))) { 11510 continue; 11511 } 11512 if (!printed) { 11513 pw.println(" Registered Receivers:"); 11514 needSep = true; 11515 printed = true; 11516 printedAnything = true; 11517 } 11518 pw.print(" * "); pw.println(r); 11519 r.dump(pw, " "); 11520 } 11521 } 11522 11523 if (mReceiverResolver.dump(pw, needSep ? 11524 "\n Receiver Resolver Table:" : " Receiver Resolver Table:", 11525 " ", dumpPackage, false)) { 11526 needSep = true; 11527 printedAnything = true; 11528 } 11529 } 11530 11531 for (BroadcastQueue q : mBroadcastQueues) { 11532 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep); 11533 printedAnything |= needSep; 11534 } 11535 11536 needSep = true; 11537 11538 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) { 11539 for (int user=0; user<mStickyBroadcasts.size(); user++) { 11540 if (needSep) { 11541 pw.println(); 11542 } 11543 needSep = true; 11544 printedAnything = true; 11545 pw.print(" Sticky broadcasts for user "); 11546 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":"); 11547 StringBuilder sb = new StringBuilder(128); 11548 for (Map.Entry<String, ArrayList<Intent>> ent 11549 : mStickyBroadcasts.valueAt(user).entrySet()) { 11550 pw.print(" * Sticky action "); pw.print(ent.getKey()); 11551 if (dumpAll) { 11552 pw.println(":"); 11553 ArrayList<Intent> intents = ent.getValue(); 11554 final int N = intents.size(); 11555 for (int i=0; i<N; i++) { 11556 sb.setLength(0); 11557 sb.append(" Intent: "); 11558 intents.get(i).toShortString(sb, false, true, false, false); 11559 pw.println(sb.toString()); 11560 Bundle bundle = intents.get(i).getExtras(); 11561 if (bundle != null) { 11562 pw.print(" "); 11563 pw.println(bundle.toString()); 11564 } 11565 } 11566 } else { 11567 pw.println(""); 11568 } 11569 } 11570 } 11571 } 11572 11573 if (!onlyHistory && dumpAll) { 11574 pw.println(); 11575 for (BroadcastQueue queue : mBroadcastQueues) { 11576 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]=" 11577 + queue.mBroadcastsScheduled); 11578 } 11579 pw.println(" mHandler:"); 11580 mHandler.dump(new PrintWriterPrinter(pw), " "); 11581 needSep = true; 11582 printedAnything = true; 11583 } 11584 11585 if (!printedAnything) { 11586 pw.println(" (nothing)"); 11587 } 11588 } 11589 11590 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11591 int opti, boolean dumpAll, String dumpPackage) { 11592 boolean needSep; 11593 boolean printedAnything = false; 11594 11595 ItemMatcher matcher = new ItemMatcher(); 11596 matcher.build(args, opti); 11597 11598 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)"); 11599 11600 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage); 11601 printedAnything |= needSep; 11602 11603 if (mLaunchingProviders.size() > 0) { 11604 boolean printed = false; 11605 for (int i=mLaunchingProviders.size()-1; i>=0; i--) { 11606 ContentProviderRecord r = mLaunchingProviders.get(i); 11607 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) { 11608 continue; 11609 } 11610 if (!printed) { 11611 if (needSep) pw.println(); 11612 needSep = true; 11613 pw.println(" Launching content providers:"); 11614 printed = true; 11615 printedAnything = true; 11616 } 11617 pw.print(" Launching #"); pw.print(i); pw.print(": "); 11618 pw.println(r); 11619 } 11620 } 11621 11622 if (mGrantedUriPermissions.size() > 0) { 11623 boolean printed = false; 11624 int dumpUid = -2; 11625 if (dumpPackage != null) { 11626 try { 11627 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0); 11628 } catch (NameNotFoundException e) { 11629 dumpUid = -1; 11630 } 11631 } 11632 for (int i=0; i<mGrantedUriPermissions.size(); i++) { 11633 int uid = mGrantedUriPermissions.keyAt(i); 11634 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) { 11635 continue; 11636 } 11637 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i); 11638 if (!printed) { 11639 if (needSep) pw.println(); 11640 needSep = true; 11641 pw.println(" Granted Uri Permissions:"); 11642 printed = true; 11643 printedAnything = true; 11644 } 11645 pw.print(" * UID "); pw.print(uid); pw.println(" holds:"); 11646 for (UriPermission perm : perms.values()) { 11647 pw.print(" "); pw.println(perm); 11648 if (dumpAll) { 11649 perm.dump(pw, " "); 11650 } 11651 } 11652 } 11653 } 11654 11655 if (!printedAnything) { 11656 pw.println(" (nothing)"); 11657 } 11658 } 11659 11660 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, 11661 int opti, boolean dumpAll, String dumpPackage) { 11662 boolean printed = false; 11663 11664 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)"); 11665 11666 if (mIntentSenderRecords.size() > 0) { 11667 Iterator<WeakReference<PendingIntentRecord>> it 11668 = mIntentSenderRecords.values().iterator(); 11669 while (it.hasNext()) { 11670 WeakReference<PendingIntentRecord> ref = it.next(); 11671 PendingIntentRecord rec = ref != null ? ref.get(): null; 11672 if (dumpPackage != null && (rec == null 11673 || !dumpPackage.equals(rec.key.packageName))) { 11674 continue; 11675 } 11676 printed = true; 11677 if (rec != null) { 11678 pw.print(" * "); pw.println(rec); 11679 if (dumpAll) { 11680 rec.dump(pw, " "); 11681 } 11682 } else { 11683 pw.print(" * "); pw.println(ref); 11684 } 11685 } 11686 } 11687 11688 if (!printed) { 11689 pw.println(" (nothing)"); 11690 } 11691 } 11692 11693 private static final int dumpProcessList(PrintWriter pw, 11694 ActivityManagerService service, List list, 11695 String prefix, String normalLabel, String persistentLabel, 11696 String dumpPackage) { 11697 int numPers = 0; 11698 final int N = list.size()-1; 11699 for (int i=N; i>=0; i--) { 11700 ProcessRecord r = (ProcessRecord)list.get(i); 11701 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) { 11702 continue; 11703 } 11704 pw.println(String.format("%s%s #%2d: %s", 11705 prefix, (r.persistent ? persistentLabel : normalLabel), 11706 i, r.toString())); 11707 if (r.persistent) { 11708 numPers++; 11709 } 11710 } 11711 return numPers; 11712 } 11713 11714 private static final boolean dumpProcessOomList(PrintWriter pw, 11715 ActivityManagerService service, List<ProcessRecord> origList, 11716 String prefix, String normalLabel, String persistentLabel, 11717 boolean inclDetails, String dumpPackage) { 11718 11719 ArrayList<Pair<ProcessRecord, Integer>> list 11720 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size()); 11721 for (int i=0; i<origList.size(); i++) { 11722 ProcessRecord r = origList.get(i); 11723 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) { 11724 continue; 11725 } 11726 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i)); 11727 } 11728 11729 if (list.size() <= 0) { 11730 return false; 11731 } 11732 11733 Comparator<Pair<ProcessRecord, Integer>> comparator 11734 = new Comparator<Pair<ProcessRecord, Integer>>() { 11735 @Override 11736 public int compare(Pair<ProcessRecord, Integer> object1, 11737 Pair<ProcessRecord, Integer> object2) { 11738 if (object1.first.setAdj != object2.first.setAdj) { 11739 return object1.first.setAdj > object2.first.setAdj ? -1 : 1; 11740 } 11741 if (object1.second.intValue() != object2.second.intValue()) { 11742 return object1.second.intValue() > object2.second.intValue() ? -1 : 1; 11743 } 11744 return 0; 11745 } 11746 }; 11747 11748 Collections.sort(list, comparator); 11749 11750 final long curRealtime = SystemClock.elapsedRealtime(); 11751 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime; 11752 final long curUptime = SystemClock.uptimeMillis(); 11753 final long uptimeSince = curUptime - service.mLastPowerCheckUptime; 11754 11755 for (int i=list.size()-1; i>=0; i--) { 11756 ProcessRecord r = list.get(i).first; 11757 String oomAdj = ProcessList.makeOomAdjString(r.setAdj); 11758 char schedGroup; 11759 switch (r.setSchedGroup) { 11760 case Process.THREAD_GROUP_BG_NONINTERACTIVE: 11761 schedGroup = 'B'; 11762 break; 11763 case Process.THREAD_GROUP_DEFAULT: 11764 schedGroup = 'F'; 11765 break; 11766 default: 11767 schedGroup = '?'; 11768 break; 11769 } 11770 char foreground; 11771 if (r.foregroundActivities) { 11772 foreground = 'A'; 11773 } else if (r.foregroundServices) { 11774 foreground = 'S'; 11775 } else { 11776 foreground = ' '; 11777 } 11778 String procState = ProcessList.makeProcStateString(r.curProcState); 11779 pw.print(prefix); 11780 pw.print(r.persistent ? persistentLabel : normalLabel); 11781 pw.print(" #"); 11782 int num = (origList.size()-1)-list.get(i).second; 11783 if (num < 10) pw.print(' '); 11784 pw.print(num); 11785 pw.print(": "); 11786 pw.print(oomAdj); 11787 pw.print(' '); 11788 pw.print(schedGroup); 11789 pw.print('/'); 11790 pw.print(foreground); 11791 pw.print('/'); 11792 pw.print(procState); 11793 pw.print(" trm:"); 11794 if (r.trimMemoryLevel < 10) pw.print(' '); 11795 pw.print(r.trimMemoryLevel); 11796 pw.print(' '); 11797 pw.print(r.toShortString()); 11798 pw.print(" ("); 11799 pw.print(r.adjType); 11800 pw.println(')'); 11801 if (r.adjSource != null || r.adjTarget != null) { 11802 pw.print(prefix); 11803 pw.print(" "); 11804 if (r.adjTarget instanceof ComponentName) { 11805 pw.print(((ComponentName)r.adjTarget).flattenToShortString()); 11806 } else if (r.adjTarget != null) { 11807 pw.print(r.adjTarget.toString()); 11808 } else { 11809 pw.print("{null}"); 11810 } 11811 pw.print("<="); 11812 if (r.adjSource instanceof ProcessRecord) { 11813 pw.print("Proc{"); 11814 pw.print(((ProcessRecord)r.adjSource).toShortString()); 11815 pw.println("}"); 11816 } else if (r.adjSource != null) { 11817 pw.println(r.adjSource.toString()); 11818 } else { 11819 pw.println("{null}"); 11820 } 11821 } 11822 if (inclDetails) { 11823 pw.print(prefix); 11824 pw.print(" "); 11825 pw.print("oom: max="); pw.print(r.maxAdj); 11826 pw.print(" curRaw="); pw.print(r.curRawAdj); 11827 pw.print(" setRaw="); pw.print(r.setRawAdj); 11828 pw.print(" cur="); pw.print(r.curAdj); 11829 pw.print(" set="); pw.println(r.setAdj); 11830 pw.print(prefix); 11831 pw.print(" "); 11832 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState)); 11833 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState)); 11834 pw.print(" lastPss="); pw.print(r.lastPss); 11835 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss); 11836 pw.print(prefix); 11837 pw.print(" "); 11838 pw.print("keeping="); pw.print(r.keeping); 11839 pw.print(" cached="); pw.print(r.cached); 11840 pw.print(" empty="); pw.print(r.empty); 11841 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient); 11842 11843 if (!r.keeping) { 11844 if (r.lastWakeTime != 0) { 11845 long wtime; 11846 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics(); 11847 synchronized (stats) { 11848 wtime = stats.getProcessWakeTime(r.info.uid, 11849 r.pid, curRealtime); 11850 } 11851 long timeUsed = wtime - r.lastWakeTime; 11852 pw.print(prefix); 11853 pw.print(" "); 11854 pw.print("keep awake over "); 11855 TimeUtils.formatDuration(realtimeSince, pw); 11856 pw.print(" used "); 11857 TimeUtils.formatDuration(timeUsed, pw); 11858 pw.print(" ("); 11859 pw.print((timeUsed*100)/realtimeSince); 11860 pw.println("%)"); 11861 } 11862 if (r.lastCpuTime != 0) { 11863 long timeUsed = r.curCpuTime - r.lastCpuTime; 11864 pw.print(prefix); 11865 pw.print(" "); 11866 pw.print("run cpu over "); 11867 TimeUtils.formatDuration(uptimeSince, pw); 11868 pw.print(" used "); 11869 TimeUtils.formatDuration(timeUsed, pw); 11870 pw.print(" ("); 11871 pw.print((timeUsed*100)/uptimeSince); 11872 pw.println("%)"); 11873 } 11874 } 11875 } 11876 } 11877 return true; 11878 } 11879 11880 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) { 11881 ArrayList<ProcessRecord> procs; 11882 synchronized (this) { 11883 if (args != null && args.length > start 11884 && args[start].charAt(0) != '-') { 11885 procs = new ArrayList<ProcessRecord>(); 11886 int pid = -1; 11887 try { 11888 pid = Integer.parseInt(args[start]); 11889 } catch (NumberFormatException e) { 11890 } 11891 for (int i=mLruProcesses.size()-1; i>=0; i--) { 11892 ProcessRecord proc = mLruProcesses.get(i); 11893 if (proc.pid == pid) { 11894 procs.add(proc); 11895 } else if (proc.processName.equals(args[start])) { 11896 procs.add(proc); 11897 } 11898 } 11899 if (procs.size() <= 0) { 11900 return null; 11901 } 11902 } else { 11903 procs = new ArrayList<ProcessRecord>(mLruProcesses); 11904 } 11905 } 11906 return procs; 11907 } 11908 11909 final void dumpGraphicsHardwareUsage(FileDescriptor fd, 11910 PrintWriter pw, String[] args) { 11911 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11912 if (procs == null) { 11913 pw.println("No process found for: " + args[0]); 11914 return; 11915 } 11916 11917 long uptime = SystemClock.uptimeMillis(); 11918 long realtime = SystemClock.elapsedRealtime(); 11919 pw.println("Applications Graphics Acceleration Info:"); 11920 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 11921 11922 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11923 ProcessRecord r = procs.get(i); 11924 if (r.thread != null) { 11925 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **"); 11926 pw.flush(); 11927 try { 11928 TransferPipe tp = new TransferPipe(); 11929 try { 11930 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args); 11931 tp.go(fd); 11932 } finally { 11933 tp.kill(); 11934 } 11935 } catch (IOException e) { 11936 pw.println("Failure while dumping the app: " + r); 11937 pw.flush(); 11938 } catch (RemoteException e) { 11939 pw.println("Got a RemoteException while dumping the app " + r); 11940 pw.flush(); 11941 } 11942 } 11943 } 11944 } 11945 11946 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) { 11947 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args); 11948 if (procs == null) { 11949 pw.println("No process found for: " + args[0]); 11950 return; 11951 } 11952 11953 pw.println("Applications Database Info:"); 11954 11955 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 11956 ProcessRecord r = procs.get(i); 11957 if (r.thread != null) { 11958 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **"); 11959 pw.flush(); 11960 try { 11961 TransferPipe tp = new TransferPipe(); 11962 try { 11963 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args); 11964 tp.go(fd); 11965 } finally { 11966 tp.kill(); 11967 } 11968 } catch (IOException e) { 11969 pw.println("Failure while dumping the app: " + r); 11970 pw.flush(); 11971 } catch (RemoteException e) { 11972 pw.println("Got a RemoteException while dumping the app " + r); 11973 pw.flush(); 11974 } 11975 } 11976 } 11977 } 11978 11979 final static class MemItem { 11980 final boolean isProc; 11981 final String label; 11982 final String shortLabel; 11983 final long pss; 11984 final int id; 11985 final boolean hasActivities; 11986 ArrayList<MemItem> subitems; 11987 11988 public MemItem(String _label, String _shortLabel, long _pss, int _id, 11989 boolean _hasActivities) { 11990 isProc = true; 11991 label = _label; 11992 shortLabel = _shortLabel; 11993 pss = _pss; 11994 id = _id; 11995 hasActivities = _hasActivities; 11996 } 11997 11998 public MemItem(String _label, String _shortLabel, long _pss, int _id) { 11999 isProc = false; 12000 label = _label; 12001 shortLabel = _shortLabel; 12002 pss = _pss; 12003 id = _id; 12004 hasActivities = false; 12005 } 12006 } 12007 12008 static final void dumpMemItems(PrintWriter pw, String prefix, String tag, 12009 ArrayList<MemItem> items, boolean sort, boolean isCompact) { 12010 if (sort && !isCompact) { 12011 Collections.sort(items, new Comparator<MemItem>() { 12012 @Override 12013 public int compare(MemItem lhs, MemItem rhs) { 12014 if (lhs.pss < rhs.pss) { 12015 return 1; 12016 } else if (lhs.pss > rhs.pss) { 12017 return -1; 12018 } 12019 return 0; 12020 } 12021 }); 12022 } 12023 12024 for (int i=0; i<items.size(); i++) { 12025 MemItem mi = items.get(i); 12026 if (!isCompact) { 12027 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); 12028 } else if (mi.isProc) { 12029 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel); 12030 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); 12031 pw.println(mi.hasActivities ? ",a" : ",e"); 12032 } else { 12033 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(","); 12034 pw.println(mi.pss); 12035 } 12036 if (mi.subitems != null) { 12037 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems, 12038 true, isCompact); 12039 } 12040 } 12041 } 12042 12043 // These are in KB. 12044 static final long[] DUMP_MEM_BUCKETS = new long[] { 12045 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, 12046 120*1024, 160*1024, 200*1024, 12047 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, 12048 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 12049 }; 12050 12051 static final void appendMemBucket(StringBuilder out, long memKB, String label, 12052 boolean stackLike) { 12053 int start = label.lastIndexOf('.'); 12054 if (start >= 0) start++; 12055 else start = 0; 12056 int end = label.length(); 12057 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { 12058 if (DUMP_MEM_BUCKETS[i] >= memKB) { 12059 long bucket = DUMP_MEM_BUCKETS[i]/1024; 12060 out.append(bucket); 12061 out.append(stackLike ? "MB." : "MB "); 12062 out.append(label, start, end); 12063 return; 12064 } 12065 } 12066 out.append(memKB/1024); 12067 out.append(stackLike ? "MB." : "MB "); 12068 out.append(label, start, end); 12069 } 12070 12071 static final int[] DUMP_MEM_OOM_ADJ = new int[] { 12072 ProcessList.NATIVE_ADJ, 12073 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, 12074 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, 12075 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, 12076 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, 12077 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ 12078 }; 12079 static final String[] DUMP_MEM_OOM_LABEL = new String[] { 12080 "Native", 12081 "System", "Persistent", "Foreground", 12082 "Visible", "Perceptible", 12083 "Heavy Weight", "Backup", 12084 "A Services", "Home", 12085 "Previous", "B Services", "Cached" 12086 }; 12087 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] { 12088 "native", 12089 "sys", "pers", "fore", 12090 "vis", "percept", 12091 "heavy", "backup", 12092 "servicea", "home", 12093 "prev", "serviceb", "cached" 12094 }; 12095 12096 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, 12097 long realtime, boolean isCheckinRequest, boolean isCompact) { 12098 if (isCheckinRequest || isCompact) { 12099 // short checkin version 12100 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime); 12101 } else { 12102 pw.println("Applications Memory Usage (kB):"); 12103 pw.println("Uptime: " + uptime + " Realtime: " + realtime); 12104 } 12105 } 12106 12107 final void dumpApplicationMemoryUsage(FileDescriptor fd, 12108 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { 12109 boolean dumpDetails = false; 12110 boolean dumpFullDetails = false; 12111 boolean dumpDalvik = false; 12112 boolean oomOnly = false; 12113 boolean isCompact = false; 12114 boolean localOnly = false; 12115 12116 int opti = 0; 12117 while (opti < args.length) { 12118 String opt = args[opti]; 12119 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { 12120 break; 12121 } 12122 opti++; 12123 if ("-a".equals(opt)) { 12124 dumpDetails = true; 12125 dumpFullDetails = true; 12126 dumpDalvik = true; 12127 } else if ("-d".equals(opt)) { 12128 dumpDalvik = true; 12129 } else if ("-c".equals(opt)) { 12130 isCompact = true; 12131 } else if ("--oom".equals(opt)) { 12132 oomOnly = true; 12133 } else if ("--local".equals(opt)) { 12134 localOnly = true; 12135 } else if ("-h".equals(opt)) { 12136 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]"); 12137 pw.println(" -a: include all available information for each process."); 12138 pw.println(" -d: include dalvik details when dumping process details."); 12139 pw.println(" -c: dump in a compact machine-parseable representation."); 12140 pw.println(" --oom: only show processes organized by oom adj."); 12141 pw.println(" --local: only collect details locally, don't call process."); 12142 pw.println("If [process] is specified it can be the name or "); 12143 pw.println("pid of a specific process to dump."); 12144 return; 12145 } else { 12146 pw.println("Unknown argument: " + opt + "; use -h for help"); 12147 } 12148 } 12149 12150 final boolean isCheckinRequest = scanArgs(args, "--checkin"); 12151 long uptime = SystemClock.uptimeMillis(); 12152 long realtime = SystemClock.elapsedRealtime(); 12153 final long[] tmpLong = new long[1]; 12154 12155 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args); 12156 if (procs == null) { 12157 // No Java processes. Maybe they want to print a native process. 12158 if (args != null && args.length > opti 12159 && args[opti].charAt(0) != '-') { 12160 ArrayList<ProcessCpuTracker.Stats> nativeProcs 12161 = new ArrayList<ProcessCpuTracker.Stats>(); 12162 updateCpuStatsNow(); 12163 int findPid = -1; 12164 try { 12165 findPid = Integer.parseInt(args[opti]); 12166 } catch (NumberFormatException e) { 12167 } 12168 synchronized (mProcessCpuThread) { 12169 final int N = mProcessCpuTracker.countStats(); 12170 for (int i=0; i<N; i++) { 12171 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12172 if (st.pid == findPid || (st.baseName != null 12173 && st.baseName.equals(args[opti]))) { 12174 nativeProcs.add(st); 12175 } 12176 } 12177 } 12178 if (nativeProcs.size() > 0) { 12179 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, 12180 isCompact); 12181 Debug.MemoryInfo mi = null; 12182 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) { 12183 final ProcessCpuTracker.Stats r = nativeProcs.get(i); 12184 final int pid = r.pid; 12185 if (!isCheckinRequest && dumpDetails) { 12186 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **"); 12187 } 12188 if (mi == null) { 12189 mi = new Debug.MemoryInfo(); 12190 } 12191 if (dumpDetails || (!brief && !oomOnly)) { 12192 Debug.getMemoryInfo(pid, mi); 12193 } else { 12194 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12195 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12196 } 12197 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12198 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0); 12199 if (isCheckinRequest) { 12200 pw.println(); 12201 } 12202 } 12203 return; 12204 } 12205 } 12206 pw.println("No process found for: " + args[opti]); 12207 return; 12208 } 12209 12210 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) { 12211 dumpDetails = true; 12212 } 12213 12214 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact); 12215 12216 String[] innerArgs = new String[args.length-opti]; 12217 System.arraycopy(args, opti, innerArgs, 0, args.length-opti); 12218 12219 ArrayList<MemItem> procMems = new ArrayList<MemItem>(); 12220 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>(); 12221 long nativePss=0, dalvikPss=0, otherPss=0; 12222 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; 12223 12224 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; 12225 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) 12226 new ArrayList[DUMP_MEM_OOM_LABEL.length]; 12227 12228 long totalPss = 0; 12229 long cachedPss = 0; 12230 12231 Debug.MemoryInfo mi = null; 12232 for (int i = procs.size() - 1 ; i >= 0 ; i--) { 12233 final ProcessRecord r = procs.get(i); 12234 final IApplicationThread thread; 12235 final int pid; 12236 final int oomAdj; 12237 final boolean hasActivities; 12238 synchronized (this) { 12239 thread = r.thread; 12240 pid = r.pid; 12241 oomAdj = r.getSetAdjWithServices(); 12242 hasActivities = r.activities.size() > 0; 12243 } 12244 if (thread != null) { 12245 if (!isCheckinRequest && dumpDetails) { 12246 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **"); 12247 } 12248 if (mi == null) { 12249 mi = new Debug.MemoryInfo(); 12250 } 12251 if (dumpDetails || (!brief && !oomOnly)) { 12252 Debug.getMemoryInfo(pid, mi); 12253 } else { 12254 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong); 12255 mi.dalvikPrivateDirty = (int)tmpLong[0]; 12256 } 12257 if (dumpDetails) { 12258 if (localOnly) { 12259 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails, 12260 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0); 12261 if (isCheckinRequest) { 12262 pw.println(); 12263 } 12264 } else { 12265 try { 12266 pw.flush(); 12267 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails, 12268 dumpDalvik, innerArgs); 12269 } catch (RemoteException e) { 12270 if (!isCheckinRequest) { 12271 pw.println("Got RemoteException!"); 12272 pw.flush(); 12273 } 12274 } 12275 } 12276 } 12277 12278 final long myTotalPss = mi.getTotalPss(); 12279 final long myTotalUss = mi.getTotalUss(); 12280 12281 synchronized (this) { 12282 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) { 12283 // Record this for posterity if the process has been stable. 12284 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList); 12285 } 12286 } 12287 12288 if (!isCheckinRequest && mi != null) { 12289 totalPss += myTotalPss; 12290 MemItem pssItem = new MemItem(r.processName + " (pid " + pid + 12291 (hasActivities ? " / activities)" : ")"), 12292 r.processName, myTotalPss, pid, hasActivities); 12293 procMems.add(pssItem); 12294 procMemsMap.put(pid, pssItem); 12295 12296 nativePss += mi.nativePss; 12297 dalvikPss += mi.dalvikPss; 12298 otherPss += mi.otherPss; 12299 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12300 long mem = mi.getOtherPss(j); 12301 miscPss[j] += mem; 12302 otherPss -= mem; 12303 } 12304 12305 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 12306 cachedPss += myTotalPss; 12307 } 12308 12309 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { 12310 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] 12311 || oomIndex == (oomPss.length-1)) { 12312 oomPss[oomIndex] += myTotalPss; 12313 if (oomProcs[oomIndex] == null) { 12314 oomProcs[oomIndex] = new ArrayList<MemItem>(); 12315 } 12316 oomProcs[oomIndex].add(pssItem); 12317 break; 12318 } 12319 } 12320 } 12321 } 12322 } 12323 12324 if (!isCheckinRequest && procs.size() > 1) { 12325 // If we are showing aggregations, also look for native processes to 12326 // include so that our aggregations are more accurate. 12327 updateCpuStatsNow(); 12328 synchronized (mProcessCpuThread) { 12329 final int N = mProcessCpuTracker.countStats(); 12330 for (int i=0; i<N; i++) { 12331 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i); 12332 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) { 12333 if (mi == null) { 12334 mi = new Debug.MemoryInfo(); 12335 } 12336 if (!brief && !oomOnly) { 12337 Debug.getMemoryInfo(st.pid, mi); 12338 } else { 12339 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong); 12340 mi.nativePrivateDirty = (int)tmpLong[0]; 12341 } 12342 12343 final long myTotalPss = mi.getTotalPss(); 12344 totalPss += myTotalPss; 12345 12346 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")", 12347 st.name, myTotalPss, st.pid, false); 12348 procMems.add(pssItem); 12349 12350 nativePss += mi.nativePss; 12351 dalvikPss += mi.dalvikPss; 12352 otherPss += mi.otherPss; 12353 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12354 long mem = mi.getOtherPss(j); 12355 miscPss[j] += mem; 12356 otherPss -= mem; 12357 } 12358 oomPss[0] += myTotalPss; 12359 if (oomProcs[0] == null) { 12360 oomProcs[0] = new ArrayList<MemItem>(); 12361 } 12362 oomProcs[0].add(pssItem); 12363 } 12364 } 12365 } 12366 12367 ArrayList<MemItem> catMems = new ArrayList<MemItem>(); 12368 12369 catMems.add(new MemItem("Native", "Native", nativePss, -1)); 12370 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); 12371 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); 12372 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { 12373 String label = Debug.MemoryInfo.getOtherLabel(j); 12374 catMems.add(new MemItem(label, label, miscPss[j], j)); 12375 } 12376 12377 ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); 12378 for (int j=0; j<oomPss.length; j++) { 12379 if (oomPss[j] != 0) { 12380 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j] 12381 : DUMP_MEM_OOM_LABEL[j]; 12382 MemItem item = new MemItem(label, label, oomPss[j], 12383 DUMP_MEM_OOM_ADJ[j]); 12384 item.subitems = oomProcs[j]; 12385 oomMems.add(item); 12386 } 12387 } 12388 12389 if (!brief && !oomOnly && !isCompact) { 12390 pw.println(); 12391 pw.println("Total PSS by process:"); 12392 dumpMemItems(pw, " ", "proc", procMems, true, isCompact); 12393 pw.println(); 12394 } 12395 if (!isCompact) { 12396 pw.println("Total PSS by OOM adjustment:"); 12397 } 12398 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact); 12399 if (!brief && !oomOnly) { 12400 PrintWriter out = categoryPw != null ? categoryPw : pw; 12401 if (!isCompact) { 12402 out.println(); 12403 out.println("Total PSS by category:"); 12404 } 12405 dumpMemItems(out, " ", "cat", catMems, true, isCompact); 12406 } 12407 if (!isCompact) { 12408 pw.println(); 12409 } 12410 MemInfoReader memInfo = new MemInfoReader(); 12411 memInfo.readMemInfo(); 12412 if (!brief) { 12413 if (!isCompact) { 12414 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb()); 12415 pw.print(" kB (status "); 12416 switch (mLastMemoryLevel) { 12417 case ProcessStats.ADJ_MEM_FACTOR_NORMAL: 12418 pw.println("normal)"); 12419 break; 12420 case ProcessStats.ADJ_MEM_FACTOR_MODERATE: 12421 pw.println("moderate)"); 12422 break; 12423 case ProcessStats.ADJ_MEM_FACTOR_LOW: 12424 pw.println("low)"); 12425 break; 12426 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 12427 pw.println("critical)"); 12428 break; 12429 default: 12430 pw.print(mLastMemoryLevel); 12431 pw.println(")"); 12432 break; 12433 } 12434 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb() 12435 + memInfo.getFreeSizeKb()); pw.print(" kB ("); 12436 pw.print(cachedPss); pw.print(" cached pss + "); 12437 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + "); 12438 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)"); 12439 } else { 12440 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(","); 12441 pw.print(cachedPss + memInfo.getCachedSizeKb() 12442 + memInfo.getFreeSizeKb()); pw.print(","); 12443 pw.println(totalPss - cachedPss); 12444 } 12445 } 12446 if (!isCompact) { 12447 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss 12448 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb() 12449 + memInfo.getSlabSizeKb()); pw.print(" kB ("); 12450 pw.print(totalPss - cachedPss); pw.print(" used pss + "); 12451 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + "); 12452 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + "); 12453 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)"); 12454 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb() 12455 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb() 12456 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb() 12457 - memInfo.getSlabSizeKb()); pw.println(" kB"); 12458 } 12459 if (!brief) { 12460 if (memInfo.getZramTotalSizeKb() != 0) { 12461 if (!isCompact) { 12462 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb()); 12463 pw.print(" kB physical used for "); 12464 pw.print(memInfo.getSwapTotalSizeKb() 12465 - memInfo.getSwapFreeSizeKb()); 12466 pw.print(" kB in swap ("); 12467 pw.print(memInfo.getSwapTotalSizeKb()); 12468 pw.println(" kB total swap)"); 12469 } else { 12470 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(","); 12471 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(","); 12472 pw.println(memInfo.getSwapFreeSizeKb()); 12473 } 12474 } 12475 final int[] SINGLE_LONG_FORMAT = new int[] { 12476 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG 12477 }; 12478 long[] longOut = new long[1]; 12479 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared", 12480 SINGLE_LONG_FORMAT, null, longOut, null); 12481 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12482 longOut[0] = 0; 12483 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing", 12484 SINGLE_LONG_FORMAT, null, longOut, null); 12485 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12486 longOut[0] = 0; 12487 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared", 12488 SINGLE_LONG_FORMAT, null, longOut, null); 12489 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12490 longOut[0] = 0; 12491 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile", 12492 SINGLE_LONG_FORMAT, null, longOut, null); 12493 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024; 12494 if (!isCompact) { 12495 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) { 12496 pw.print(" KSM: "); pw.print(sharing); 12497 pw.print(" kB saved from shared "); 12498 pw.print(shared); pw.println(" kB"); 12499 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; "); 12500 pw.print(voltile); pw.println(" kB volatile"); 12501 } 12502 pw.print(" Tuning: "); 12503 pw.print(ActivityManager.staticGetMemoryClass()); 12504 pw.print(" (large "); 12505 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12506 pw.print("), oom "); 12507 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12508 pw.print(" kB"); 12509 pw.print(", restore limit "); 12510 pw.print(mProcessList.getCachedRestoreThresholdKb()); 12511 pw.print(" kB"); 12512 if (ActivityManager.isLowRamDeviceStatic()) { 12513 pw.print(" (low-ram)"); 12514 } 12515 if (ActivityManager.isHighEndGfx()) { 12516 pw.print(" (high-end-gfx)"); 12517 } 12518 pw.println(); 12519 } else { 12520 pw.print("ksm,"); pw.print(sharing); pw.print(","); 12521 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(","); 12522 pw.println(voltile); 12523 pw.print("tuning,"); 12524 pw.print(ActivityManager.staticGetMemoryClass()); 12525 pw.print(','); 12526 pw.print(ActivityManager.staticGetLargeMemoryClass()); 12527 pw.print(','); 12528 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024); 12529 if (ActivityManager.isLowRamDeviceStatic()) { 12530 pw.print(",low-ram"); 12531 } 12532 if (ActivityManager.isHighEndGfx()) { 12533 pw.print(",high-end-gfx"); 12534 } 12535 pw.println(); 12536 } 12537 } 12538 } 12539 } 12540 12541 /** 12542 * Searches array of arguments for the specified string 12543 * @param args array of argument strings 12544 * @param value value to search for 12545 * @return true if the value is contained in the array 12546 */ 12547 private static boolean scanArgs(String[] args, String value) { 12548 if (args != null) { 12549 for (String arg : args) { 12550 if (value.equals(arg)) { 12551 return true; 12552 } 12553 } 12554 } 12555 return false; 12556 } 12557 12558 private final boolean removeDyingProviderLocked(ProcessRecord proc, 12559 ContentProviderRecord cpr, boolean always) { 12560 final boolean inLaunching = mLaunchingProviders.contains(cpr); 12561 12562 if (!inLaunching || always) { 12563 synchronized (cpr) { 12564 cpr.launchingApp = null; 12565 cpr.notifyAll(); 12566 } 12567 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid)); 12568 String names[] = cpr.info.authority.split(";"); 12569 for (int j = 0; j < names.length; j++) { 12570 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid)); 12571 } 12572 } 12573 12574 for (int i=0; i<cpr.connections.size(); i++) { 12575 ContentProviderConnection conn = cpr.connections.get(i); 12576 if (conn.waiting) { 12577 // If this connection is waiting for the provider, then we don't 12578 // need to mess with its process unless we are always removing 12579 // or for some reason the provider is not currently launching. 12580 if (inLaunching && !always) { 12581 continue; 12582 } 12583 } 12584 ProcessRecord capp = conn.client; 12585 conn.dead = true; 12586 if (conn.stableCount > 0) { 12587 if (!capp.persistent && capp.thread != null 12588 && capp.pid != 0 12589 && capp.pid != MY_PID) { 12590 killUnneededProcessLocked(capp, "depends on provider " 12591 + cpr.name.flattenToShortString() 12592 + " in dying proc " + (proc != null ? proc.processName : "??")); 12593 } 12594 } else if (capp.thread != null && conn.provider.provider != null) { 12595 try { 12596 capp.thread.unstableProviderDied(conn.provider.provider.asBinder()); 12597 } catch (RemoteException e) { 12598 } 12599 // In the protocol here, we don't expect the client to correctly 12600 // clean up this connection, we'll just remove it. 12601 cpr.connections.remove(i); 12602 conn.client.conProviders.remove(conn); 12603 } 12604 } 12605 12606 if (inLaunching && always) { 12607 mLaunchingProviders.remove(cpr); 12608 } 12609 return inLaunching; 12610 } 12611 12612 /** 12613 * Main code for cleaning up a process when it has gone away. This is 12614 * called both as a result of the process dying, or directly when stopping 12615 * a process when running in single process mode. 12616 */ 12617 private final void cleanUpApplicationRecordLocked(ProcessRecord app, 12618 boolean restarting, boolean allowRestart, int index) { 12619 if (index >= 0) { 12620 removeLruProcessLocked(app); 12621 ProcessList.remove(app.pid); 12622 } 12623 12624 mProcessesToGc.remove(app); 12625 mPendingPssProcesses.remove(app); 12626 12627 // Dismiss any open dialogs. 12628 if (app.crashDialog != null && !app.forceCrashReport) { 12629 app.crashDialog.dismiss(); 12630 app.crashDialog = null; 12631 } 12632 if (app.anrDialog != null) { 12633 app.anrDialog.dismiss(); 12634 app.anrDialog = null; 12635 } 12636 if (app.waitDialog != null) { 12637 app.waitDialog.dismiss(); 12638 app.waitDialog = null; 12639 } 12640 12641 app.crashing = false; 12642 app.notResponding = false; 12643 12644 app.resetPackageList(mProcessStats); 12645 app.unlinkDeathRecipient(); 12646 app.makeInactive(mProcessStats); 12647 app.forcingToForeground = null; 12648 updateProcessForegroundLocked(app, false, false); 12649 app.foregroundActivities = false; 12650 app.hasShownUi = false; 12651 app.treatLikeActivity = false; 12652 app.hasAboveClient = false; 12653 app.hasClientActivities = false; 12654 12655 mServices.killServicesLocked(app, allowRestart); 12656 12657 boolean restart = false; 12658 12659 // Remove published content providers. 12660 for (int i=app.pubProviders.size()-1; i>=0; i--) { 12661 ContentProviderRecord cpr = app.pubProviders.valueAt(i); 12662 final boolean always = app.bad || !allowRestart; 12663 if (removeDyingProviderLocked(app, cpr, always) || always) { 12664 // We left the provider in the launching list, need to 12665 // restart it. 12666 restart = true; 12667 } 12668 12669 cpr.provider = null; 12670 cpr.proc = null; 12671 } 12672 app.pubProviders.clear(); 12673 12674 // Take care of any launching providers waiting for this process. 12675 if (checkAppInLaunchingProvidersLocked(app, false)) { 12676 restart = true; 12677 } 12678 12679 // Unregister from connected content providers. 12680 if (!app.conProviders.isEmpty()) { 12681 for (int i=0; i<app.conProviders.size(); i++) { 12682 ContentProviderConnection conn = app.conProviders.get(i); 12683 conn.provider.connections.remove(conn); 12684 } 12685 app.conProviders.clear(); 12686 } 12687 12688 // At this point there may be remaining entries in mLaunchingProviders 12689 // where we were the only one waiting, so they are no longer of use. 12690 // Look for these and clean up if found. 12691 // XXX Commented out for now. Trying to figure out a way to reproduce 12692 // the actual situation to identify what is actually going on. 12693 if (false) { 12694 for (int i=0; i<mLaunchingProviders.size(); i++) { 12695 ContentProviderRecord cpr = (ContentProviderRecord) 12696 mLaunchingProviders.get(i); 12697 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) { 12698 synchronized (cpr) { 12699 cpr.launchingApp = null; 12700 cpr.notifyAll(); 12701 } 12702 } 12703 } 12704 } 12705 12706 skipCurrentReceiverLocked(app); 12707 12708 // Unregister any receivers. 12709 for (int i=app.receivers.size()-1; i>=0; i--) { 12710 removeReceiverLocked(app.receivers.valueAt(i)); 12711 } 12712 app.receivers.clear(); 12713 12714 // If the app is undergoing backup, tell the backup manager about it 12715 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) { 12716 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App " 12717 + mBackupTarget.appInfo + " died during backup"); 12718 try { 12719 IBackupManager bm = IBackupManager.Stub.asInterface( 12720 ServiceManager.getService(Context.BACKUP_SERVICE)); 12721 bm.agentDisconnected(app.info.packageName); 12722 } catch (RemoteException e) { 12723 // can't happen; backup manager is local 12724 } 12725 } 12726 12727 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) { 12728 ProcessChangeItem item = mPendingProcessChanges.get(i); 12729 if (item.pid == app.pid) { 12730 mPendingProcessChanges.remove(i); 12731 mAvailProcessChanges.add(item); 12732 } 12733 } 12734 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget(); 12735 12736 // If the caller is restarting this app, then leave it in its 12737 // current lists and let the caller take care of it. 12738 if (restarting) { 12739 return; 12740 } 12741 12742 if (!app.persistent || app.isolated) { 12743 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, 12744 "Removing non-persistent process during cleanup: " + app); 12745 mProcessNames.remove(app.processName, app.uid); 12746 mIsolatedProcesses.remove(app.uid); 12747 if (mHeavyWeightProcess == app) { 12748 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG, 12749 mHeavyWeightProcess.userId, 0)); 12750 mHeavyWeightProcess = null; 12751 } 12752 } else if (!app.removed) { 12753 // This app is persistent, so we need to keep its record around. 12754 // If it is not already on the pending app list, add it there 12755 // and start a new process for it. 12756 if (mPersistentStartingProcesses.indexOf(app) < 0) { 12757 mPersistentStartingProcesses.add(app); 12758 restart = true; 12759 } 12760 } 12761 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG, 12762 "Clean-up removing on hold: " + app); 12763 mProcessesOnHold.remove(app); 12764 12765 if (app == mHomeProcess) { 12766 mHomeProcess = null; 12767 } 12768 if (app == mPreviousProcess) { 12769 mPreviousProcess = null; 12770 } 12771 12772 if (restart && !app.isolated) { 12773 // We have components that still need to be running in the 12774 // process, so re-launch it. 12775 mProcessNames.put(app.processName, app.uid, app); 12776 startProcessLocked(app, "restart", app.processName); 12777 } else if (app.pid > 0 && app.pid != MY_PID) { 12778 // Goodbye! 12779 boolean removed; 12780 synchronized (mPidsSelfLocked) { 12781 mPidsSelfLocked.remove(app.pid); 12782 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 12783 } 12784 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH, 12785 app.processName, app.info.uid); 12786 if (app.isolated) { 12787 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 12788 } 12789 app.setPid(0); 12790 } 12791 } 12792 12793 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { 12794 // Look through the content providers we are waiting to have launched, 12795 // and if any run in this process then either schedule a restart of 12796 // the process or kill the client waiting for it if this process has 12797 // gone bad. 12798 int NL = mLaunchingProviders.size(); 12799 boolean restart = false; 12800 for (int i=0; i<NL; i++) { 12801 ContentProviderRecord cpr = mLaunchingProviders.get(i); 12802 if (cpr.launchingApp == app) { 12803 if (!alwaysBad && !app.bad) { 12804 restart = true; 12805 } else { 12806 removeDyingProviderLocked(app, cpr, true); 12807 // cpr should have been removed from mLaunchingProviders 12808 NL = mLaunchingProviders.size(); 12809 i--; 12810 } 12811 } 12812 } 12813 return restart; 12814 } 12815 12816 // ========================================================= 12817 // SERVICES 12818 // ========================================================= 12819 12820 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum, 12821 int flags) { 12822 enforceNotIsolatedCaller("getServices"); 12823 synchronized (this) { 12824 return mServices.getRunningServiceInfoLocked(maxNum, flags); 12825 } 12826 } 12827 12828 public PendingIntent getRunningServiceControlPanel(ComponentName name) { 12829 enforceNotIsolatedCaller("getRunningServiceControlPanel"); 12830 synchronized (this) { 12831 return mServices.getRunningServiceControlPanelLocked(name); 12832 } 12833 } 12834 12835 public ComponentName startService(IApplicationThread caller, Intent service, 12836 String resolvedType, int userId) { 12837 enforceNotIsolatedCaller("startService"); 12838 // Refuse possible leaked file descriptors 12839 if (service != null && service.hasFileDescriptors() == true) { 12840 throw new IllegalArgumentException("File descriptors passed in Intent"); 12841 } 12842 12843 if (DEBUG_SERVICE) 12844 Slog.v(TAG, "startService: " + service + " type=" + resolvedType); 12845 synchronized(this) { 12846 final int callingPid = Binder.getCallingPid(); 12847 final int callingUid = Binder.getCallingUid(); 12848 final long origId = Binder.clearCallingIdentity(); 12849 ComponentName res = mServices.startServiceLocked(caller, service, 12850 resolvedType, callingPid, callingUid, userId); 12851 Binder.restoreCallingIdentity(origId); 12852 return res; 12853 } 12854 } 12855 12856 ComponentName startServiceInPackage(int uid, 12857 Intent service, String resolvedType, int userId) { 12858 synchronized(this) { 12859 if (DEBUG_SERVICE) 12860 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType); 12861 final long origId = Binder.clearCallingIdentity(); 12862 ComponentName res = mServices.startServiceLocked(null, service, 12863 resolvedType, -1, uid, userId); 12864 Binder.restoreCallingIdentity(origId); 12865 return res; 12866 } 12867 } 12868 12869 public int stopService(IApplicationThread caller, Intent service, 12870 String resolvedType, int userId) { 12871 enforceNotIsolatedCaller("stopService"); 12872 // Refuse possible leaked file descriptors 12873 if (service != null && service.hasFileDescriptors() == true) { 12874 throw new IllegalArgumentException("File descriptors passed in Intent"); 12875 } 12876 12877 synchronized(this) { 12878 return mServices.stopServiceLocked(caller, service, resolvedType, userId); 12879 } 12880 } 12881 12882 public IBinder peekService(Intent service, String resolvedType) { 12883 enforceNotIsolatedCaller("peekService"); 12884 // Refuse possible leaked file descriptors 12885 if (service != null && service.hasFileDescriptors() == true) { 12886 throw new IllegalArgumentException("File descriptors passed in Intent"); 12887 } 12888 synchronized(this) { 12889 return mServices.peekServiceLocked(service, resolvedType); 12890 } 12891 } 12892 12893 public boolean stopServiceToken(ComponentName className, IBinder token, 12894 int startId) { 12895 synchronized(this) { 12896 return mServices.stopServiceTokenLocked(className, token, startId); 12897 } 12898 } 12899 12900 public void setServiceForeground(ComponentName className, IBinder token, 12901 int id, Notification notification, boolean removeNotification) { 12902 synchronized(this) { 12903 mServices.setServiceForegroundLocked(className, token, id, notification, 12904 removeNotification); 12905 } 12906 } 12907 12908 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, 12909 boolean requireFull, String name, String callerPackage) { 12910 final int callingUserId = UserHandle.getUserId(callingUid); 12911 if (callingUserId != userId) { 12912 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) { 12913 if ((requireFull || checkComponentPermission( 12914 android.Manifest.permission.INTERACT_ACROSS_USERS, 12915 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) 12916 && checkComponentPermission( 12917 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, 12918 callingPid, callingUid, -1, true) 12919 != PackageManager.PERMISSION_GRANTED) { 12920 if (userId == UserHandle.USER_CURRENT_OR_SELF) { 12921 // In this case, they would like to just execute as their 12922 // owner user instead of failing. 12923 userId = callingUserId; 12924 } else { 12925 StringBuilder builder = new StringBuilder(128); 12926 builder.append("Permission Denial: "); 12927 builder.append(name); 12928 if (callerPackage != null) { 12929 builder.append(" from "); 12930 builder.append(callerPackage); 12931 } 12932 builder.append(" asks to run as user "); 12933 builder.append(userId); 12934 builder.append(" but is calling from user "); 12935 builder.append(UserHandle.getUserId(callingUid)); 12936 builder.append("; this requires "); 12937 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); 12938 if (!requireFull) { 12939 builder.append(" or "); 12940 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS); 12941 } 12942 String msg = builder.toString(); 12943 Slog.w(TAG, msg); 12944 throw new SecurityException(msg); 12945 } 12946 } 12947 } 12948 if (userId == UserHandle.USER_CURRENT 12949 || userId == UserHandle.USER_CURRENT_OR_SELF) { 12950 // Note that we may be accessing this outside of a lock... 12951 // shouldn't be a big deal, if this is being called outside 12952 // of a locked context there is intrinsically a race with 12953 // the value the caller will receive and someone else changing it. 12954 userId = mCurrentUserId; 12955 } 12956 if (!allowAll && userId < 0) { 12957 throw new IllegalArgumentException( 12958 "Call does not support special user #" + userId); 12959 } 12960 } 12961 return userId; 12962 } 12963 12964 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo, 12965 String className, int flags) { 12966 boolean result = false; 12967 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) { 12968 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) { 12969 if (ActivityManager.checkUidPermission( 12970 android.Manifest.permission.INTERACT_ACROSS_USERS, 12971 aInfo.uid) != PackageManager.PERMISSION_GRANTED) { 12972 ComponentName comp = new ComponentName(aInfo.packageName, className); 12973 String msg = "Permission Denial: Component " + comp.flattenToShortString() 12974 + " requests FLAG_SINGLE_USER, but app does not hold " 12975 + android.Manifest.permission.INTERACT_ACROSS_USERS; 12976 Slog.w(TAG, msg); 12977 throw new SecurityException(msg); 12978 } 12979 result = true; 12980 } 12981 } else if (componentProcessName == aInfo.packageName) { 12982 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0; 12983 } else if ("system".equals(componentProcessName)) { 12984 result = true; 12985 } 12986 if (DEBUG_MU) { 12987 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo 12988 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result); 12989 } 12990 return result; 12991 } 12992 12993 public int bindService(IApplicationThread caller, IBinder token, 12994 Intent service, String resolvedType, 12995 IServiceConnection connection, int flags, int userId) { 12996 enforceNotIsolatedCaller("bindService"); 12997 // Refuse possible leaked file descriptors 12998 if (service != null && service.hasFileDescriptors() == true) { 12999 throw new IllegalArgumentException("File descriptors passed in Intent"); 13000 } 13001 13002 synchronized(this) { 13003 return mServices.bindServiceLocked(caller, token, service, resolvedType, 13004 connection, flags, userId); 13005 } 13006 } 13007 13008 public boolean unbindService(IServiceConnection connection) { 13009 synchronized (this) { 13010 return mServices.unbindServiceLocked(connection); 13011 } 13012 } 13013 13014 public void publishService(IBinder token, Intent intent, IBinder service) { 13015 // Refuse possible leaked file descriptors 13016 if (intent != null && intent.hasFileDescriptors() == true) { 13017 throw new IllegalArgumentException("File descriptors passed in Intent"); 13018 } 13019 13020 synchronized(this) { 13021 if (!(token instanceof ServiceRecord)) { 13022 throw new IllegalArgumentException("Invalid service token"); 13023 } 13024 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 13025 } 13026 } 13027 13028 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) { 13029 // Refuse possible leaked file descriptors 13030 if (intent != null && intent.hasFileDescriptors() == true) { 13031 throw new IllegalArgumentException("File descriptors passed in Intent"); 13032 } 13033 13034 synchronized(this) { 13035 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind); 13036 } 13037 } 13038 13039 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) { 13040 synchronized(this) { 13041 if (!(token instanceof ServiceRecord)) { 13042 throw new IllegalArgumentException("Invalid service token"); 13043 } 13044 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res); 13045 } 13046 } 13047 13048 // ========================================================= 13049 // BACKUP AND RESTORE 13050 // ========================================================= 13051 13052 // Cause the target app to be launched if necessary and its backup agent 13053 // instantiated. The backup agent will invoke backupAgentCreated() on the 13054 // activity manager to announce its creation. 13055 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) { 13056 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode); 13057 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent"); 13058 13059 synchronized(this) { 13060 // !!! TODO: currently no check here that we're already bound 13061 BatteryStatsImpl.Uid.Pkg.Serv ss = null; 13062 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 13063 synchronized (stats) { 13064 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name); 13065 } 13066 13067 // Backup agent is now in use, its package can't be stopped. 13068 try { 13069 AppGlobals.getPackageManager().setPackageStoppedState( 13070 app.packageName, false, UserHandle.getUserId(app.uid)); 13071 } catch (RemoteException e) { 13072 } catch (IllegalArgumentException e) { 13073 Slog.w(TAG, "Failed trying to unstop package " 13074 + app.packageName + ": " + e); 13075 } 13076 13077 BackupRecord r = new BackupRecord(ss, app, backupMode); 13078 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) 13079 ? new ComponentName(app.packageName, app.backupAgentName) 13080 : new ComponentName("android", "FullBackupAgent"); 13081 // startProcessLocked() returns existing proc's record if it's already running 13082 ProcessRecord proc = startProcessLocked(app.processName, app, 13083 false, 0, "backup", hostingName, false, false, false); 13084 if (proc == null) { 13085 Slog.e(TAG, "Unable to start backup agent process " + r); 13086 return false; 13087 } 13088 13089 r.app = proc; 13090 mBackupTarget = r; 13091 mBackupAppName = app.packageName; 13092 13093 // Try not to kill the process during backup 13094 updateOomAdjLocked(proc); 13095 13096 // If the process is already attached, schedule the creation of the backup agent now. 13097 // If it is not yet live, this will be done when it attaches to the framework. 13098 if (proc.thread != null) { 13099 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc); 13100 try { 13101 proc.thread.scheduleCreateBackupAgent(app, 13102 compatibilityInfoForPackageLocked(app), backupMode); 13103 } catch (RemoteException e) { 13104 // Will time out on the backup manager side 13105 } 13106 } else { 13107 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach"); 13108 } 13109 // Invariants: at this point, the target app process exists and the application 13110 // is either already running or in the process of coming up. mBackupTarget and 13111 // mBackupAppName describe the app, so that when it binds back to the AM we 13112 // know that it's scheduled for a backup-agent operation. 13113 } 13114 13115 return true; 13116 } 13117 13118 @Override 13119 public void clearPendingBackup() { 13120 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup"); 13121 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup"); 13122 13123 synchronized (this) { 13124 mBackupTarget = null; 13125 mBackupAppName = null; 13126 } 13127 } 13128 13129 // A backup agent has just come up 13130 public void backupAgentCreated(String agentPackageName, IBinder agent) { 13131 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName 13132 + " = " + agent); 13133 13134 synchronized(this) { 13135 if (!agentPackageName.equals(mBackupAppName)) { 13136 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!"); 13137 return; 13138 } 13139 } 13140 13141 long oldIdent = Binder.clearCallingIdentity(); 13142 try { 13143 IBackupManager bm = IBackupManager.Stub.asInterface( 13144 ServiceManager.getService(Context.BACKUP_SERVICE)); 13145 bm.agentConnected(agentPackageName, agent); 13146 } catch (RemoteException e) { 13147 // can't happen; the backup manager service is local 13148 } catch (Exception e) { 13149 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: "); 13150 e.printStackTrace(); 13151 } finally { 13152 Binder.restoreCallingIdentity(oldIdent); 13153 } 13154 } 13155 13156 // done with this agent 13157 public void unbindBackupAgent(ApplicationInfo appInfo) { 13158 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo); 13159 if (appInfo == null) { 13160 Slog.w(TAG, "unbind backup agent for null app"); 13161 return; 13162 } 13163 13164 synchronized(this) { 13165 try { 13166 if (mBackupAppName == null) { 13167 Slog.w(TAG, "Unbinding backup agent with no active backup"); 13168 return; 13169 } 13170 13171 if (!mBackupAppName.equals(appInfo.packageName)) { 13172 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target"); 13173 return; 13174 } 13175 13176 // Not backing this app up any more; reset its OOM adjustment 13177 final ProcessRecord proc = mBackupTarget.app; 13178 updateOomAdjLocked(proc); 13179 13180 // If the app crashed during backup, 'thread' will be null here 13181 if (proc.thread != null) { 13182 try { 13183 proc.thread.scheduleDestroyBackupAgent(appInfo, 13184 compatibilityInfoForPackageLocked(appInfo)); 13185 } catch (Exception e) { 13186 Slog.e(TAG, "Exception when unbinding backup agent:"); 13187 e.printStackTrace(); 13188 } 13189 } 13190 } finally { 13191 mBackupTarget = null; 13192 mBackupAppName = null; 13193 } 13194 } 13195 } 13196 // ========================================================= 13197 // BROADCASTS 13198 // ========================================================= 13199 13200 private final List getStickiesLocked(String action, IntentFilter filter, 13201 List cur, int userId) { 13202 final ContentResolver resolver = mContext.getContentResolver(); 13203 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13204 if (stickies == null) { 13205 return cur; 13206 } 13207 final ArrayList<Intent> list = stickies.get(action); 13208 if (list == null) { 13209 return cur; 13210 } 13211 int N = list.size(); 13212 for (int i=0; i<N; i++) { 13213 Intent intent = list.get(i); 13214 if (filter.match(resolver, intent, true, TAG) >= 0) { 13215 if (cur == null) { 13216 cur = new ArrayList<Intent>(); 13217 } 13218 cur.add(intent); 13219 } 13220 } 13221 return cur; 13222 } 13223 13224 boolean isPendingBroadcastProcessLocked(int pid) { 13225 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid) 13226 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid); 13227 } 13228 13229 void skipPendingBroadcastLocked(int pid) { 13230 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping"); 13231 for (BroadcastQueue queue : mBroadcastQueues) { 13232 queue.skipPendingBroadcastLocked(pid); 13233 } 13234 } 13235 13236 // The app just attached; send any pending broadcasts that it should receive 13237 boolean sendPendingBroadcastsLocked(ProcessRecord app) { 13238 boolean didSomething = false; 13239 for (BroadcastQueue queue : mBroadcastQueues) { 13240 didSomething |= queue.sendPendingBroadcastsLocked(app); 13241 } 13242 return didSomething; 13243 } 13244 13245 public Intent registerReceiver(IApplicationThread caller, String callerPackage, 13246 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) { 13247 enforceNotIsolatedCaller("registerReceiver"); 13248 int callingUid; 13249 int callingPid; 13250 synchronized(this) { 13251 ProcessRecord callerApp = null; 13252 if (caller != null) { 13253 callerApp = getRecordForAppLocked(caller); 13254 if (callerApp == null) { 13255 throw new SecurityException( 13256 "Unable to find app for caller " + caller 13257 + " (pid=" + Binder.getCallingPid() 13258 + ") when registering receiver " + receiver); 13259 } 13260 if (callerApp.info.uid != Process.SYSTEM_UID && 13261 !callerApp.pkgList.containsKey(callerPackage) && 13262 !"android".equals(callerPackage)) { 13263 throw new SecurityException("Given caller package " + callerPackage 13264 + " is not running in process " + callerApp); 13265 } 13266 callingUid = callerApp.info.uid; 13267 callingPid = callerApp.pid; 13268 } else { 13269 callerPackage = null; 13270 callingUid = Binder.getCallingUid(); 13271 callingPid = Binder.getCallingPid(); 13272 } 13273 13274 userId = this.handleIncomingUser(callingPid, callingUid, userId, 13275 true, true, "registerReceiver", callerPackage); 13276 13277 List allSticky = null; 13278 13279 // Look for any matching sticky broadcasts... 13280 Iterator actions = filter.actionsIterator(); 13281 if (actions != null) { 13282 while (actions.hasNext()) { 13283 String action = (String)actions.next(); 13284 allSticky = getStickiesLocked(action, filter, allSticky, 13285 UserHandle.USER_ALL); 13286 allSticky = getStickiesLocked(action, filter, allSticky, 13287 UserHandle.getUserId(callingUid)); 13288 } 13289 } else { 13290 allSticky = getStickiesLocked(null, filter, allSticky, 13291 UserHandle.USER_ALL); 13292 allSticky = getStickiesLocked(null, filter, allSticky, 13293 UserHandle.getUserId(callingUid)); 13294 } 13295 13296 // The first sticky in the list is returned directly back to 13297 // the client. 13298 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null; 13299 13300 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter 13301 + ": " + sticky); 13302 13303 if (receiver == null) { 13304 return sticky; 13305 } 13306 13307 ReceiverList rl 13308 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder()); 13309 if (rl == null) { 13310 rl = new ReceiverList(this, callerApp, callingPid, callingUid, 13311 userId, receiver); 13312 if (rl.app != null) { 13313 rl.app.receivers.add(rl); 13314 } else { 13315 try { 13316 receiver.asBinder().linkToDeath(rl, 0); 13317 } catch (RemoteException e) { 13318 return sticky; 13319 } 13320 rl.linkedToDeath = true; 13321 } 13322 mRegisteredReceivers.put(receiver.asBinder(), rl); 13323 } else if (rl.uid != callingUid) { 13324 throw new IllegalArgumentException( 13325 "Receiver requested to register for uid " + callingUid 13326 + " was previously registered for uid " + rl.uid); 13327 } else if (rl.pid != callingPid) { 13328 throw new IllegalArgumentException( 13329 "Receiver requested to register for pid " + callingPid 13330 + " was previously registered for pid " + rl.pid); 13331 } else if (rl.userId != userId) { 13332 throw new IllegalArgumentException( 13333 "Receiver requested to register for user " + userId 13334 + " was previously registered for user " + rl.userId); 13335 } 13336 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, 13337 permission, callingUid, userId); 13338 rl.add(bf); 13339 if (!bf.debugCheck()) { 13340 Slog.w(TAG, "==> For Dynamic broadast"); 13341 } 13342 mReceiverResolver.addFilter(bf); 13343 13344 // Enqueue broadcasts for all existing stickies that match 13345 // this filter. 13346 if (allSticky != null) { 13347 ArrayList receivers = new ArrayList(); 13348 receivers.add(bf); 13349 13350 int N = allSticky.size(); 13351 for (int i=0; i<N; i++) { 13352 Intent intent = (Intent)allSticky.get(i); 13353 BroadcastQueue queue = broadcastQueueForIntent(intent); 13354 BroadcastRecord r = new BroadcastRecord(queue, intent, null, 13355 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0, 13356 null, null, false, true, true, -1); 13357 queue.enqueueParallelBroadcastLocked(r); 13358 queue.scheduleBroadcastsLocked(); 13359 } 13360 } 13361 13362 return sticky; 13363 } 13364 } 13365 13366 public void unregisterReceiver(IIntentReceiver receiver) { 13367 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver); 13368 13369 final long origId = Binder.clearCallingIdentity(); 13370 try { 13371 boolean doTrim = false; 13372 13373 synchronized(this) { 13374 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); 13375 if (rl != null) { 13376 if (rl.curBroadcast != null) { 13377 BroadcastRecord r = rl.curBroadcast; 13378 final boolean doNext = finishReceiverLocked( 13379 receiver.asBinder(), r.resultCode, r.resultData, 13380 r.resultExtras, r.resultAbort); 13381 if (doNext) { 13382 doTrim = true; 13383 r.queue.processNextBroadcast(false); 13384 } 13385 } 13386 13387 if (rl.app != null) { 13388 rl.app.receivers.remove(rl); 13389 } 13390 removeReceiverLocked(rl); 13391 if (rl.linkedToDeath) { 13392 rl.linkedToDeath = false; 13393 rl.receiver.asBinder().unlinkToDeath(rl, 0); 13394 } 13395 } 13396 } 13397 13398 // If we actually concluded any broadcasts, we might now be able 13399 // to trim the recipients' apps from our working set 13400 if (doTrim) { 13401 trimApplications(); 13402 return; 13403 } 13404 13405 } finally { 13406 Binder.restoreCallingIdentity(origId); 13407 } 13408 } 13409 13410 void removeReceiverLocked(ReceiverList rl) { 13411 mRegisteredReceivers.remove(rl.receiver.asBinder()); 13412 int N = rl.size(); 13413 for (int i=0; i<N; i++) { 13414 mReceiverResolver.removeFilter(rl.get(i)); 13415 } 13416 } 13417 13418 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 13419 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 13420 ProcessRecord r = mLruProcesses.get(i); 13421 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 13422 try { 13423 r.thread.dispatchPackageBroadcast(cmd, packages); 13424 } catch (RemoteException ex) { 13425 } 13426 } 13427 } 13428 } 13429 13430 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType, 13431 int[] users) { 13432 List<ResolveInfo> receivers = null; 13433 try { 13434 HashSet<ComponentName> singleUserReceivers = null; 13435 boolean scannedFirstReceivers = false; 13436 for (int user : users) { 13437 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager() 13438 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user); 13439 if (user != 0 && newReceivers != null) { 13440 // If this is not the primary user, we need to check for 13441 // any receivers that should be filtered out. 13442 for (int i=0; i<newReceivers.size(); i++) { 13443 ResolveInfo ri = newReceivers.get(i); 13444 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) { 13445 newReceivers.remove(i); 13446 i--; 13447 } 13448 } 13449 } 13450 if (newReceivers != null && newReceivers.size() == 0) { 13451 newReceivers = null; 13452 } 13453 if (receivers == null) { 13454 receivers = newReceivers; 13455 } else if (newReceivers != null) { 13456 // We need to concatenate the additional receivers 13457 // found with what we have do far. This would be easy, 13458 // but we also need to de-dup any receivers that are 13459 // singleUser. 13460 if (!scannedFirstReceivers) { 13461 // Collect any single user receivers we had already retrieved. 13462 scannedFirstReceivers = true; 13463 for (int i=0; i<receivers.size(); i++) { 13464 ResolveInfo ri = receivers.get(i); 13465 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13466 ComponentName cn = new ComponentName( 13467 ri.activityInfo.packageName, ri.activityInfo.name); 13468 if (singleUserReceivers == null) { 13469 singleUserReceivers = new HashSet<ComponentName>(); 13470 } 13471 singleUserReceivers.add(cn); 13472 } 13473 } 13474 } 13475 // Add the new results to the existing results, tracking 13476 // and de-dupping single user receivers. 13477 for (int i=0; i<newReceivers.size(); i++) { 13478 ResolveInfo ri = newReceivers.get(i); 13479 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) { 13480 ComponentName cn = new ComponentName( 13481 ri.activityInfo.packageName, ri.activityInfo.name); 13482 if (singleUserReceivers == null) { 13483 singleUserReceivers = new HashSet<ComponentName>(); 13484 } 13485 if (!singleUserReceivers.contains(cn)) { 13486 singleUserReceivers.add(cn); 13487 receivers.add(ri); 13488 } 13489 } else { 13490 receivers.add(ri); 13491 } 13492 } 13493 } 13494 } 13495 } catch (RemoteException ex) { 13496 // pm is in same process, this will never happen. 13497 } 13498 return receivers; 13499 } 13500 13501 private final int broadcastIntentLocked(ProcessRecord callerApp, 13502 String callerPackage, Intent intent, String resolvedType, 13503 IIntentReceiver resultTo, int resultCode, String resultData, 13504 Bundle map, String requiredPermission, int appOp, 13505 boolean ordered, boolean sticky, int callingPid, int callingUid, 13506 int userId) { 13507 intent = new Intent(intent); 13508 13509 // By default broadcasts do not go to stopped apps. 13510 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 13511 13512 if (DEBUG_BROADCAST_LIGHT) Slog.v( 13513 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent 13514 + " ordered=" + ordered + " userid=" + userId); 13515 if ((resultTo != null) && !ordered) { 13516 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); 13517 } 13518 13519 userId = handleIncomingUser(callingPid, callingUid, userId, 13520 true, false, "broadcast", callerPackage); 13521 13522 // Make sure that the user who is receiving this broadcast is started. 13523 // If not, we will just skip it. 13524 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) { 13525 if (callingUid != Process.SYSTEM_UID || (intent.getFlags() 13526 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) { 13527 Slog.w(TAG, "Skipping broadcast of " + intent 13528 + ": user " + userId + " is stopped"); 13529 return ActivityManager.BROADCAST_SUCCESS; 13530 } 13531 } 13532 13533 /* 13534 * Prevent non-system code (defined here to be non-persistent 13535 * processes) from sending protected broadcasts. 13536 */ 13537 int callingAppId = UserHandle.getAppId(callingUid); 13538 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID 13539 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID || 13540 callingUid == 0) { 13541 // Always okay. 13542 } else if (callerApp == null || !callerApp.persistent) { 13543 try { 13544 if (AppGlobals.getPackageManager().isProtectedBroadcast( 13545 intent.getAction())) { 13546 String msg = "Permission Denial: not allowed to send broadcast " 13547 + intent.getAction() + " from pid=" 13548 + callingPid + ", uid=" + callingUid; 13549 Slog.w(TAG, msg); 13550 throw new SecurityException(msg); 13551 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) { 13552 // Special case for compatibility: we don't want apps to send this, 13553 // but historically it has not been protected and apps may be using it 13554 // to poke their own app widget. So, instead of making it protected, 13555 // just limit it to the caller. 13556 if (callerApp == null) { 13557 String msg = "Permission Denial: not allowed to send broadcast " 13558 + intent.getAction() + " from unknown caller."; 13559 Slog.w(TAG, msg); 13560 throw new SecurityException(msg); 13561 } else if (intent.getComponent() != null) { 13562 // They are good enough to send to an explicit component... verify 13563 // it is being sent to the calling app. 13564 if (!intent.getComponent().getPackageName().equals( 13565 callerApp.info.packageName)) { 13566 String msg = "Permission Denial: not allowed to send broadcast " 13567 + intent.getAction() + " to " 13568 + intent.getComponent().getPackageName() + " from " 13569 + callerApp.info.packageName; 13570 Slog.w(TAG, msg); 13571 throw new SecurityException(msg); 13572 } 13573 } else { 13574 // Limit broadcast to their own package. 13575 intent.setPackage(callerApp.info.packageName); 13576 } 13577 } 13578 } catch (RemoteException e) { 13579 Slog.w(TAG, "Remote exception", e); 13580 return ActivityManager.BROADCAST_SUCCESS; 13581 } 13582 } 13583 13584 // Handle special intents: if this broadcast is from the package 13585 // manager about a package being removed, we need to remove all of 13586 // its activities from the history stack. 13587 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals( 13588 intent.getAction()); 13589 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction()) 13590 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction()) 13591 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction()) 13592 || uidRemoved) { 13593 if (checkComponentPermission( 13594 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, 13595 callingPid, callingUid, -1, true) 13596 == PackageManager.PERMISSION_GRANTED) { 13597 if (uidRemoved) { 13598 final Bundle intentExtras = intent.getExtras(); 13599 final int uid = intentExtras != null 13600 ? intentExtras.getInt(Intent.EXTRA_UID) : -1; 13601 if (uid >= 0) { 13602 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics(); 13603 synchronized (bs) { 13604 bs.removeUidStatsLocked(uid); 13605 } 13606 mAppOpsService.uidRemoved(uid); 13607 } 13608 } else { 13609 // If resources are unavailable just force stop all 13610 // those packages and flush the attribute cache as well. 13611 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) { 13612 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13613 if (list != null && (list.length > 0)) { 13614 for (String pkg : list) { 13615 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId, 13616 "storage unmount"); 13617 } 13618 sendPackageBroadcastLocked( 13619 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId); 13620 } 13621 } else { 13622 Uri data = intent.getData(); 13623 String ssp; 13624 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13625 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals( 13626 intent.getAction()); 13627 boolean fullUninstall = removed && 13628 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false); 13629 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) { 13630 forceStopPackageLocked(ssp, UserHandle.getAppId( 13631 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, 13632 false, fullUninstall, userId, 13633 removed ? "pkg removed" : "pkg changed"); 13634 } 13635 if (removed) { 13636 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED, 13637 new String[] {ssp}, userId); 13638 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { 13639 mAppOpsService.packageRemoved( 13640 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp); 13641 13642 // Remove all permissions granted from/to this package 13643 removeUriPermissionsForPackageLocked(ssp, userId, true); 13644 } 13645 } 13646 } 13647 } 13648 } 13649 } else { 13650 String msg = "Permission Denial: " + intent.getAction() 13651 + " broadcast from " + callerPackage + " (pid=" + callingPid 13652 + ", uid=" + callingUid + ")" 13653 + " requires " 13654 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED; 13655 Slog.w(TAG, msg); 13656 throw new SecurityException(msg); 13657 } 13658 13659 // Special case for adding a package: by default turn on compatibility 13660 // mode. 13661 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) { 13662 Uri data = intent.getData(); 13663 String ssp; 13664 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) { 13665 mCompatModePackages.handlePackageAddedLocked(ssp, 13666 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)); 13667 } 13668 } 13669 13670 /* 13671 * If this is the time zone changed action, queue up a message that will reset the timezone 13672 * of all currently running processes. This message will get queued up before the broadcast 13673 * happens. 13674 */ 13675 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) { 13676 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE); 13677 } 13678 13679 /* 13680 * If the user set the time, let all running processes know. 13681 */ 13682 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) { 13683 final int is24Hour = intent.getBooleanExtra( 13684 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0; 13685 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0)); 13686 } 13687 13688 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) { 13689 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG); 13690 } 13691 13692 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) { 13693 ProxyProperties proxy = intent.getParcelableExtra("proxy"); 13694 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy)); 13695 } 13696 13697 // Add to the sticky list if requested. 13698 if (sticky) { 13699 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, 13700 callingPid, callingUid) 13701 != PackageManager.PERMISSION_GRANTED) { 13702 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" 13703 + callingPid + ", uid=" + callingUid 13704 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13705 Slog.w(TAG, msg); 13706 throw new SecurityException(msg); 13707 } 13708 if (requiredPermission != null) { 13709 Slog.w(TAG, "Can't broadcast sticky intent " + intent 13710 + " and enforce permission " + requiredPermission); 13711 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION; 13712 } 13713 if (intent.getComponent() != null) { 13714 throw new SecurityException( 13715 "Sticky broadcasts can't target a specific component"); 13716 } 13717 // We use userId directly here, since the "all" target is maintained 13718 // as a separate set of sticky broadcasts. 13719 if (userId != UserHandle.USER_ALL) { 13720 // But first, if this is not a broadcast to all users, then 13721 // make sure it doesn't conflict with an existing broadcast to 13722 // all users. 13723 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get( 13724 UserHandle.USER_ALL); 13725 if (stickies != null) { 13726 ArrayList<Intent> list = stickies.get(intent.getAction()); 13727 if (list != null) { 13728 int N = list.size(); 13729 int i; 13730 for (i=0; i<N; i++) { 13731 if (intent.filterEquals(list.get(i))) { 13732 throw new IllegalArgumentException( 13733 "Sticky broadcast " + intent + " for user " 13734 + userId + " conflicts with existing global broadcast"); 13735 } 13736 } 13737 } 13738 } 13739 } 13740 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13741 if (stickies == null) { 13742 stickies = new ArrayMap<String, ArrayList<Intent>>(); 13743 mStickyBroadcasts.put(userId, stickies); 13744 } 13745 ArrayList<Intent> list = stickies.get(intent.getAction()); 13746 if (list == null) { 13747 list = new ArrayList<Intent>(); 13748 stickies.put(intent.getAction(), list); 13749 } 13750 int N = list.size(); 13751 int i; 13752 for (i=0; i<N; i++) { 13753 if (intent.filterEquals(list.get(i))) { 13754 // This sticky already exists, replace it. 13755 list.set(i, new Intent(intent)); 13756 break; 13757 } 13758 } 13759 if (i >= N) { 13760 list.add(new Intent(intent)); 13761 } 13762 } 13763 13764 int[] users; 13765 if (userId == UserHandle.USER_ALL) { 13766 // Caller wants broadcast to go to all started users. 13767 users = mStartedUserArray; 13768 } else { 13769 // Caller wants broadcast to go to one specific user. 13770 users = new int[] {userId}; 13771 } 13772 13773 // Figure out who all will receive this broadcast. 13774 List receivers = null; 13775 List<BroadcastFilter> registeredReceivers = null; 13776 // Need to resolve the intent to interested receivers... 13777 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) 13778 == 0) { 13779 receivers = collectReceiverComponents(intent, resolvedType, users); 13780 } 13781 if (intent.getComponent() == null) { 13782 registeredReceivers = mReceiverResolver.queryIntent(intent, 13783 resolvedType, false, userId); 13784 } 13785 13786 final boolean replacePending = 13787 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; 13788 13789 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction() 13790 + " replacePending=" + replacePending); 13791 13792 int NR = registeredReceivers != null ? registeredReceivers.size() : 0; 13793 if (!ordered && NR > 0) { 13794 // If we are not serializing this broadcast, then send the 13795 // registered receivers separately so they don't wait for the 13796 // components to be launched. 13797 final BroadcastQueue queue = broadcastQueueForIntent(intent); 13798 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13799 callerPackage, callingPid, callingUid, resolvedType, requiredPermission, 13800 appOp, registeredReceivers, resultTo, resultCode, resultData, map, 13801 ordered, sticky, false, userId); 13802 if (DEBUG_BROADCAST) Slog.v( 13803 TAG, "Enqueueing parallel broadcast " + r); 13804 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r); 13805 if (!replaced) { 13806 queue.enqueueParallelBroadcastLocked(r); 13807 queue.scheduleBroadcastsLocked(); 13808 } 13809 registeredReceivers = null; 13810 NR = 0; 13811 } 13812 13813 // Merge into one list. 13814 int ir = 0; 13815 if (receivers != null) { 13816 // A special case for PACKAGE_ADDED: do not allow the package 13817 // being added to see this broadcast. This prevents them from 13818 // using this as a back door to get run as soon as they are 13819 // installed. Maybe in the future we want to have a special install 13820 // broadcast or such for apps, but we'd like to deliberately make 13821 // this decision. 13822 String skipPackages[] = null; 13823 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) 13824 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) 13825 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) { 13826 Uri data = intent.getData(); 13827 if (data != null) { 13828 String pkgName = data.getSchemeSpecificPart(); 13829 if (pkgName != null) { 13830 skipPackages = new String[] { pkgName }; 13831 } 13832 } 13833 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) { 13834 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST); 13835 } 13836 if (skipPackages != null && (skipPackages.length > 0)) { 13837 for (String skipPackage : skipPackages) { 13838 if (skipPackage != null) { 13839 int NT = receivers.size(); 13840 for (int it=0; it<NT; it++) { 13841 ResolveInfo curt = (ResolveInfo)receivers.get(it); 13842 if (curt.activityInfo.packageName.equals(skipPackage)) { 13843 receivers.remove(it); 13844 it--; 13845 NT--; 13846 } 13847 } 13848 } 13849 } 13850 } 13851 13852 int NT = receivers != null ? receivers.size() : 0; 13853 int it = 0; 13854 ResolveInfo curt = null; 13855 BroadcastFilter curr = null; 13856 while (it < NT && ir < NR) { 13857 if (curt == null) { 13858 curt = (ResolveInfo)receivers.get(it); 13859 } 13860 if (curr == null) { 13861 curr = registeredReceivers.get(ir); 13862 } 13863 if (curr.getPriority() >= curt.priority) { 13864 // Insert this broadcast record into the final list. 13865 receivers.add(it, curr); 13866 ir++; 13867 curr = null; 13868 it++; 13869 NT++; 13870 } else { 13871 // Skip to the next ResolveInfo in the final list. 13872 it++; 13873 curt = null; 13874 } 13875 } 13876 } 13877 while (ir < NR) { 13878 if (receivers == null) { 13879 receivers = new ArrayList(); 13880 } 13881 receivers.add(registeredReceivers.get(ir)); 13882 ir++; 13883 } 13884 13885 if ((receivers != null && receivers.size() > 0) 13886 || resultTo != null) { 13887 BroadcastQueue queue = broadcastQueueForIntent(intent); 13888 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, 13889 callerPackage, callingPid, callingUid, resolvedType, 13890 requiredPermission, appOp, receivers, resultTo, resultCode, 13891 resultData, map, ordered, sticky, false, userId); 13892 if (DEBUG_BROADCAST) Slog.v( 13893 TAG, "Enqueueing ordered broadcast " + r 13894 + ": prev had " + queue.mOrderedBroadcasts.size()); 13895 if (DEBUG_BROADCAST) { 13896 int seq = r.intent.getIntExtra("seq", -1); 13897 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq); 13898 } 13899 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 13900 if (!replaced) { 13901 queue.enqueueOrderedBroadcastLocked(r); 13902 queue.scheduleBroadcastsLocked(); 13903 } 13904 } 13905 13906 return ActivityManager.BROADCAST_SUCCESS; 13907 } 13908 13909 final Intent verifyBroadcastLocked(Intent intent) { 13910 // Refuse possible leaked file descriptors 13911 if (intent != null && intent.hasFileDescriptors() == true) { 13912 throw new IllegalArgumentException("File descriptors passed in Intent"); 13913 } 13914 13915 int flags = intent.getFlags(); 13916 13917 if (!mProcessesReady) { 13918 // if the caller really truly claims to know what they're doing, go 13919 // ahead and allow the broadcast without launching any receivers 13920 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) { 13921 intent = new Intent(intent); 13922 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 13923 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) { 13924 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent 13925 + " before boot completion"); 13926 throw new IllegalStateException("Cannot broadcast before boot completed"); 13927 } 13928 } 13929 13930 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) { 13931 throw new IllegalArgumentException( 13932 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here"); 13933 } 13934 13935 return intent; 13936 } 13937 13938 public final int broadcastIntent(IApplicationThread caller, 13939 Intent intent, String resolvedType, IIntentReceiver resultTo, 13940 int resultCode, String resultData, Bundle map, 13941 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) { 13942 enforceNotIsolatedCaller("broadcastIntent"); 13943 synchronized(this) { 13944 intent = verifyBroadcastLocked(intent); 13945 13946 final ProcessRecord callerApp = getRecordForAppLocked(caller); 13947 final int callingPid = Binder.getCallingPid(); 13948 final int callingUid = Binder.getCallingUid(); 13949 final long origId = Binder.clearCallingIdentity(); 13950 int res = broadcastIntentLocked(callerApp, 13951 callerApp != null ? callerApp.info.packageName : null, 13952 intent, resolvedType, resultTo, 13953 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky, 13954 callingPid, callingUid, userId); 13955 Binder.restoreCallingIdentity(origId); 13956 return res; 13957 } 13958 } 13959 13960 int broadcastIntentInPackage(String packageName, int uid, 13961 Intent intent, String resolvedType, IIntentReceiver resultTo, 13962 int resultCode, String resultData, Bundle map, 13963 String requiredPermission, boolean serialized, boolean sticky, int userId) { 13964 synchronized(this) { 13965 intent = verifyBroadcastLocked(intent); 13966 13967 final long origId = Binder.clearCallingIdentity(); 13968 int res = broadcastIntentLocked(null, packageName, intent, resolvedType, 13969 resultTo, resultCode, resultData, map, requiredPermission, 13970 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId); 13971 Binder.restoreCallingIdentity(origId); 13972 return res; 13973 } 13974 } 13975 13976 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) { 13977 // Refuse possible leaked file descriptors 13978 if (intent != null && intent.hasFileDescriptors() == true) { 13979 throw new IllegalArgumentException("File descriptors passed in Intent"); 13980 } 13981 13982 userId = handleIncomingUser(Binder.getCallingPid(), 13983 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null); 13984 13985 synchronized(this) { 13986 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY) 13987 != PackageManager.PERMISSION_GRANTED) { 13988 String msg = "Permission Denial: unbroadcastIntent() from pid=" 13989 + Binder.getCallingPid() 13990 + ", uid=" + Binder.getCallingUid() 13991 + " requires " + android.Manifest.permission.BROADCAST_STICKY; 13992 Slog.w(TAG, msg); 13993 throw new SecurityException(msg); 13994 } 13995 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId); 13996 if (stickies != null) { 13997 ArrayList<Intent> list = stickies.get(intent.getAction()); 13998 if (list != null) { 13999 int N = list.size(); 14000 int i; 14001 for (i=0; i<N; i++) { 14002 if (intent.filterEquals(list.get(i))) { 14003 list.remove(i); 14004 break; 14005 } 14006 } 14007 if (list.size() <= 0) { 14008 stickies.remove(intent.getAction()); 14009 } 14010 } 14011 if (stickies.size() <= 0) { 14012 mStickyBroadcasts.remove(userId); 14013 } 14014 } 14015 } 14016 } 14017 14018 private final boolean finishReceiverLocked(IBinder receiver, int resultCode, 14019 String resultData, Bundle resultExtras, boolean resultAbort) { 14020 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver); 14021 if (r == null) { 14022 Slog.w(TAG, "finishReceiver called but not found on queue"); 14023 return false; 14024 } 14025 14026 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false); 14027 } 14028 14029 void backgroundServicesFinishedLocked(int userId) { 14030 for (BroadcastQueue queue : mBroadcastQueues) { 14031 queue.backgroundServicesFinishedLocked(userId); 14032 } 14033 } 14034 14035 public void finishReceiver(IBinder who, int resultCode, String resultData, 14036 Bundle resultExtras, boolean resultAbort) { 14037 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who); 14038 14039 // Refuse possible leaked file descriptors 14040 if (resultExtras != null && resultExtras.hasFileDescriptors()) { 14041 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14042 } 14043 14044 final long origId = Binder.clearCallingIdentity(); 14045 try { 14046 boolean doNext = false; 14047 BroadcastRecord r; 14048 14049 synchronized(this) { 14050 r = broadcastRecordForReceiverLocked(who); 14051 if (r != null) { 14052 doNext = r.queue.finishReceiverLocked(r, resultCode, 14053 resultData, resultExtras, resultAbort, true); 14054 } 14055 } 14056 14057 if (doNext) { 14058 r.queue.processNextBroadcast(false); 14059 } 14060 trimApplications(); 14061 } finally { 14062 Binder.restoreCallingIdentity(origId); 14063 } 14064 } 14065 14066 // ========================================================= 14067 // INSTRUMENTATION 14068 // ========================================================= 14069 14070 public boolean startInstrumentation(ComponentName className, 14071 String profileFile, int flags, Bundle arguments, 14072 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, 14073 int userId) { 14074 enforceNotIsolatedCaller("startInstrumentation"); 14075 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 14076 userId, false, true, "startInstrumentation", null); 14077 // Refuse possible leaked file descriptors 14078 if (arguments != null && arguments.hasFileDescriptors()) { 14079 throw new IllegalArgumentException("File descriptors passed in Bundle"); 14080 } 14081 14082 synchronized(this) { 14083 InstrumentationInfo ii = null; 14084 ApplicationInfo ai = null; 14085 try { 14086 ii = mContext.getPackageManager().getInstrumentationInfo( 14087 className, STOCK_PM_FLAGS); 14088 ai = AppGlobals.getPackageManager().getApplicationInfo( 14089 ii.targetPackage, STOCK_PM_FLAGS, userId); 14090 } catch (PackageManager.NameNotFoundException e) { 14091 } catch (RemoteException e) { 14092 } 14093 if (ii == null) { 14094 reportStartInstrumentationFailure(watcher, className, 14095 "Unable to find instrumentation info for: " + className); 14096 return false; 14097 } 14098 if (ai == null) { 14099 reportStartInstrumentationFailure(watcher, className, 14100 "Unable to find instrumentation target package: " + ii.targetPackage); 14101 return false; 14102 } 14103 14104 int match = mContext.getPackageManager().checkSignatures( 14105 ii.targetPackage, ii.packageName); 14106 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) { 14107 String msg = "Permission Denial: starting instrumentation " 14108 + className + " from pid=" 14109 + Binder.getCallingPid() 14110 + ", uid=" + Binder.getCallingPid() 14111 + " not allowed because package " + ii.packageName 14112 + " does not have a signature matching the target " 14113 + ii.targetPackage; 14114 reportStartInstrumentationFailure(watcher, className, msg); 14115 throw new SecurityException(msg); 14116 } 14117 14118 final long origId = Binder.clearCallingIdentity(); 14119 // Instrumentation can kill and relaunch even persistent processes 14120 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId, 14121 "start instr"); 14122 ProcessRecord app = addAppLocked(ai, false); 14123 app.instrumentationClass = className; 14124 app.instrumentationInfo = ai; 14125 app.instrumentationProfileFile = profileFile; 14126 app.instrumentationArguments = arguments; 14127 app.instrumentationWatcher = watcher; 14128 app.instrumentationUiAutomationConnection = uiAutomationConnection; 14129 app.instrumentationResultClass = className; 14130 Binder.restoreCallingIdentity(origId); 14131 } 14132 14133 return true; 14134 } 14135 14136 /** 14137 * Report errors that occur while attempting to start Instrumentation. Always writes the 14138 * error to the logs, but if somebody is watching, send the report there too. This enables 14139 * the "am" command to report errors with more information. 14140 * 14141 * @param watcher The IInstrumentationWatcher. Null if there isn't one. 14142 * @param cn The component name of the instrumentation. 14143 * @param report The error report. 14144 */ 14145 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, 14146 ComponentName cn, String report) { 14147 Slog.w(TAG, report); 14148 try { 14149 if (watcher != null) { 14150 Bundle results = new Bundle(); 14151 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); 14152 results.putString("Error", report); 14153 watcher.instrumentationStatus(cn, -1, results); 14154 } 14155 } catch (RemoteException e) { 14156 Slog.w(TAG, e); 14157 } 14158 } 14159 14160 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { 14161 if (app.instrumentationWatcher != null) { 14162 try { 14163 // NOTE: IInstrumentationWatcher *must* be oneway here 14164 app.instrumentationWatcher.instrumentationFinished( 14165 app.instrumentationClass, 14166 resultCode, 14167 results); 14168 } catch (RemoteException e) { 14169 } 14170 } 14171 if (app.instrumentationUiAutomationConnection != null) { 14172 try { 14173 app.instrumentationUiAutomationConnection.shutdown(); 14174 } catch (RemoteException re) { 14175 /* ignore */ 14176 } 14177 // Only a UiAutomation can set this flag and now that 14178 // it is finished we make sure it is reset to its default. 14179 mUserIsMonkey = false; 14180 } 14181 app.instrumentationWatcher = null; 14182 app.instrumentationUiAutomationConnection = null; 14183 app.instrumentationClass = null; 14184 app.instrumentationInfo = null; 14185 app.instrumentationProfileFile = null; 14186 app.instrumentationArguments = null; 14187 14188 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId, 14189 "finished inst"); 14190 } 14191 14192 public void finishInstrumentation(IApplicationThread target, 14193 int resultCode, Bundle results) { 14194 int userId = UserHandle.getCallingUserId(); 14195 // Refuse possible leaked file descriptors 14196 if (results != null && results.hasFileDescriptors()) { 14197 throw new IllegalArgumentException("File descriptors passed in Intent"); 14198 } 14199 14200 synchronized(this) { 14201 ProcessRecord app = getRecordForAppLocked(target); 14202 if (app == null) { 14203 Slog.w(TAG, "finishInstrumentation: no app for " + target); 14204 return; 14205 } 14206 final long origId = Binder.clearCallingIdentity(); 14207 finishInstrumentationLocked(app, resultCode, results); 14208 Binder.restoreCallingIdentity(origId); 14209 } 14210 } 14211 14212 // ========================================================= 14213 // CONFIGURATION 14214 // ========================================================= 14215 14216 public ConfigurationInfo getDeviceConfigurationInfo() { 14217 ConfigurationInfo config = new ConfigurationInfo(); 14218 synchronized (this) { 14219 config.reqTouchScreen = mConfiguration.touchscreen; 14220 config.reqKeyboardType = mConfiguration.keyboard; 14221 config.reqNavigation = mConfiguration.navigation; 14222 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD 14223 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) { 14224 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV; 14225 } 14226 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED 14227 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) { 14228 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD; 14229 } 14230 config.reqGlEsVersion = GL_ES_VERSION; 14231 } 14232 return config; 14233 } 14234 14235 ActivityStack getFocusedStack() { 14236 return mStackSupervisor.getFocusedStack(); 14237 } 14238 14239 public Configuration getConfiguration() { 14240 Configuration ci; 14241 synchronized(this) { 14242 ci = new Configuration(mConfiguration); 14243 } 14244 return ci; 14245 } 14246 14247 public void updatePersistentConfiguration(Configuration values) { 14248 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14249 "updateConfiguration()"); 14250 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS, 14251 "updateConfiguration()"); 14252 if (values == null) { 14253 throw new NullPointerException("Configuration must not be null"); 14254 } 14255 14256 synchronized(this) { 14257 final long origId = Binder.clearCallingIdentity(); 14258 updateConfigurationLocked(values, null, true, false); 14259 Binder.restoreCallingIdentity(origId); 14260 } 14261 } 14262 14263 public void updateConfiguration(Configuration values) { 14264 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION, 14265 "updateConfiguration()"); 14266 14267 synchronized(this) { 14268 if (values == null && mWindowManager != null) { 14269 // sentinel: fetch the current configuration from the window manager 14270 values = mWindowManager.computeNewConfiguration(); 14271 } 14272 14273 if (mWindowManager != null) { 14274 mProcessList.applyDisplaySize(mWindowManager); 14275 } 14276 14277 final long origId = Binder.clearCallingIdentity(); 14278 if (values != null) { 14279 Settings.System.clearConfiguration(values); 14280 } 14281 updateConfigurationLocked(values, null, false, false); 14282 Binder.restoreCallingIdentity(origId); 14283 } 14284 } 14285 14286 /** 14287 * Do either or both things: (1) change the current configuration, and (2) 14288 * make sure the given activity is running with the (now) current 14289 * configuration. Returns true if the activity has been left running, or 14290 * false if <var>starting</var> is being destroyed to match the new 14291 * configuration. 14292 * @param persistent TODO 14293 */ 14294 boolean updateConfigurationLocked(Configuration values, 14295 ActivityRecord starting, boolean persistent, boolean initLocale) { 14296 int changes = 0; 14297 14298 if (values != null) { 14299 Configuration newConfig = new Configuration(mConfiguration); 14300 changes = newConfig.updateFrom(values); 14301 if (changes != 0) { 14302 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) { 14303 Slog.i(TAG, "Updating configuration to: " + values); 14304 } 14305 14306 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes); 14307 14308 if (values.locale != null && !initLocale) { 14309 saveLocaleLocked(values.locale, 14310 !values.locale.equals(mConfiguration.locale), 14311 values.userSetLocale); 14312 } 14313 14314 mConfigurationSeq++; 14315 if (mConfigurationSeq <= 0) { 14316 mConfigurationSeq = 1; 14317 } 14318 newConfig.seq = mConfigurationSeq; 14319 mConfiguration = newConfig; 14320 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig); 14321 14322 final Configuration configCopy = new Configuration(mConfiguration); 14323 14324 // TODO: If our config changes, should we auto dismiss any currently 14325 // showing dialogs? 14326 mShowDialogs = shouldShowDialogs(newConfig); 14327 14328 AttributeCache ac = AttributeCache.instance(); 14329 if (ac != null) { 14330 ac.updateConfiguration(configCopy); 14331 } 14332 14333 // Make sure all resources in our process are updated 14334 // right now, so that anyone who is going to retrieve 14335 // resource values after we return will be sure to get 14336 // the new ones. This is especially important during 14337 // boot, where the first config change needs to guarantee 14338 // all resources have that config before following boot 14339 // code is executed. 14340 mSystemThread.applyConfigurationToResources(configCopy); 14341 14342 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) { 14343 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG); 14344 msg.obj = new Configuration(configCopy); 14345 mHandler.sendMessage(msg); 14346 } 14347 14348 for (int i=mLruProcesses.size()-1; i>=0; i--) { 14349 ProcessRecord app = mLruProcesses.get(i); 14350 try { 14351 if (app.thread != null) { 14352 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc " 14353 + app.processName + " new config " + mConfiguration); 14354 app.thread.scheduleConfigurationChanged(configCopy); 14355 } 14356 } catch (Exception e) { 14357 } 14358 } 14359 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED); 14360 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 14361 | Intent.FLAG_RECEIVER_REPLACE_PENDING 14362 | Intent.FLAG_RECEIVER_FOREGROUND); 14363 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, 14364 null, AppOpsManager.OP_NONE, false, false, MY_PID, 14365 Process.SYSTEM_UID, UserHandle.USER_ALL); 14366 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) { 14367 intent = new Intent(Intent.ACTION_LOCALE_CHANGED); 14368 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 14369 broadcastIntentLocked(null, null, intent, 14370 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 14371 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 14372 } 14373 } 14374 } 14375 14376 boolean kept = true; 14377 final ActivityStack mainStack = mStackSupervisor.getFocusedStack(); 14378 // mainStack is null during startup. 14379 if (mainStack != null) { 14380 if (changes != 0 && starting == null) { 14381 // If the configuration changed, and the caller is not already 14382 // in the process of starting an activity, then find the top 14383 // activity to check if its configuration needs to change. 14384 starting = mainStack.topRunningActivityLocked(null); 14385 } 14386 14387 if (starting != null) { 14388 kept = mainStack.ensureActivityConfigurationLocked(starting, changes); 14389 // And we need to make sure at this point that all other activities 14390 // are made visible with the correct configuration. 14391 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes); 14392 } 14393 } 14394 14395 if (values != null && mWindowManager != null) { 14396 mWindowManager.setNewConfiguration(mConfiguration); 14397 } 14398 14399 return kept; 14400 } 14401 14402 /** 14403 * Decide based on the configuration whether we should shouw the ANR, 14404 * crash, etc dialogs. The idea is that if there is no affordnace to 14405 * press the on-screen buttons, we shouldn't show the dialog. 14406 * 14407 * A thought: SystemUI might also want to get told about this, the Power 14408 * dialog / global actions also might want different behaviors. 14409 */ 14410 private static final boolean shouldShowDialogs(Configuration config) { 14411 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS 14412 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH); 14413 } 14414 14415 /** 14416 * Save the locale. You must be inside a synchronized (this) block. 14417 */ 14418 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) { 14419 if(isDiff) { 14420 SystemProperties.set("user.language", l.getLanguage()); 14421 SystemProperties.set("user.region", l.getCountry()); 14422 } 14423 14424 if(isPersist) { 14425 SystemProperties.set("persist.sys.language", l.getLanguage()); 14426 SystemProperties.set("persist.sys.country", l.getCountry()); 14427 SystemProperties.set("persist.sys.localevar", l.getVariant()); 14428 } 14429 } 14430 14431 @Override 14432 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) { 14433 ActivityRecord srec = ActivityRecord.forToken(token); 14434 return srec != null && srec.task.affinity != null && 14435 srec.task.affinity.equals(destAffinity); 14436 } 14437 14438 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode, 14439 Intent resultData) { 14440 14441 synchronized (this) { 14442 final ActivityStack stack = ActivityRecord.getStackLocked(token); 14443 if (stack != null) { 14444 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData); 14445 } 14446 return false; 14447 } 14448 } 14449 14450 public int getLaunchedFromUid(IBinder activityToken) { 14451 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14452 if (srec == null) { 14453 return -1; 14454 } 14455 return srec.launchedFromUid; 14456 } 14457 14458 public String getLaunchedFromPackage(IBinder activityToken) { 14459 ActivityRecord srec = ActivityRecord.forToken(activityToken); 14460 if (srec == null) { 14461 return null; 14462 } 14463 return srec.launchedFromPackage; 14464 } 14465 14466 // ========================================================= 14467 // LIFETIME MANAGEMENT 14468 // ========================================================= 14469 14470 // Returns which broadcast queue the app is the current [or imminent] receiver 14471 // on, or 'null' if the app is not an active broadcast recipient. 14472 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) { 14473 BroadcastRecord r = app.curReceiver; 14474 if (r != null) { 14475 return r.queue; 14476 } 14477 14478 // It's not the current receiver, but it might be starting up to become one 14479 synchronized (this) { 14480 for (BroadcastQueue queue : mBroadcastQueues) { 14481 r = queue.mPendingBroadcast; 14482 if (r != null && r.curApp == app) { 14483 // found it; report which queue it's in 14484 return queue; 14485 } 14486 } 14487 } 14488 14489 return null; 14490 } 14491 14492 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, 14493 boolean doingAll, long now) { 14494 if (mAdjSeq == app.adjSeq) { 14495 // This adjustment has already been computed. 14496 return app.curRawAdj; 14497 } 14498 14499 if (app.thread == null) { 14500 app.adjSeq = mAdjSeq; 14501 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14502 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14503 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ); 14504 } 14505 14506 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN; 14507 app.adjSource = null; 14508 app.adjTarget = null; 14509 app.empty = false; 14510 app.cached = false; 14511 14512 final int activitiesSize = app.activities.size(); 14513 14514 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) { 14515 // The max adjustment doesn't allow this app to be anything 14516 // below foreground, so it is not worth doing work for it. 14517 app.adjType = "fixed"; 14518 app.adjSeq = mAdjSeq; 14519 app.curRawAdj = app.maxAdj; 14520 app.foregroundActivities = false; 14521 app.keeping = true; 14522 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; 14523 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT; 14524 // System process can do UI, and when they do we want to have 14525 // them trim their memory after the user leaves the UI. To 14526 // facilitate this, here we need to determine whether or not it 14527 // is currently showing UI. 14528 app.systemNoUi = true; 14529 if (app == TOP_APP) { 14530 app.systemNoUi = false; 14531 } else if (activitiesSize > 0) { 14532 for (int j = 0; j < activitiesSize; j++) { 14533 final ActivityRecord r = app.activities.get(j); 14534 if (r.visible) { 14535 app.systemNoUi = false; 14536 } 14537 } 14538 } 14539 if (!app.systemNoUi) { 14540 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI; 14541 } 14542 return (app.curAdj=app.maxAdj); 14543 } 14544 14545 app.keeping = false; 14546 app.systemNoUi = false; 14547 14548 // Determine the importance of the process, starting with most 14549 // important to least, and assign an appropriate OOM adjustment. 14550 int adj; 14551 int schedGroup; 14552 int procState; 14553 boolean foregroundActivities = false; 14554 boolean interesting = false; 14555 BroadcastQueue queue; 14556 if (app == TOP_APP) { 14557 // The last app on the list is the foreground app. 14558 adj = ProcessList.FOREGROUND_APP_ADJ; 14559 schedGroup = Process.THREAD_GROUP_DEFAULT; 14560 app.adjType = "top-activity"; 14561 foregroundActivities = true; 14562 interesting = true; 14563 procState = ActivityManager.PROCESS_STATE_TOP; 14564 } else if (app.instrumentationClass != null) { 14565 // Don't want to kill running instrumentation. 14566 adj = ProcessList.FOREGROUND_APP_ADJ; 14567 schedGroup = Process.THREAD_GROUP_DEFAULT; 14568 app.adjType = "instrumentation"; 14569 interesting = true; 14570 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14571 } else if ((queue = isReceivingBroadcast(app)) != null) { 14572 // An app that is currently receiving a broadcast also 14573 // counts as being in the foreground for OOM killer purposes. 14574 // It's placed in a sched group based on the nature of the 14575 // broadcast as reflected by which queue it's active in. 14576 adj = ProcessList.FOREGROUND_APP_ADJ; 14577 schedGroup = (queue == mFgBroadcastQueue) 14578 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14579 app.adjType = "broadcast"; 14580 procState = ActivityManager.PROCESS_STATE_RECEIVER; 14581 } else if (app.executingServices.size() > 0) { 14582 // An app that is currently executing a service callback also 14583 // counts as being in the foreground. 14584 adj = ProcessList.FOREGROUND_APP_ADJ; 14585 schedGroup = app.execServicesFg ? 14586 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE; 14587 app.adjType = "exec-service"; 14588 procState = ActivityManager.PROCESS_STATE_SERVICE; 14589 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app); 14590 } else { 14591 // As far as we know the process is empty. We may change our mind later. 14592 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14593 // At this point we don't actually know the adjustment. Use the cached adj 14594 // value that the caller wants us to. 14595 adj = cachedAdj; 14596 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14597 app.cached = true; 14598 app.empty = true; 14599 app.adjType = "cch-empty"; 14600 } 14601 14602 // Examine all activities if not already foreground. 14603 if (!foregroundActivities && activitiesSize > 0) { 14604 for (int j = 0; j < activitiesSize; j++) { 14605 final ActivityRecord r = app.activities.get(j); 14606 if (r.app != app) { 14607 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc " 14608 + app + "?!?"); 14609 continue; 14610 } 14611 if (r.visible) { 14612 // App has a visible activity; only upgrade adjustment. 14613 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14614 adj = ProcessList.VISIBLE_APP_ADJ; 14615 app.adjType = "visible"; 14616 } 14617 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14618 procState = ActivityManager.PROCESS_STATE_TOP; 14619 } 14620 schedGroup = Process.THREAD_GROUP_DEFAULT; 14621 app.cached = false; 14622 app.empty = false; 14623 foregroundActivities = true; 14624 break; 14625 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) { 14626 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14627 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14628 app.adjType = "pausing"; 14629 } 14630 if (procState > ActivityManager.PROCESS_STATE_TOP) { 14631 procState = ActivityManager.PROCESS_STATE_TOP; 14632 } 14633 schedGroup = Process.THREAD_GROUP_DEFAULT; 14634 app.cached = false; 14635 app.empty = false; 14636 foregroundActivities = true; 14637 } else if (r.state == ActivityState.STOPPING) { 14638 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14639 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14640 app.adjType = "stopping"; 14641 } 14642 // For the process state, we will at this point consider the 14643 // process to be cached. It will be cached either as an activity 14644 // or empty depending on whether the activity is finishing. We do 14645 // this so that we can treat the process as cached for purposes of 14646 // memory trimming (determing current memory level, trim command to 14647 // send to process) since there can be an arbitrary number of stopping 14648 // processes and they should soon all go into the cached state. 14649 if (!r.finishing) { 14650 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14651 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14652 } 14653 } 14654 app.cached = false; 14655 app.empty = false; 14656 foregroundActivities = true; 14657 } else { 14658 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14659 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 14660 app.adjType = "cch-act"; 14661 } 14662 } 14663 } 14664 } 14665 14666 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14667 if (app.foregroundServices) { 14668 // The user is aware of this app, so make it visible. 14669 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14670 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14671 app.cached = false; 14672 app.adjType = "fg-service"; 14673 schedGroup = Process.THREAD_GROUP_DEFAULT; 14674 } else if (app.forcingToForeground != null) { 14675 // The user is aware of this app, so make it visible. 14676 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14677 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14678 app.cached = false; 14679 app.adjType = "force-fg"; 14680 app.adjSource = app.forcingToForeground; 14681 schedGroup = Process.THREAD_GROUP_DEFAULT; 14682 } 14683 } 14684 14685 if (app.foregroundServices) { 14686 interesting = true; 14687 } 14688 14689 if (app == mHeavyWeightProcess) { 14690 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) { 14691 // We don't want to kill the current heavy-weight process. 14692 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ; 14693 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14694 app.cached = false; 14695 app.adjType = "heavy"; 14696 } 14697 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 14698 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 14699 } 14700 } 14701 14702 if (app == mHomeProcess) { 14703 if (adj > ProcessList.HOME_APP_ADJ) { 14704 // This process is hosting what we currently consider to be the 14705 // home app, so we don't want to let it go into the background. 14706 adj = ProcessList.HOME_APP_ADJ; 14707 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14708 app.cached = false; 14709 app.adjType = "home"; 14710 } 14711 if (procState > ActivityManager.PROCESS_STATE_HOME) { 14712 procState = ActivityManager.PROCESS_STATE_HOME; 14713 } 14714 } 14715 14716 if (app == mPreviousProcess && app.activities.size() > 0) { 14717 if (adj > ProcessList.PREVIOUS_APP_ADJ) { 14718 // This was the previous process that showed UI to the user. 14719 // We want to try to keep it around more aggressively, to give 14720 // a good experience around switching between two apps. 14721 adj = ProcessList.PREVIOUS_APP_ADJ; 14722 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; 14723 app.cached = false; 14724 app.adjType = "previous"; 14725 } 14726 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) { 14727 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 14728 } 14729 } 14730 14731 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 14732 + " reason=" + app.adjType); 14733 14734 // By default, we use the computed adjustment. It may be changed if 14735 // there are applications dependent on our services or providers, but 14736 // this gives us a baseline and makes sure we don't get into an 14737 // infinite recursion. 14738 app.adjSeq = mAdjSeq; 14739 app.curRawAdj = adj; 14740 app.hasStartedServices = false; 14741 14742 if (mBackupTarget != null && app == mBackupTarget.app) { 14743 // If possible we want to avoid killing apps while they're being backed up 14744 if (adj > ProcessList.BACKUP_APP_ADJ) { 14745 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app); 14746 adj = ProcessList.BACKUP_APP_ADJ; 14747 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14748 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14749 } 14750 app.adjType = "backup"; 14751 app.cached = false; 14752 } 14753 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 14754 procState = ActivityManager.PROCESS_STATE_BACKUP; 14755 } 14756 } 14757 14758 boolean mayBeTop = false; 14759 14760 for (int is = app.services.size()-1; 14761 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14762 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14763 || procState > ActivityManager.PROCESS_STATE_TOP); 14764 is--) { 14765 ServiceRecord s = app.services.valueAt(is); 14766 if (s.startRequested) { 14767 app.hasStartedServices = true; 14768 if (procState > ActivityManager.PROCESS_STATE_SERVICE) { 14769 procState = ActivityManager.PROCESS_STATE_SERVICE; 14770 } 14771 if (app.hasShownUi && app != mHomeProcess) { 14772 // If this process has shown some UI, let it immediately 14773 // go to the LRU list because it may be pretty heavy with 14774 // UI stuff. We'll tag it with a label just to help 14775 // debug and understand what is going on. 14776 if (adj > ProcessList.SERVICE_ADJ) { 14777 app.adjType = "cch-started-ui-services"; 14778 } 14779 } else { 14780 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14781 // This service has seen some activity within 14782 // recent memory, so we will keep its process ahead 14783 // of the background processes. 14784 if (adj > ProcessList.SERVICE_ADJ) { 14785 adj = ProcessList.SERVICE_ADJ; 14786 app.adjType = "started-services"; 14787 app.cached = false; 14788 } 14789 } 14790 // If we have let the service slide into the background 14791 // state, still have some text describing what it is doing 14792 // even though the service no longer has an impact. 14793 if (adj > ProcessList.SERVICE_ADJ) { 14794 app.adjType = "cch-started-services"; 14795 } 14796 } 14797 // Don't kill this process because it is doing work; it 14798 // has said it is doing work. 14799 app.keeping = true; 14800 } 14801 for (int conni = s.connections.size()-1; 14802 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14803 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14804 || procState > ActivityManager.PROCESS_STATE_TOP); 14805 conni--) { 14806 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni); 14807 for (int i = 0; 14808 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ 14809 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14810 || procState > ActivityManager.PROCESS_STATE_TOP); 14811 i++) { 14812 // XXX should compute this based on the max of 14813 // all connected clients. 14814 ConnectionRecord cr = clist.get(i); 14815 if (cr.binding.client == app) { 14816 // Binding to ourself is not interesting. 14817 continue; 14818 } 14819 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) { 14820 ProcessRecord client = cr.binding.client; 14821 int clientAdj = computeOomAdjLocked(client, cachedAdj, 14822 TOP_APP, doingAll, now); 14823 int clientProcState = client.curProcState; 14824 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14825 // If the other app is cached for any reason, for purposes here 14826 // we are going to consider it empty. The specific cached state 14827 // doesn't propagate except under certain conditions. 14828 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14829 } 14830 String adjType = null; 14831 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) { 14832 // Not doing bind OOM management, so treat 14833 // this guy more like a started service. 14834 if (app.hasShownUi && app != mHomeProcess) { 14835 // If this process has shown some UI, let it immediately 14836 // go to the LRU list because it may be pretty heavy with 14837 // UI stuff. We'll tag it with a label just to help 14838 // debug and understand what is going on. 14839 if (adj > clientAdj) { 14840 adjType = "cch-bound-ui-services"; 14841 } 14842 app.cached = false; 14843 clientAdj = adj; 14844 clientProcState = procState; 14845 } else { 14846 if (now >= (s.lastActivity 14847 + ActiveServices.MAX_SERVICE_INACTIVITY)) { 14848 // This service has not seen activity within 14849 // recent memory, so allow it to drop to the 14850 // LRU list if there is no other reason to keep 14851 // it around. We'll also tag it with a label just 14852 // to help debug and undertand what is going on. 14853 if (adj > clientAdj) { 14854 adjType = "cch-bound-services"; 14855 } 14856 clientAdj = adj; 14857 } 14858 } 14859 } 14860 if (adj > clientAdj) { 14861 // If this process has recently shown UI, and 14862 // the process that is binding to it is less 14863 // important than being visible, then we don't 14864 // care about the binding as much as we care 14865 // about letting this process get into the LRU 14866 // list to be killed and restarted if needed for 14867 // memory. 14868 if (app.hasShownUi && app != mHomeProcess 14869 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14870 adjType = "cch-bound-ui-services"; 14871 } else { 14872 if ((cr.flags&(Context.BIND_ABOVE_CLIENT 14873 |Context.BIND_IMPORTANT)) != 0) { 14874 adj = clientAdj; 14875 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 14876 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ 14877 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14878 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 14879 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) { 14880 adj = clientAdj; 14881 } else { 14882 if (adj > ProcessList.VISIBLE_APP_ADJ) { 14883 adj = ProcessList.VISIBLE_APP_ADJ; 14884 } 14885 } 14886 if (!client.cached) { 14887 app.cached = false; 14888 } 14889 if (client.keeping) { 14890 app.keeping = true; 14891 } 14892 adjType = "service"; 14893 } 14894 } 14895 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14896 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 14897 schedGroup = Process.THREAD_GROUP_DEFAULT; 14898 } 14899 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 14900 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 14901 // Special handling of clients who are in the top state. 14902 // We *may* want to consider this process to be in the 14903 // top state as well, but only if there is not another 14904 // reason for it to be running. Being on the top is a 14905 // special state, meaning you are specifically running 14906 // for the current top app. If the process is already 14907 // running in the background for some other reason, it 14908 // is more important to continue considering it to be 14909 // in the background state. 14910 mayBeTop = true; 14911 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14912 } else { 14913 // Special handling for above-top states (persistent 14914 // processes). These should not bring the current process 14915 // into the top state, since they are not on top. Instead 14916 // give them the best state after that. 14917 clientProcState = 14918 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 14919 } 14920 } 14921 } else { 14922 if (clientProcState < 14923 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) { 14924 clientProcState = 14925 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 14926 } 14927 } 14928 if (procState > clientProcState) { 14929 procState = clientProcState; 14930 } 14931 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 14932 && (cr.flags&Context.BIND_SHOWING_UI) != 0) { 14933 app.pendingUiClean = true; 14934 } 14935 if (adjType != null) { 14936 app.adjType = adjType; 14937 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14938 .REASON_SERVICE_IN_USE; 14939 app.adjSource = cr.binding.client; 14940 app.adjSourceOom = clientAdj; 14941 app.adjTarget = s.name; 14942 } 14943 } 14944 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) { 14945 app.treatLikeActivity = true; 14946 } 14947 final ActivityRecord a = cr.activity; 14948 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) { 14949 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ && 14950 (a.visible || a.state == ActivityState.RESUMED 14951 || a.state == ActivityState.PAUSING)) { 14952 adj = ProcessList.FOREGROUND_APP_ADJ; 14953 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) { 14954 schedGroup = Process.THREAD_GROUP_DEFAULT; 14955 } 14956 app.cached = false; 14957 app.adjType = "service"; 14958 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 14959 .REASON_SERVICE_IN_USE; 14960 app.adjSource = a; 14961 app.adjSourceOom = adj; 14962 app.adjTarget = s.name; 14963 } 14964 } 14965 } 14966 } 14967 } 14968 14969 for (int provi = app.pubProviders.size()-1; 14970 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14971 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14972 || procState > ActivityManager.PROCESS_STATE_TOP); 14973 provi--) { 14974 ContentProviderRecord cpr = app.pubProviders.valueAt(provi); 14975 for (int i = cpr.connections.size()-1; 14976 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ 14977 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE 14978 || procState > ActivityManager.PROCESS_STATE_TOP); 14979 i--) { 14980 ContentProviderConnection conn = cpr.connections.get(i); 14981 ProcessRecord client = conn.client; 14982 if (client == app) { 14983 // Being our own client is not interesting. 14984 continue; 14985 } 14986 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now); 14987 int clientProcState = client.curProcState; 14988 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) { 14989 // If the other app is cached for any reason, for purposes here 14990 // we are going to consider it empty. 14991 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 14992 } 14993 if (adj > clientAdj) { 14994 if (app.hasShownUi && app != mHomeProcess 14995 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) { 14996 app.adjType = "cch-ui-provider"; 14997 } else { 14998 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ 14999 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ; 15000 app.adjType = "provider"; 15001 } 15002 app.cached &= client.cached; 15003 app.keeping |= client.keeping; 15004 app.adjTypeCode = ActivityManager.RunningAppProcessInfo 15005 .REASON_PROVIDER_IN_USE; 15006 app.adjSource = client; 15007 app.adjSourceOom = clientAdj; 15008 app.adjTarget = cpr.name; 15009 } 15010 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) { 15011 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) { 15012 // Special handling of clients who are in the top state. 15013 // We *may* want to consider this process to be in the 15014 // top state as well, but only if there is not another 15015 // reason for it to be running. Being on the top is a 15016 // special state, meaning you are specifically running 15017 // for the current top app. If the process is already 15018 // running in the background for some other reason, it 15019 // is more important to continue considering it to be 15020 // in the background state. 15021 mayBeTop = true; 15022 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY; 15023 } else { 15024 // Special handling for above-top states (persistent 15025 // processes). These should not bring the current process 15026 // into the top state, since they are not on top. Instead 15027 // give them the best state after that. 15028 clientProcState = 15029 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15030 } 15031 } 15032 if (procState > clientProcState) { 15033 procState = clientProcState; 15034 } 15035 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) { 15036 schedGroup = Process.THREAD_GROUP_DEFAULT; 15037 } 15038 } 15039 // If the provider has external (non-framework) process 15040 // dependencies, ensure that its adjustment is at least 15041 // FOREGROUND_APP_ADJ. 15042 if (cpr.hasExternalProcessHandles()) { 15043 if (adj > ProcessList.FOREGROUND_APP_ADJ) { 15044 adj = ProcessList.FOREGROUND_APP_ADJ; 15045 schedGroup = Process.THREAD_GROUP_DEFAULT; 15046 app.cached = false; 15047 app.keeping = true; 15048 app.adjType = "provider"; 15049 app.adjTarget = cpr.name; 15050 } 15051 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) { 15052 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15053 } 15054 } 15055 } 15056 15057 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) { 15058 // A client of one of our services or providers is in the top state. We 15059 // *may* want to be in the top state, but not if we are already running in 15060 // the background for some other reason. For the decision here, we are going 15061 // to pick out a few specific states that we want to remain in when a client 15062 // is top (states that tend to be longer-term) and otherwise allow it to go 15063 // to the top state. 15064 switch (procState) { 15065 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 15066 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 15067 case ActivityManager.PROCESS_STATE_SERVICE: 15068 // These all are longer-term states, so pull them up to the top 15069 // of the background states, but not all the way to the top state. 15070 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 15071 break; 15072 default: 15073 // Otherwise, top is a better choice, so take it. 15074 procState = ActivityManager.PROCESS_STATE_TOP; 15075 break; 15076 } 15077 } 15078 15079 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 15080 if (app.hasClientActivities) { 15081 // This is a cached process, but with client activities. Mark it so. 15082 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 15083 app.adjType = "cch-client-act"; 15084 } else if (app.treatLikeActivity) { 15085 // This is a cached process, but somebody wants us to treat it like it has 15086 // an activity, okay! 15087 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 15088 app.adjType = "cch-as-act"; 15089 } 15090 } 15091 15092 if (adj == ProcessList.SERVICE_ADJ) { 15093 if (doingAll) { 15094 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3); 15095 mNewNumServiceProcs++; 15096 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb); 15097 if (!app.serviceb) { 15098 // This service isn't far enough down on the LRU list to 15099 // normally be a B service, but if we are low on RAM and it 15100 // is large we want to force it down since we would prefer to 15101 // keep launcher over it. 15102 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 15103 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) { 15104 app.serviceHighRam = true; 15105 app.serviceb = true; 15106 //Slog.i(TAG, "ADJ " + app + " high ram!"); 15107 } else { 15108 mNewNumAServiceProcs++; 15109 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 15110 } 15111 } else { 15112 app.serviceHighRam = false; 15113 } 15114 } 15115 if (app.serviceb) { 15116 adj = ProcessList.SERVICE_B_ADJ; 15117 } 15118 } 15119 15120 app.curRawAdj = adj; 15121 15122 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid + 15123 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); 15124 if (adj > app.maxAdj) { 15125 adj = app.maxAdj; 15126 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) { 15127 schedGroup = Process.THREAD_GROUP_DEFAULT; 15128 } 15129 } 15130 if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 15131 app.keeping = true; 15132 } 15133 15134 // Do final modification to adj. Everything we do between here and applying 15135 // the final setAdj must be done in this function, because we will also use 15136 // it when computing the final cached adj later. Note that we don't need to 15137 // worry about this for max adj above, since max adj will always be used to 15138 // keep it out of the cached vaues. 15139 adj = app.modifyRawOomAdj(adj); 15140 15141 app.curProcState = procState; 15142 15143 int importance = app.memImportance; 15144 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) { 15145 app.curAdj = adj; 15146 app.curSchedGroup = schedGroup; 15147 if (!interesting) { 15148 // For this reporting, if there is not something explicitly 15149 // interesting in this process then we will push it to the 15150 // background importance. 15151 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15152 } else if (adj >= ProcessList.CACHED_APP_MIN_ADJ) { 15153 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15154 } else if (adj >= ProcessList.SERVICE_B_ADJ) { 15155 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15156 } else if (adj >= ProcessList.HOME_APP_ADJ) { 15157 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND; 15158 } else if (adj >= ProcessList.SERVICE_ADJ) { 15159 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; 15160 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 15161 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE; 15162 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 15163 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; 15164 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) { 15165 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 15166 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) { 15167 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 15168 } else { 15169 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT; 15170 } 15171 } 15172 15173 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0; 15174 if (foregroundActivities != app.foregroundActivities) { 15175 changes |= ProcessChangeItem.CHANGE_ACTIVITIES; 15176 } 15177 if (changes != 0) { 15178 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes); 15179 app.memImportance = importance; 15180 app.foregroundActivities = foregroundActivities; 15181 int i = mPendingProcessChanges.size()-1; 15182 ProcessChangeItem item = null; 15183 while (i >= 0) { 15184 item = mPendingProcessChanges.get(i); 15185 if (item.pid == app.pid) { 15186 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item); 15187 break; 15188 } 15189 i--; 15190 } 15191 if (i < 0) { 15192 // No existing item in pending changes; need a new one. 15193 final int NA = mAvailProcessChanges.size(); 15194 if (NA > 0) { 15195 item = mAvailProcessChanges.remove(NA-1); 15196 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item); 15197 } else { 15198 item = new ProcessChangeItem(); 15199 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item); 15200 } 15201 item.changes = 0; 15202 item.pid = app.pid; 15203 item.uid = app.info.uid; 15204 if (mPendingProcessChanges.size() == 0) { 15205 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, 15206 "*** Enqueueing dispatch processes changed!"); 15207 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget(); 15208 } 15209 mPendingProcessChanges.add(item); 15210 } 15211 item.changes |= changes; 15212 item.importance = importance; 15213 item.foregroundActivities = foregroundActivities; 15214 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item " 15215 + Integer.toHexString(System.identityHashCode(item)) 15216 + " " + app.toShortString() + ": changes=" + item.changes 15217 + " importance=" + item.importance 15218 + " foreground=" + item.foregroundActivities 15219 + " type=" + app.adjType + " source=" + app.adjSource 15220 + " target=" + app.adjTarget); 15221 } 15222 15223 return app.curRawAdj; 15224 } 15225 15226 /** 15227 * Schedule PSS collection of a process. 15228 */ 15229 void requestPssLocked(ProcessRecord proc, int procState) { 15230 if (mPendingPssProcesses.contains(proc)) { 15231 return; 15232 } 15233 if (mPendingPssProcesses.size() == 0) { 15234 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15235 } 15236 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc); 15237 proc.pssProcState = procState; 15238 mPendingPssProcesses.add(proc); 15239 } 15240 15241 /** 15242 * Schedule PSS collection of all processes. 15243 */ 15244 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) { 15245 if (!always) { 15246 if (now < (mLastFullPssTime + 15247 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) { 15248 return; 15249 } 15250 } 15251 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered); 15252 mLastFullPssTime = now; 15253 mPendingPssProcesses.ensureCapacity(mLruProcesses.size()); 15254 mPendingPssProcesses.clear(); 15255 for (int i=mLruProcesses.size()-1; i>=0; i--) { 15256 ProcessRecord app = mLruProcesses.get(i); 15257 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) { 15258 app.pssProcState = app.setProcState; 15259 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15260 mSleeping, now); 15261 mPendingPssProcesses.add(app); 15262 } 15263 } 15264 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG); 15265 } 15266 15267 /** 15268 * Ask a given process to GC right now. 15269 */ 15270 final void performAppGcLocked(ProcessRecord app) { 15271 try { 15272 app.lastRequestedGc = SystemClock.uptimeMillis(); 15273 if (app.thread != null) { 15274 if (app.reportLowMemory) { 15275 app.reportLowMemory = false; 15276 app.thread.scheduleLowMemory(); 15277 } else { 15278 app.thread.processInBackground(); 15279 } 15280 } 15281 } catch (Exception e) { 15282 // whatever. 15283 } 15284 } 15285 15286 /** 15287 * Returns true if things are idle enough to perform GCs. 15288 */ 15289 private final boolean canGcNowLocked() { 15290 boolean processingBroadcasts = false; 15291 for (BroadcastQueue q : mBroadcastQueues) { 15292 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) { 15293 processingBroadcasts = true; 15294 } 15295 } 15296 return !processingBroadcasts 15297 && (mSleeping || mStackSupervisor.allResumedActivitiesIdle()); 15298 } 15299 15300 /** 15301 * Perform GCs on all processes that are waiting for it, but only 15302 * if things are idle. 15303 */ 15304 final void performAppGcsLocked() { 15305 final int N = mProcessesToGc.size(); 15306 if (N <= 0) { 15307 return; 15308 } 15309 if (canGcNowLocked()) { 15310 while (mProcessesToGc.size() > 0) { 15311 ProcessRecord proc = mProcessesToGc.remove(0); 15312 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { 15313 if ((proc.lastRequestedGc+GC_MIN_INTERVAL) 15314 <= SystemClock.uptimeMillis()) { 15315 // To avoid spamming the system, we will GC processes one 15316 // at a time, waiting a few seconds between each. 15317 performAppGcLocked(proc); 15318 scheduleAppGcsLocked(); 15319 return; 15320 } else { 15321 // It hasn't been long enough since we last GCed this 15322 // process... put it in the list to wait for its time. 15323 addProcessToGcListLocked(proc); 15324 break; 15325 } 15326 } 15327 } 15328 15329 scheduleAppGcsLocked(); 15330 } 15331 } 15332 15333 /** 15334 * If all looks good, perform GCs on all processes waiting for them. 15335 */ 15336 final void performAppGcsIfAppropriateLocked() { 15337 if (canGcNowLocked()) { 15338 performAppGcsLocked(); 15339 return; 15340 } 15341 // Still not idle, wait some more. 15342 scheduleAppGcsLocked(); 15343 } 15344 15345 /** 15346 * Schedule the execution of all pending app GCs. 15347 */ 15348 final void scheduleAppGcsLocked() { 15349 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG); 15350 15351 if (mProcessesToGc.size() > 0) { 15352 // Schedule a GC for the time to the next process. 15353 ProcessRecord proc = mProcessesToGc.get(0); 15354 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG); 15355 15356 long when = proc.lastRequestedGc + GC_MIN_INTERVAL; 15357 long now = SystemClock.uptimeMillis(); 15358 if (when < (now+GC_TIMEOUT)) { 15359 when = now + GC_TIMEOUT; 15360 } 15361 mHandler.sendMessageAtTime(msg, when); 15362 } 15363 } 15364 15365 /** 15366 * Add a process to the array of processes waiting to be GCed. Keeps the 15367 * list in sorted order by the last GC time. The process can't already be 15368 * on the list. 15369 */ 15370 final void addProcessToGcListLocked(ProcessRecord proc) { 15371 boolean added = false; 15372 for (int i=mProcessesToGc.size()-1; i>=0; i--) { 15373 if (mProcessesToGc.get(i).lastRequestedGc < 15374 proc.lastRequestedGc) { 15375 added = true; 15376 mProcessesToGc.add(i+1, proc); 15377 break; 15378 } 15379 } 15380 if (!added) { 15381 mProcessesToGc.add(0, proc); 15382 } 15383 } 15384 15385 /** 15386 * Set up to ask a process to GC itself. This will either do it 15387 * immediately, or put it on the list of processes to gc the next 15388 * time things are idle. 15389 */ 15390 final void scheduleAppGcLocked(ProcessRecord app) { 15391 long now = SystemClock.uptimeMillis(); 15392 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) { 15393 return; 15394 } 15395 if (!mProcessesToGc.contains(app)) { 15396 addProcessToGcListLocked(app); 15397 scheduleAppGcsLocked(); 15398 } 15399 } 15400 15401 final void checkExcessivePowerUsageLocked(boolean doKills) { 15402 updateCpuStatsNow(); 15403 15404 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15405 boolean doWakeKills = doKills; 15406 boolean doCpuKills = doKills; 15407 if (mLastPowerCheckRealtime == 0) { 15408 doWakeKills = false; 15409 } 15410 if (mLastPowerCheckUptime == 0) { 15411 doCpuKills = false; 15412 } 15413 if (stats.isScreenOn()) { 15414 doWakeKills = false; 15415 } 15416 final long curRealtime = SystemClock.elapsedRealtime(); 15417 final long realtimeSince = curRealtime - mLastPowerCheckRealtime; 15418 final long curUptime = SystemClock.uptimeMillis(); 15419 final long uptimeSince = curUptime - mLastPowerCheckUptime; 15420 mLastPowerCheckRealtime = curRealtime; 15421 mLastPowerCheckUptime = curUptime; 15422 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) { 15423 doWakeKills = false; 15424 } 15425 if (uptimeSince < CPU_MIN_CHECK_DURATION) { 15426 doCpuKills = false; 15427 } 15428 int i = mLruProcesses.size(); 15429 while (i > 0) { 15430 i--; 15431 ProcessRecord app = mLruProcesses.get(i); 15432 if (!app.keeping) { 15433 long wtime; 15434 synchronized (stats) { 15435 wtime = stats.getProcessWakeTime(app.info.uid, 15436 app.pid, curRealtime); 15437 } 15438 long wtimeUsed = wtime - app.lastWakeTime; 15439 long cputimeUsed = app.curCpuTime - app.lastCpuTime; 15440 if (DEBUG_POWER) { 15441 StringBuilder sb = new StringBuilder(128); 15442 sb.append("Wake for "); 15443 app.toShortString(sb); 15444 sb.append(": over "); 15445 TimeUtils.formatDuration(realtimeSince, sb); 15446 sb.append(" used "); 15447 TimeUtils.formatDuration(wtimeUsed, sb); 15448 sb.append(" ("); 15449 sb.append((wtimeUsed*100)/realtimeSince); 15450 sb.append("%)"); 15451 Slog.i(TAG, sb.toString()); 15452 sb.setLength(0); 15453 sb.append("CPU for "); 15454 app.toShortString(sb); 15455 sb.append(": over "); 15456 TimeUtils.formatDuration(uptimeSince, sb); 15457 sb.append(" used "); 15458 TimeUtils.formatDuration(cputimeUsed, sb); 15459 sb.append(" ("); 15460 sb.append((cputimeUsed*100)/uptimeSince); 15461 sb.append("%)"); 15462 Slog.i(TAG, sb.toString()); 15463 } 15464 // If a process has held a wake lock for more 15465 // than 50% of the time during this period, 15466 // that sounds bad. Kill! 15467 if (doWakeKills && realtimeSince > 0 15468 && ((wtimeUsed*100)/realtimeSince) >= 50) { 15469 synchronized (stats) { 15470 stats.reportExcessiveWakeLocked(app.info.uid, app.processName, 15471 realtimeSince, wtimeUsed); 15472 } 15473 killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed 15474 + " during " + realtimeSince); 15475 app.baseProcessTracker.reportExcessiveWake(app.pkgList); 15476 } else if (doCpuKills && uptimeSince > 0 15477 && ((cputimeUsed*100)/uptimeSince) >= 50) { 15478 synchronized (stats) { 15479 stats.reportExcessiveCpuLocked(app.info.uid, app.processName, 15480 uptimeSince, cputimeUsed); 15481 } 15482 killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed 15483 + " during " + uptimeSince); 15484 app.baseProcessTracker.reportExcessiveCpu(app.pkgList); 15485 } else { 15486 app.lastWakeTime = wtime; 15487 app.lastCpuTime = app.curCpuTime; 15488 } 15489 } 15490 } 15491 } 15492 15493 private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping, 15494 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15495 boolean success = true; 15496 15497 if (app.curRawAdj != app.setRawAdj) { 15498 if (wasKeeping && !app.keeping) { 15499 // This app is no longer something we want to keep. Note 15500 // its current wake lock time to later know to kill it if 15501 // it is not behaving well. 15502 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); 15503 synchronized (stats) { 15504 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid, 15505 app.pid, SystemClock.elapsedRealtime()); 15506 } 15507 app.lastCpuTime = app.curCpuTime; 15508 } 15509 15510 app.setRawAdj = app.curRawAdj; 15511 } 15512 15513 if (app.curAdj != app.setAdj) { 15514 ProcessList.setOomAdj(app.pid, app.curAdj); 15515 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v( 15516 TAG, "Set " + app.pid + " " + app.processName + 15517 " adj " + app.curAdj + ": " + app.adjType); 15518 app.setAdj = app.curAdj; 15519 } 15520 15521 if (app.setSchedGroup != app.curSchedGroup) { 15522 app.setSchedGroup = app.curSchedGroup; 15523 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15524 "Setting process group of " + app.processName 15525 + " to " + app.curSchedGroup); 15526 if (app.waitingToKill != null && 15527 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) { 15528 killUnneededProcessLocked(app, app.waitingToKill); 15529 success = false; 15530 } else { 15531 if (true) { 15532 long oldId = Binder.clearCallingIdentity(); 15533 try { 15534 Process.setProcessGroup(app.pid, app.curSchedGroup); 15535 } catch (Exception e) { 15536 Slog.w(TAG, "Failed setting process group of " + app.pid 15537 + " to " + app.curSchedGroup); 15538 e.printStackTrace(); 15539 } finally { 15540 Binder.restoreCallingIdentity(oldId); 15541 } 15542 } else { 15543 if (app.thread != null) { 15544 try { 15545 app.thread.setSchedulingGroup(app.curSchedGroup); 15546 } catch (RemoteException e) { 15547 } 15548 } 15549 } 15550 Process.setSwappiness(app.pid, 15551 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE); 15552 } 15553 } 15554 if (app.repProcState != app.curProcState) { 15555 app.repProcState = app.curProcState; 15556 if (!reportingProcessState && app.thread != null) { 15557 try { 15558 if (false) { 15559 //RuntimeException h = new RuntimeException("here"); 15560 Slog.i(TAG, "Sending new process state " + app.repProcState 15561 + " to " + app /*, h*/); 15562 } 15563 app.thread.setProcessState(app.repProcState); 15564 } catch (RemoteException e) { 15565 } 15566 } 15567 } 15568 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState, 15569 app.setProcState)) { 15570 app.lastStateTime = now; 15571 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true, 15572 mSleeping, now); 15573 if (DEBUG_PSS) Slog.d(TAG, "Process state change from " 15574 + ProcessList.makeProcStateString(app.setProcState) + " to " 15575 + ProcessList.makeProcStateString(app.curProcState) + " next pss in " 15576 + (app.nextPssTime-now) + ": " + app); 15577 } else { 15578 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL) 15579 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) { 15580 requestPssLocked(app, app.setProcState); 15581 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false, 15582 mSleeping, now); 15583 } else if (false && DEBUG_PSS) { 15584 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now)); 15585 } 15586 } 15587 if (app.setProcState != app.curProcState) { 15588 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15589 "Proc state change of " + app.processName 15590 + " to " + app.curProcState); 15591 app.setProcState = app.curProcState; 15592 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { 15593 app.notCachedSinceIdle = false; 15594 } 15595 if (!doingAll) { 15596 setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now); 15597 } else { 15598 app.procStateChanged = true; 15599 } 15600 } 15601 return success; 15602 } 15603 15604 private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) { 15605 if (proc.thread != null && proc.baseProcessTracker != null) { 15606 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList); 15607 } 15608 } 15609 15610 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj, 15611 ProcessRecord TOP_APP, boolean doingAll, boolean reportingProcessState, long now) { 15612 if (app.thread == null) { 15613 return false; 15614 } 15615 15616 final boolean wasKeeping = app.keeping; 15617 15618 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now); 15619 15620 return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, 15621 reportingProcessState, now); 15622 } 15623 15624 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, 15625 boolean oomAdj) { 15626 if (isForeground != proc.foregroundServices) { 15627 proc.foregroundServices = isForeground; 15628 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName, 15629 proc.info.uid); 15630 if (isForeground) { 15631 if (curProcs == null) { 15632 curProcs = new ArrayList<ProcessRecord>(); 15633 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs); 15634 } 15635 if (!curProcs.contains(proc)) { 15636 curProcs.add(proc); 15637 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START, 15638 proc.info.packageName, proc.info.uid); 15639 } 15640 } else { 15641 if (curProcs != null) { 15642 if (curProcs.remove(proc)) { 15643 mBatteryStatsService.noteEvent( 15644 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH, 15645 proc.info.packageName, proc.info.uid); 15646 if (curProcs.size() <= 0) { 15647 mForegroundPackages.remove(proc.info.packageName, proc.info.uid); 15648 } 15649 } 15650 } 15651 } 15652 if (oomAdj) { 15653 updateOomAdjLocked(); 15654 } 15655 } 15656 } 15657 15658 private final ActivityRecord resumedAppLocked() { 15659 ActivityRecord act = mStackSupervisor.resumedAppLocked(); 15660 String pkg; 15661 int uid; 15662 if (act != null && !act.sleeping) { 15663 pkg = act.packageName; 15664 uid = act.info.applicationInfo.uid; 15665 } else { 15666 pkg = null; 15667 uid = -1; 15668 } 15669 // Has the UID or resumed package name changed? 15670 if (uid != mCurResumedUid || (pkg != mCurResumedPackage 15671 && (pkg == null || !pkg.equals(mCurResumedPackage)))) { 15672 if (mCurResumedPackage != null) { 15673 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH, 15674 mCurResumedPackage, mCurResumedUid); 15675 } 15676 mCurResumedPackage = pkg; 15677 mCurResumedUid = uid; 15678 if (mCurResumedPackage != null) { 15679 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START, 15680 mCurResumedPackage, mCurResumedUid); 15681 } 15682 } 15683 return act; 15684 } 15685 15686 final boolean updateOomAdjLocked(ProcessRecord app) { 15687 return updateOomAdjLocked(app, false); 15688 } 15689 15690 final boolean updateOomAdjLocked(ProcessRecord app, boolean doingProcessState) { 15691 final ActivityRecord TOP_ACT = resumedAppLocked(); 15692 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15693 final boolean wasCached = app.cached; 15694 15695 mAdjSeq++; 15696 15697 // This is the desired cached adjusment we want to tell it to use. 15698 // If our app is currently cached, we know it, and that is it. Otherwise, 15699 // we don't know it yet, and it needs to now be cached we will then 15700 // need to do a complete oom adj. 15701 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ 15702 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ; 15703 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false, doingProcessState, 15704 SystemClock.uptimeMillis()); 15705 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) { 15706 // Changed to/from cached state, so apps after it in the LRU 15707 // list may also be changed. 15708 updateOomAdjLocked(); 15709 } 15710 return success; 15711 } 15712 15713 final void updateOomAdjLocked() { 15714 final ActivityRecord TOP_ACT = resumedAppLocked(); 15715 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null; 15716 final long now = SystemClock.uptimeMillis(); 15717 final long oldTime = now - ProcessList.MAX_EMPTY_TIME; 15718 final int N = mLruProcesses.size(); 15719 15720 if (false) { 15721 RuntimeException e = new RuntimeException(); 15722 e.fillInStackTrace(); 15723 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e); 15724 } 15725 15726 mAdjSeq++; 15727 mNewNumServiceProcs = 0; 15728 mNewNumAServiceProcs = 0; 15729 15730 final int emptyProcessLimit; 15731 final int cachedProcessLimit; 15732 if (mProcessLimit <= 0) { 15733 emptyProcessLimit = cachedProcessLimit = 0; 15734 } else if (mProcessLimit == 1) { 15735 emptyProcessLimit = 1; 15736 cachedProcessLimit = 0; 15737 } else { 15738 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit); 15739 cachedProcessLimit = mProcessLimit - emptyProcessLimit; 15740 } 15741 15742 // Let's determine how many processes we have running vs. 15743 // how many slots we have for background processes; we may want 15744 // to put multiple processes in a slot of there are enough of 15745 // them. 15746 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ 15747 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2; 15748 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs; 15749 if (numEmptyProcs > cachedProcessLimit) { 15750 // If there are more empty processes than our limit on cached 15751 // processes, then use the cached process limit for the factor. 15752 // This ensures that the really old empty processes get pushed 15753 // down to the bottom, so if we are running low on memory we will 15754 // have a better chance at keeping around more cached processes 15755 // instead of a gazillion empty processes. 15756 numEmptyProcs = cachedProcessLimit; 15757 } 15758 int emptyFactor = numEmptyProcs/numSlots; 15759 if (emptyFactor < 1) emptyFactor = 1; 15760 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots; 15761 if (cachedFactor < 1) cachedFactor = 1; 15762 int stepCached = 0; 15763 int stepEmpty = 0; 15764 int numCached = 0; 15765 int numEmpty = 0; 15766 int numTrimming = 0; 15767 15768 mNumNonCachedProcs = 0; 15769 mNumCachedHiddenProcs = 0; 15770 15771 // First update the OOM adjustment for each of the 15772 // application processes based on their current state. 15773 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ; 15774 int nextCachedAdj = curCachedAdj+1; 15775 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ; 15776 int nextEmptyAdj = curEmptyAdj+2; 15777 for (int i=N-1; i>=0; i--) { 15778 ProcessRecord app = mLruProcesses.get(i); 15779 if (!app.killedByAm && app.thread != null) { 15780 app.procStateChanged = false; 15781 final boolean wasKeeping = app.keeping; 15782 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now); 15783 15784 // If we haven't yet assigned the final cached adj 15785 // to the process, do that now. 15786 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) { 15787 switch (app.curProcState) { 15788 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15789 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15790 // This process is a cached process holding activities... 15791 // assign it the next cached value for that type, and then 15792 // step that cached level. 15793 app.curRawAdj = curCachedAdj; 15794 app.curAdj = app.modifyRawOomAdj(curCachedAdj); 15795 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i 15796 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj 15797 + ")"); 15798 if (curCachedAdj != nextCachedAdj) { 15799 stepCached++; 15800 if (stepCached >= cachedFactor) { 15801 stepCached = 0; 15802 curCachedAdj = nextCachedAdj; 15803 nextCachedAdj += 2; 15804 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15805 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ; 15806 } 15807 } 15808 } 15809 break; 15810 default: 15811 // For everything else, assign next empty cached process 15812 // level and bump that up. Note that this means that 15813 // long-running services that have dropped down to the 15814 // cached level will be treated as empty (since their process 15815 // state is still as a service), which is what we want. 15816 app.curRawAdj = curEmptyAdj; 15817 app.curAdj = app.modifyRawOomAdj(curEmptyAdj); 15818 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i 15819 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj 15820 + ")"); 15821 if (curEmptyAdj != nextEmptyAdj) { 15822 stepEmpty++; 15823 if (stepEmpty >= emptyFactor) { 15824 stepEmpty = 0; 15825 curEmptyAdj = nextEmptyAdj; 15826 nextEmptyAdj += 2; 15827 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) { 15828 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ; 15829 } 15830 } 15831 } 15832 break; 15833 } 15834 } 15835 15836 applyOomAdjLocked(app, wasKeeping, TOP_APP, true, false, now); 15837 15838 // Count the number of process types. 15839 switch (app.curProcState) { 15840 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 15841 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 15842 mNumCachedHiddenProcs++; 15843 numCached++; 15844 if (numCached > cachedProcessLimit) { 15845 killUnneededProcessLocked(app, "cached #" + numCached); 15846 } 15847 break; 15848 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 15849 if (numEmpty > ProcessList.TRIM_EMPTY_APPS 15850 && app.lastActivityTime < oldTime) { 15851 killUnneededProcessLocked(app, "empty for " 15852 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime) 15853 / 1000) + "s"); 15854 } else { 15855 numEmpty++; 15856 if (numEmpty > emptyProcessLimit) { 15857 killUnneededProcessLocked(app, "empty #" + numEmpty); 15858 } 15859 } 15860 break; 15861 default: 15862 mNumNonCachedProcs++; 15863 break; 15864 } 15865 15866 if (app.isolated && app.services.size() <= 0) { 15867 // If this is an isolated process, and there are no 15868 // services running in it, then the process is no longer 15869 // needed. We agressively kill these because we can by 15870 // definition not re-use the same process again, and it is 15871 // good to avoid having whatever code was running in them 15872 // left sitting around after no longer needed. 15873 killUnneededProcessLocked(app, "isolated not needed"); 15874 } 15875 15876 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15877 && !app.killedByAm) { 15878 numTrimming++; 15879 } 15880 } 15881 } 15882 15883 mNumServiceProcs = mNewNumServiceProcs; 15884 15885 // Now determine the memory trimming level of background processes. 15886 // Unfortunately we need to start at the back of the list to do this 15887 // properly. We only do this if the number of background apps we 15888 // are managing to keep around is less than half the maximum we desire; 15889 // if we are keeping a good number around, we'll let them use whatever 15890 // memory they want. 15891 final int numCachedAndEmpty = numCached + numEmpty; 15892 int memFactor; 15893 if (numCached <= ProcessList.TRIM_CACHED_APPS 15894 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) { 15895 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) { 15896 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL; 15897 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) { 15898 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW; 15899 } else { 15900 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE; 15901 } 15902 } else { 15903 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL; 15904 } 15905 // We always allow the memory level to go up (better). We only allow it to go 15906 // down if we are in a state where that is allowed, *and* the total number of processes 15907 // has gone down since last time. 15908 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel 15909 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size() 15910 + " last=" + mLastNumProcesses); 15911 if (memFactor > mLastMemoryLevel) { 15912 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) { 15913 memFactor = mLastMemoryLevel; 15914 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!"); 15915 } 15916 } 15917 mLastMemoryLevel = memFactor; 15918 mLastNumProcesses = mLruProcesses.size(); 15919 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !mSleeping, now); 15920 final int trackerMemFactor = mProcessStats.getMemFactorLocked(); 15921 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) { 15922 if (mLowRamStartTime == 0) { 15923 mLowRamStartTime = now; 15924 } 15925 int step = 0; 15926 int fgTrimLevel; 15927 switch (memFactor) { 15928 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL: 15929 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL; 15930 break; 15931 case ProcessStats.ADJ_MEM_FACTOR_LOW: 15932 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW; 15933 break; 15934 default: 15935 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE; 15936 break; 15937 } 15938 int factor = numTrimming/3; 15939 int minFactor = 2; 15940 if (mHomeProcess != null) minFactor++; 15941 if (mPreviousProcess != null) minFactor++; 15942 if (factor < minFactor) factor = minFactor; 15943 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; 15944 for (int i=N-1; i>=0; i--) { 15945 ProcessRecord app = mLruProcesses.get(i); 15946 if (allChanged || app.procStateChanged) { 15947 setProcessTrackerState(app, trackerMemFactor, now); 15948 app.procStateChanged = false; 15949 } 15950 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME 15951 && !app.killedByAm) { 15952 if (app.trimMemoryLevel < curLevel && app.thread != null) { 15953 try { 15954 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15955 "Trimming memory of " + app.processName 15956 + " to " + curLevel); 15957 app.thread.scheduleTrimMemory(curLevel); 15958 } catch (RemoteException e) { 15959 } 15960 if (false) { 15961 // For now we won't do this; our memory trimming seems 15962 // to be good enough at this point that destroying 15963 // activities causes more harm than good. 15964 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE 15965 && app != mHomeProcess && app != mPreviousProcess) { 15966 // Need to do this on its own message because the stack may not 15967 // be in a consistent state at this point. 15968 // For these apps we will also finish their activities 15969 // to help them free memory. 15970 mStackSupervisor.scheduleDestroyAllActivities(app, "trim"); 15971 } 15972 } 15973 } 15974 app.trimMemoryLevel = curLevel; 15975 step++; 15976 if (step >= factor) { 15977 step = 0; 15978 switch (curLevel) { 15979 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE: 15980 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE; 15981 break; 15982 case ComponentCallbacks2.TRIM_MEMORY_MODERATE: 15983 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 15984 break; 15985 } 15986 } 15987 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 15988 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND 15989 && app.thread != null) { 15990 try { 15991 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 15992 "Trimming memory of heavy-weight " + app.processName 15993 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15994 app.thread.scheduleTrimMemory( 15995 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 15996 } catch (RemoteException e) { 15997 } 15998 } 15999 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; 16000 } else { 16001 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16002 || app.systemNoUi) && app.pendingUiClean) { 16003 // If this application is now in the background and it 16004 // had done UI, then give it the special trim level to 16005 // have it free UI resources. 16006 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; 16007 if (app.trimMemoryLevel < level && app.thread != null) { 16008 try { 16009 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16010 "Trimming memory of bg-ui " + app.processName 16011 + " to " + level); 16012 app.thread.scheduleTrimMemory(level); 16013 } catch (RemoteException e) { 16014 } 16015 } 16016 app.pendingUiClean = false; 16017 } 16018 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) { 16019 try { 16020 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16021 "Trimming memory of fg " + app.processName 16022 + " to " + fgTrimLevel); 16023 app.thread.scheduleTrimMemory(fgTrimLevel); 16024 } catch (RemoteException e) { 16025 } 16026 } 16027 app.trimMemoryLevel = fgTrimLevel; 16028 } 16029 } 16030 } else { 16031 if (mLowRamStartTime != 0) { 16032 mLowRamTimeSinceLastIdle += now - mLowRamStartTime; 16033 mLowRamStartTime = 0; 16034 } 16035 for (int i=N-1; i>=0; i--) { 16036 ProcessRecord app = mLruProcesses.get(i); 16037 if (allChanged || app.procStateChanged) { 16038 setProcessTrackerState(app, trackerMemFactor, now); 16039 app.procStateChanged = false; 16040 } 16041 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 16042 || app.systemNoUi) && app.pendingUiClean) { 16043 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN 16044 && app.thread != null) { 16045 try { 16046 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG, 16047 "Trimming memory of ui hidden " + app.processName 16048 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16049 app.thread.scheduleTrimMemory( 16050 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN); 16051 } catch (RemoteException e) { 16052 } 16053 } 16054 app.pendingUiClean = false; 16055 } 16056 app.trimMemoryLevel = 0; 16057 } 16058 } 16059 16060 if (mAlwaysFinishActivities) { 16061 // Need to do this on its own message because the stack may not 16062 // be in a consistent state at this point. 16063 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish"); 16064 } 16065 16066 if (allChanged) { 16067 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered()); 16068 } 16069 16070 if (mProcessStats.shouldWriteNowLocked(now)) { 16071 mHandler.post(new Runnable() { 16072 @Override public void run() { 16073 synchronized (ActivityManagerService.this) { 16074 mProcessStats.writeStateAsyncLocked(); 16075 } 16076 } 16077 }); 16078 } 16079 16080 if (DEBUG_OOM_ADJ) { 16081 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms"); 16082 } 16083 } 16084 16085 final void trimApplications() { 16086 synchronized (this) { 16087 int i; 16088 16089 // First remove any unused application processes whose package 16090 // has been removed. 16091 for (i=mRemovedProcesses.size()-1; i>=0; i--) { 16092 final ProcessRecord app = mRemovedProcesses.get(i); 16093 if (app.activities.size() == 0 16094 && app.curReceiver == null && app.services.size() == 0) { 16095 Slog.i( 16096 TAG, "Exiting empty application process " 16097 + app.processName + " (" 16098 + (app.thread != null ? app.thread.asBinder() : null) 16099 + ")\n"); 16100 if (app.pid > 0 && app.pid != MY_PID) { 16101 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid, 16102 app.processName, app.setAdj, "empty"); 16103 app.killedByAm = true; 16104 Process.killProcessQuiet(app.pid); 16105 } else { 16106 try { 16107 app.thread.scheduleExit(); 16108 } catch (Exception e) { 16109 // Ignore exceptions. 16110 } 16111 } 16112 cleanUpApplicationRecordLocked(app, false, true, -1); 16113 mRemovedProcesses.remove(i); 16114 16115 if (app.persistent) { 16116 if (app.persistent) { 16117 addAppLocked(app.info, false); 16118 } 16119 } 16120 } 16121 } 16122 16123 // Now update the oom adj for all processes. 16124 updateOomAdjLocked(); 16125 } 16126 } 16127 16128 /** This method sends the specified signal to each of the persistent apps */ 16129 public void signalPersistentProcesses(int sig) throws RemoteException { 16130 if (sig != Process.SIGNAL_USR1) { 16131 throw new SecurityException("Only SIGNAL_USR1 is allowed"); 16132 } 16133 16134 synchronized (this) { 16135 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES) 16136 != PackageManager.PERMISSION_GRANTED) { 16137 throw new SecurityException("Requires permission " 16138 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES); 16139 } 16140 16141 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 16142 ProcessRecord r = mLruProcesses.get(i); 16143 if (r.thread != null && r.persistent) { 16144 Process.sendSignal(r.pid, sig); 16145 } 16146 } 16147 } 16148 } 16149 16150 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) { 16151 if (proc == null || proc == mProfileProc) { 16152 proc = mProfileProc; 16153 path = mProfileFile; 16154 profileType = mProfileType; 16155 clearProfilerLocked(); 16156 } 16157 if (proc == null) { 16158 return; 16159 } 16160 try { 16161 proc.thread.profilerControl(false, path, null, profileType); 16162 } catch (RemoteException e) { 16163 throw new IllegalStateException("Process disappeared"); 16164 } 16165 } 16166 16167 private void clearProfilerLocked() { 16168 if (mProfileFd != null) { 16169 try { 16170 mProfileFd.close(); 16171 } catch (IOException e) { 16172 } 16173 } 16174 mProfileApp = null; 16175 mProfileProc = null; 16176 mProfileFile = null; 16177 mProfileType = 0; 16178 mAutoStopProfiler = false; 16179 } 16180 16181 public boolean profileControl(String process, int userId, boolean start, 16182 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException { 16183 16184 try { 16185 synchronized (this) { 16186 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16187 // its own permission. 16188 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16189 != PackageManager.PERMISSION_GRANTED) { 16190 throw new SecurityException("Requires permission " 16191 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16192 } 16193 16194 if (start && fd == null) { 16195 throw new IllegalArgumentException("null fd"); 16196 } 16197 16198 ProcessRecord proc = null; 16199 if (process != null) { 16200 proc = findProcessLocked(process, userId, "profileControl"); 16201 } 16202 16203 if (start && (proc == null || proc.thread == null)) { 16204 throw new IllegalArgumentException("Unknown process: " + process); 16205 } 16206 16207 if (start) { 16208 stopProfilerLocked(null, null, 0); 16209 setProfileApp(proc.info, proc.processName, path, fd, false); 16210 mProfileProc = proc; 16211 mProfileType = profileType; 16212 try { 16213 fd = fd.dup(); 16214 } catch (IOException e) { 16215 fd = null; 16216 } 16217 proc.thread.profilerControl(start, path, fd, profileType); 16218 fd = null; 16219 mProfileFd = null; 16220 } else { 16221 stopProfilerLocked(proc, path, profileType); 16222 if (fd != null) { 16223 try { 16224 fd.close(); 16225 } catch (IOException e) { 16226 } 16227 } 16228 } 16229 16230 return true; 16231 } 16232 } catch (RemoteException e) { 16233 throw new IllegalStateException("Process disappeared"); 16234 } finally { 16235 if (fd != null) { 16236 try { 16237 fd.close(); 16238 } catch (IOException e) { 16239 } 16240 } 16241 } 16242 } 16243 16244 private ProcessRecord findProcessLocked(String process, int userId, String callName) { 16245 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 16246 userId, true, true, callName, null); 16247 ProcessRecord proc = null; 16248 try { 16249 int pid = Integer.parseInt(process); 16250 synchronized (mPidsSelfLocked) { 16251 proc = mPidsSelfLocked.get(pid); 16252 } 16253 } catch (NumberFormatException e) { 16254 } 16255 16256 if (proc == null) { 16257 ArrayMap<String, SparseArray<ProcessRecord>> all 16258 = mProcessNames.getMap(); 16259 SparseArray<ProcessRecord> procs = all.get(process); 16260 if (procs != null && procs.size() > 0) { 16261 proc = procs.valueAt(0); 16262 if (userId != UserHandle.USER_ALL && proc.userId != userId) { 16263 for (int i=1; i<procs.size(); i++) { 16264 ProcessRecord thisProc = procs.valueAt(i); 16265 if (thisProc.userId == userId) { 16266 proc = thisProc; 16267 break; 16268 } 16269 } 16270 } 16271 } 16272 } 16273 16274 return proc; 16275 } 16276 16277 public boolean dumpHeap(String process, int userId, boolean managed, 16278 String path, ParcelFileDescriptor fd) throws RemoteException { 16279 16280 try { 16281 synchronized (this) { 16282 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to 16283 // its own permission (same as profileControl). 16284 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) 16285 != PackageManager.PERMISSION_GRANTED) { 16286 throw new SecurityException("Requires permission " 16287 + android.Manifest.permission.SET_ACTIVITY_WATCHER); 16288 } 16289 16290 if (fd == null) { 16291 throw new IllegalArgumentException("null fd"); 16292 } 16293 16294 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap"); 16295 if (proc == null || proc.thread == null) { 16296 throw new IllegalArgumentException("Unknown process: " + process); 16297 } 16298 16299 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0")); 16300 if (!isDebuggable) { 16301 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) { 16302 throw new SecurityException("Process not debuggable: " + proc); 16303 } 16304 } 16305 16306 proc.thread.dumpHeap(managed, path, fd); 16307 fd = null; 16308 return true; 16309 } 16310 } catch (RemoteException e) { 16311 throw new IllegalStateException("Process disappeared"); 16312 } finally { 16313 if (fd != null) { 16314 try { 16315 fd.close(); 16316 } catch (IOException e) { 16317 } 16318 } 16319 } 16320 } 16321 16322 /** In this method we try to acquire our lock to make sure that we have not deadlocked */ 16323 public void monitor() { 16324 synchronized (this) { } 16325 } 16326 16327 void onCoreSettingsChange(Bundle settings) { 16328 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 16329 ProcessRecord processRecord = mLruProcesses.get(i); 16330 try { 16331 if (processRecord.thread != null) { 16332 processRecord.thread.setCoreSettings(settings); 16333 } 16334 } catch (RemoteException re) { 16335 /* ignore */ 16336 } 16337 } 16338 } 16339 16340 // Multi-user methods 16341 16342 /** 16343 * Start user, if its not already running, but don't bring it to foreground. 16344 */ 16345 @Override 16346 public boolean startUserInBackground(final int userId) { 16347 return startUser(userId, /* foreground */ false); 16348 } 16349 16350 /** 16351 * Refreshes the list of users related to the current user when either a 16352 * user switch happens or when a new related user is started in the 16353 * background. 16354 */ 16355 private void updateCurrentProfileIdsLocked() { 16356 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16357 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null 16358 for (int i = 0; i < currentProfileIds.length; i++) { 16359 currentProfileIds[i] = profiles.get(i).id; 16360 } 16361 mCurrentProfileIds = currentProfileIds; 16362 } 16363 16364 private Set getProfileIdsLocked(int userId) { 16365 Set userIds = new HashSet<Integer>(); 16366 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(userId); 16367 for (UserInfo user : profiles) { 16368 userIds.add(Integer.valueOf(user.id)); 16369 } 16370 return userIds; 16371 } 16372 16373 @Override 16374 public boolean switchUser(final int userId) { 16375 return startUser(userId, /* foregound */ true); 16376 } 16377 16378 private boolean startUser(final int userId, boolean foreground) { 16379 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16380 != PackageManager.PERMISSION_GRANTED) { 16381 String msg = "Permission Denial: switchUser() from pid=" 16382 + Binder.getCallingPid() 16383 + ", uid=" + Binder.getCallingUid() 16384 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16385 Slog.w(TAG, msg); 16386 throw new SecurityException(msg); 16387 } 16388 16389 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground); 16390 16391 final long ident = Binder.clearCallingIdentity(); 16392 try { 16393 synchronized (this) { 16394 final int oldUserId = mCurrentUserId; 16395 if (oldUserId == userId) { 16396 return true; 16397 } 16398 16399 mStackSupervisor.setLockTaskModeLocked(null); 16400 16401 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId); 16402 if (userInfo == null) { 16403 Slog.w(TAG, "No user info for user #" + userId); 16404 return false; 16405 } 16406 16407 if (foreground) { 16408 mWindowManager.startFreezingScreen(R.anim.screen_user_exit, 16409 R.anim.screen_user_enter); 16410 } 16411 16412 boolean needStart = false; 16413 16414 // If the user we are switching to is not currently started, then 16415 // we need to start it now. 16416 if (mStartedUsers.get(userId) == null) { 16417 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false)); 16418 updateStartedUserArrayLocked(); 16419 needStart = true; 16420 } 16421 16422 final Integer userIdInt = Integer.valueOf(userId); 16423 mUserLru.remove(userIdInt); 16424 mUserLru.add(userIdInt); 16425 16426 if (foreground) { 16427 mCurrentUserId = userId; 16428 updateCurrentProfileIdsLocked(); 16429 mWindowManager.setCurrentUser(userId, mCurrentProfileIds); 16430 // Once the internal notion of the active user has switched, we lock the device 16431 // with the option to show the user switcher on the keyguard. 16432 mWindowManager.lockNow(null); 16433 } else { 16434 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId); 16435 updateCurrentProfileIdsLocked(); 16436 mWindowManager.setCurrentProfileIds(mCurrentProfileIds); 16437 mUserLru.remove(currentUserIdInt); 16438 mUserLru.add(currentUserIdInt); 16439 } 16440 16441 final UserStartedState uss = mStartedUsers.get(userId); 16442 16443 // Make sure user is in the started state. If it is currently 16444 // stopping, we need to knock that off. 16445 if (uss.mState == UserStartedState.STATE_STOPPING) { 16446 // If we are stopping, we haven't sent ACTION_SHUTDOWN, 16447 // so we can just fairly silently bring the user back from 16448 // the almost-dead. 16449 uss.mState = UserStartedState.STATE_RUNNING; 16450 updateStartedUserArrayLocked(); 16451 needStart = true; 16452 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) { 16453 // This means ACTION_SHUTDOWN has been sent, so we will 16454 // need to treat this as a new boot of the user. 16455 uss.mState = UserStartedState.STATE_BOOTING; 16456 updateStartedUserArrayLocked(); 16457 needStart = true; 16458 } 16459 16460 if (foreground) { 16461 mHandler.removeMessages(REPORT_USER_SWITCH_MSG); 16462 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16463 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG, 16464 oldUserId, userId, uss)); 16465 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG, 16466 oldUserId, userId, uss), USER_SWITCH_TIMEOUT); 16467 } 16468 16469 if (needStart) { 16470 Intent intent = new Intent(Intent.ACTION_USER_STARTED); 16471 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16472 | Intent.FLAG_RECEIVER_FOREGROUND); 16473 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16474 broadcastIntentLocked(null, null, intent, 16475 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16476 false, false, MY_PID, Process.SYSTEM_UID, userId); 16477 } 16478 16479 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) { 16480 if (userId != 0) { 16481 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE); 16482 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 16483 broadcastIntentLocked(null, null, intent, null, 16484 new IIntentReceiver.Stub() { 16485 public void performReceive(Intent intent, int resultCode, 16486 String data, Bundle extras, boolean ordered, 16487 boolean sticky, int sendingUser) { 16488 userInitialized(uss, userId); 16489 } 16490 }, 0, null, null, null, AppOpsManager.OP_NONE, 16491 true, false, MY_PID, Process.SYSTEM_UID, 16492 userId); 16493 uss.initializing = true; 16494 } else { 16495 getUserManagerLocked().makeInitialized(userInfo.id); 16496 } 16497 } 16498 16499 if (foreground) { 16500 boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss); 16501 if (homeInFront) { 16502 startHomeActivityLocked(userId); 16503 } else { 16504 mStackSupervisor.resumeTopActivitiesLocked(); 16505 } 16506 EventLogTags.writeAmSwitchUser(userId); 16507 getUserManagerLocked().userForeground(userId); 16508 sendUserSwitchBroadcastsLocked(oldUserId, userId); 16509 } 16510 16511 if (needStart) { 16512 Intent intent = new Intent(Intent.ACTION_USER_STARTING); 16513 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16514 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16515 broadcastIntentLocked(null, null, intent, 16516 null, new IIntentReceiver.Stub() { 16517 @Override 16518 public void performReceive(Intent intent, int resultCode, String data, 16519 Bundle extras, boolean ordered, boolean sticky, int sendingUser) 16520 throws RemoteException { 16521 } 16522 }, 0, null, null, 16523 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16524 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16525 } 16526 } 16527 } finally { 16528 Binder.restoreCallingIdentity(ident); 16529 } 16530 16531 return true; 16532 } 16533 16534 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) { 16535 long ident = Binder.clearCallingIdentity(); 16536 try { 16537 Intent intent; 16538 if (oldUserId >= 0) { 16539 intent = new Intent(Intent.ACTION_USER_BACKGROUND); 16540 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16541 | Intent.FLAG_RECEIVER_FOREGROUND); 16542 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId); 16543 broadcastIntentLocked(null, null, intent, 16544 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16545 false, false, MY_PID, Process.SYSTEM_UID, oldUserId); 16546 } 16547 if (newUserId >= 0) { 16548 intent = new Intent(Intent.ACTION_USER_FOREGROUND); 16549 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16550 | Intent.FLAG_RECEIVER_FOREGROUND); 16551 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16552 broadcastIntentLocked(null, null, intent, 16553 null, null, 0, null, null, null, AppOpsManager.OP_NONE, 16554 false, false, MY_PID, Process.SYSTEM_UID, newUserId); 16555 intent = new Intent(Intent.ACTION_USER_SWITCHED); 16556 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY 16557 | Intent.FLAG_RECEIVER_FOREGROUND); 16558 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId); 16559 broadcastIntentLocked(null, null, intent, 16560 null, null, 0, null, null, 16561 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE, 16562 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16563 } 16564 } finally { 16565 Binder.restoreCallingIdentity(ident); 16566 } 16567 } 16568 16569 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId, 16570 final int newUserId) { 16571 final int N = mUserSwitchObservers.beginBroadcast(); 16572 if (N > 0) { 16573 final IRemoteCallback callback = new IRemoteCallback.Stub() { 16574 int mCount = 0; 16575 @Override 16576 public void sendResult(Bundle data) throws RemoteException { 16577 synchronized (ActivityManagerService.this) { 16578 if (mCurUserSwitchCallback == this) { 16579 mCount++; 16580 if (mCount == N) { 16581 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16582 } 16583 } 16584 } 16585 } 16586 }; 16587 synchronized (this) { 16588 uss.switching = true; 16589 mCurUserSwitchCallback = callback; 16590 } 16591 for (int i=0; i<N; i++) { 16592 try { 16593 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching( 16594 newUserId, callback); 16595 } catch (RemoteException e) { 16596 } 16597 } 16598 } else { 16599 synchronized (this) { 16600 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16601 } 16602 } 16603 mUserSwitchObservers.finishBroadcast(); 16604 } 16605 16606 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16607 synchronized (this) { 16608 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId); 16609 sendContinueUserSwitchLocked(uss, oldUserId, newUserId); 16610 } 16611 } 16612 16613 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) { 16614 mCurUserSwitchCallback = null; 16615 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG); 16616 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG, 16617 oldUserId, newUserId, uss)); 16618 } 16619 16620 void userInitialized(UserStartedState uss, int newUserId) { 16621 completeSwitchAndInitalize(uss, newUserId, true, false); 16622 } 16623 16624 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) { 16625 completeSwitchAndInitalize(uss, newUserId, false, true); 16626 } 16627 16628 void completeSwitchAndInitalize(UserStartedState uss, int newUserId, 16629 boolean clearInitializing, boolean clearSwitching) { 16630 boolean unfrozen = false; 16631 synchronized (this) { 16632 if (clearInitializing) { 16633 uss.initializing = false; 16634 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier()); 16635 } 16636 if (clearSwitching) { 16637 uss.switching = false; 16638 } 16639 if (!uss.switching && !uss.initializing) { 16640 mWindowManager.stopFreezingScreen(); 16641 unfrozen = true; 16642 } 16643 } 16644 if (unfrozen) { 16645 final int N = mUserSwitchObservers.beginBroadcast(); 16646 for (int i=0; i<N; i++) { 16647 try { 16648 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId); 16649 } catch (RemoteException e) { 16650 } 16651 } 16652 mUserSwitchObservers.finishBroadcast(); 16653 } 16654 } 16655 16656 void scheduleStartProfilesLocked() { 16657 if (!mHandler.hasMessages(START_PROFILES_MSG)) { 16658 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG), 16659 DateUtils.SECOND_IN_MILLIS); 16660 } 16661 } 16662 16663 void startProfilesLocked() { 16664 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked"); 16665 List<UserInfo> profiles = getUserManagerLocked().getProfiles(mCurrentUserId); 16666 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size()); 16667 for (UserInfo user : profiles) { 16668 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED 16669 && user.id != mCurrentUserId) { 16670 toStart.add(user); 16671 } 16672 } 16673 final int n = toStart.size(); 16674 int i = 0; 16675 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) { 16676 startUserInBackground(toStart.get(i).id); 16677 } 16678 if (i < n) { 16679 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS"); 16680 } 16681 } 16682 16683 void finishUserSwitch(UserStartedState uss) { 16684 synchronized (this) { 16685 if (uss.mState == UserStartedState.STATE_BOOTING 16686 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) { 16687 uss.mState = UserStartedState.STATE_RUNNING; 16688 final int userId = uss.mHandle.getIdentifier(); 16689 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null); 16690 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16691 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT); 16692 broadcastIntentLocked(null, null, intent, 16693 null, null, 0, null, null, 16694 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE, 16695 true, false, MY_PID, Process.SYSTEM_UID, userId); 16696 } 16697 16698 startProfilesLocked(); 16699 16700 int num = mUserLru.size(); 16701 int i = 0; 16702 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) { 16703 Integer oldUserId = mUserLru.get(i); 16704 UserStartedState oldUss = mStartedUsers.get(oldUserId); 16705 if (oldUss == null) { 16706 // Shouldn't happen, but be sane if it does. 16707 mUserLru.remove(i); 16708 num--; 16709 continue; 16710 } 16711 if (oldUss.mState == UserStartedState.STATE_STOPPING 16712 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) { 16713 // This user is already stopping, doesn't count. 16714 num--; 16715 i++; 16716 continue; 16717 } 16718 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) { 16719 // Owner and current can't be stopped, but count as running. 16720 i++; 16721 continue; 16722 } 16723 // This is a user to be stopped. 16724 stopUserLocked(oldUserId, null); 16725 num--; 16726 i++; 16727 } 16728 } 16729 } 16730 16731 @Override 16732 public int stopUser(final int userId, final IStopUserCallback callback) { 16733 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16734 != PackageManager.PERMISSION_GRANTED) { 16735 String msg = "Permission Denial: switchUser() from pid=" 16736 + Binder.getCallingPid() 16737 + ", uid=" + Binder.getCallingUid() 16738 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16739 Slog.w(TAG, msg); 16740 throw new SecurityException(msg); 16741 } 16742 if (userId <= 0) { 16743 throw new IllegalArgumentException("Can't stop primary user " + userId); 16744 } 16745 synchronized (this) { 16746 return stopUserLocked(userId, callback); 16747 } 16748 } 16749 16750 private int stopUserLocked(final int userId, final IStopUserCallback callback) { 16751 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId); 16752 if (mCurrentUserId == userId) { 16753 return ActivityManager.USER_OP_IS_CURRENT; 16754 } 16755 16756 final UserStartedState uss = mStartedUsers.get(userId); 16757 if (uss == null) { 16758 // User is not started, nothing to do... but we do need to 16759 // callback if requested. 16760 if (callback != null) { 16761 mHandler.post(new Runnable() { 16762 @Override 16763 public void run() { 16764 try { 16765 callback.userStopped(userId); 16766 } catch (RemoteException e) { 16767 } 16768 } 16769 }); 16770 } 16771 return ActivityManager.USER_OP_SUCCESS; 16772 } 16773 16774 if (callback != null) { 16775 uss.mStopCallbacks.add(callback); 16776 } 16777 16778 if (uss.mState != UserStartedState.STATE_STOPPING 16779 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16780 uss.mState = UserStartedState.STATE_STOPPING; 16781 updateStartedUserArrayLocked(); 16782 16783 long ident = Binder.clearCallingIdentity(); 16784 try { 16785 // We are going to broadcast ACTION_USER_STOPPING and then 16786 // once that is done send a final ACTION_SHUTDOWN and then 16787 // stop the user. 16788 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING); 16789 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); 16790 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); 16791 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true); 16792 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN); 16793 // This is the result receiver for the final shutdown broadcast. 16794 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() { 16795 @Override 16796 public void performReceive(Intent intent, int resultCode, String data, 16797 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16798 finishUserStop(uss); 16799 } 16800 }; 16801 // This is the result receiver for the initial stopping broadcast. 16802 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() { 16803 @Override 16804 public void performReceive(Intent intent, int resultCode, String data, 16805 Bundle extras, boolean ordered, boolean sticky, int sendingUser) { 16806 // On to the next. 16807 synchronized (ActivityManagerService.this) { 16808 if (uss.mState != UserStartedState.STATE_STOPPING) { 16809 // Whoops, we are being started back up. Abort, abort! 16810 return; 16811 } 16812 uss.mState = UserStartedState.STATE_SHUTDOWN; 16813 } 16814 broadcastIntentLocked(null, null, shutdownIntent, 16815 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE, 16816 true, false, MY_PID, Process.SYSTEM_UID, userId); 16817 } 16818 }; 16819 // Kick things off. 16820 broadcastIntentLocked(null, null, stoppingIntent, 16821 null, stoppingReceiver, 0, null, null, 16822 android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE, 16823 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL); 16824 } finally { 16825 Binder.restoreCallingIdentity(ident); 16826 } 16827 } 16828 16829 return ActivityManager.USER_OP_SUCCESS; 16830 } 16831 16832 void finishUserStop(UserStartedState uss) { 16833 final int userId = uss.mHandle.getIdentifier(); 16834 boolean stopped; 16835 ArrayList<IStopUserCallback> callbacks; 16836 synchronized (this) { 16837 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks); 16838 if (mStartedUsers.get(userId) != uss) { 16839 stopped = false; 16840 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) { 16841 stopped = false; 16842 } else { 16843 stopped = true; 16844 // User can no longer run. 16845 mStartedUsers.remove(userId); 16846 mUserLru.remove(Integer.valueOf(userId)); 16847 updateStartedUserArrayLocked(); 16848 16849 // Clean up all state and processes associated with the user. 16850 // Kill all the processes for the user. 16851 forceStopUserLocked(userId, "finish user"); 16852 } 16853 } 16854 16855 for (int i=0; i<callbacks.size(); i++) { 16856 try { 16857 if (stopped) callbacks.get(i).userStopped(userId); 16858 else callbacks.get(i).userStopAborted(userId); 16859 } catch (RemoteException e) { 16860 } 16861 } 16862 16863 mStackSupervisor.removeUserLocked(userId); 16864 } 16865 16866 @Override 16867 public UserInfo getCurrentUser() { 16868 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16869 != PackageManager.PERMISSION_GRANTED) && ( 16870 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16871 != PackageManager.PERMISSION_GRANTED)) { 16872 String msg = "Permission Denial: getCurrentUser() from pid=" 16873 + Binder.getCallingPid() 16874 + ", uid=" + Binder.getCallingUid() 16875 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16876 Slog.w(TAG, msg); 16877 throw new SecurityException(msg); 16878 } 16879 synchronized (this) { 16880 return getUserManagerLocked().getUserInfo(mCurrentUserId); 16881 } 16882 } 16883 16884 int getCurrentUserIdLocked() { 16885 return mCurrentUserId; 16886 } 16887 16888 @Override 16889 public boolean isUserRunning(int userId, boolean orStopped) { 16890 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16891 != PackageManager.PERMISSION_GRANTED) { 16892 String msg = "Permission Denial: isUserRunning() from pid=" 16893 + Binder.getCallingPid() 16894 + ", uid=" + Binder.getCallingUid() 16895 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16896 Slog.w(TAG, msg); 16897 throw new SecurityException(msg); 16898 } 16899 synchronized (this) { 16900 return isUserRunningLocked(userId, orStopped); 16901 } 16902 } 16903 16904 boolean isUserRunningLocked(int userId, boolean orStopped) { 16905 UserStartedState state = mStartedUsers.get(userId); 16906 if (state == null) { 16907 return false; 16908 } 16909 if (orStopped) { 16910 return true; 16911 } 16912 return state.mState != UserStartedState.STATE_STOPPING 16913 && state.mState != UserStartedState.STATE_SHUTDOWN; 16914 } 16915 16916 @Override 16917 public int[] getRunningUserIds() { 16918 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 16919 != PackageManager.PERMISSION_GRANTED) { 16920 String msg = "Permission Denial: isUserRunning() from pid=" 16921 + Binder.getCallingPid() 16922 + ", uid=" + Binder.getCallingUid() 16923 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS; 16924 Slog.w(TAG, msg); 16925 throw new SecurityException(msg); 16926 } 16927 synchronized (this) { 16928 return mStartedUserArray; 16929 } 16930 } 16931 16932 private void updateStartedUserArrayLocked() { 16933 int num = 0; 16934 for (int i=0; i<mStartedUsers.size(); i++) { 16935 UserStartedState uss = mStartedUsers.valueAt(i); 16936 // This list does not include stopping users. 16937 if (uss.mState != UserStartedState.STATE_STOPPING 16938 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16939 num++; 16940 } 16941 } 16942 mStartedUserArray = new int[num]; 16943 num = 0; 16944 for (int i=0; i<mStartedUsers.size(); i++) { 16945 UserStartedState uss = mStartedUsers.valueAt(i); 16946 if (uss.mState != UserStartedState.STATE_STOPPING 16947 && uss.mState != UserStartedState.STATE_SHUTDOWN) { 16948 mStartedUserArray[num] = mStartedUsers.keyAt(i); 16949 num++; 16950 } 16951 } 16952 } 16953 16954 @Override 16955 public void registerUserSwitchObserver(IUserSwitchObserver observer) { 16956 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) 16957 != PackageManager.PERMISSION_GRANTED) { 16958 String msg = "Permission Denial: registerUserSwitchObserver() from pid=" 16959 + Binder.getCallingPid() 16960 + ", uid=" + Binder.getCallingUid() 16961 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; 16962 Slog.w(TAG, msg); 16963 throw new SecurityException(msg); 16964 } 16965 16966 mUserSwitchObservers.register(observer); 16967 } 16968 16969 @Override 16970 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) { 16971 mUserSwitchObservers.unregister(observer); 16972 } 16973 16974 private boolean userExists(int userId) { 16975 if (userId == 0) { 16976 return true; 16977 } 16978 UserManagerService ums = getUserManagerLocked(); 16979 return ums != null ? (ums.getUserInfo(userId) != null) : false; 16980 } 16981 16982 int[] getUsersLocked() { 16983 UserManagerService ums = getUserManagerLocked(); 16984 return ums != null ? ums.getUserIds() : new int[] { 0 }; 16985 } 16986 16987 UserManagerService getUserManagerLocked() { 16988 if (mUserManager == null) { 16989 IBinder b = ServiceManager.getService(Context.USER_SERVICE); 16990 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b); 16991 } 16992 return mUserManager; 16993 } 16994 16995 private int applyUserId(int uid, int userId) { 16996 return UserHandle.getUid(userId, uid); 16997 } 16998 16999 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) { 17000 if (info == null) return null; 17001 ApplicationInfo newInfo = new ApplicationInfo(info); 17002 newInfo.uid = applyUserId(info.uid, userId); 17003 newInfo.dataDir = USER_DATA_DIR + userId + "/" 17004 + info.packageName; 17005 return newInfo; 17006 } 17007 17008 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) { 17009 if (aInfo == null 17010 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) { 17011 return aInfo; 17012 } 17013 17014 ActivityInfo info = new ActivityInfo(aInfo); 17015 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); 17016 return info; 17017 } 17018 17019 private final class LocalService extends ActivityManagerInternal { 17020 @Override 17021 public void goingToSleep() { 17022 ActivityManagerService.this.goingToSleep(); 17023 } 17024 17025 @Override 17026 public void wakingUp() { 17027 ActivityManagerService.this.wakingUp(); 17028 } 17029 } 17030} 17031